diff options
286 files changed, 8590 insertions, 26759 deletions
diff --git a/.cirrus.yml b/.cirrus.yml index e114ffee1a..4860bebd32 100644 --- a/.cirrus.yml +++ b/.cirrus.yml @@ -9,7 +9,7 @@ freebsd_12_task: DEFAULT_TEST_TARGET: prove DEVELOPER: 1 freebsd_instance: - image_family: freebsd-12-2 + image_family: freebsd-12-3 memory: 2G install_script: pkg install -y gettext gmake perl5 diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index c35200defb..3fa88b78b6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -119,10 +119,6 @@ jobs: - name: test shell: bash run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 - - name: ci/print-test-failures.sh - if: failure() - shell: bash - run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v2 @@ -204,10 +200,6 @@ jobs: env: NO_SVN_TESTS: 1 run: . /etc/profile && ci/run-test-slice.sh ${{matrix.nr}} 10 - - name: ci/print-test-failures.sh - if: failure() - shell: bash - run: ci/print-test-failures.sh - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v2 @@ -261,8 +253,6 @@ jobs: - uses: actions/checkout@v2 - run: ci/install-dependencies.sh - run: ci/run-build-and-tests.sh - - run: ci/print-test-failures.sh - if: failure() - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v2 @@ -292,8 +282,6 @@ jobs: - uses: actions/checkout@v1 - run: ci/install-docker-dependencies.sh - run: ci/run-build-and-tests.sh - - run: ci/print-test-failures.sh - if: failure() - name: Upload failed tests' directories if: failure() && env.FAILED_TEST_ARTIFACTS != '' uses: actions/upload-artifact@v1 diff --git a/.gitignore b/.gitignore index e81de1063a..a452215764 100644 --- a/.gitignore +++ b/.gitignore @@ -200,6 +200,7 @@ *.[aos] *.o.json *.py[co] +.build/ .depend/ *.gcda *.gcno diff --git a/Documentation/Makefile b/Documentation/Makefile index d3f043f50d..f2e7fc1daa 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -95,6 +95,7 @@ TECH_DOCS += MyFirstObjectWalk TECH_DOCS += SubmittingPatches TECH_DOCS += ToolsForGit TECH_DOCS += technical/bundle-format +TECH_DOCS += technical/cruft-packs TECH_DOCS += technical/hash-function-transition TECH_DOCS += technical/http-protocol TECH_DOCS += technical/index-format diff --git a/Documentation/RelNotes/2.36.2.txt b/Documentation/RelNotes/2.36.2.txt new file mode 100644 index 0000000000..ba5d5acd07 --- /dev/null +++ b/Documentation/RelNotes/2.36.2.txt @@ -0,0 +1,50 @@ +Git v2.36.2 Release Notes +========================= + +This maintenance release is primarily to merge down updates to the +build and CI procedures from the 'master' front, in order to ensure +that we can cut healthy maintenance releases in the future. It also +contains a handful of small and trivially-correct bugfixes. + +Fixes since v2.36.1 +------------------- + + * Fixes real problems noticed by gcc 12 and works around false + positives. + + * Update URL to the gitk repository. + + * The "--current" option of "git show-branch" should have been made + incompatible with the "--reflog" mode, but this was not enforced, + which has been corrected. + + * "git archive --add-file=<path>" picked up the raw permission bits + from the path and propagated to zip output in some cases, without + normalization, which has been corrected (tar output did not have + this issue). + + * A bit of test framework fixes with a few fixes to issues found by + valgrind. + + * macOS CI jobs have been occasionally flaky due to tentative version + skew between perforce and the homebrew packager. Instead of + failing the whole CI job, just let it skip the p4 tests when this + happens. + + * The commit summary shown after making a commit is matched to what + is given in "git status" not to use the break-rewrite heuristics. + + * Avoid problems from interaction between malloc_check and address + sanitizer. + + * "git rebase --keep-base <upstream> <branch-to-rebase>" computed the + commit to rebase onto incorrectly, which has been corrected. + + * The path taken by "git multi-pack-index" command from the end user + was compared with path internally prepared by the tool withut first + normalizing, which lead to duplicated paths not being noticed, + which has been corrected. + + * "git clone --origin X" leaked piece of memory that held value read + from the clone.defaultRemoteName configuration variable, which has + been plugged. diff --git a/Documentation/RelNotes/2.37.0.txt b/Documentation/RelNotes/2.37.0.txt index a619b5f79c..3ceb73fd09 100644 --- a/Documentation/RelNotes/2.37.0.txt +++ b/Documentation/RelNotes/2.37.0.txt @@ -38,6 +38,22 @@ UI, Workflows & Features testing; the reimplementation is now exposed to general public by default. + * Deprecate non-cone mode of the sparse-checkout feature. + + * Introduce a filesystem-dependent mechanism to optimize the way the + bits for many loose object files are ensured to hit the disk + platter. + + * The "do not remove the directory the user started Git in" logic, + when Git cannot tell where that directory is, is disabled. Earlier + we refused to run in such a case. + + * A mechanism to pack unreachable objects into a "cruft pack", + instead of ejecting them into loose form to be reclaimed later, has + been introduced. + + * Update the doctype written in gitweb output to xhtml5. + Performance, Internal Implementation, Development Support etc. @@ -54,6 +70,25 @@ Performance, Internal Implementation, Development Support etc. comparison between a pointer and NULL, and applies the clean-up to the maintenance track. + * Preliminary code refactoring around transport and bundle code. + + * "sparse-checkout" learns to work better with the sparse-index + feature. + + * A workflow change for translators are being proposed. git.pot is + no longer version controlled and it is local responsibility of + translaters to generate it. + + * Plug the memory leaks from the trickiest API of all, the revision + walker. + + * Rename .env_array member to .env in the child_process structure. + + * More fsmonitor--daemon. + + * A new bug() and BUG_if_bug() API is introduced to make it easier to + uniformly log "detect multiple bugs and abort in the end" pattern. + Fixes since v2.36 ----------------- @@ -196,6 +231,37 @@ Fixes since v2.36 * Some real problems noticed by gcc 12 have been fixed, while false positives have been worked around. + * Update the version of FreeBSD image used in Cirrus CI. + (merge c58bebd4c6 pb/use-freebsd-12.3-in-cirrus-ci later to maint). + + * The multi-pack-index code did not protect the packfile it is going + to depend on from getting removed while in use, which has been + corrected. + (merge 4090511e40 tb/midx-race-in-pack-objects later to maint). + + * Teach "git repack --geometric" work better with "--keep-pack" and + avoid corrupting the repository when packsize limit is used. + (merge 66731ff921 tb/geom-repack-with-keep-and-max later to maint). + + * The documentation on the interaction between "--add-file" and + "--prefix" options of "git archive" has been improved. + (merge a75910602a rs/document-archive-prefix later to maint). + + * A git subcommand like "git add -p" spawns a separate git process + while relaying its command line arguments. A pathspec with only + negative elements was mistakenly passed with an empty string, which + has been corrected. + (merge b02fdbc80a jc/all-negative-pathspec later to maint). + + * With a more targetted workaround in http.c in another topic, we may + be able to lift this blanket "GCC12 dangling-pointer warning is + broken and unsalvageable" workaround. + (merge 419141e495 cb/buggy-gcc-12-workaround later to maint). + + * A misconfigured 'branch..remote' led to a bug in configuration + parsing. + (merge f1dfbd9ee0 gc/zero-length-branch-config-fix later to maint). + * Other code cleanup, docfix, build fix, etc. (merge e6b2582da3 cm/reftable-0-length-memset later to maint). (merge 0b75e5bf22 ab/misc-cleanup later to maint). @@ -216,3 +282,4 @@ Fixes since v2.36 (merge af845a604d tb/receive-pack-code-cleanup later to maint). (merge 2acf4cf001 js/ci-gcc-12-fixes later to maint). (merge 05e280c0a6 jc/http-clear-finished-pointer later to maint). + (merge 8c49d704ef fh/transport-push-leakfix later to maint). diff --git a/Documentation/config/core.txt b/Documentation/config/core.txt index e67392cc83..41e330f306 100644 --- a/Documentation/config/core.txt +++ b/Documentation/config/core.txt @@ -628,6 +628,14 @@ core.fsyncMethod:: * `writeout-only` issues pagecache writeback requests, but depending on the filesystem and storage hardware, data added to the repository may not be durable in the event of a system crash. This is the default mode on macOS. +* `batch` enables a mode that uses writeout-only flushes to stage multiple + updates in the disk writeback cache and then does a single full fsync of + a dummy file to trigger the disk cache flush at the end of the operation. ++ +Currently `batch` mode only applies to loose-object files. Other repository +data is made durable as if `fsync` was specified. This mode is expected to +be as safe as `fsync` on macOS for repos stored on HFS+ or APFS filesystems +and on Windows for repos stored on NTFS or ReFS filesystems. core.fsyncObjectFiles:: This boolean will enable 'fsync()' when writing object files. @@ -698,8 +706,10 @@ core.sparseCheckout:: core.sparseCheckoutCone:: Enables the "cone mode" of the sparse checkout feature. When the - sparse-checkout file contains a limited set of patterns, then this - mode provides significant performance advantages. See + sparse-checkout file contains a limited set of patterns, this + mode provides significant performance advantages. The "non + cone mode" can be requested to allow specifying a more flexible + patterns by setting this variable to 'false'. See linkgit:git-sparse-checkout[1] for more information. core.abbrev:: diff --git a/Documentation/config/gc.txt b/Documentation/config/gc.txt index c834e07991..38fea076a2 100644 --- a/Documentation/config/gc.txt +++ b/Documentation/config/gc.txt @@ -81,14 +81,21 @@ gc.packRefs:: to enable it within all non-bare repos or it can be set to a boolean value. The default is `true`. +gc.cruftPacks:: + Store unreachable objects in a cruft pack (see + linkgit:git-repack[1]) instead of as loose objects. The default + is `false`. + gc.pruneExpire:: - When 'git gc' is run, it will call 'prune --expire 2.weeks.ago'. - Override the grace period with this config variable. The value - "now" may be used to disable this grace period and always prune - unreachable objects immediately, or "never" may be used to - suppress pruning. This feature helps prevent corruption when - 'git gc' runs concurrently with another process writing to the - repository; see the "NOTES" section of linkgit:git-gc[1]. + When 'git gc' is run, it will call 'prune --expire 2.weeks.ago' + (and 'repack --cruft --cruft-expiration 2.weeks.ago' if using + cruft packs via `gc.cruftPacks` or `--cruft`). Override the + grace period with this config variable. The value "now" may be + used to disable this grace period and always prune unreachable + objects immediately, or "never" may be used to suppress pruning. + This feature helps prevent corruption when 'git gc' runs + concurrently with another process writing to the repository; see + the "NOTES" section of linkgit:git-gc[1]. gc.worktreePruneExpire:: When 'git gc' is run, it calls diff --git a/Documentation/config/repack.txt b/Documentation/config/repack.txt index 41ac6953c8..c79af6d7b8 100644 --- a/Documentation/config/repack.txt +++ b/Documentation/config/repack.txt @@ -30,3 +30,12 @@ repack.updateServerInfo:: If set to false, linkgit:git-repack[1] will not run linkgit:git-update-server-info[1]. Defaults to true. Can be overridden when true by the `-n` option of linkgit:git-repack[1]. + +repack.cruftWindow:: +repack.cruftWindowMemory:: +repack.cruftDepth:: +repack.cruftThreads:: + Parameters used by linkgit:git-pack-objects[1] when generating + a cruft pack and the respective parameters are not given over + the command line. See similarly named `pack.*` configuration + variables for defaults and meaning. diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index bc4e76a783..56989a2f34 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -49,7 +49,9 @@ OPTIONS Report progress to stderr. --prefix=<prefix>/:: - Prepend <prefix>/ to each filename in the archive. + Prepend <prefix>/ to paths in the archive. Can be repeated; its + rightmost value is used for all tracked files. See below which + value gets used by `--add-file` and `--add-virtual-file`. -o <file>:: --output=<file>:: @@ -57,9 +59,26 @@ OPTIONS --add-file=<file>:: Add a non-tracked file to the archive. Can be repeated to add + multiple files. The path of the file in the archive is built by + concatenating the value of the last `--prefix` option (if any) + before this `--add-file` and the basename of <file>. + +--add-virtual-file=<path>:<content>:: + Add the specified contents to the archive. Can be repeated to add multiple files. The path of the file in the archive is built - by concatenating the value for `--prefix` (if any) and the - basename of <file>. + by concatenating the value of the last `--prefix` option (if any) + before this `--add-virtual-file` and `<path>`. ++ +The `<path>` argument can start and end with a literal double-quote +character; the contained file name is interpreted as a C-style string, +i.e. the backslash is interpreted as escape character. The path must +be quoted if it contains a colon, to avoid the colon from being +misinterpreted as the separator between the path and the contents, or +if the path begins or ends with a double-quote character. ++ +The file mode is limited to a regular file, and the option may be +subject to platform-dependent command-line limits. For non-trivial +cases, write an untracked file and use `--add-file` instead. --worktree-attributes:: Look for attributes in .gitattributes files in the working tree @@ -194,6 +213,12 @@ EXAMPLES commit on the current branch. Note that the output format is inferred by the extension of the output file. +`git archive -o latest.tar --prefix=build/ --add-file=configure --prefix= HEAD`:: + + Creates a tar archive that contains the contents of the latest + commit on the current branch with no prefix and the untracked + file 'configure' with the prefix 'build/'. + `git config tar.tar.xz.command "xz -c"`:: Configure a "tar.xz" format for making LZMA-compressed tarfiles. diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index 853967dea0..ba4e67700e 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -54,6 +54,11 @@ other housekeeping tasks (e.g. rerere, working trees, reflog...) will be performed as well. +--cruft:: + When expiring unreachable objects, pack them separately into a + cruft pack instead of storing the loose objects as loose + objects. + --prune=<date>:: Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable `gc.pruneExpire`). diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index f8344e1e5b..a9995a932c 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -13,6 +13,7 @@ SYNOPSIS [--no-reuse-delta] [--delta-base-offset] [--non-empty] [--local] [--incremental] [--window=<n>] [--depth=<n>] [--revs [--unpacked | --all]] [--keep-pack=<pack-name>] + [--cruft] [--cruft-expiration=<time>] [--stdout [--filter=<filter-spec>] | <base-name>] [--shallow] [--keep-true-parents] [--[no-]sparse] < <object-list> @@ -95,6 +96,35 @@ base-name:: Incompatible with `--revs`, or options that imply `--revs` (such as `--all`), with the exception of `--unpacked`, which is compatible. +--cruft:: + Packs unreachable objects into a separate "cruft" pack, denoted + by the existence of a `.mtimes` file. Typically used by `git + repack --cruft`. Callers provide a list of pack names and + indicate which packs will remain in the repository, along with + which packs will be deleted (indicated by the `-` prefix). The + contents of the cruft pack are all objects not contained in the + surviving packs which have not exceeded the grace period (see + `--cruft-expiration` below), or which have exceeded the grace + period, but are reachable from an other object which hasn't. ++ +When the input lists a pack containing all reachable objects (and lists +all other packs as pending deletion), the corresponding cruft pack will +contain all unreachable objects (with mtime newer than the +`--cruft-expiration`) along with any unreachable objects whose mtime is +older than the `--cruft-expiration`, but are reachable from an +unreachable object whose mtime is newer than the `--cruft-expiration`). ++ +Incompatible with `--unpack-unreachable`, `--keep-unreachable`, +`--pack-loose-unreachable`, `--stdin-packs`, as well as any other +options which imply `--revs`. Also incompatible with `--max-pack-size`; +when this option is set, the maximum pack size is not inferred from +`pack.packSizeLimit`. + +--cruft-expiration=<approxidate>:: + If specified, objects are eliminated from the cruft pack if they + have an mtime older than `<approxidate>`. If unspecified (and + given `--cruft`), then no objects are eliminated. + --window=<n>:: --depth=<n>:: These two options affect how the objects contained in diff --git a/Documentation/git-read-tree.txt b/Documentation/git-read-tree.txt index a5356a230b..b9bfdc0a31 100644 --- a/Documentation/git-read-tree.txt +++ b/Documentation/git-read-tree.txt @@ -375,10 +375,13 @@ have finished your work-in-progress), attempt the merge again. SPARSE CHECKOUT --------------- -Note: The `update-index` and `read-tree` primitives for supporting the -skip-worktree bit predated the introduction of -linkgit:git-sparse-checkout[1]. Users are encouraged to use -`sparse-checkout` in preference to these low-level primitives. +Note: The skip-worktree capabilities in linkgit:git-update-index[1] +and `read-tree` predated the introduction of +linkgit:git-sparse-checkout[1]. Users are encouraged to use the +`sparse-checkout` command in preference to these plumbing commands for +sparse-checkout/skip-worktree related needs. However, the information +below might be useful to users trying to understand the pattern style +used in non-cone mode of the `sparse-checkout` command. "Sparse checkout" allows populating the working directory sparsely. It uses the skip-worktree bit (see linkgit:git-update-index[1]) to diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index ee30edc178..0bf13893d8 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -63,6 +63,17 @@ to the new separate pack will be written. Also run 'git prune-packed' to remove redundant loose object files. +--cruft:: + Same as `-a`, unless `-d` is used. Then any unreachable objects + are packed into a separate cruft pack. Unreachable objects can + be pruned using the normal expiry rules with the next `git gc` + invocation (see linkgit:git-gc[1]). Incompatible with `-k`. + +--cruft-expiration=<approxidate>:: + Expire unreachable objects older than `<approxidate>` + immediately instead of waiting for the next `git gc` invocation. + Only useful with `--cruft -d`. + -l:: Pass the `--local` option to 'git pack-objects'. See linkgit:git-pack-objects[1]. diff --git a/Documentation/git-sparse-checkout.txt b/Documentation/git-sparse-checkout.txt index 88e55f432f..3776705bf5 100644 --- a/Documentation/git-sparse-checkout.txt +++ b/Documentation/git-sparse-checkout.txt @@ -15,15 +15,15 @@ SYNOPSIS DESCRIPTION ----------- -This command is used to create sparse checkouts, which means that it -changes the working tree from having all tracked files present, to only -have a subset of them. It can also switch which subset of files are -present, or undo and go back to having all tracked files present in the -working copy. +This command is used to create sparse checkouts, which change the +working tree from having all tracked files present to only having a +subset of those files. It can also switch which subset of files are +present, or undo and go back to having all tracked files present in +the working copy. The subset of files is chosen by providing a list of directories in -cone mode (which is recommended), or by providing a list of patterns -in non-cone mode. +cone mode (the default), or by providing a list of patterns in +non-cone mode. When in a sparse-checkout, other Git commands behave a bit differently. For example, switching branches will not update paths outside the @@ -44,9 +44,9 @@ COMMANDS Enable the necessary sparse-checkout config settings (`core.sparseCheckout`, `core.sparseCheckoutCone`, and `index.sparse`) if they are not already set to the desired values, - and write a set of patterns to the sparse-checkout file from the - list of arguments following the 'set' subcommand. Update the - working directory to match the new patterns. + populate the sparse-checkout file from the list of arguments + following the 'set' subcommand, and update the working directory to + match. + To ensure that adjusting the sparse-checkout settings within a worktree does not alter the sparse-checkout settings in other worktrees, the 'set' @@ -60,22 +60,20 @@ When the `--stdin` option is provided, the directories or patterns are read from standard in as a newline-delimited list instead of from the arguments. + -When `--cone` is passed or `core.sparseCheckoutCone` is enabled, the -input list is considered a list of directories. This allows for -better performance with a limited set of patterns (see 'CONE PATTERN -SET' below). The input format matches the output of `git ls-tree ---name-only`. This includes interpreting pathnames that begin with a -double quote (") as C-style quoted strings. Note that the set command -will write patterns to the sparse-checkout file to include all files -contained in those directories (recursively) as well as files that are -siblings of ancestor directories. This may become the default in the -future; --no-cone can be passed to request non-cone mode. +By default, the input list is considered a list of directories, matching +the output of `git ls-tree -d --name-only`. This includes interpreting +pathnames that begin with a double quote (") as C-style quoted strings. +Note that all files under the specified directories (at any depth) will +be included in the sparse checkout, as well as files that are siblings +of either the given directory or any of its ancestors (see 'CONE PATTERN +SET' below for more details). In the past, this was not the default, +and `--cone` needed to be specified or `core.sparseCheckoutCone` needed +to be enabled. + -When `--no-cone` is passed or `core.sparseCheckoutCone` is not enabled, -the input list is considered a list of patterns. This mode is harder -to use and less performant, and is thus not recommended. See the -"Sparse Checkout" section of linkgit:git-read-tree[1] and the "Pattern -Set" sections below for more details. +When `--no-cone` is passed, the input list is considered a list of +patterns. This mode has a number of drawbacks, including not working +with some options like `--sparse-index`. As explained in the +"Non-cone Problems" section below, we do not recommend using it. + Use the `--[no-]sparse-index` option to use a sparse index (the default is to not use it). A sparse index reduces the size of the @@ -137,8 +135,45 @@ paths to pass to a subsequent 'set' or 'add' command. However, the disable command, so the easy restore of calling a plain `init` decreased in utility. -SPARSE CHECKOUT ---------------- +EXAMPLES +-------- +`git sparse-checkout set MY/DIR1 SUB/DIR2`:: + + Change to a sparse checkout with all files (at any depth) under + MY/DIR1/ and SUB/DIR2/ present in the working copy (plus all + files immediately under MY/ and SUB/ and the toplevel + directory). If already in a sparse checkout, change which files + are present in the working copy to this new selection. Note + that this command will also delete all ignored files in any + directory that no longer has either tracked or + non-ignored-untracked files present. + +`git sparse-checkout disable`:: + + Repopulate the working directory with all files, disabling sparse + checkouts. + +`git sparse-checkout add SOME/DIR/ECTORY`:: + + Add all files under SOME/DIR/ECTORY/ (at any depth) to the + sparse checkout, as well as all files immediately under + SOME/DIR/ and immediately under SOME/. Must already be in a + sparse checkout before using this command. + +`git sparse-checkout reapply`:: + + It is possible for commands to update the working tree in a + way that does not respect the selected sparsity directories. + This can come from tools external to Git writing files, or + even affect Git commands because of either special cases (such + as hitting conflicts when merging/rebasing), or because some + commands didn't fully support sparse checkouts (e.g. the old + `recursive` merge backend had only limited support). This + command reapplies the existing sparse directory specifications + to make the working directory match. + +INTERNALS -- SPARSE CHECKOUT +---------------------------- "Sparse checkout" allows populating the working directory sparsely. It uses the skip-worktree bit (see linkgit:git-update-index[1]) to tell Git @@ -155,64 +190,196 @@ directory, it updates the skip-worktree bits in the index based on this file. The files matching the patterns in the file will appear in the working directory, and the rest will not. -To enable the sparse-checkout feature, run `git sparse-checkout set` to -set the patterns you want to use. +INTERNALS -- NON-CONE PROBLEMS +------------------------------ + +The `$GIT_DIR/info/sparse-checkout` file populated by the `set` and +`add` subcommands is defined to be a bunch of patterns (one per line) +using the same syntax as `.gitignore` files. In cone mode, these +patterns are restricted to matching directories (and users only ever +need supply or see directory names), while in non-cone mode any +gitignore-style pattern is permitted. Using the full gitignore-style +patterns in non-cone mode has a number of shortcomings: + + * Fundamentally, it makes various worktree-updating processes (pull, + merge, rebase, switch, reset, checkout, etc.) require O(N*M) pattern + matches, where N is the number of patterns and M is the number of + paths in the index. This scales poorly. + + * Avoiding the scaling issue has to be done via limiting the number + of patterns via specifying leading directory name or glob. + + * Passing globs on the command line is error-prone as users may + forget to quote the glob, causing the shell to expand it into all + matching files and pass them all individually along to + sparse-checkout set/add. While this could also be a problem with + e.g. "git grep -- *.c", mistakes with grep/log/status appear in + the immediate output. With sparse-checkout, the mistake gets + recorded at the time the sparse-checkout command is run and might + not be problematic until the user later switches branches or rebases + or merges, thus putting a delay between the user's error and when + they have a chance to catch/notice it. + + * Related to the previous item, sparse-checkout has an 'add' + subcommand but no 'remove' subcommand. Even if a 'remove' + subcommand were added, undoing an accidental unquoted glob runs + the risk of "removing too much", as it may remove entries that had + been included before the accidental add. + + * Non-cone mode uses gitignore-style patterns to select what to + *include* (with the exception of negated patterns), while + .gitignore files use gitignore-style patterns to select what to + *exclude* (with the exception of negated patterns). The + documentation on gitignore-style patterns usually does not talk in + terms of matching or non-matching, but on what the user wants to + "exclude". This can cause confusion for users trying to learn how + to specify sparse-checkout patterns to get their desired behavior. + + * Every other git subcommand that wants to provide "special path + pattern matching" of some sort uses pathspecs, but non-cone mode + for sparse-checkout uses gitignore patterns, which feels + inconsistent. + + * It has edge cases where the "right" behavior is unclear. Two examples: + + First, two users are in a subdirectory, and the first runs + git sparse-checkout set '/toplevel-dir/*.c' + while the second runs + git sparse-checkout set relative-dir + Should those arguments be transliterated into + current/subdirectory/toplevel-dir/*.c + and + current/subdirectory/relative-dir + before inserting into the sparse-checkout file? The user who typed + the first command is probably aware that arguments to set/add are + supposed to be patterns in non-cone mode, and probably would not be + happy with such a transliteration. However, many gitignore-style + patterns are just paths, which might be what the user who typed the + second command was thinking, and they'd be upset if their argument + wasn't transliterated. + + Second, what should bash-completion complete on for set/add commands + for non-cone users? If it suggests paths, is it exacerbating the + problem above? Also, if it suggests paths, what if the user has a + file or directory that begins with either a '!' or '#' or has a '*', + '\', '?', '[', or ']' in its name? And if it suggests paths, will + it complete "/pro" to "/proc" (in the root filesytem) rather than to + "/progress.txt" in the current directory? (Note that users are + likely to want to start paths with a leading '/' in non-cone mode, + for the same reason that .gitignore files often have one.) + Completing on files or directories might give nasty surprises in + all these cases. + + * The excessive flexibility made other extensions essentially + impractical. `--sparse-index` is likely impossible in non-cone + mode; even if it is somehow feasible, it would have been far more + work to implement and may have been too slow in practice. Some + ideas for adding coupling between partial clones and sparse + checkouts are only practical with a more restricted set of paths + as well. + +For all these reasons, non-cone mode is deprecated. Please switch to +using cone mode. + + +INTERNALS -- CONE MODE HANDLING +------------------------------- + +The "cone mode", which is the default, lets you specify only what +directories to include. For any directory specified, all paths below +that directory will be included, and any paths immediately under +leading directories (including the toplevel directory) will also be +included. Thus, if you specified the directory + Documentation/technical/ +then your sparse checkout would contain: + + * all files in the toplevel-directory + * all files immediately under Documentation/ + * all files at any depth under Documentation/technical/ + +Also, in cone mode, even if no directories are specified, then the +files in the toplevel directory will be included. -To repopulate the working directory with all files, use the -`git sparse-checkout disable` command. +When changing the sparse-checkout patterns in cone mode, Git will inspect each +tracked directory that is not within the sparse-checkout cone to see if it +contains any untracked files. If all of those files are ignored due to the +`.gitignore` patterns, then the directory will be deleted. If any of the +untracked files within that directory is not ignored, then no deletions will +occur within that directory and a warning message will appear. If these files +are important, then reset your sparse-checkout definition so they are included, +use `git add` and `git commit` to store them, then remove any remaining files +manually to ensure Git can behave optimally. +See also the "Internals -- Cone Pattern Set" section to learn how the +directories are transformed under the hood into a subset of the +Full Pattern Set of sparse-checkout. -FULL PATTERN SET ----------------- -By default, the sparse-checkout file uses the same syntax as `.gitignore` -files. +INTERNALS -- FULL PATTERN SET +----------------------------- -While `$GIT_DIR/info/sparse-checkout` is usually used to specify what -files are included, you can also specify what files are _not_ included, -using negative patterns. For example, to remove the file `unwanted`: +The full pattern set allows for arbitrary pattern matches and complicated +inclusion/exclusion rules. These can result in O(N*M) pattern matches when +updating the index, where N is the number of patterns and M is the number +of paths in the index. To combat this performance issue, a more restricted +pattern set is allowed when `core.sparseCheckoutCone` is enabled. + +The sparse-checkout file uses the same syntax as `.gitignore` files; +see linkgit:gitignore[5] for details. Here, though, the patterns are +usually being used to select which files to include rather than which +files to exclude. (However, it can get a bit confusing since +gitignore-style patterns have negations defined by patterns which +begin with a '!', so you can also select files to _not_ include.) + +For example, to select everything, and then to remove the file +`unwanted` (so that every file will appear in your working tree except +the file named `unwanted`): + + git sparse-checkout set --no-cone '/*' '!unwanted' + +These patterns are just placed into the +`$GIT_DIR/info/sparse-checkout` as-is, so the contents of that file +at this point would be ---------------- /* !unwanted ---------------- +See also the "Sparse Checkout" section of linkgit:git-read-tree[1] to +learn more about the gitignore-style patterns used in sparse +checkouts. -CONE PATTERN SET ----------------- -The full pattern set allows for arbitrary pattern matches and complicated -inclusion/exclusion rules. These can result in O(N*M) pattern matches when -updating the index, where N is the number of patterns and M is the number -of paths in the index. To combat this performance issue, a more restricted -pattern set is allowed when `core.sparseCheckoutCone` is enabled. +INTERNALS -- CONE PATTERN SET +----------------------------- -The accepted patterns in the cone pattern set are: +In cone mode, only directories are accepted, but they are translated into +the same gitignore-style patterns used in the full pattern set. We refer +to the particular patterns used in those mode as being of one of two types: 1. *Recursive:* All paths inside a directory are included. 2. *Parent:* All files immediately inside a directory are included. -In addition to the above two patterns, we also expect that all files in the -root directory are included. If a recursive pattern is added, then all -leading directories are added as parent patterns. - -By default, when running `git sparse-checkout init`, the root directory is -added as a parent pattern. At this point, the sparse-checkout file contains -the following patterns: +Since cone mode always includes files at the toplevel, when running +`git sparse-checkout set` with no directories specified, the toplevel +directory is added as a parent pattern. At this point, the +sparse-checkout file contains the following patterns: ---------------- /* !/*/ ---------------- -This says "include everything in root, but nothing two levels below root." +This says "include everything immediately under the toplevel +directory, but nothing at any level below that." -When in cone mode, the `git sparse-checkout set` subcommand takes a list of -directories instead of a list of sparse-checkout patterns. In this mode, -the command `git sparse-checkout set A/B/C` sets the directory `A/B/C` as -a recursive pattern, the directories `A` and `A/B` are added as parent -patterns. The resulting sparse-checkout file is now +When in cone mode, the `git sparse-checkout set` subcommand takes a +list of directories. The command `git sparse-checkout set A/B/C` sets +the directory `A/B/C` as a recursive pattern, the directories `A` and +`A/B` are added as parent patterns. The resulting sparse-checkout file +is now ---------------- /* @@ -227,14 +394,18 @@ patterns. The resulting sparse-checkout file is now Here, order matters, so the negative patterns are overridden by the positive patterns that appear lower in the file. -If `core.sparseCheckoutCone=true`, then Git will parse the sparse-checkout file -expecting patterns of these types. Git will warn if the patterns do not match. -If the patterns do match the expected format, then Git will use faster hash- -based algorithms to compute inclusion in the sparse-checkout. +Unless `core.sparseCheckoutCone` is explicitly set to `false`, Git will +parse the sparse-checkout file expecting patterns of these types. Git will +warn if the patterns do not match. If the patterns do match the expected +format, then Git will use faster hash-based algorithms to compute inclusion +in the sparse-checkout. If they do not match, git will behave as though +`core.sparseCheckoutCone` was false, regardless of its setting. -In the cone mode case, the `git sparse-checkout list` subcommand will list the -directories that define the recursive patterns. For the example sparse-checkout -file above, the output is as follows: +In the cone mode case, despite the fact that full patterns are written +to the $GIT_DIR/info/sparse-checkout file, the `git sparse-checkout +list` subcommand will list the directories that define the recursive +patterns. For the example sparse-checkout file above, the output is as +follows: -------------------------- $ git sparse-checkout list @@ -246,19 +417,9 @@ case-insensitive check. This corrects for case mismatched filenames in the 'git sparse-checkout set' command to reflect the expected cone in the working directory. -When changing the sparse-checkout patterns in cone mode, Git will inspect each -tracked directory that is not within the sparse-checkout cone to see if it -contains any untracked files. If all of those files are ignored due to the -`.gitignore` patterns, then the directory will be deleted. If any of the -untracked files within that directory is not ignored, then no deletions will -occur within that directory and a warning message will appear. If these files -are important, then reset your sparse-checkout definition so they are included, -use `git add` and `git commit` to store them, then remove any remaining files -manually to ensure Git can behave optimally. - -SUBMODULES ----------- +INTERNALS -- SUBMODULES +----------------------- If your repository contains one or more submodules, then submodules are populated based on interactions with the `git submodule` command. diff --git a/Documentation/technical/api-error-handling.txt b/Documentation/technical/api-error-handling.txt index 8be4f4d0d6..70bf1d3e52 100644 --- a/Documentation/technical/api-error-handling.txt +++ b/Documentation/technical/api-error-handling.txt @@ -1,12 +1,34 @@ Error reporting in git ====================== -`BUG`, `die`, `usage`, `error`, and `warning` report errors of +`BUG`, `bug`, `die`, `usage`, `error`, and `warning` report errors of various kinds. - `BUG` is for failed internal assertions that should never happen, i.e. a bug in git itself. +- `bug` (lower-case, not `BUG`) is supposed to be used like `BUG` but + prints a "BUG" message instead of calling `abort()`. ++ +A call to `bug()` will then result in a "real" call to the `BUG()` +function, either explicitly by invoking `BUG_if_bug()` after call(s) +to `bug()`, or implicitly at `exit()` time where we'll check if we +encountered any outstanding `bug()` invocations. ++ +If there were no prior calls to `bug()` before invoking `BUG_if_bug()` +the latter is a NOOP. The `BUG_if_bug()` function takes the same +arguments as `BUG()` itself. Calling `BUG_if_bug()` explicitly isn't +necessary, but ensures that we die as soon as possible. ++ +If you know you had prior calls to `bug()` then calling `BUG()` itself +is equivalent to calling `BUG_if_bug()`, the latter being a wrapper +calling `BUG()` if we've set a flag indicating that we've called +`bug()`. ++ +This is for the convenience of APIs who'd like to potentially report +more than one "bug", such as the optbug() validation in +parse-options.c. + - `die` is for fatal application errors. It prints a message to the user and exits with status 128. diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt index f4a8a69087..77a150b30e 100644 --- a/Documentation/technical/api-trace2.txt +++ b/Documentation/technical/api-trace2.txt @@ -465,8 +465,8 @@ completed.) ------------ `"error"`:: - This event is emitted when one of the `BUG()`, `error()`, `die()`, - `warning()`, or `usage()` functions are called. + This event is emitted when one of the `BUG()`, `bug()`, `error()`, + `die()`, `warning()`, or `usage()` functions are called. + ------------ { diff --git a/Documentation/technical/cruft-packs.txt b/Documentation/technical/cruft-packs.txt new file mode 100644 index 0000000000..d81f3a8982 --- /dev/null +++ b/Documentation/technical/cruft-packs.txt @@ -0,0 +1,123 @@ += Cruft packs + +The cruft packs feature offer an alternative to Git's traditional mechanism of +removing unreachable objects. This document provides an overview of Git's +pruning mechanism, and how a cruft pack can be used instead to accomplish the +same. + +== Background + +To remove unreachable objects from your repository, Git offers `git repack -Ad` +(see linkgit:git-repack[1]). Quoting from the documentation: + +[quote] +[...] unreachable objects in a previous pack become loose, unpacked objects, +instead of being left in the old pack. [...] loose unreachable objects will be +pruned according to normal expiry rules with the next 'git gc' invocation. + +Unreachable objects aren't removed immediately, since doing so could race with +an incoming push which may reference an object which is about to be deleted. +Instead, those unreachable objects are stored as loose objects and stay that way +until they are older than the expiration window, at which point they are removed +by linkgit:git-prune[1]. + +Git must store these unreachable objects loose in order to keep track of their +per-object mtimes. If these unreachable objects were written into one big pack, +then either freshening that pack (because an object contained within it was +re-written) or creating a new pack of unreachable objects would cause the pack's +mtime to get updated, and the objects within it would never leave the expiration +window. Instead, objects are stored loose in order to keep track of the +individual object mtimes and avoid a situation where all cruft objects are +freshened at once. + +This can lead to undesirable situations when a repository contains many +unreachable objects which have not yet left the grace period. Having large +directories in the shards of `.git/objects` can lead to decreased performance in +the repository. But given enough unreachable objects, this can lead to inode +starvation and degrade the performance of the whole system. Since we +can never pack those objects, these repositories often take up a large amount of +disk space, since we can only zlib compress them, but not store them in delta +chains. + +== Cruft packs + +A cruft pack eliminates the need for storing unreachable objects in a loose +state by including the per-object mtimes in a separate file alongside a single +pack containing all loose objects. + +A cruft pack is written by `git repack --cruft` when generating a new pack. +linkgit:git-pack-objects[1]'s `--cruft` option. Note that `git repack --cruft` +is a classic all-into-one repack, meaning that everything in the resulting pack is +reachable, and everything else is unreachable. Once written, the `--cruft` +option instructs `git repack` to generate another pack containing only objects +not packed in the previous step (which equates to packing all unreachable +objects together). This progresses as follows: + + 1. Enumerate every object, marking any object which is (a) not contained in a + kept-pack, and (b) whose mtime is within the grace period as a traversal + tip. + + 2. Perform a reachability traversal based on the tips gathered in the previous + step, adding every object along the way to the pack. + + 3. Write the pack out, along with a `.mtimes` file that records the per-object + timestamps. + +This mode is invoked internally by linkgit:git-repack[1] when instructed to +write a cruft pack. Crucially, the set of in-core kept packs is exactly the set +of packs which will not be deleted by the repack; in other words, they contain +all of the repository's reachable objects. + +When a repository already has a cruft pack, `git repack --cruft` typically only +adds objects to it. An exception to this is when `git repack` is given the +`--cruft-expiration` option, which allows the generated cruft pack to omit +expired objects instead of waiting for linkgit:git-gc[1] to expire those objects +later on. + +It is linkgit:git-gc[1] that is typically responsible for removing expired +unreachable objects. + +== Caution for mixed-version environments + +Repositories that have cruft packs in them will continue to work with any older +version of Git. Note, however, that previous versions of Git which do not +understand the `.mtimes` file will use the cruft pack's mtime as the mtime for +all of the objects in it. In other words, do not expect older (pre-cruft pack) +versions of Git to interpret or even read the contents of the `.mtimes` file. + +Note that having mixed versions of Git GC-ing the same repository can lead to +unreachable objects never being completely pruned. This can happen under the +following circumstances: + + - An older version of Git running GC explodes the contents of an existing + cruft pack loose, using the cruft pack's mtime. + - A newer version running GC collects those loose objects into a cruft pack, + where the .mtime file reflects the loose object's actual mtimes, but the + cruft pack mtime is "now". + +Repeating this process will lead to unreachable objects not getting pruned as a +result of repeatedly resetting the objects' mtimes to the present time. + +If you are GC-ing repositories in a mixed version environment, consider omitting +the `--cruft` option when using linkgit:git-repack[1] and linkgit:git-gc[1], and +leaving the `gc.cruftPacks` configuration unset until all writers understand +cruft packs. + +== Alternatives + +Notable alternatives to this design include: + + - The location of the per-object mtime data, and + - Storing unreachable objects in multiple cruft packs. + +On the location of mtime data, a new auxiliary file tied to the pack was chosen +to avoid complicating the `.idx` format. If the `.idx` format were ever to gain +support for optional chunks of data, it may make sense to consolidate the +`.mtimes` format into the `.idx` itself. + +Storing unreachable objects among multiple cruft packs (e.g., creating a new +cruft pack during each repacking operation including only unreachable objects +which aren't already stored in an earlier cruft pack) is significantly more +complicated to construct, and so aren't pursued here. The obvious drawback to +the current implementation is that the entire cruft pack must be re-written from +scratch. diff --git a/Documentation/technical/pack-format.txt b/Documentation/technical/pack-format.txt index 6d3efb7d16..b520aa9c45 100644 --- a/Documentation/technical/pack-format.txt +++ b/Documentation/technical/pack-format.txt @@ -294,6 +294,25 @@ Pack file entry: <+ All 4-byte numbers are in network order. +== pack-*.mtimes files have the format: + +All 4-byte numbers are in network byte order. + + - A 4-byte magic number '0x4d544d45' ('MTME'). + + - A 4-byte version identifier (= 1). + + - A 4-byte hash function identifier (= 1 for SHA-1, 2 for SHA-256). + + - A table of 4-byte unsigned integers. The ith value is the + modification time (mtime) of the ith object in the corresponding + pack by lexicographic (index) order. The mtimes count standard + epoch seconds. + + - A trailer, containing a checksum of the corresponding packfile, + and a checksum of all of the above (each having length according + to the specified hash function). + == multi-pack-index (MIDX) files have the following format: The multi-pack-index files refer to multiple pack-files and loose objects. @@ -477,8 +477,14 @@ include shared.mak # # If your platform supports a built-in fsmonitor backend, set # FSMONITOR_DAEMON_BACKEND to the "<name>" of the corresponding -# `compat/fsmonitor/fsm-listen-<name>.c` that implements the -# `fsm_listen__*()` routines. +# `compat/fsmonitor/fsm-listen-<name>.c` and +# `compat/fsmonitor/fsm-health-<name>.c` files +# that implement the `fsm_listen__*()` and `fsm_health__*()` routines. +# +# If your platform has OS-specific ways to tell if a repo is incompatible with +# fsmonitor (whether the hook or IPC daemon version), set FSMONITOR_OS_SETTINGS +# to the "<name>" of the corresponding `compat/fsmonitor/fsm-settings-<name>.c` +# that implements the `fsm_os_settings__*()` routines. # # Define DEVELOPER to enable more compiler warnings. Compiler version # and family are auto detected, but could be overridden by defining @@ -569,7 +575,9 @@ INSTALL = install TCL_PATH = tclsh TCLTK_PATH = wish XGETTEXT = xgettext +MSGCAT = msgcat MSGFMT = msgfmt +MSGMERGE = msgmerge CURL_CONFIG = curl-config GCOV = gcov STRIP = strip @@ -728,6 +736,7 @@ TEST_BUILTINS_OBJS += test-getcwd.o TEST_BUILTINS_OBJS += test-hash-speed.o TEST_BUILTINS_OBJS += test-hash.o TEST_BUILTINS_OBJS += test-hashmap.o +TEST_BUILTINS_OBJS += test-hexdump.o TEST_BUILTINS_OBJS += test-index-version.o TEST_BUILTINS_OBJS += test-json-writer.o TEST_BUILTINS_OBJS += test-lazy-init-name-hash.o @@ -738,6 +747,7 @@ TEST_BUILTINS_OBJS += test-oid-array.o TEST_BUILTINS_OBJS += test-oidmap.o TEST_BUILTINS_OBJS += test-oidtree.o TEST_BUILTINS_OBJS += test-online-cpus.o +TEST_BUILTINS_OBJS += test-pack-mtimes.o TEST_BUILTINS_OBJS += test-parse-options.o TEST_BUILTINS_OBJS += test-parse-pathspec-file.o TEST_BUILTINS_OBJS += test-partial-clone.o @@ -844,7 +854,7 @@ generated-hdrs: $(GENERATED_H) ## Exhaustive lists of our source files, either dynamically generated, ## or hardcoded. SOURCES_CMD = ( \ - git ls-files \ + git ls-files --deduplicate \ '*.[hcS]' \ '*.sh' \ ':!*[tp][0-9][0-9][0-9][0-9]*' \ @@ -855,12 +865,13 @@ SOURCES_CMD = ( \ -o \( -name '[tp][0-9][0-9][0-9][0-9]*' -prune \) \ -o \( -name contrib -type d -prune \) \ -o \( -name build -type d -prune \) \ + -o \( -name .build -type d -prune \) \ -o \( -name 'trash*' -type d -prune \) \ -o \( -name '*.[hcS]' -type f -print \) \ -o \( -name '*.sh' -type f -print \) \ | sed -e 's|^\./||' \ ) -FOUND_SOURCE_FILES := $(shell $(SOURCES_CMD)) +FOUND_SOURCE_FILES := $(filter-out $(GENERATED_H),$(shell $(SOURCES_CMD))) FOUND_C_SOURCES = $(filter %.c,$(FOUND_SOURCE_FILES)) FOUND_H_SOURCES = $(filter %.h,$(FOUND_SOURCE_FILES)) @@ -993,6 +1004,7 @@ LIB_OBJS += oidtree.o LIB_OBJS += pack-bitmap-write.o LIB_OBJS += pack-bitmap.o LIB_OBJS += pack-check.o +LIB_OBJS += pack-mtimes.o LIB_OBJS += pack-objects.o LIB_OBJS += pack-revindex.o LIB_OBJS += pack-write.o @@ -2007,6 +2019,12 @@ endif ifdef FSMONITOR_DAEMON_BACKEND COMPAT_CFLAGS += -DHAVE_FSMONITOR_DAEMON_BACKEND COMPAT_OBJS += compat/fsmonitor/fsm-listen-$(FSMONITOR_DAEMON_BACKEND).o + COMPAT_OBJS += compat/fsmonitor/fsm-health-$(FSMONITOR_DAEMON_BACKEND).o +endif + +ifdef FSMONITOR_OS_SETTINGS + COMPAT_CFLAGS += -DHAVE_FSMONITOR_OS_SETTINGS + COMPAT_OBJS += compat/fsmonitor/fsm-settings-$(FSMONITOR_OS_SETTINGS).o endif ifeq ($(TCLTK_PATH),) @@ -2708,17 +2726,18 @@ XGETTEXT_FLAGS = \ --force-po \ --add-comments=TRANSLATORS: \ --msgid-bugs-address="Git Mailing List <git@vger.kernel.org>" \ - --from-code=UTF-8 + --package-name=Git XGETTEXT_FLAGS_C = $(XGETTEXT_FLAGS) --language=C \ --keyword=_ --keyword=N_ --keyword="Q_:1,2" XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --language=Perl \ --keyword=__ --keyword=N__ --keyword="__n:1,2" -LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) -LOCALIZED_SH += git-sh-setup.sh -LOCALIZED_PERL = $(SCRIPT_PERL) +MSGMERGE_FLAGS = --add-location --backup=off --update +LOCALIZED_C = $(sort $(FOUND_C_SOURCES) $(FOUND_H_SOURCES) $(SCALAR_SOURCES) \ + $(GENERATED_H)) +LOCALIZED_SH = $(sort $(SCRIPT_SH) git-sh-setup.sh) +LOCALIZED_PERL = $(sort $(SCRIPT_PERL)) ifdef XGETTEXT_INCLUDE_TESTS LOCALIZED_C += t/t0200/test.c @@ -2726,38 +2745,129 @@ LOCALIZED_SH += t/t0200/test.sh LOCALIZED_PERL += t/t0200/test.perl endif -## Note that this is meant to be run only by the localization coordinator -## under a very controlled condition, i.e. (1) it is to be run in a -## Git repository (not a tarball extract), (2) any local modifications -## will be lost. +## We generate intermediate .build/pot/po/%.po files containing a +## extract of the translations we find in each file in the source +## tree. We will assemble them using msgcat to create the final +## "po/git.pot" file. +LOCALIZED_ALL_GEN_PO = + +LOCALIZED_C_GEN_PO = $(LOCALIZED_C:%=.build/pot/po/%.po) +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_C_GEN_PO) + +LOCALIZED_SH_GEN_PO = $(LOCALIZED_SH:%=.build/pot/po/%.po) +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_SH_GEN_PO) + +LOCALIZED_PERL_GEN_PO = $(LOCALIZED_PERL:%=.build/pot/po/%.po) +LOCALIZED_ALL_GEN_PO += $(LOCALIZED_PERL_GEN_PO) + ## Gettext tools cannot work with our own custom PRItime type, so ## we replace PRItime with PRIuMAX. We need to update this to ## PRIdMAX if we switch to a signed type later. +$(LOCALIZED_C_GEN_PO): .build/pot/po/%.po: % + $(call mkdir_p_parent_template) + $(QUIET_XGETTEXT) \ + if grep -q PRItime $<; then \ + (\ + sed -e 's|PRItime|PRIuMAX|g' <$< \ + >.build/pot/po/$< && \ + cd .build/pot/po && \ + $(XGETTEXT) --omit-header \ + -o $(@:.build/pot/po/%=%) \ + $(XGETTEXT_FLAGS_C) $< && \ + rm $<; \ + ); \ + else \ + $(XGETTEXT) --omit-header \ + -o $@ $(XGETTEXT_FLAGS_C) $<; \ + fi -po/git.pot: $(GENERATED_H) FORCE - # All modifications will be reverted at the end, so we do not - # want to have any local change. - git diff --quiet HEAD && git diff --quiet --cached +$(LOCALIZED_SH_GEN_PO): .build/pot/po/%.po: % + $(call mkdir_p_parent_template) + $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \ + -o$@ $(XGETTEXT_FLAGS_SH) $< - @for s in $(LOCALIZED_C) $(LOCALIZED_SH) $(LOCALIZED_PERL); \ - do \ - sed -e 's|PRItime|PRIuMAX|g' <"$$s" >"$$s+" && \ - cat "$$s+" >"$$s" && rm "$$s+"; \ - done +$(LOCALIZED_PERL_GEN_PO): .build/pot/po/%.po: % + $(call mkdir_p_parent_template) + $(QUIET_XGETTEXT)$(XGETTEXT) --omit-header \ + -o$@ $(XGETTEXT_FLAGS_PERL) $< + +define gen_pot_header +$(XGETTEXT) $(XGETTEXT_FLAGS_C) \ + -o - /dev/null | \ +sed -e 's|charset=CHARSET|charset=UTF-8|' \ + -e 's|\(Last-Translator: \)FULL NAME <.*>|\1make by the Makefile|' \ + -e 's|\(Language-Team: \)LANGUAGE <.*>|\1Git Mailing List <git@vger.kernel.org>|' \ + >$@ && \ +echo '"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\\n"' >>$@ +endef - $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ $(XGETTEXT_FLAGS_C) $(LOCALIZED_C) - $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_SH) \ - $(LOCALIZED_SH) - $(QUIET_XGETTEXT)$(XGETTEXT) -o$@+ --join-existing $(XGETTEXT_FLAGS_PERL) \ - $(LOCALIZED_PERL) +.build/pot/git.header: $(LOCALIZED_ALL_GEN_PO) + $(call mkdir_p_parent_template) + $(QUIET_GEN)$(gen_pot_header) - # Reverting the munged source, leaving only the updated $@ - git reset --hard - mv $@+ $@ +po/git.pot: .build/pot/git.header $(LOCALIZED_ALL_GEN_PO) + $(QUIET_GEN)$(MSGCAT) $^ >$@ .PHONY: pot pot: po/git.pot +define check_po_file_envvar + $(if $(PO_FILE), \ + $(if $(filter po/%.po,$(PO_FILE)), , \ + $(error PO_FILE should match pattern: "po/%.po")), \ + $(error PO_FILE is not defined)) +endef + +.PHONY: po-update +po-update: po/git.pot + $(check_po_file_envvar) + @if test ! -e $(PO_FILE); then \ + echo >&2 "error: $(PO_FILE) does not exist"; \ + echo >&2 'To create an initial po file, use: "make po-init PO_FILE=po/XX.po"'; \ + exit 1; \ + fi + $(QUIET_MSGMERGE)$(MSGMERGE) $(MSGMERGE_FLAGS) $(PO_FILE) po/git.pot + +.PHONY: check-pot +check-pot: $(LOCALIZED_ALL_GEN_PO) + +### TODO FIXME: Translating everything in these files is a bad +### heuristic for "core", as we'll translate obscure error() messages +### along with commonly seen i18n messages. A better heuristic would +### be to e.g. use spatch to first remove error/die/warning +### etc. messages. +LOCALIZED_C_CORE = +LOCALIZED_C_CORE += builtin/checkout.c +LOCALIZED_C_CORE += builtin/clone.c +LOCALIZED_C_CORE += builtin/index-pack.c +LOCALIZED_C_CORE += builtin/push.c +LOCALIZED_C_CORE += builtin/reset.c +LOCALIZED_C_CORE += remote.c +LOCALIZED_C_CORE += wt-status.c + +LOCALIZED_C_CORE_GEN_PO = $(LOCALIZED_C_CORE:%=.build/pot/po/%.po) + +.build/pot/git-core.header: $(LOCALIZED_C_CORE_GEN_PO) + $(call mkdir_p_parent_template) + $(QUIET_GEN)$(gen_pot_header) + +po/git-core.pot: .build/pot/git-core.header $(LOCALIZED_C_CORE_GEN_PO) + $(QUIET_GEN)$(MSGCAT) $^ >$@ + +.PHONY: po-init +po-init: po/git-core.pot + $(check_po_file_envvar) + @if test -e $(PO_FILE); then \ + echo >&2 "error: $(PO_FILE) exists already"; \ + exit 1; \ + fi + $(QUIET_MSGINIT)msginit \ + --input=$< \ + --output=$(PO_FILE) \ + --no-translator \ + --locale=$(PO_FILE:po/%.po=%) + +## po/*.po files & their rules ifdef NO_GETTEXT POFILES := MOFILES := @@ -2869,6 +2979,9 @@ GIT-BUILD-OPTIONS: FORCE 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 @@ -3293,6 +3406,8 @@ cocciclean: $(RM) contrib/coccinelle/*.cocci.patch* clean: profile-clean coverage-clean cocciclean + $(RM) -r .build + $(RM) po/git.pot po/git-core.pot $(RM) *.res $(RM) $(OBJECTS) $(RM) $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(REFTABLE_TEST_LIB) diff --git a/add-interactive.c b/add-interactive.c index 7247210301..6047e8f648 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -568,8 +568,7 @@ static int get_modified_files(struct repository *r, run_diff_files(&rev, 0); } - if (ps) - clear_pathspec(&rev.prune_data); + release_revisions(&rev); } hashmap_clear_and_free(&s.file_map, struct pathname_entry, ent); if (unmerged_count) diff --git a/add-patch.c b/add-patch.c index 55d719f784..509ca04456 100644 --- a/add-patch.c +++ b/add-patch.c @@ -305,7 +305,7 @@ static void setup_child_process(struct add_p_state *s, va_end(ap); cp->git_cmd = 1; - strvec_pushf(&cp->env_array, + strvec_pushf(&cp->env, INDEX_ENVIRONMENT "=%s", s->s.r->index_file); } @@ -9,6 +9,7 @@ #include "parse-options.h" #include "unpack-trees.h" #include "dir.h" +#include "quote.h" static char const * const archive_usage[] = { N_("git archive [<options>] <tree-ish> [<path>...]"), @@ -263,6 +264,7 @@ static int queue_or_write_archive_entry(const struct object_id *oid, struct extra_file_info { char *base; struct stat stat; + void *content; }; int write_archive_entries(struct archiver_args *args, @@ -331,19 +333,27 @@ int write_archive_entries(struct archiver_args *args, put_be64(fake_oid.hash, i + 1); - strbuf_reset(&path_in_archive); - if (info->base) - strbuf_addstr(&path_in_archive, info->base); - strbuf_addstr(&path_in_archive, basename(path)); - - strbuf_reset(&content); - if (strbuf_read_file(&content, path, info->stat.st_size) < 0) - err = error_errno(_("cannot read '%s'"), path); - else - err = write_entry(args, &fake_oid, path_in_archive.buf, - path_in_archive.len, + if (!info->content) { + strbuf_reset(&path_in_archive); + if (info->base) + strbuf_addstr(&path_in_archive, info->base); + strbuf_addstr(&path_in_archive, basename(path)); + + strbuf_reset(&content); + if (strbuf_read_file(&content, path, info->stat.st_size) < 0) + err = error_errno(_("cannot read '%s'"), path); + else + err = write_entry(args, &fake_oid, path_in_archive.buf, + path_in_archive.len, + canon_mode(info->stat.st_mode), + content.buf, content.len); + } else { + err = write_entry(args, &fake_oid, + path, strlen(path), canon_mode(info->stat.st_mode), - content.buf, content.len); + info->content, info->stat.st_size); + } + if (err) break; } @@ -493,6 +503,7 @@ static void extra_file_info_clear(void *util, const char *str) { struct extra_file_info *info = util; free(info->base); + free(info->content); free(info); } @@ -514,14 +525,49 @@ static int add_file_cb(const struct option *opt, const char *arg, int unset) if (!arg) return -1; - path = prefix_filename(args->prefix, arg); - item = string_list_append_nodup(&args->extra_files, path); - item->util = info = xmalloc(sizeof(*info)); + info = xmalloc(sizeof(*info)); info->base = xstrdup_or_null(base); - if (stat(path, &info->stat)) - die(_("File not found: %s"), path); - if (!S_ISREG(info->stat.st_mode)) - die(_("Not a regular file: %s"), path); + + if (!strcmp(opt->long_name, "add-file")) { + path = prefix_filename(args->prefix, arg); + if (stat(path, &info->stat)) + die(_("File not found: %s"), path); + if (!S_ISREG(info->stat.st_mode)) + die(_("Not a regular file: %s"), path); + info->content = NULL; /* read the file later */ + } else if (!strcmp(opt->long_name, "add-virtual-file")) { + struct strbuf buf = STRBUF_INIT; + const char *p = arg; + + if (*p != '"') + p = strchr(p, ':'); + else if (unquote_c_style(&buf, p, &p) < 0) + die(_("unclosed quote: '%s'"), arg); + + if (!p || *p != ':') + die(_("missing colon: '%s'"), arg); + + if (p == arg) + die(_("empty file name: '%s'"), arg); + + path = buf.len ? + strbuf_detach(&buf, NULL) : xstrndup(arg, p - arg); + + if (args->prefix) { + char *save = path; + path = prefix_filename(args->prefix, path); + free(save); + } + memset(&info->stat, 0, sizeof(info->stat)); + info->stat.st_mode = S_IFREG | 0644; + info->content = xstrdup(p + 1); + info->stat.st_size = strlen(info->content); + } else { + BUG("add_file_cb() called for %s", opt->long_name); + } + item = string_list_append_nodup(&args->extra_files, path); + item->util = info; + return 0; } @@ -554,6 +600,9 @@ static int parse_archive_args(int argc, const char **argv, { OPTION_CALLBACK, 0, "add-file", args, N_("file"), N_("add untracked file to archive"), 0, add_file_cb, (intptr_t)&base }, + { OPTION_CALLBACK, 0, "add-virtual-file", args, + N_("path:content"), N_("add untracked file to archive"), 0, + add_file_cb, (intptr_t)&base }, OPT_STRING('o', "output", &output, N_("file"), N_("write the archive to this file")), OPT_BOOL(0, "worktree-attributes", &worktree_attributes, @@ -884,6 +884,7 @@ static int check_ancestors(struct repository *r, int rev_nr, /* Clean up objects used, as they will be reused. */ clear_commit_marks_many(rev_nr, rev, ALL_REV_FLAGS); + release_revisions(&revs); return res; } @@ -964,6 +965,7 @@ static void show_diff_tree(struct repository *r, setup_revisions(ARRAY_SIZE(argv) - 1, argv, &opt, NULL); log_tree_commit(&opt, commit); + release_revisions(&opt); } /* @@ -1008,7 +1010,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good) */ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) { - struct rev_info revs; + struct rev_info revs = REV_INFO_INIT; struct commit_list *tried; int reaches = 0, all = 0, nr, steps; enum bisect_error res = BISECT_OK; @@ -1033,7 +1035,7 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) res = check_good_are_ancestors_of_bad(r, prefix, no_checkout); if (res) - return res; + goto cleanup; bisect_rev_setup(r, &revs, prefix, "%s", "^%s", 1); @@ -1058,14 +1060,16 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) term_good, term_bad); - return BISECT_FAILED; + res = BISECT_FAILED; + goto cleanup; } if (!all) { fprintf(stderr, _("No testable commit found.\n" "Maybe you started with bad path arguments?\n")); - return BISECT_NO_TESTABLE_COMMIT; + res = BISECT_NO_TESTABLE_COMMIT; + goto cleanup; } bisect_rev = &revs.commits->item->object.oid; @@ -1085,7 +1089,8 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) * for negative return values for early returns up * until the cmd_bisect__helper() caller. */ - return BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND; + res = BISECT_INTERNAL_SUCCESS_1ST_BAD_FOUND; + goto cleanup; } nr = all - reaches - 1; @@ -1104,7 +1109,10 @@ enum bisect_error bisect_next_all(struct repository *r, const char *prefix) /* Clean up objects used, as they will be reused. */ repo_clear_commit_marks(r, ALL_REV_FLAGS); - return bisect_checkout(bisect_rev, no_checkout); + res = bisect_checkout(bisect_rev, no_checkout); +cleanup: + release_revisions(&revs); + return res; } static inline int log2i(int n) @@ -587,7 +587,7 @@ static int submodule_create_branch(struct repository *r, child.err = -1; child.stdout_to_stderr = 1; - prepare_other_repo_env(&child.env_array, r->gitdir); + prepare_other_repo_env(&child.env, r->gitdir); /* * submodule_create_branch() is indirectly invoked by "git * branch", but we cannot invoke "git branch" in the child diff --git a/builtin/add.c b/builtin/add.c index 343fe2c353..f84372964c 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -141,8 +141,17 @@ int add_files_to_cache(const char *prefix, rev.diffopt.format_callback_data = &data; rev.diffopt.flags.override_submodule_config = 1; rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ + + /* + * Use an ODB transaction to optimize adding multiple objects. + * This function is invoked from commands other than 'add', which + * may not have their own transaction active. + */ + begin_odb_transaction(); run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); - clear_pathspec(&rev.prune_data); + end_odb_transaction(); + + release_revisions(&rev); return !!data.add_errors; } @@ -335,6 +344,7 @@ static int edit_patch(int argc, const char **argv, const char *prefix) unlink(file); free(file); + release_revisions(&rev); return 0; } @@ -665,7 +675,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) string_list_clear(&only_match_skip_worktree, 0); } - plug_bulk_checkin(); + begin_odb_transaction(); if (add_renormalize) exit_status |= renormalize_tracked_files(&pathspec, flags); @@ -677,7 +687,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) if (chmod_arg && pathspec.nr) exit_status |= chmod_pathspec(&pathspec, chmod_arg[0], show_only); - unplug_bulk_checkin(); + end_odb_transaction(); finish: if (write_locked_index(&the_index, &lock_file, diff --git a/builtin/am.c b/builtin/am.c index 0f4111bafa..93bec62afa 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -1397,6 +1397,7 @@ static void write_commit_patch(const struct am_state *state, struct commit *comm add_pending_object(&rev_info, &commit->object, ""); diff_setup_done(&rev_info.diffopt); log_tree_commit(&rev_info, commit); + release_revisions(&rev_info); } /** @@ -1429,6 +1430,7 @@ static void write_index_patch(const struct am_state *state) add_pending_object(&rev_info, &tree->object, ""); diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, 1); + release_revisions(&rev_info); } /** @@ -1582,6 +1584,7 @@ static int fall_back_threeway(const struct am_state *state, const char *index_pa add_pending_oid(&rev_info, "HEAD", &our_tree, 0); diff_setup_done(&rev_info.diffopt); run_diff_index(&rev_info, 1); + release_revisions(&rev_info); } if (run_apply(state, index_path)) diff --git a/builtin/bisect--helper.c b/builtin/bisect--helper.c index d4eaaa345e..8a052c7111 100644 --- a/builtin/bisect--helper.c +++ b/builtin/bisect--helper.c @@ -596,6 +596,7 @@ static int bisect_skipped_commits(struct bisect_terms *terms) reset_revision_walk(); strbuf_release(&commit_name); + release_revisions(&revs); fclose(fp); return 0; } @@ -1084,6 +1085,7 @@ static enum bisect_error bisect_skip(struct bisect_terms *terms, const char **ar oid_to_hex(&commit->object.oid)); reset_revision_walk(); + release_revisions(&revs); } else { strvec_push(&argv_state, argv[i]); } diff --git a/builtin/blame.c b/builtin/blame.c index e33372c56b..02e39420b6 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1171,7 +1171,7 @@ parse_done: if (!incremental) setup_pager(); else - return 0; + goto cleanup; blame_sort_final(&sb); @@ -1205,6 +1205,8 @@ parse_done: printf("num commits: %d\n", sb.num_commits); } +cleanup: cleanup_scoreboard(&sb); + release_revisions(&revs); return 0; } diff --git a/builtin/checkout.c b/builtin/checkout.c index f988936ddf..2eefda81d8 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -629,7 +629,7 @@ static void show_local_changes(struct object *head, diff_setup_done(&rev.diffopt); add_pending_object(&rev, head, NULL); run_diff_index(&rev, 0); - object_array_clear(&rev.pending); + release_revisions(&rev); } static void describe_detached_head(const char *msg, struct commit *commit) @@ -1082,6 +1082,7 @@ static void orphaned_commit_warning(struct commit *old_commit, struct commit *ne /* Clean up objects used, as they will be reused. */ repo_clear_commit_marks(the_repository, ALL_REV_FLAGS); + release_revisions(&revs); } static int switch_branches(const struct checkout_opts *opts, diff --git a/builtin/commit.c b/builtin/commit.c index 9bbc7f8075..fcf9c85947 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -1100,7 +1100,6 @@ static const char *find_author_by_nickname(const char *name) struct rev_info revs; struct commit *commit; struct strbuf buf = STRBUF_INIT; - struct string_list mailmap = STRING_LIST_INIT_NODUP; const char *av[20]; int ac = 0; @@ -1111,7 +1110,8 @@ static const char *find_author_by_nickname(const char *name) av[++ac] = buf.buf; av[++ac] = NULL; setup_revisions(ac, av, &revs, NULL); - revs.mailmap = &mailmap; + revs.mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(revs.mailmap); read_mailmap(revs.mailmap); if (prepare_revision_walk(&revs)) @@ -1122,7 +1122,7 @@ static const char *find_author_by_nickname(const char *name) ctx.date_mode.type = DATE_NORMAL; strbuf_release(&buf); format_commit_message(commit, "%aN <%aE>", &buf, &ctx); - clear_mailmap(&mailmap); + release_revisions(&revs); return strbuf_detach(&buf, NULL); } die(_("--author '%s' is not 'Name <email>' and matches no existing author"), name); diff --git a/builtin/describe.c b/builtin/describe.c index 42159cd26b..a76f1a1a7a 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -517,6 +517,7 @@ static void describe_blob(struct object_id oid, struct strbuf *dst) traverse_commit_list(&revs, process_commit, process_object, &pcd); reset_revision_walk(); + release_revisions(&revs); } static void describe(const char *arg, int last_one) @@ -667,6 +668,7 @@ int cmd_describe(int argc, const char **argv, const char *prefix) suffix = NULL; else suffix = dirty; + release_revisions(&revs); } describe("HEAD", 1); } else if (dirty) { diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 70103c4095..2bfaf9ba7a 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -77,8 +77,12 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); - return -1; + result = -1; + goto cleanup; } +cleanup: result = run_diff_files(&rev, options); - return diff_result_code(&rev.diffopt, result); + result = diff_result_code(&rev.diffopt, result); + release_revisions(&rev); + return result; } diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 5fd23ab5b6..7d158af6b6 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -70,6 +70,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) return -1; } result = run_diff_index(&rev, option); - UNLEAK(rev); - return diff_result_code(&rev.diffopt, result); + result = diff_result_code(&rev.diffopt, result); + release_revisions(&rev); + return result; } diff --git a/builtin/diff.c b/builtin/diff.c index 3397f44d5a..54bb3de964 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -594,7 +594,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) result = diff_result_code(&rev.diffopt, result); if (1 < rev.diffopt.skip_stat_unmatch) refresh_index_quietly(); - UNLEAK(rev); + release_revisions(&rev); UNLEAK(ent); UNLEAK(blob); return result; diff --git a/builtin/difftool.c b/builtin/difftool.c index faa3507369..b3c509b8de 100644 --- a/builtin/difftool.c +++ b/builtin/difftool.c @@ -217,7 +217,7 @@ static void changed_files(struct hashmap *result, const char *index_path, update_index.use_shell = 0; update_index.clean_on_exit = 1; update_index.dir = workdir; - strvec_pushf(&update_index.env_array, "GIT_INDEX_FILE=%s", index_path); + strvec_pushf(&update_index.env, "GIT_INDEX_FILE=%s", index_path); /* Ignore any errors of update-index */ run_command(&update_index); @@ -230,7 +230,7 @@ static void changed_files(struct hashmap *result, const char *index_path, diff_files.clean_on_exit = 1; diff_files.out = -1; diff_files.dir = workdir; - strvec_pushf(&diff_files.env_array, "GIT_INDEX_FILE=%s", index_path); + strvec_pushf(&diff_files.env, "GIT_INDEX_FILE=%s", index_path); if (start_command(&diff_files)) die("could not obtain raw diff"); fp = xfdopen(diff_files.out, "r"); @@ -675,7 +675,7 @@ static int run_file_diff(int prompt, const char *prefix, child->git_cmd = 1; child->dir = prefix; - strvec_pushv(&child->env_array, env); + strvec_pushv(&child->env, env); return run_command(child); } diff --git a/builtin/fast-export.c b/builtin/fast-export.c index 1355b5a96d..e1748fb98b 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -1276,6 +1276,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) printf("done\n"); refspec_clear(&refspecs); + release_revisions(&revs); return 0; } diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 46be55a461..2c109cf8b3 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -3,6 +3,7 @@ #include "parse-options.h" #include "fsmonitor.h" #include "fsmonitor-ipc.h" +#include "compat/fsmonitor/fsm-health.h" #include "compat/fsmonitor/fsm-listen.h" #include "fsmonitor--daemon.h" #include "simple-ipc.h" @@ -1136,6 +1137,18 @@ void fsmonitor_publish(struct fsmonitor_daemon_state *state, pthread_mutex_unlock(&state->main_lock); } +static void *fsm_health__thread_proc(void *_state) +{ + struct fsmonitor_daemon_state *state = _state; + + trace2_thread_start("fsm-health"); + + fsm_health__loop(state); + + trace2_thread_exit(); + return NULL; +} + static void *fsm_listen__thread_proc(void *_state) { struct fsmonitor_daemon_state *state = _state; @@ -1174,6 +1187,9 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) */ .uds_disallow_chdir = 0 }; + int health_started = 0; + int listener_started = 0; + int err = 0; /* * Start the IPC thread pool before the we've started the file @@ -1181,11 +1197,11 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * before we need it. */ if (ipc_server_run_async(&state->ipc_server_data, - fsmonitor_ipc__get_path(), &ipc_opts, + state->path_ipc.buf, &ipc_opts, handle_client, state)) return error_errno( _("could not start IPC thread pool on '%s'"), - fsmonitor_ipc__get_path()); + state->path_ipc.buf); /* * Start the fsmonitor listener thread to collect filesystem @@ -1194,15 +1210,31 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) if (pthread_create(&state->listener_thread, NULL, fsm_listen__thread_proc, state) < 0) { ipc_server_stop_async(state->ipc_server_data); - ipc_server_await(state->ipc_server_data); + err = error(_("could not start fsmonitor listener thread")); + goto cleanup; + } + listener_started = 1; - return error(_("could not start fsmonitor listener thread")); + /* + * Start the health thread to watch over our process. + */ + if (pthread_create(&state->health_thread, NULL, + fsm_health__thread_proc, state) < 0) { + ipc_server_stop_async(state->ipc_server_data); + err = error(_("could not start fsmonitor health thread")); + goto cleanup; } + health_started = 1; /* * The daemon is now fully functional in background threads. + * Our primary thread should now just wait while the threads + * do all the work. + */ +cleanup: + /* * Wait for the IPC thread pool to shutdown (whether by client - * request or from filesystem activity). + * request, from filesystem activity, or an error). */ ipc_server_await(state->ipc_server_data); @@ -1211,15 +1243,29 @@ static int fsmonitor_run_daemon_1(struct fsmonitor_daemon_state *state) * event from the IPC thread pool, but it doesn't hurt to tell * it again. And wait for it to shutdown. */ - fsm_listen__stop_async(state); - pthread_join(state->listener_thread, NULL); + if (listener_started) { + fsm_listen__stop_async(state); + pthread_join(state->listener_thread, NULL); + } - return state->error_code; + if (health_started) { + fsm_health__stop_async(state); + pthread_join(state->health_thread, NULL); + } + + if (err) + return err; + if (state->listen_error_code) + return state->listen_error_code; + if (state->health_error_code) + return state->health_error_code; + return 0; } static int fsmonitor_run_daemon(void) { struct fsmonitor_daemon_state state; + const char *home; int err; memset(&state, 0, sizeof(state)); @@ -1227,7 +1273,8 @@ static int fsmonitor_run_daemon(void) hashmap_init(&state.cookies, cookies_cmp, NULL, 0); pthread_mutex_init(&state.main_lock, NULL); pthread_cond_init(&state.cookies_cond, NULL); - state.error_code = 0; + state.listen_error_code = 0; + state.health_error_code = 0; state.current_token_data = fsmonitor_new_token_data(); /* Prepare to (recursively) watch the <worktree-root> directory. */ @@ -1290,6 +1337,15 @@ static int fsmonitor_run_daemon(void) strbuf_addch(&state.path_cookie_prefix, '/'); /* + * We create a named-pipe or unix domain socket inside of the + * ".git" directory. (Well, on Windows, we base our named + * pipe in the NPFS on the absolute path of the git + * directory.) + */ + strbuf_init(&state.path_ipc, 0); + strbuf_addstr(&state.path_ipc, absolute_path(fsmonitor_ipc__get_path())); + + /* * Confirm that we can create platform-specific resources for the * filesystem listener before we bother starting all the threads. */ @@ -1298,18 +1354,42 @@ static int fsmonitor_run_daemon(void) goto done; } + if (fsm_health__ctor(&state)) { + err = error(_("could not initialize health thread")); + goto done; + } + + /* + * CD out of the worktree root directory. + * + * The common Git startup mechanism causes our CWD to be the + * root of the worktree. On Windows, this causes our process + * to hold a locked handle on the CWD. This prevents the + * worktree from being moved or deleted while the daemon is + * running. + * + * We assume that our FS and IPC listener threads have either + * opened all of the handles that they need or will do + * everything using absolute paths. + */ + home = getenv("HOME"); + if (home && *home && chdir(home)) + die_errno(_("could not cd home '%s'"), home); + err = fsmonitor_run_daemon_1(&state); done: pthread_cond_destroy(&state.cookies_cond); pthread_mutex_destroy(&state.main_lock); fsm_listen__dtor(&state); + fsm_health__dtor(&state); ipc_server_free(state.ipc_server_data); strbuf_release(&state.path_worktree_watch); strbuf_release(&state.path_gitdir_watch); strbuf_release(&state.path_cookie_prefix); + strbuf_release(&state.path_ipc); return err; } @@ -1423,6 +1503,7 @@ static int try_to_start_background_daemon(void) int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) { const char *subcmd; + enum fsmonitor_reason reason; int detach_console = 0; struct option options[] = { @@ -1449,6 +1530,23 @@ int cmd_fsmonitor__daemon(int argc, const char **argv, const char *prefix) die(_("invalid 'ipc-threads' value (%d)"), fsmonitor__ipc_threads); + prepare_repo_settings(the_repository); + /* + * If the repo is fsmonitor-compatible, explicitly set IPC-mode + * (without bothering to load the `core.fsmonitor` config settings). + * + * If the repo is not compatible, the repo-settings will be set to + * incompatible rather than IPC, so we can use one of the __get + * routines to detect the discrepancy. + */ + fsm_settings__set_ipc(the_repository); + + reason = fsm_settings__get_reason(the_repository); + if (reason > FSMONITOR_REASON_OK) + die("%s", + fsm_settings__get_incompatible_msg(the_repository, + reason)); + if (!strcmp(subcmd, "start")) return !!try_to_start_background_daemon(); diff --git a/builtin/gc.c b/builtin/gc.c index daa4535f1c..4ea70089c9 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -42,6 +42,7 @@ static const char * const builtin_gc_usage[] = { static int pack_refs = 1; static int prune_reflogs = 1; +static int cruft_packs = 0; static int aggressive_depth = 50; static int aggressive_window = 250; static int gc_auto_threshold = 6700; @@ -152,6 +153,7 @@ static void gc_config(void) git_config_get_int("gc.auto", &gc_auto_threshold); git_config_get_int("gc.autopacklimit", &gc_auto_pack_limit); git_config_get_bool("gc.autodetach", &detach_auto); + git_config_get_bool("gc.cruftpacks", &cruft_packs); git_config_get_expiry("gc.pruneexpire", &prune_expire); git_config_get_expiry("gc.worktreepruneexpire", &prune_worktrees_expire); git_config_get_expiry("gc.logexpiry", &gc_log_expire); @@ -331,7 +333,11 @@ static void add_repack_all_option(struct string_list *keep_pack) { if (prune_expire && !strcmp(prune_expire, "now")) strvec_push(&repack, "-a"); - else { + else if (cruft_packs) { + strvec_push(&repack, "--cruft"); + if (prune_expire) + strvec_pushf(&repack, "--cruft-expiration=%s", prune_expire); + } else { strvec_push(&repack, "-A"); if (prune_expire) strvec_pushf(&repack, "--unpack-unreachable=%s", prune_expire); @@ -551,6 +557,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) { OPTION_STRING, 0, "prune", &prune_expire, N_("date"), N_("prune unreferenced objects"), PARSE_OPT_OPTARG, NULL, (intptr_t)prune_expire }, + OPT_BOOL(0, "cruft", &cruft_packs, N_("pack unreferenced objects separately")), OPT_BOOL(0, "aggressive", &aggressive, N_("be more thorough (increased runtime)")), OPT_BOOL_F(0, "auto", &auto_gc, N_("enable auto-gc mode"), PARSE_OPT_NOCOMPLETE), @@ -670,6 +677,7 @@ int cmd_gc(int argc, const char **argv, const char *prefix) die(FAILED_RUN, repack.v[0]); if (prune_expire) { + /* run `git prune` even if using cruft packs */ strvec_push(&prune, prune_expire); if (quiet) strvec_push(&prune, "--no-progress"); diff --git a/builtin/log.c b/builtin/log.c index 2eb0063cc1..88a5e98875 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -231,7 +231,8 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, } if (mailmap) { - rev->mailmap = xcalloc(1, sizeof(struct string_list)); + rev->mailmap = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(rev->mailmap); read_mailmap(rev->mailmap); } @@ -294,6 +295,12 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, cmd_log_init_finish(argc, argv, prefix, rev, opt); } +static int cmd_log_deinit(int ret, struct rev_info *rev) +{ + release_revisions(rev); + return ret; +} + /* * This gives a rough estimate for how many commits we * will print out in the list. @@ -565,7 +572,7 @@ int cmd_whatchanged(int argc, const char **argv, const char *prefix) cmd_log_init(argc, argv, prefix, &rev, &opt); if (!rev.diffopt.output_format) rev.diffopt.output_format = DIFF_FORMAT_RAW; - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } static void show_tagger(const char *buf, struct rev_info *rev) @@ -689,7 +696,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) cmd_log_init(argc, argv, prefix, &rev, &opt); if (!rev.no_walk) - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); count = rev.pending.nr; objects = rev.pending.objects; @@ -749,8 +756,7 @@ int cmd_show(int argc, const char **argv, const char *prefix) rev.diffopt.no_free = 0; diff_free(&rev.diffopt); - free(objects); - return ret; + return cmd_log_deinit(ret, &rev); } /* @@ -778,7 +784,7 @@ int cmd_log_reflog(int argc, const char **argv, const char *prefix) rev.always_show_header = 1; cmd_log_init_finish(argc, argv, prefix, &rev, &opt); - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } static void log_setup_revisions_tweak(struct rev_info *rev, @@ -809,7 +815,7 @@ int cmd_log(int argc, const char **argv, const char *prefix) opt.revarg_opt = REVARG_COMMITTISH; opt.tweak = log_setup_revisions_tweak; cmd_log_init(argc, argv, prefix, &rev, &opt); - return cmd_log_walk(&rev); + return cmd_log_deinit(cmd_log_walk(&rev), &rev); } /* format-patch */ @@ -1764,6 +1770,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) struct commit *commit; struct commit **list = NULL; struct rev_info rev; + char *to_free = NULL; struct setup_revision_opt s_r_opt; int nr = 0, total, i; int use_stdout = 0; @@ -1965,7 +1972,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) strbuf_addch(&buf, '\n'); } - rev.extra_headers = strbuf_detach(&buf, NULL); + rev.extra_headers = to_free = strbuf_detach(&buf, NULL); if (from) { if (split_ident_line(&rev.from_ident, from, strlen(from))) @@ -2186,8 +2193,10 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) prepare_bases(&bases, base, list, nr); } - if (in_reply_to || thread || cover_letter) - rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); + if (in_reply_to || thread || cover_letter) { + rev.ref_message_ids = xmalloc(sizeof(*rev.ref_message_ids)); + string_list_init_nodup(rev.ref_message_ids); + } if (in_reply_to) { const char *msgid = clean_message_id(in_reply_to); string_list_append(rev.ref_message_ids, msgid); @@ -2294,8 +2303,11 @@ done: strbuf_release(&rdiff1); strbuf_release(&rdiff2); strbuf_release(&rdiff_title); - UNLEAK(rev); - return 0; + free(to_free); + if (rev.ref_message_ids) + string_list_clear(rev.ref_message_ids, 0); + free(rev.ref_message_ids); + return cmd_log_deinit(0, &rev); } static int add_pending_commit(const char *arg, struct rev_info *revs, int flags) diff --git a/builtin/merge.c b/builtin/merge.c index f178f5a3ee..d9784d4891 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -443,6 +443,7 @@ static void squash_message(struct commit *commit, struct commit_list *remotehead } write_file_buf(git_path_squash_msg(the_repository), out.buf, out.len); strbuf_release(&out); + release_revisions(&rev); } static void finish(struct commit *head_commit, @@ -998,6 +999,7 @@ static int evaluate_result(void) */ cnt += count_unmerged_entries(); + release_revisions(&rev); return cnt; } diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 014dcd4bc9..cc5f41086d 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -36,6 +36,7 @@ #include "trace2.h" #include "shallow.h" #include "promisor-remote.h" +#include "pack-mtimes.h" /* * Objects we are going to pack are collected in the `to_pack` structure. @@ -194,6 +195,8 @@ static int reuse_delta = 1, reuse_object = 1; static int keep_unreachable, unpack_unreachable, include_tag; static timestamp_t unpack_unreachable_expiration; static int pack_loose_unreachable; +static int cruft; +static timestamp_t cruft_expiration; static int local; static int have_non_local_packs; static int incremental; @@ -1260,9 +1263,13 @@ static void write_pack_file(void) &to_pack, written_list, nr_written); } + if (cruft) + pack_idx_opts.flags |= WRITE_MTIMES; + stage_tmp_packfiles(&tmpname, pack_tmp_name, written_list, nr_written, - &pack_idx_opts, hash, &idx_tmp_name); + &to_pack, &pack_idx_opts, hash, + &idx_tmp_name); if (write_bitmap_index) { size_t tmpname_len = tmpname.len; @@ -1357,6 +1364,9 @@ static int want_found_object(const struct object_id *oid, int exclude, if (incremental) return 0; + if (!is_pack_valid(p)) + return -1; + /* * When asked to do --local (do not include an object that appears in a * pack we borrow from elsewhere) or --honor-pack-keep (do not include @@ -1472,6 +1482,9 @@ static int want_object_in_pack(const struct object_id *oid, want = want_found_object(oid, exclude, *found_pack); if (want != -1) return want; + + *found_pack = NULL; + *found_offset = 0; } for (m = get_multi_pack_index(the_repository); m; m = m->next) { @@ -1515,13 +1528,13 @@ static int want_object_in_pack(const struct object_id *oid, return 1; } -static void create_object_entry(const struct object_id *oid, - enum object_type type, - uint32_t hash, - int exclude, - int no_try_delta, - struct packed_git *found_pack, - off_t found_offset) +static struct object_entry *create_object_entry(const struct object_id *oid, + enum object_type type, + uint32_t hash, + int exclude, + int no_try_delta, + struct packed_git *found_pack, + off_t found_offset) { struct object_entry *entry; @@ -1538,6 +1551,8 @@ static void create_object_entry(const struct object_id *oid, } entry->no_try_delta = no_try_delta; + + return entry; } static const char no_closure_warning[] = N_( @@ -3201,10 +3216,8 @@ static int add_object_entry_from_pack(const struct object_id *oid, uint32_t pos, void *_data) { - struct rev_info *revs = _data; - struct object_info oi = OBJECT_INFO_INIT; off_t ofs; - enum object_type type; + enum object_type type = OBJ_NONE; display_progress(progress_state, ++nr_seen); @@ -3215,19 +3228,24 @@ static int add_object_entry_from_pack(const struct object_id *oid, if (!want_object_in_pack(oid, 0, &p, &ofs)) return 0; - oi.typep = &type; - if (packed_object_info(the_repository, p, ofs, &oi) < 0) - die(_("could not get type of object %s in pack %s"), - oid_to_hex(oid), p->pack_name); - else if (type == OBJ_COMMIT) { - /* - * commits in included packs are used as starting points for the - * subsequent revision walk - */ - add_pending_oid(revs, NULL, oid, 0); - } + if (p) { + struct rev_info *revs = _data; + struct object_info oi = OBJECT_INFO_INIT; - stdin_packs_found_nr++; + oi.typep = &type; + if (packed_object_info(the_repository, p, ofs, &oi) < 0) { + die(_("could not get type of object %s in pack %s"), + oid_to_hex(oid), p->pack_name); + } else if (type == OBJ_COMMIT) { + /* + * commits in included packs are used as starting points for the + * subsequent revision walk + */ + add_pending_oid(revs, NULL, oid, 0); + } + + stdin_packs_found_nr++; + } create_object_entry(oid, type, 0, 0, 0, p, ofs); @@ -3346,6 +3364,8 @@ static void read_packs_list_from_stdin(void) struct packed_git *p = item->util; if (!p) die(_("could not find pack '%s'"), item->string); + if (!is_pack_valid(p)) + die(_("packfile %s cannot be accessed"), p->pack_name); } /* @@ -3369,8 +3389,6 @@ static void read_packs_list_from_stdin(void) for_each_string_list_item(item, &include_packs) { struct packed_git *p = item->util; - if (!p) - die(_("could not find pack '%s'"), item->string); for_each_object_in_pack(p, add_object_entry_from_pack, &revs, @@ -3394,6 +3412,217 @@ static void read_packs_list_from_stdin(void) string_list_clear(&exclude_packs, 0); } +static void add_cruft_object_entry(const struct object_id *oid, enum object_type type, + struct packed_git *pack, off_t offset, + const char *name, uint32_t mtime) +{ + struct object_entry *entry; + + display_progress(progress_state, ++nr_seen); + + entry = packlist_find(&to_pack, oid); + if (entry) { + if (name) { + entry->hash = pack_name_hash(name); + entry->no_try_delta = no_try_delta(name); + } + } else { + if (!want_object_in_pack(oid, 0, &pack, &offset)) + return; + if (!pack && type == OBJ_BLOB && !has_loose_object(oid)) { + /* + * If a traversed tree has a missing blob then we want + * to avoid adding that missing object to our pack. + * + * This only applies to missing blobs, not trees, + * because the traversal needs to parse sub-trees but + * not blobs. + * + * Note we only perform this check when we couldn't + * already find the object in a pack, so we're really + * limited to "ensure non-tip blobs which don't exist in + * packs do exist via loose objects". Confused? + */ + return; + } + + entry = create_object_entry(oid, type, pack_name_hash(name), + 0, name && no_try_delta(name), + pack, offset); + } + + if (mtime > oe_cruft_mtime(&to_pack, entry)) + oe_set_cruft_mtime(&to_pack, entry, mtime); + return; +} + +static void show_cruft_object(struct object *obj, const char *name, void *data) +{ + /* + * if we did not record it earlier, it's at least as old as our + * expiration value. Rather than find it exactly, just use that + * value. This may bump it forward from its real mtime, but it + * will still be "too old" next time we run with the same + * expiration. + * + * if obj does appear in the packing list, this call is a noop (or may + * set the namehash). + */ + add_cruft_object_entry(&obj->oid, obj->type, NULL, 0, name, cruft_expiration); +} + +static void show_cruft_commit(struct commit *commit, void *data) +{ + show_cruft_object((struct object*)commit, NULL, data); +} + +static int cruft_include_check_obj(struct object *obj, void *data) +{ + return !has_object_kept_pack(&obj->oid, IN_CORE_KEEP_PACKS); +} + +static int cruft_include_check(struct commit *commit, void *data) +{ + return cruft_include_check_obj((struct object*)commit, data); +} + +static void set_cruft_mtime(const struct object *object, + struct packed_git *pack, + off_t offset, time_t mtime) +{ + add_cruft_object_entry(&object->oid, object->type, pack, offset, NULL, + mtime); +} + +static void mark_pack_kept_in_core(struct string_list *packs, unsigned keep) +{ + struct string_list_item *item = NULL; + for_each_string_list_item(item, packs) { + struct packed_git *p = item->util; + if (!p) + die(_("could not find pack '%s'"), item->string); + p->pack_keep_in_core = keep; + } +} + +static void add_unreachable_loose_objects(void); +static void add_objects_in_unpacked_packs(void); + +static void enumerate_cruft_objects(void) +{ + if (progress) + progress_state = start_progress(_("Enumerating cruft objects"), 0); + + add_objects_in_unpacked_packs(); + add_unreachable_loose_objects(); + + stop_progress(&progress_state); +} + +static void enumerate_and_traverse_cruft_objects(struct string_list *fresh_packs) +{ + struct packed_git *p; + struct rev_info revs; + int ret; + + repo_init_revisions(the_repository, &revs, NULL); + + revs.tag_objects = 1; + revs.tree_objects = 1; + revs.blob_objects = 1; + + revs.include_check = cruft_include_check; + revs.include_check_obj = cruft_include_check_obj; + + revs.ignore_missing_links = 1; + + if (progress) + progress_state = start_progress(_("Enumerating cruft objects"), 0); + ret = add_unseen_recent_objects_to_traversal(&revs, cruft_expiration, + set_cruft_mtime, 1); + stop_progress(&progress_state); + + if (ret) + die(_("unable to add cruft objects")); + + /* + * Re-mark only the fresh packs as kept so that objects in + * unknown packs do not halt the reachability traversal early. + */ + for (p = get_all_packs(the_repository); p; p = p->next) + p->pack_keep_in_core = 0; + mark_pack_kept_in_core(fresh_packs, 1); + + if (prepare_revision_walk(&revs)) + die(_("revision walk setup failed")); + if (progress) + progress_state = start_progress(_("Traversing cruft objects"), 0); + nr_seen = 0; + traverse_commit_list(&revs, show_cruft_commit, show_cruft_object, NULL); + + stop_progress(&progress_state); +} + +static void read_cruft_objects(void) +{ + struct strbuf buf = STRBUF_INIT; + struct string_list discard_packs = STRING_LIST_INIT_DUP; + struct string_list fresh_packs = STRING_LIST_INIT_DUP; + struct packed_git *p; + + ignore_packed_keep_in_core = 1; + + while (strbuf_getline(&buf, stdin) != EOF) { + if (!buf.len) + continue; + + if (*buf.buf == '-') + string_list_append(&discard_packs, buf.buf + 1); + else + string_list_append(&fresh_packs, buf.buf); + strbuf_reset(&buf); + } + + string_list_sort(&discard_packs); + string_list_sort(&fresh_packs); + + for (p = get_all_packs(the_repository); p; p = p->next) { + const char *pack_name = pack_basename(p); + struct string_list_item *item; + + item = string_list_lookup(&fresh_packs, pack_name); + if (!item) + item = string_list_lookup(&discard_packs, pack_name); + + if (item) { + item->util = p; + } else { + /* + * This pack wasn't mentioned in either the "fresh" or + * "discard" list, so the caller didn't know about it. + * + * Mark it as kept so that its objects are ignored by + * add_unseen_recent_objects_to_traversal(). We'll + * unmark it before starting the traversal so it doesn't + * halt the traversal early. + */ + p->pack_keep_in_core = 1; + } + } + + mark_pack_kept_in_core(&fresh_packs, 1); + mark_pack_kept_in_core(&discard_packs, 0); + + if (cruft_expiration) + enumerate_and_traverse_cruft_objects(&fresh_packs); + else + enumerate_cruft_objects(); + + strbuf_release(&buf); + string_list_clear(&discard_packs, 0); + string_list_clear(&fresh_packs, 0); +} + static void read_object_list_from_stdin(void) { char line[GIT_MAX_HEXSZ + 1 + PATH_MAX + 2]; @@ -3526,7 +3755,24 @@ static int add_object_in_unpacked_pack(const struct object_id *oid, uint32_t pos, void *_data) { - add_object_entry(oid, OBJ_NONE, "", 0); + if (cruft) { + off_t offset; + time_t mtime; + + if (pack->is_cruft) { + if (load_pack_mtimes(pack) < 0) + die(_("could not load cruft pack .mtimes")); + mtime = nth_packed_mtime(pack, pos); + } else { + mtime = pack->mtime; + } + offset = nth_packed_object_offset(pack, pos); + + add_cruft_object_entry(oid, OBJ_NONE, pack, offset, + NULL, mtime); + } else { + add_object_entry(oid, OBJ_NONE, "", 0); + } return 0; } @@ -3550,7 +3796,19 @@ static int add_loose_object(const struct object_id *oid, const char *path, return 0; } - add_object_entry(oid, type, "", 0); + if (cruft) { + struct stat st; + if (stat(path, &st) < 0) { + if (errno == ENOENT) + return 0; + return error_errno("unable to stat %s", oid_to_hex(oid)); + } + + add_cruft_object_entry(oid, type, NULL, 0, NULL, + st.st_mtime); + } else { + add_object_entry(oid, type, "", 0); + } return 0; } @@ -3790,7 +4048,7 @@ static void get_object_list(struct rev_info *revs, int ac, const char **av) if (unpack_unreachable_expiration) { revs->ignore_missing_links = 1; if (add_unseen_recent_objects_to_traversal(revs, - unpack_unreachable_expiration)) + unpack_unreachable_expiration, NULL, 0)) die(_("unable to add recent objects")); if (prepare_revision_walk(revs)) die(_("revision walk setup failed")); @@ -3867,6 +4125,20 @@ static int option_parse_unpack_unreachable(const struct option *opt, return 0; } +static int option_parse_cruft_expiration(const struct option *opt, + const char *arg, int unset) +{ + if (unset) { + cruft = 0; + cruft_expiration = 0; + } else { + cruft = 1; + if (arg) + cruft_expiration = approxidate(arg); + } + return 0; +} + struct po_filter_data { unsigned have_revs:1; struct rev_info revs; @@ -3956,6 +4228,10 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) OPT_CALLBACK_F(0, "unpack-unreachable", NULL, N_("time"), N_("unpack unreachable objects newer than <time>"), PARSE_OPT_OPTARG, option_parse_unpack_unreachable), + OPT_BOOL(0, "cruft", &cruft, N_("create a cruft pack")), + OPT_CALLBACK_F(0, "cruft-expiration", NULL, N_("time"), + N_("expire cruft objects older than <time>"), + PARSE_OPT_OPTARG, option_parse_cruft_expiration), OPT_BOOL(0, "sparse", &sparse, N_("use the sparse reachability algorithm")), OPT_BOOL(0, "thin", &thin, @@ -4082,7 +4358,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (!HAVE_THREADS && delta_search_threads != 1) warning(_("no threads support, ignoring --threads")); - if (!pack_to_stdout && !pack_size_limit) + if (!pack_to_stdout && !pack_size_limit && !cruft) pack_size_limit = pack_size_limit_cfg; if (pack_to_stdout && pack_size_limit) die(_("--max-pack-size cannot be used to build a pack for transfer")); @@ -4109,6 +4385,15 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (stdin_packs && use_internal_rev_list) die(_("cannot use internal rev list with --stdin-packs")); + if (cruft) { + if (use_internal_rev_list) + die(_("cannot use internal rev list with --cruft")); + if (stdin_packs) + die(_("cannot use --stdin-packs with --cruft")); + if (pack_size_limit) + die(_("cannot use --max-pack-size with --cruft")); + } + /* * "soft" reasons not to use bitmaps - for on-disk repack by default we want * @@ -4165,7 +4450,7 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) the_repository); prepare_packing_data(the_repository, &to_pack); - if (progress) + if (progress && !cruft) progress_state = start_progress(_("Enumerating objects"), 0); if (stdin_packs) { /* avoids adding objects in excluded packs */ @@ -4173,15 +4458,19 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) read_packs_list_from_stdin(); if (rev_list_unpacked) add_unreachable_loose_objects(); + } else if (cruft) { + read_cruft_objects(); } else if (!use_internal_rev_list) { read_object_list_from_stdin(); } else if (pfd.have_revs) { get_object_list(&pfd.revs, rp.nr, rp.v); + release_revisions(&pfd.revs); } else { struct rev_info revs; repo_init_revisions(the_repository, &revs, NULL); get_object_list(&revs, rp.nr, rp.v); + release_revisions(&revs); } cleanup_preferred_base(); if (include_tag && nr_result) diff --git a/builtin/prune.c b/builtin/prune.c index c2bcdc07db..df376b2ed1 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -196,5 +196,6 @@ int cmd_prune(int argc, const char **argv, const char *prefix) prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0); } + release_revisions(&revs); return 0; } diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index daa153d044..31b48e728b 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -764,23 +764,23 @@ static void prepare_push_cert_sha1(struct child_process *proc) nonce_status = check_nonce(push_cert.buf, bogs); } if (!is_null_oid(&push_cert_oid)) { - strvec_pushf(&proc->env_array, "GIT_PUSH_CERT=%s", + strvec_pushf(&proc->env, "GIT_PUSH_CERT=%s", oid_to_hex(&push_cert_oid)); - strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_SIGNER=%s", + strvec_pushf(&proc->env, "GIT_PUSH_CERT_SIGNER=%s", sigcheck.signer ? sigcheck.signer : ""); - strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_KEY=%s", + strvec_pushf(&proc->env, "GIT_PUSH_CERT_KEY=%s", sigcheck.key ? sigcheck.key : ""); - strvec_pushf(&proc->env_array, "GIT_PUSH_CERT_STATUS=%c", + strvec_pushf(&proc->env, "GIT_PUSH_CERT_STATUS=%c", sigcheck.result); if (push_cert_nonce) { - strvec_pushf(&proc->env_array, + strvec_pushf(&proc->env, "GIT_PUSH_CERT_NONCE=%s", push_cert_nonce); - strvec_pushf(&proc->env_array, + strvec_pushf(&proc->env, "GIT_PUSH_CERT_NONCE_STATUS=%s", nonce_status); if (nonce_status == NONCE_SLOP) - strvec_pushf(&proc->env_array, + strvec_pushf(&proc->env, "GIT_PUSH_CERT_NONCE_SLOP=%ld", nonce_stamp_slop); } @@ -815,17 +815,17 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, if (feed_state->push_options) { size_t i; for (i = 0; i < feed_state->push_options->nr; i++) - strvec_pushf(&proc.env_array, + strvec_pushf(&proc.env, "GIT_PUSH_OPTION_%"PRIuMAX"=%s", (uintmax_t)i, feed_state->push_options->items[i].string); - strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT=%"PRIuMAX"", + strvec_pushf(&proc.env, "GIT_PUSH_OPTION_COUNT=%"PRIuMAX"", (uintmax_t)feed_state->push_options->nr); } else - strvec_pushf(&proc.env_array, "GIT_PUSH_OPTION_COUNT"); + strvec_pushf(&proc.env, "GIT_PUSH_OPTION_COUNT"); if (tmp_objdir) - strvec_pushv(&proc.env_array, tmp_objdir_env(tmp_objdir)); + strvec_pushv(&proc.env, tmp_objdir_env(tmp_objdir)); if (use_sideband) { memset(&muxer, 0, sizeof(muxer)); @@ -1357,7 +1357,7 @@ static const char *push_to_deploy(unsigned char *sha1, strvec_pushl(&child.args, "update-index", "-q", "--ignore-submodules", "--refresh", NULL); - strvec_pushv(&child.env_array, env->v); + strvec_pushv(&child.env, env->v); child.dir = work_tree; child.no_stdin = 1; child.stdout_to_stderr = 1; @@ -1369,7 +1369,7 @@ static const char *push_to_deploy(unsigned char *sha1, child_process_init(&child); strvec_pushl(&child.args, "diff-files", "--quiet", "--ignore-submodules", "--", NULL); - strvec_pushv(&child.env_array, env->v); + strvec_pushv(&child.env, env->v); child.dir = work_tree; child.no_stdin = 1; child.stdout_to_stderr = 1; @@ -1383,7 +1383,7 @@ static const char *push_to_deploy(unsigned char *sha1, /* diff-index with either HEAD or an empty tree */ head_has_history() ? "HEAD" : empty_tree_oid_hex(), "--", NULL); - strvec_pushv(&child.env_array, env->v); + strvec_pushv(&child.env, env->v); child.no_stdin = 1; child.no_stdout = 1; child.stdout_to_stderr = 0; @@ -1394,7 +1394,7 @@ static const char *push_to_deploy(unsigned char *sha1, child_process_init(&child); strvec_pushl(&child.args, "read-tree", "-u", "-m", hash_to_hex(sha1), NULL); - strvec_pushv(&child.env_array, env->v); + strvec_pushv(&child.env, env->v); child.dir = work_tree; child.no_stdin = 1; child.no_stdout = 1; @@ -1810,21 +1810,17 @@ static int should_process_cmd(struct command *cmd) return !cmd->error_string && !cmd->skip_update; } -static void warn_if_skipped_connectivity_check(struct command *commands, +static void BUG_if_skipped_connectivity_check(struct command *commands, struct shallow_info *si) { struct command *cmd; - int checked_connectivity = 1; for (cmd = commands; cmd; cmd = cmd->next) { - if (should_process_cmd(cmd) && si->shallow_ref[cmd->index]) { - error("BUG: connectivity check has not been run on ref %s", - cmd->ref_name); - checked_connectivity = 0; - } + if (should_process_cmd(cmd) && si->shallow_ref[cmd->index]) + bug("connectivity check has not been run on ref %s", + cmd->ref_name); } - if (!checked_connectivity) - BUG("connectivity check skipped???"); + BUG_if_bug("connectivity check skipped???"); } static void execute_commands_non_atomic(struct command *commands, @@ -2005,7 +2001,7 @@ static void execute_commands(struct command *commands, execute_commands_non_atomic(commands, si); if (shallow_update) - warn_if_skipped_connectivity_check(commands, si); + BUG_if_skipped_connectivity_check(commands, si); } static struct command **queue_command(struct command **tail, @@ -2214,7 +2210,7 @@ static const char *unpack(int err_fd, struct shallow_info *si) close(err_fd); return "unable to create temporary object directory"; } - strvec_pushv(&child.env_array, tmp_objdir_env(tmp_objdir)); + strvec_pushv(&child.env, tmp_objdir_env(tmp_objdir)); /* * Normally we just pass the tmp_objdir environment to the child diff --git a/builtin/reflog.c b/builtin/reflog.c index c943c2aabe..4dd297dce8 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -293,6 +293,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) if (verbose) printf(_("Marking reachable objects...")); mark_reachable_objects(&revs, 0, 0, NULL); + release_revisions(&revs); if (verbose) putchar('\n'); } diff --git a/builtin/repack.c b/builtin/repack.c index d1a563d5b6..c957b2959f 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -18,12 +18,21 @@ #include "pack-bitmap.h" #include "refs.h" +#define ALL_INTO_ONE 1 +#define LOOSEN_UNREACHABLE 2 +#define PACK_CRUFT 4 + +#define DELETE_PACK 1 +#define CRUFT_PACK 2 + +static int pack_everything; static int delta_base_offset = 1; static int pack_kept_objects = -1; static int write_bitmaps = -1; static int use_delta_islands; static int run_update_server_info = 1; static char *packdir, *packtmp_name, *packtmp; +static char *cruft_expiration; static const char *const git_repack_usage[] = { N_("git repack [<options>]"), @@ -35,9 +44,21 @@ static const char incremental_bitmap_conflict_error[] = N_( "--no-write-bitmap-index or disable the pack.writebitmaps configuration." ); +struct pack_objects_args { + const char *window; + const char *window_memory; + const char *depth; + const char *threads; + const char *max_pack_size; + int no_reuse_delta; + int no_reuse_object; + int quiet; + int local; +}; static int repack_config(const char *var, const char *value, void *cb) { + struct pack_objects_args *cruft_po_args = cb; if (!strcmp(var, "repack.usedeltabaseoffset")) { delta_base_offset = git_config_bool(var, value); return 0; @@ -59,6 +80,14 @@ static int repack_config(const char *var, const char *value, void *cb) run_update_server_info = git_config_bool(var, value); return 0; } + if (!strcmp(var, "repack.cruftwindow")) + return git_config_string(&cruft_po_args->window, var, value); + if (!strcmp(var, "repack.cruftwindowmemory")) + return git_config_string(&cruft_po_args->window_memory, var, value); + if (!strcmp(var, "repack.cruftdepth")) + return git_config_string(&cruft_po_args->depth, var, value); + if (!strcmp(var, "repack.cruftthreads")) + return git_config_string(&cruft_po_args->threads, var, value); return git_default_config(var, value, cb); } @@ -131,12 +160,19 @@ static void collect_pack_filenames(struct string_list *fname_nonkept_list, fname = xmemdupz(e->d_name, len); if ((extra_keep->nr > 0 && i < extra_keep->nr) || - (file_exists(mkpath("%s/%s.keep", packdir, fname)))) + (file_exists(mkpath("%s/%s.keep", packdir, fname)))) { string_list_append_nodup(fname_kept_list, fname); - else - string_list_append_nodup(fname_nonkept_list, fname); + } else { + struct string_list_item *item; + item = string_list_append_nodup(fname_nonkept_list, + fname); + if (file_exists(mkpath("%s/%s.mtimes", packdir, fname))) + item->util = (void*)(uintptr_t)CRUFT_PACK; + } } closedir(dir); + + string_list_sort(fname_kept_list); } static void remove_redundant_pack(const char *dir_name, const char *base_name) @@ -151,18 +187,6 @@ static void remove_redundant_pack(const char *dir_name, const char *base_name) strbuf_release(&buf); } -struct pack_objects_args { - const char *window; - const char *window_memory; - const char *depth; - const char *threads; - const char *max_pack_size; - int no_reuse_delta; - int no_reuse_object; - int quiet; - int local; -}; - static void prepare_pack_objects(struct child_process *cmd, const struct pack_objects_args *args) { @@ -217,6 +241,7 @@ static struct { } exts[] = { {".pack"}, {".rev", 1}, + {".mtimes", 1}, {".bitmap", 1}, {".promisor", 1}, {".idx"}, @@ -304,9 +329,6 @@ static void repack_promisor_objects(const struct pack_objects_args *args, die(_("could not finish pack-objects to repack promisor objects")); } -#define ALL_INTO_ONE 1 -#define LOOSEN_UNREACHABLE 2 - struct pack_geometry { struct packed_git **pack; uint32_t pack_nr, pack_alloc; @@ -332,16 +354,39 @@ static int geometry_cmp(const void *va, const void *vb) return 0; } -static void init_pack_geometry(struct pack_geometry **geometry_p) +static void init_pack_geometry(struct pack_geometry **geometry_p, + struct string_list *existing_kept_packs) { struct packed_git *p; struct pack_geometry *geometry; + struct strbuf buf = STRBUF_INIT; *geometry_p = xcalloc(1, sizeof(struct pack_geometry)); geometry = *geometry_p; for (p = get_all_packs(the_repository); p; p = p->next) { - if (!pack_kept_objects && p->pack_keep) + if (!pack_kept_objects) { + /* + * Any pack that has its pack_keep bit set will appear + * in existing_kept_packs below, but this saves us from + * doing a more expensive check. + */ + if (p->pack_keep) + continue; + + /* + * The pack may be kept via the --keep-pack option; + * check 'existing_kept_packs' to determine whether to + * ignore it. + */ + strbuf_reset(&buf); + strbuf_addstr(&buf, pack_basename(p)); + strbuf_strip_suffix(&buf, ".pack"); + + if (string_list_has_string(existing_kept_packs, buf.buf)) + continue; + } + if (p->is_cruft) continue; ALLOC_GROW(geometry->pack, @@ -353,6 +398,7 @@ static void init_pack_geometry(struct pack_geometry **geometry_p) } QSORT(geometry->pack, geometry->pack_nr, geometry_cmp); + strbuf_release(&buf); } static void split_pack_geometry(struct pack_geometry *geometry, int factor) @@ -548,9 +594,20 @@ static void midx_included_packs(struct string_list *include, string_list_insert(include, strbuf_detach(&buf, NULL)); } + + for_each_string_list_item(item, existing_nonkept_packs) { + if (!((uintptr_t)item->util & CRUFT_PACK)) { + /* + * no need to check DELETE_PACK, since we're not + * doing an ALL_INTO_ONE repack + */ + continue; + } + string_list_insert(include, xstrfmt("%s.idx", item->string)); + } } else { for_each_string_list_item(item, existing_nonkept_packs) { - if (item->util) + if ((uintptr_t)item->util & DELETE_PACK) continue; string_list_insert(include, xstrfmt("%s.idx", item->string)); } @@ -604,6 +661,67 @@ static int write_midx_included_packs(struct string_list *include, return finish_command(&cmd); } +static int write_cruft_pack(const struct pack_objects_args *args, + const char *pack_prefix, + struct string_list *names, + struct string_list *existing_packs, + struct string_list *existing_kept_packs) +{ + struct child_process cmd = CHILD_PROCESS_INIT; + struct strbuf line = STRBUF_INIT; + struct string_list_item *item; + FILE *in, *out; + int ret; + + prepare_pack_objects(&cmd, args); + + strvec_push(&cmd.args, "--cruft"); + if (cruft_expiration) + strvec_pushf(&cmd.args, "--cruft-expiration=%s", + cruft_expiration); + + strvec_push(&cmd.args, "--honor-pack-keep"); + strvec_push(&cmd.args, "--non-empty"); + strvec_push(&cmd.args, "--max-pack-size=0"); + + cmd.in = -1; + + ret = start_command(&cmd); + if (ret) + return ret; + + /* + * names has a confusing double use: it both provides the list + * of just-written new packs, and accepts the name of the cruft + * pack we are writing. + * + * By the time it is read here, it contains only the pack(s) + * that were just written, which is exactly the set of packs we + * want to consider kept. + */ + in = xfdopen(cmd.in, "w"); + for_each_string_list_item(item, names) + fprintf(in, "%s-%s.pack\n", pack_prefix, item->string); + for_each_string_list_item(item, existing_packs) + fprintf(in, "-%s.pack\n", item->string); + for_each_string_list_item(item, existing_kept_packs) + fprintf(in, "%s.pack\n", item->string); + fclose(in); + + out = xfdopen(cmd.out, "r"); + while (strbuf_getline_lf(&line, out) != EOF) { + if (line.len != the_hash_algo->hexsz) + die(_("repack: Expecting full hex object ID lines only " + "from pack-objects.")); + string_list_append(names, line.buf); + } + fclose(out); + + strbuf_release(&line); + + return finish_command(&cmd); +} + int cmd_repack(int argc, const char **argv, const char *prefix) { struct child_process cmd = CHILD_PROCESS_INIT; @@ -620,12 +738,12 @@ int cmd_repack(int argc, const char **argv, const char *prefix) int show_progress; /* variables to be filled by option parsing */ - int pack_everything = 0; int delete_redundant = 0; const char *unpack_unreachable = NULL; int keep_unreachable = 0; struct string_list keep_pack_list = STRING_LIST_INIT_NODUP; struct pack_objects_args po_args = {NULL}; + struct pack_objects_args cruft_po_args = {NULL}; int geometric_factor = 0; int write_midx = 0; @@ -635,6 +753,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix) OPT_BIT('A', NULL, &pack_everything, N_("same as -a, and turn unreachable objects loose"), LOOSEN_UNREACHABLE | ALL_INTO_ONE), + OPT_BIT(0, "cruft", &pack_everything, + N_("same as -a, pack unreachable cruft objects separately"), + PACK_CRUFT), + OPT_STRING(0, "cruft-expiration", &cruft_expiration, N_("approxidate"), + N_("with -C, expire objects older than this")), OPT_BOOL('d', NULL, &delete_redundant, N_("remove redundant packs, and run git-prune-packed")), OPT_BOOL('f', NULL, &po_args.no_reuse_delta, @@ -675,7 +798,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) OPT_END() }; - git_config(repack_config, NULL); + git_config(repack_config, &cruft_po_args); argc = parse_options(argc, argv, prefix, builtin_repack_options, git_repack_usage, 0); @@ -687,6 +810,15 @@ int cmd_repack(int argc, const char **argv, const char *prefix) (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE))) die(_("options '%s' and '%s' cannot be used together"), "--keep-unreachable", "-A"); + if (pack_everything & PACK_CRUFT) { + pack_everything |= ALL_INTO_ONE; + + if (unpack_unreachable || (pack_everything & LOOSEN_UNREACHABLE)) + die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-A"); + if (keep_unreachable) + die(_("options '%s' and '%s' cannot be used together"), "--cruft", "-k"); + } + if (write_bitmaps < 0) { if (!write_midx && (!(pack_everything & ALL_INTO_ONE) || !is_bare_repository())) @@ -714,17 +846,20 @@ int cmd_repack(int argc, const char **argv, const char *prefix) strbuf_release(&path); } + packdir = mkpathdup("%s/pack", get_object_directory()); + packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid()); + packtmp = mkpathdup("%s/%s", packdir, packtmp_name); + + collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs, + &keep_pack_list); + if (geometric_factor) { if (pack_everything) die(_("options '%s' and '%s' cannot be used together"), "--geometric", "-A/-a"); - init_pack_geometry(&geometry); + init_pack_geometry(&geometry, &existing_kept_packs); split_pack_geometry(geometry, geometric_factor); } - packdir = mkpathdup("%s/pack", get_object_directory()); - packtmp_name = xstrfmt(".tmp-%d-pack", (int)getpid()); - packtmp = mkpathdup("%s/%s", packdir, packtmp_name); - sigchain_push_common(remove_pack_on_signal); prepare_pack_objects(&cmd, &po_args); @@ -764,13 +899,11 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (use_delta_islands) strvec_push(&cmd.args, "--delta-islands"); - collect_pack_filenames(&existing_nonkept_packs, &existing_kept_packs, - &keep_pack_list); - if (pack_everything & ALL_INTO_ONE) { repack_promisor_objects(&po_args, &names); - if (existing_nonkept_packs.nr && delete_redundant) { + if (existing_nonkept_packs.nr && delete_redundant && + !(pack_everything & PACK_CRUFT)) { for_each_string_list_item(item, &names) { strvec_pushf(&cmd.args, "--keep-pack=%s-%s.pack", packtmp_name, item->string); @@ -832,6 +965,35 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (!names.nr && !po_args.quiet) printf_ln(_("Nothing new to pack.")); + if (pack_everything & PACK_CRUFT) { + const char *pack_prefix; + if (!skip_prefix(packtmp, packdir, &pack_prefix)) + die(_("pack prefix %s does not begin with objdir %s"), + packtmp, packdir); + if (*pack_prefix == '/') + pack_prefix++; + + if (!cruft_po_args.window) + cruft_po_args.window = po_args.window; + if (!cruft_po_args.window_memory) + cruft_po_args.window_memory = po_args.window_memory; + if (!cruft_po_args.depth) + cruft_po_args.depth = po_args.depth; + if (!cruft_po_args.threads) + cruft_po_args.threads = po_args.threads; + + cruft_po_args.local = po_args.local; + cruft_po_args.quiet = po_args.quiet; + + ret = write_cruft_pack(&cruft_po_args, pack_prefix, &names, + &existing_nonkept_packs, + &existing_kept_packs); + if (ret) + return ret; + } + + string_list_sort(&names); + for_each_string_list_item(item, &names) { item->util = (void *)(uintptr_t)populate_pack_exts(item->string); } @@ -872,7 +1034,6 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (delete_redundant && pack_everything & ALL_INTO_ONE) { const int hexsz = the_hash_algo->hexsz; - string_list_sort(&names); for_each_string_list_item(item, &existing_nonkept_packs) { char *sha1; size_t len = strlen(item->string); @@ -885,7 +1046,8 @@ int cmd_repack(int argc, const char **argv, const char *prefix) * was given) and that we will actually delete this pack * (if `-d` was given). */ - item->util = (void*)(intptr_t)!string_list_has_string(&names, sha1); + if (!string_list_has_string(&names, sha1)) + item->util = (void*)(uintptr_t)((size_t)item->util | DELETE_PACK); } } @@ -909,7 +1071,7 @@ int cmd_repack(int argc, const char **argv, const char *prefix) if (delete_redundant) { int opts = 0; for_each_string_list_item(item, &existing_nonkept_packs) { - if (!item->util) + if (!((uintptr_t)item->util & DELETE_PACK)) continue; remove_redundant_pack(packdir, item->string); } diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 572da1472e..30fd8e83ea 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -213,10 +213,8 @@ static void show_commit(struct commit *commit, void *data) static void finish_commit(struct commit *commit) { - if (commit->parents) { - free_commit_list(commit->parents); - commit->parents = NULL; - } + free_commit_list(commit->parents); + commit->parents = NULL; free_commit_buffer(the_repository->parsed_objects, commit); } @@ -502,6 +500,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) int use_bitmap_index = 0; int filter_provided_objects = 0; const char *show_progress = NULL; + int ret = 0; if (argc == 2 && !strcmp(argv[1], "-h")) usage(rev_list_usage); @@ -585,7 +584,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) } if (!strcmp(arg, "--test-bitmap")) { test_bitmap_walk(&revs); - return 0; + goto cleanup; } if (skip_prefix(arg, "--progress=", &arg)) { show_progress = arg; @@ -674,11 +673,11 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (use_bitmap_index) { if (!try_bitmap_count(&revs, filter_provided_objects)) - return 0; + goto cleanup; if (!try_bitmap_disk_usage(&revs, filter_provided_objects)) - return 0; + goto cleanup; if (!try_bitmap_traversal(&revs, filter_provided_objects)) - return 0; + goto cleanup; } if (prepare_revision_walk(&revs)) @@ -698,8 +697,10 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) find_bisection(&revs.commits, &reaches, &all, bisect_flags); - if (bisect_show_vars) - return show_bisect_vars(&info, reaches, all); + if (bisect_show_vars) { + ret = show_bisect_vars(&info, reaches, all); + goto cleanup; + } } if (filter_provided_objects) { @@ -754,5 +755,7 @@ int cmd_rev_list(int argc, const char **argv, const char *prefix) if (show_disk_usage) printf("%"PRIuMAX"\n", (uintmax_t)total_disk_usage); - return 0; +cleanup: + release_revisions(&revs); + return ret; } diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 62c4a4eaba..35825f075e 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -81,8 +81,10 @@ static void insert_one_record(struct shortlog *log, format_subject(&subject, oneline, " "); buffer = strbuf_detach(&subject, NULL); - if (!item->util) - item->util = xcalloc(1, sizeof(struct string_list)); + if (!item->util) { + item->util = xmalloc(sizeof(struct string_list)); + string_list_init_nodup(item->util); + } string_list_append(item->util, buffer); } } @@ -420,6 +422,8 @@ parse_done: else get_from_rev(&rev, &log); + release_revisions(&rev); + shortlog_output(&log); if (log.file != stdout) fclose(log.file); diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 0217d44c5b..f91e29b56a 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -128,7 +128,7 @@ static void clean_tracked_sparse_directories(struct repository *r) * sparse index will not delete directories that contain * conflicted entries or submodules. */ - if (!r->index->sparse_index) { + if (r->index->sparse_index == INDEX_EXPANDED) { /* * If something, such as a merge conflict or other concern, * prevents us from converting to a sparse index, then do @@ -395,7 +395,7 @@ static int update_modes(int *cone_mode, int *sparse_index) /* Set cone/non-cone mode appropriately */ core_apply_sparse_checkout = 1; - if (*cone_mode == 1) { + if (*cone_mode == 1 || *cone_mode == -1) { mode = MODE_CONE_PATTERNS; core_sparse_checkout_cone = 1; } else { @@ -413,6 +413,9 @@ static int update_modes(int *cone_mode, int *sparse_index) /* force an index rewrite */ repo_read_index(the_repository); the_repository->index->updated_workdir = 1; + + if (!*sparse_index) + ensure_full_index(the_repository->index); } return 0; @@ -934,6 +937,9 @@ int cmd_sparse_checkout(int argc, const char **argv, const char *prefix) git_config(git_default_config, NULL); + prepare_repo_settings(the_repository); + the_repository->settings.command_requires_full_index = 0; + if (argc > 0) { if (!strcmp(argv[0], "list")) return sparse_checkout_list(argc, argv); diff --git a/builtin/stash.c b/builtin/stash.c index 3fe549f7d3..30fa101460 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -117,6 +117,10 @@ struct stash_info { int has_u; }; +#define STASH_INFO_INIT { \ + .revision = STRBUF_INIT, \ +} + static void free_stash_info(struct stash_info *info) { strbuf_release(&info->revision); @@ -158,10 +162,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) if (argc == 1) commit = argv[0]; - strbuf_init(&info->revision, 0); if (!commit) { if (!ref_exists(ref_stash)) { - free_stash_info(info); fprintf_ln(stderr, _("No stash entries found.")); return -1; } @@ -175,11 +177,8 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) revision = info->revision.buf; - if (get_oid(revision, &info->w_commit)) { - error(_("%s is not a valid reference"), revision); - free_stash_info(info); - return -1; - } + if (get_oid(revision, &info->w_commit)) + return error(_("%s is not a valid reference"), revision); assert_stash_like(info, revision); @@ -198,7 +197,7 @@ static int get_stash_info(struct stash_info *info, int argc, const char **argv) info->is_stash_ref = !strcmp(expanded_ref, ref_stash); break; default: /* Invalid or ambiguous */ - free_stash_info(info); + break; } free(expanded_ref); @@ -357,7 +356,7 @@ static int restore_untracked(struct object_id *u_tree) cp.git_cmd = 1; strvec_push(&cp.args, "read-tree"); strvec_push(&cp.args, oid_to_hex(u_tree)); - strvec_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", + strvec_pushf(&cp.env, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp)) { remove_path(stash_index_path.buf); @@ -367,7 +366,7 @@ static int restore_untracked(struct object_id *u_tree) child_process_init(&cp); cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout-index", "--all", NULL); - strvec_pushf(&cp.env_array, "GIT_INDEX_FILE=%s", + strvec_pushf(&cp.env, "GIT_INDEX_FILE=%s", stash_index_path.buf); res = run_command(&cp); @@ -603,9 +602,9 @@ restore_untracked: */ cp.git_cmd = 1; cp.dir = prefix; - strvec_pushf(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT"=%s", + strvec_pushf(&cp.env, GIT_WORK_TREE_ENVIRONMENT"=%s", absolute_path(get_git_work_tree())); - strvec_pushf(&cp.env_array, GIT_DIR_ENVIRONMENT"=%s", + strvec_pushf(&cp.env, GIT_DIR_ENVIRONMENT"=%s", absolute_path(get_git_dir())); strvec_push(&cp.args, "status"); run_command(&cp); @@ -616,10 +615,10 @@ restore_untracked: static int apply_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int quiet = 0; int index = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "index", &index, @@ -631,9 +630,10 @@ static int apply_stash(int argc, const char **argv, const char *prefix) git_stash_apply_usage, 0); if (get_stash_info(&info, argc, argv)) - return -1; + goto cleanup; ret = do_apply_stash(prefix, &info, index, quiet); +cleanup: free_stash_info(&info); return ret; } @@ -669,20 +669,25 @@ static int do_drop_stash(struct stash_info *info, int quiet) return 0; } -static void assert_stash_ref(struct stash_info *info) +static int get_stash_info_assert(struct stash_info *info, int argc, + const char **argv) { - if (!info->is_stash_ref) { - error(_("'%s' is not a stash reference"), info->revision.buf); - free_stash_info(info); - exit(1); - } + int ret = get_stash_info(info, argc, argv); + + if (ret < 0) + return ret; + + if (!info->is_stash_ref) + return error(_("'%s' is not a stash reference"), info->revision.buf); + + return 0; } static int drop_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int quiet = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_END() @@ -691,22 +696,21 @@ static int drop_stash(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_stash_drop_usage, 0); - if (get_stash_info(&info, argc, argv)) - return -1; - - assert_stash_ref(&info); + if (get_stash_info_assert(&info, argc, argv)) + goto cleanup; ret = do_drop_stash(&info, quiet); +cleanup: free_stash_info(&info); return ret; } static int pop_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; int index = 0; int quiet = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "index", &index, @@ -717,25 +721,25 @@ static int pop_stash(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, git_stash_pop_usage, 0); - if (get_stash_info(&info, argc, argv)) - return -1; + if (get_stash_info_assert(&info, argc, argv)) + goto cleanup; - assert_stash_ref(&info); if ((ret = do_apply_stash(prefix, &info, index, quiet))) printf_ln(_("The stash entry is kept in case " "you need it again.")); else ret = do_drop_stash(&info, quiet); +cleanup: free_stash_info(&info); return ret; } static int branch_stash(int argc, const char **argv, const char *prefix) { - int ret; + int ret = -1; const char *branch = NULL; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct child_process cp = CHILD_PROCESS_INIT; struct option options[] = { OPT_END() @@ -752,7 +756,7 @@ static int branch_stash(int argc, const char **argv, const char *prefix) branch = argv[0]; if (get_stash_info(&info, argc - 1, argv + 1)) - return -1; + goto cleanup; cp.git_cmd = 1; strvec_pushl(&cp.args, "checkout", "-b", NULL); @@ -764,8 +768,8 @@ static int branch_stash(int argc, const char **argv, const char *prefix) if (!ret && info.is_stash_ref) ret = do_drop_stash(&info, 0); +cleanup: free_stash_info(&info); - return ret; } @@ -843,8 +847,8 @@ static void diff_include_untracked(const struct stash_info *info, struct diff_op static int show_stash(int argc, const char **argv, const char *prefix) { int i; - int ret = 0; - struct stash_info info; + int ret = -1; + struct stash_info info = STASH_INFO_INIT; struct rev_info rev; struct strvec stash_args = STRVEC_INIT; struct strvec revision_args = STRVEC_INIT; @@ -862,6 +866,7 @@ static int show_stash(int argc, const char **argv, const char *prefix) UNTRACKED_ONLY, PARSE_OPT_NONEG), OPT_END() }; + int do_usage = 0; init_diff_ui_defaults(); git_config(git_diff_ui_config, NULL); @@ -879,10 +884,8 @@ static int show_stash(int argc, const char **argv, const char *prefix) strvec_push(&revision_args, argv[i]); } - ret = get_stash_info(&info, stash_args.nr, stash_args.v); - strvec_clear(&stash_args); - if (ret) - return -1; + if (get_stash_info(&info, stash_args.nr, stash_args.v)) + goto cleanup; /* * The config settings are applied only if there are not passed @@ -896,16 +899,14 @@ static int show_stash(int argc, const char **argv, const char *prefix) rev.diffopt.output_format |= DIFF_FORMAT_PATCH; if (!show_stat && !show_patch) { - free_stash_info(&info); - return 0; + ret = 0; + goto cleanup; } } argc = setup_revisions(revision_args.nr, revision_args.v, &rev, NULL); - if (argc > 1) { - free_stash_info(&info); - usage_with_options(git_stash_show_usage, options); - } + if (argc > 1) + goto usage; if (!rev.diffopt.output_format) { rev.diffopt.output_format = DIFF_FORMAT_PATCH; diff_setup_done(&rev.diffopt); @@ -930,8 +931,17 @@ static int show_stash(int argc, const char **argv, const char *prefix) } log_tree_diff_flush(&rev); + ret = diff_result_code(&rev.diffopt, 0); +cleanup: + strvec_clear(&stash_args); free_stash_info(&info); - return diff_result_code(&rev.diffopt, 0); + release_revisions(&rev); + if (do_usage) + usage_with_options(git_stash_show_usage, options); + return ret; +usage: + do_usage = 1; + goto cleanup; } static int do_store_stash(const struct object_id *w_commit, const char *stash_msg, @@ -1065,7 +1075,6 @@ static int check_changes_tracked_files(const struct pathspec *ps) goto done; } - object_array_clear(&rev.pending); result = run_diff_files(&rev, 0); if (diff_result_code(&rev.diffopt, result)) { ret = 1; @@ -1073,7 +1082,7 @@ static int check_changes_tracked_files(const struct pathspec *ps) } done: - clear_pathspec(&rev.prune_data); + release_revisions(&rev); return ret; } @@ -1106,7 +1115,7 @@ static int save_untracked_files(struct stash_info *info, struct strbuf *msg, cp_upd_index.git_cmd = 1; strvec_pushl(&cp_upd_index.args, "update-index", "-z", "--add", "--remove", "--stdin", NULL); - strvec_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", + strvec_pushf(&cp_upd_index.env, "GIT_INDEX_FILE=%s", stash_index_path.buf); strbuf_addf(&untracked_msg, "untracked files on %s\n", msg->buf); @@ -1180,7 +1189,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, cp_read_tree.git_cmd = 1; strvec_pushl(&cp_read_tree.args, "read-tree", "HEAD", NULL); - strvec_pushf(&cp_read_tree.env_array, "GIT_INDEX_FILE=%s", + strvec_pushf(&cp_read_tree.env, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (run_command(&cp_read_tree)) { ret = -1; @@ -1267,7 +1276,7 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps strvec_pushl(&cp_upd_index.args, "update-index", "--ignore-skip-worktree-entries", "-z", "--add", "--remove", "--stdin", NULL); - strvec_pushf(&cp_upd_index.env_array, "GIT_INDEX_FILE=%s", + strvec_pushf(&cp_upd_index.env, "GIT_INDEX_FILE=%s", stash_index_path.buf); if (pipe_command(&cp_upd_index, diff_output.buf, diff_output.len, @@ -1284,9 +1293,7 @@ static int stash_working_tree(struct stash_info *info, const struct pathspec *ps done: discard_index(&istate); - UNLEAK(rev); - object_array_clear(&rev.pending); - clear_pathspec(&rev.prune_data); + release_revisions(&rev); strbuf_release(&diff_output); remove_path(stash_index_path.buf); return ret; @@ -1428,9 +1435,9 @@ done: static int create_stash(int argc, const char **argv, const char *prefix) { - int ret = 0; + int ret; struct strbuf stash_msg_buf = STRBUF_INIT; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct pathspec ps; /* Starting with argv[1], since argv[0] is "create" */ @@ -1445,6 +1452,7 @@ static int create_stash(int argc, const char **argv, const char *prefix) if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); + free_stash_info(&info); strbuf_release(&stash_msg_buf); return ret; } @@ -1453,7 +1461,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q int keep_index, int patch_mode, int include_untracked, int only_staged) { int ret = 0; - struct stash_info info; + struct stash_info info = STASH_INFO_INIT; struct strbuf patch = STRBUF_INIT; struct strbuf stash_msg_buf = STRBUF_INIT; struct strbuf untracked_files = STRBUF_INIT; @@ -1543,7 +1551,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q cp.git_cmd = 1; if (startup_info->original_cwd) { cp.dir = startup_info->original_cwd; - strvec_pushf(&cp.env_array, "%s=%s", + strvec_pushf(&cp.env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, the_repository->worktree); } @@ -1652,6 +1660,7 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q } done: + free_stash_info(&info); strbuf_release(&stash_msg_buf); return ret; } diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 1a8e5d0621..5c77dfcffe 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -72,135 +72,6 @@ static char *get_default_remote(void) return repo_get_default_remote(the_repository); } -static int starts_with_dot_slash(const char *str) -{ - return str[0] == '.' && is_dir_sep(str[1]); -} - -static int starts_with_dot_dot_slash(const char *str) -{ - return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]); -} - -/* - * Returns 1 if it was the last chop before ':'. - */ -static int chop_last_dir(char **remoteurl, int is_relative) -{ - char *rfind = find_last_dir_sep(*remoteurl); - if (rfind) { - *rfind = '\0'; - return 0; - } - - rfind = strrchr(*remoteurl, ':'); - if (rfind) { - *rfind = '\0'; - return 1; - } - - if (is_relative || !strcmp(".", *remoteurl)) - die(_("cannot strip one component off url '%s'"), - *remoteurl); - - free(*remoteurl); - *remoteurl = xstrdup("."); - return 0; -} - -/* - * The `url` argument is the URL that navigates to the submodule origin - * repo. When relative, this URL is relative to the superproject origin - * URL repo. The `up_path` argument, if specified, is the relative - * path that navigates from the submodule working tree to the superproject - * working tree. Returns the origin URL of the submodule. - * - * Return either an absolute URL or filesystem path (if the superproject - * origin URL is an absolute URL or filesystem path, respectively) or a - * relative file system path (if the superproject origin URL is a relative - * file system path). - * - * When the output is a relative file system path, the path is either - * relative to the submodule working tree, if up_path is specified, or to - * the superproject working tree otherwise. - * - * NEEDSWORK: This works incorrectly on the domain and protocol part. - * remote_url url outcome expectation - * http://a.com/b ../c http://a.com/c as is - * http://a.com/b/ ../c http://a.com/c same as previous line, but - * ignore trailing slash in url - * http://a.com/b ../../c http://c error out - * http://a.com/b ../../../c http:/c error out - * http://a.com/b ../../../../c http:c error out - * http://a.com/b ../../../../../c .:c error out - * NEEDSWORK: Given how chop_last_dir() works, this function is broken - * when a local part has a colon in its path component, too. - */ -static char *relative_url(const char *remote_url, - const char *url, - const char *up_path) -{ - int is_relative = 0; - int colonsep = 0; - char *out; - char *remoteurl = xstrdup(remote_url); - struct strbuf sb = STRBUF_INIT; - size_t len = strlen(remoteurl); - - if (is_dir_sep(remoteurl[len-1])) - remoteurl[len-1] = '\0'; - - if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl)) - is_relative = 0; - else { - is_relative = 1; - /* - * Prepend a './' to ensure all relative - * remoteurls start with './' or '../' - */ - if (!starts_with_dot_slash(remoteurl) && - !starts_with_dot_dot_slash(remoteurl)) { - strbuf_reset(&sb); - strbuf_addf(&sb, "./%s", remoteurl); - free(remoteurl); - remoteurl = strbuf_detach(&sb, NULL); - } - } - /* - * When the url starts with '../', remove that and the - * last directory in remoteurl. - */ - while (url) { - if (starts_with_dot_dot_slash(url)) { - url += 3; - colonsep |= chop_last_dir(&remoteurl, is_relative); - } else if (starts_with_dot_slash(url)) - url += 2; - else - break; - } - strbuf_reset(&sb); - strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url); - if (ends_with(url, "/")) - strbuf_setlen(&sb, sb.len - 1); - free(remoteurl); - - if (starts_with_dot_slash(sb.buf)) - out = xstrdup(sb.buf + 2); - else - out = xstrdup(sb.buf); - - if (!up_path || !is_relative) { - strbuf_release(&sb); - return out; - } - - strbuf_reset(&sb); - strbuf_addf(&sb, "%s%s", up_path, out); - free(out); - return strbuf_detach(&sb, NULL); -} - static char *resolve_relative_url(const char *rel_url, const char *up_path, int quiet) { char *remoteurl, *resolved_url; @@ -292,7 +163,7 @@ static char *compute_rev_name(const char *sub_path, const char* object_id) for (d = describe_argv; *d; d++) { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.dir = sub_path; cp.git_cmd = 1; cp.no_stderr = 1; @@ -479,7 +350,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, if (!is_submodule_populated_gently(path, NULL)) goto cleanup; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); /* * For the purpose of executing <command> in the submodule, @@ -499,12 +370,12 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, char *toplevel = xgetcwd(); struct strbuf sb = STRBUF_INIT; - strvec_pushf(&cp.env_array, "name=%s", sub->name); - strvec_pushf(&cp.env_array, "sm_path=%s", path); - strvec_pushf(&cp.env_array, "displaypath=%s", displaypath); - strvec_pushf(&cp.env_array, "sha1=%s", + strvec_pushf(&cp.env, "name=%s", sub->name); + strvec_pushf(&cp.env, "sm_path=%s", path); + strvec_pushf(&cp.env, "displaypath=%s", displaypath); + strvec_pushf(&cp.env, "sha1=%s", oid_to_hex(ce_oid)); - strvec_pushf(&cp.env_array, "toplevel=%s", toplevel); + strvec_pushf(&cp.env, "toplevel=%s", toplevel); /* * Since the path variable was accessible from the script @@ -513,7 +384,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, * on windows. And since environment variables are * case-insensitive in windows, it interferes with the * existing PATH variable. Hence, to avoid that, we expose - * path via the args strvec and not via env_array. + * path via the args strvec and not via env. */ sq_quote_buf(&sb, path); strvec_pushf(&cp.args, "path=%s; %s", @@ -536,7 +407,7 @@ static void runcommand_in_submodule_cb(const struct cache_entry *list_item, cpr.git_cmd = 1; cpr.dir = path; - prepare_submodule_repo_env(&cpr.env_array); + prepare_submodule_repo_env(&cpr.env); strvec_pushl(&cpr.args, "--super-prefix", NULL); strvec_pushf(&cpr.args, "%s/", displaypath); @@ -592,6 +463,18 @@ static int module_foreach(int argc, const char **argv, const char *prefix) return 0; } +static int starts_with_dot_slash(const char *const path) +{ + return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH | + PATH_MATCH_XPLATFORM); +} + +static int starts_with_dot_dot_slash(const char *const path) +{ + return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH | + PATH_MATCH_XPLATFORM); +} + struct init_cb { const char *prefix; const char *superprefix; @@ -766,7 +649,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, { char *displaypath; struct strvec diff_files_args = STRVEC_INIT; - struct rev_info rev; + struct rev_info rev = REV_INFO_INIT; int diff_files_result; struct strbuf buf = STRBUF_INIT; const char *git_dir; @@ -833,7 +716,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, cpr.git_cmd = 1; cpr.dir = path; - prepare_submodule_repo_env(&cpr.env_array); + prepare_submodule_repo_env(&cpr.env); strvec_push(&cpr.args, "--super-prefix"); strvec_pushf(&cpr.args, "%s/", displaypath); @@ -853,6 +736,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, cleanup: strvec_clear(&diff_files_args); free(displaypath); + release_revisions(&rev); } static void status_submodule_cb(const struct cache_entry *list_item, @@ -955,7 +839,7 @@ static char *verify_submodule_committish(const char *sm_path, cp_rev_parse.git_cmd = 1; cp_rev_parse.dir = sm_path; - prepare_submodule_repo_env(&cp_rev_parse.env_array); + prepare_submodule_repo_env(&cp_rev_parse.env); strvec_pushl(&cp_rev_parse.args, "rev-parse", "-q", "--short", NULL); strvec_pushf(&cp_rev_parse.args, "%s^0", committish); strvec_push(&cp_rev_parse.args, "--"); @@ -996,7 +880,7 @@ static void print_submodule_summary(struct summary_cb *info, char *errmsg, cp_log.git_cmd = 1; cp_log.dir = p->sm_path; - prepare_submodule_repo_env(&cp_log.env_array); + prepare_submodule_repo_env(&cp_log.env); strvec_pushl(&cp_log.args, "log", NULL); if (S_ISGITLINK(p->mod_src) && S_ISGITLINK(p->mod_dst)) { @@ -1113,7 +997,7 @@ static void generate_submodule_summary(struct summary_cb *info, cp_rev_list.git_cmd = 1; cp_rev_list.dir = p->sm_path; - prepare_submodule_repo_env(&cp_rev_list.env_array); + prepare_submodule_repo_env(&cp_rev_list.env); if (!capture_command(&cp_rev_list, &sb_rev_list, 0)) total_commits = atoi(sb_rev_list.buf); @@ -1231,6 +1115,7 @@ static int compute_summary_module_list(struct object_id *head_oid, struct strvec diff_args = STRVEC_INIT; struct rev_info rev; struct module_cb_list list = MODULE_CB_LIST_INIT; + int ret = 0; strvec_push(&diff_args, get_diff_cmd(diff_cmd)); if (info->cached) @@ -1256,11 +1141,13 @@ static int compute_summary_module_list(struct object_id *head_oid, setup_work_tree(); if (read_cache_preload(&rev.diffopt.pathspec) < 0) { perror("read_cache_preload"); - return -1; + ret = -1; + goto cleanup; } } else if (read_cache() < 0) { perror("read_cache"); - return -1; + ret = -1; + goto cleanup; } if (diff_cmd == DIFF_INDEX) @@ -1268,8 +1155,10 @@ static int compute_summary_module_list(struct object_id *head_oid, else run_diff_files(&rev, 0); prepare_submodule_summary(info, &list); +cleanup: strvec_clear(&diff_args); - return 0; + release_revisions(&rev); + return ret; } static int module_summary(int argc, const char **argv, const char *prefix) @@ -1414,7 +1303,7 @@ static void sync_submodule(const char *path, const char *prefix, cpr.git_cmd = 1; cpr.dir = path; - prepare_submodule_repo_env(&cpr.env_array); + prepare_submodule_repo_env(&cpr.env); strvec_push(&cpr.args, "--super-prefix"); strvec_pushf(&cpr.args, "%s/", displaypath); @@ -1819,7 +1708,7 @@ static int clone_submodule(struct module_clone_data *clone_data) strvec_push(&cp.args, clone_data->path); cp.git_cmd = 1; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.no_stdin = 1; if(run_command(&cp)) @@ -2294,7 +2183,7 @@ static int is_tip_reachable(const char *path, struct object_id *oid) cp.no_stderr = 1; strvec_pushl(&cp.args, "rev-list", "-n", "1", hex, "--not", "--all", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); if (capture_command(&cp, &rev, GIT_MAX_HEXSZ + 1) || rev.len) return 0; @@ -2306,7 +2195,7 @@ static int fetch_in_submodule(const char *module_path, int depth, int quiet, str { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.dir = xstrdup(module_path); @@ -2363,7 +2252,7 @@ static int run_update_command(struct update_data *ud, int subforce) strvec_push(&cp.args, oid); cp.dir = xstrdup(ud->sm_path); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); if (run_command(&cp)) { switch (ud->update_strategy.type) { case SM_UPDATE_CHECKOUT: @@ -2629,7 +2518,7 @@ static int update_submodule(struct update_data *update_data) cp.dir = update_data->sm_path; cp.git_cmd = 1; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); update_data_to_args(&next, &cp.args); /* die() if child process die()'d */ @@ -3122,9 +3011,9 @@ static void append_fetch_remotes(struct strbuf *msg, const char *git_dir_path) struct strbuf sb_remote_out = STRBUF_INIT; cp_remote.git_cmd = 1; - strvec_pushf(&cp_remote.env_array, + strvec_pushf(&cp_remote.env, "GIT_DIR=%s", git_dir_path); - strvec_push(&cp_remote.env_array, "GIT_WORK_TREE=."); + strvec_push(&cp_remote.env, "GIT_WORK_TREE=."); strvec_pushl(&cp_remote.args, "remote", "-v", NULL); if (!capture_command(&cp_remote, &sb_remote_out, 0)) { char *next_line; @@ -3208,7 +3097,7 @@ static int add_submodule(const struct add_data *add_data) if (clone_submodule(&clone_data)) return -1; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.dir = add_data->sm_path; /* @@ -3377,7 +3266,7 @@ static int module_add(int argc, const char **argv, const char *prefix) N_("reference repository")), OPT_BOOL(0, "dissociate", &dissociate, N_("borrow the objects from reference repositories")), OPT_STRING(0, "name", &add_data.sm_name, N_("name"), - N_("sets the submodule’s name to the given string " + N_("sets the submodule's name to the given string " "instead of defaulting to its path")), OPT_INTEGER(0, "depth", &add_data.depth, N_("depth for shallow clones")), OPT_END() diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index dbeb0680a5..56d05e2725 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "cache.h" +#include "bulk-checkin.h" #include "config.h" #include "object-store.h" #include "object.h" @@ -503,10 +504,12 @@ static void unpack_all(void) if (!quiet) progress = start_progress(_("Unpacking objects"), nr_objects); CALLOC_ARRAY(obj_list, nr_objects); + begin_odb_transaction(); for (i = 0; i < nr_objects; i++) { unpack_one(i); display_progress(progress, i + 1); } + end_odb_transaction(); stop_progress(&progress); if (delta_list) diff --git a/builtin/update-index.c b/builtin/update-index.c index 876112abb2..b62249905f 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -5,6 +5,7 @@ */ #define USE_THE_INDEX_COMPATIBILITY_MACROS #include "cache.h" +#include "bulk-checkin.h" #include "config.h" #include "lockfile.h" #include "quote.h" @@ -57,6 +58,14 @@ static void report(const char *fmt, ...) if (!verbose) return; + /* + * It is possible, though unlikely, that a caller could use the verbose + * output to synchronize with addition of objects to the object + * database. The current implementation of ODB transactions leaves + * objects invisible while a transaction is active, so flush the + * transaction here before reporting a change made by update-index. + */ + flush_odb_transaction(); va_start(vp, fmt); vprintf(fmt, vp); putchar('\n'); @@ -1116,6 +1125,12 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) */ parse_options_start(&ctx, argc, argv, prefix, options, PARSE_OPT_STOP_AT_NON_OPTION); + + /* + * Allow the object layer to optimize adding multiple objects in + * a batch. + */ + begin_odb_transaction(); while (ctx.argc) { if (parseopt_state != PARSE_OPT_DONE) parseopt_state = parse_options_step(&ctx, options, @@ -1190,6 +1205,11 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) strbuf_release(&buf); } + /* + * By now we have added all of the new objects + */ + end_odb_transaction(); + if (split_index > 0) { if (git_config_get_split_index() == 0) warning(_("core.splitIndex is set to false; " @@ -1237,6 +1257,22 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) if (fsmonitor > 0) { enum fsmonitor_mode fsm_mode = fsm_settings__get_mode(r); + enum fsmonitor_reason reason = fsm_settings__get_reason(r); + + /* + * The user wants to turn on FSMonitor using the command + * line argument. (We don't know (or care) whether that + * is the IPC or HOOK version.) + * + * Use one of the __get routines to force load the FSMonitor + * config settings into the repo-settings. That will detect + * whether the file system is compatible so that we can stop + * here with a nice error message. + */ + if (reason > FSMONITOR_REASON_OK) + die("%s", + fsm_settings__get_incompatible_msg(r, reason)); + if (fsm_mode == FSMONITOR_MODE_DISABLED) { warning(_("core.fsmonitor is unset; " "set it if you really want to " diff --git a/builtin/worktree.c b/builtin/worktree.c index 8b32cd1651..cd62eef240 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -301,7 +301,7 @@ static int checkout_worktree(const struct add_opts *opts, strvec_pushl(&cp.args, "reset", "--hard", "--no-recurse-submodules", NULL); if (opts->quiet) strvec_push(&cp.args, "--quiet"); - strvec_pushv(&cp.env_array, child_env->v); + strvec_pushv(&cp.env, child_env->v); return run_command(&cp); } @@ -433,7 +433,7 @@ static int add_worktree(const char *path, const char *refname, strvec_push(&cp.args, "--quiet"); } - strvec_pushv(&cp.env_array, child_env.v); + strvec_pushv(&cp.env, child_env.v); ret = run_command(&cp); if (ret) goto done; @@ -989,9 +989,9 @@ static void check_clean_worktree(struct worktree *wt, validate_no_submodules(wt); child_process_init(&cp); - strvec_pushf(&cp.env_array, "%s=%s/.git", + strvec_pushf(&cp.env, "%s=%s/.git", GIT_DIR_ENVIRONMENT, wt->path); - strvec_pushf(&cp.env_array, "%s=%s", + strvec_pushf(&cp.env, "%s=%s", GIT_WORK_TREE_ENVIRONMENT, wt->path); strvec_pushl(&cp.args, "status", "--porcelain", "--ignore-submodules=none", diff --git a/bulk-checkin.c b/bulk-checkin.c index 6d6c37171c..98ec893842 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -3,16 +3,21 @@ */ #include "cache.h" #include "bulk-checkin.h" +#include "lockfile.h" #include "repository.h" #include "csum-file.h" #include "pack.h" #include "strbuf.h" +#include "string-list.h" +#include "tmp-objdir.h" #include "packfile.h" #include "object-store.h" -static struct bulk_checkin_state { - unsigned plugged:1; +static int odb_transaction_nesting; +static struct tmp_objdir *bulk_fsync_objdir; + +static struct bulk_checkin_packfile { char *pack_tmp_name; struct hashfile *f; off_t offset; @@ -21,7 +26,7 @@ static struct bulk_checkin_state { struct pack_idx_entry **written; uint32_t alloc_written; uint32_t nr_written; -} state; +} bulk_checkin_packfile; static void finish_tmp_packfile(struct strbuf *basename, const char *pack_tmp_name, @@ -33,13 +38,13 @@ static void finish_tmp_packfile(struct strbuf *basename, char *idx_tmp_name = NULL; stage_tmp_packfiles(basename, pack_tmp_name, written_list, nr_written, - pack_idx_opts, hash, &idx_tmp_name); + NULL, pack_idx_opts, hash, &idx_tmp_name); rename_tmp_packfile_idx(basename, &idx_tmp_name); free(idx_tmp_name); } -static void finish_bulk_checkin(struct bulk_checkin_state *state) +static void flush_bulk_checkin_packfile(struct bulk_checkin_packfile *state) { unsigned char hash[GIT_MAX_RAWSZ]; struct strbuf packname = STRBUF_INIT; @@ -80,7 +85,41 @@ clear_exit: reprepare_packed_git(the_repository); } -static int already_written(struct bulk_checkin_state *state, struct object_id *oid) +/* + * Cleanup after batch-mode fsync_object_files. + */ +static void flush_batch_fsync(void) +{ + struct strbuf temp_path = STRBUF_INIT; + struct tempfile *temp; + + if (!bulk_fsync_objdir) + return; + + /* + * Issue a full hardware flush against a temporary file to ensure + * that all objects are durable before any renames occur. The code in + * fsync_loose_object_bulk_checkin has already issued a writeout + * request, but it has not flushed any writeback cache in the storage + * hardware or any filesystem logs. This fsync call acts as a barrier + * to ensure that the data in each new object file is durable before + * the final name is visible. + */ + strbuf_addf(&temp_path, "%s/bulk_fsync_XXXXXX", get_object_directory()); + temp = xmks_tempfile(temp_path.buf); + fsync_or_die(get_tempfile_fd(temp), get_tempfile_path(temp)); + delete_tempfile(&temp); + strbuf_release(&temp_path); + + /* + * Make the object files visible in the primary ODB after their data is + * fully durable. + */ + tmp_objdir_migrate(bulk_fsync_objdir); + bulk_fsync_objdir = NULL; +} + +static int already_written(struct bulk_checkin_packfile *state, struct object_id *oid) { int i; @@ -112,7 +151,7 @@ static int already_written(struct bulk_checkin_state *state, struct object_id *o * status before calling us just in case we ask it to call us again * with a new pack. */ -static int stream_to_pack(struct bulk_checkin_state *state, +static int stream_to_pack(struct bulk_checkin_packfile *state, git_hash_ctx *ctx, off_t *already_hashed_to, int fd, size_t size, enum object_type type, const char *path, unsigned flags) @@ -189,7 +228,7 @@ static int stream_to_pack(struct bulk_checkin_state *state, } /* Lazily create backing packfile for the state */ -static void prepare_to_stream(struct bulk_checkin_state *state, +static void prepare_to_stream(struct bulk_checkin_packfile *state, unsigned flags) { if (!(flags & HASH_WRITE_OBJECT) || state->f) @@ -204,7 +243,7 @@ static void prepare_to_stream(struct bulk_checkin_state *state, die_errno("unable to write pack header"); } -static int deflate_to_pack(struct bulk_checkin_state *state, +static int deflate_to_pack(struct bulk_checkin_packfile *state, struct object_id *result_oid, int fd, size_t size, enum object_type type, const char *path, @@ -251,7 +290,7 @@ static int deflate_to_pack(struct bulk_checkin_state *state, BUG("should not happen"); hashfile_truncate(state->f, &checkpoint); state->offset = checkpoint.offset; - finish_bulk_checkin(state); + flush_bulk_checkin_packfile(state); if (lseek(fd, seekback, SEEK_SET) == (off_t) -1) return error("cannot seek back"); } @@ -274,25 +313,67 @@ static int deflate_to_pack(struct bulk_checkin_state *state, return 0; } +void prepare_loose_object_bulk_checkin(void) +{ + /* + * We lazily create the temporary object directory + * the first time an object might be added, since + * callers may not know whether any objects will be + * added at the time they call begin_odb_transaction. + */ + if (!odb_transaction_nesting || bulk_fsync_objdir) + return; + + bulk_fsync_objdir = tmp_objdir_create("bulk-fsync"); + if (bulk_fsync_objdir) + tmp_objdir_replace_primary_odb(bulk_fsync_objdir, 0); +} + +void fsync_loose_object_bulk_checkin(int fd, const char *filename) +{ + /* + * If we have an active ODB transaction, we issue a call that + * cleans the filesystem page cache but avoids a hardware flush + * command. Later on we will issue a single hardware flush + * before renaming the objects to their final names as part of + * flush_batch_fsync. + */ + if (!bulk_fsync_objdir || + git_fsync(fd, FSYNC_WRITEOUT_ONLY) < 0) { + fsync_or_die(fd, filename); + } +} + int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags) { - int status = deflate_to_pack(&state, oid, fd, size, type, + int status = deflate_to_pack(&bulk_checkin_packfile, oid, fd, size, type, path, flags); - if (!state.plugged) - finish_bulk_checkin(&state); + if (!odb_transaction_nesting) + flush_bulk_checkin_packfile(&bulk_checkin_packfile); return status; } -void plug_bulk_checkin(void) +void begin_odb_transaction(void) { - state.plugged = 1; + odb_transaction_nesting += 1; } -void unplug_bulk_checkin(void) +void flush_odb_transaction(void) { - state.plugged = 0; - if (state.f) - finish_bulk_checkin(&state); + flush_batch_fsync(); + flush_bulk_checkin_packfile(&bulk_checkin_packfile); +} + +void end_odb_transaction(void) +{ + odb_transaction_nesting -= 1; + if (odb_transaction_nesting < 0) + BUG("Unbalanced ODB transaction nesting"); + + if (odb_transaction_nesting) + return; + + flush_odb_transaction(); } diff --git a/bulk-checkin.h b/bulk-checkin.h index b26f3dc3b7..8281b9cb15 100644 --- a/bulk-checkin.h +++ b/bulk-checkin.h @@ -6,11 +6,34 @@ #include "cache.h" +void prepare_loose_object_bulk_checkin(void); +void fsync_loose_object_bulk_checkin(int fd, const char *filename); + int index_bulk_checkin(struct object_id *oid, int fd, size_t size, enum object_type type, const char *path, unsigned flags); -void plug_bulk_checkin(void); -void unplug_bulk_checkin(void); +/* + * Tell the object database to optimize for adding + * multiple objects. end_odb_transaction must be called + * to make new objects visible. Transactions can be nested, + * and objects are only visible after the outermost transaction + * is complete or the transaction is flushed. + */ +void begin_odb_transaction(void); + +/* + * Make any objects that are currently part of a pending object + * database transaction visible. It is valid to call this function + * even if no transaction is active. + */ +void flush_odb_transaction(void); + +/* + * Tell the object database to make any objects from the + * current transaction visible if this is the final nested + * transaction. + */ +void end_odb_transaction(void); #endif @@ -66,8 +66,8 @@ static int parse_bundle_signature(struct bundle_header *header, const char *line return -1; } -static int parse_bundle_header(int fd, struct bundle_header *header, - const char *report_path) +int read_bundle_header_fd(int fd, struct bundle_header *header, + const char *report_path) { struct strbuf buf = STRBUF_INIT; int status = 0; @@ -143,7 +143,7 @@ int read_bundle_header(const char *path, struct bundle_header *header) if (fd < 0) return error(_("could not open '%s'"), path); - return parse_bundle_header(fd, header, path); + return read_bundle_header_fd(fd, header, path); } int is_bundle(const char *path, int quiet) @@ -153,7 +153,7 @@ int is_bundle(const char *path, int quiet) if (fd < 0) return 0; - fd = parse_bundle_header(fd, &header, quiet ? NULL : path); + fd = read_bundle_header_fd(fd, &header, quiet ? NULL : path); if (fd >= 0) close(fd); bundle_header_release(&header); @@ -196,14 +196,16 @@ int verify_bundle(struct repository *r, * to be verbose about the errors */ struct string_list *p = &header->prerequisites; - struct rev_info revs; + struct rev_info revs = REV_INFO_INIT; const char *argv[] = {NULL, "--all", NULL}; struct commit *commit; int i, ret = 0, req_nr; const char *message = _("Repository lacks these prerequisite commits:"); - if (!r || !r->objects || !r->objects->odb) - return error(_("need a repository to verify a bundle")); + if (!r || !r->objects || !r->objects->odb) { + ret = error(_("need a repository to verify a bundle")); + goto cleanup; + } repo_init_revisions(r, &revs, NULL); for (i = 0; i < p->nr; i++) { @@ -221,7 +223,7 @@ int verify_bundle(struct repository *r, error("%s %s", oid_to_hex(oid), name); } if (revs.pending.nr != p->nr) - return ret; + goto cleanup; req_nr = revs.pending.nr; setup_revisions(2, argv, &revs, NULL); @@ -284,6 +286,8 @@ int verify_bundle(struct repository *r, printf_ln("The bundle uses this filter: %s", list_objects_filter_spec(&header->filter)); } +cleanup: + release_revisions(&revs); return ret; } @@ -24,6 +24,8 @@ void bundle_header_release(struct bundle_header *header); int is_bundle(const char *path, int quiet); int read_bundle_header(const char *path, struct bundle_header *header); +int read_bundle_header_fd(int fd, struct bundle_header *header, + const char *report_path); int create_bundle(struct repository *r, const char *path, int argc, const char **argv, struct strvec *pack_options, int version); diff --git a/cache-tree.c b/cache-tree.c index 6752f69d51..ff794d940f 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -3,6 +3,7 @@ #include "tree.h" #include "tree-walk.h" #include "cache-tree.h" +#include "bulk-checkin.h" #include "object-store.h" #include "replace-object.h" #include "promisor-remote.h" @@ -100,6 +101,33 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *it, const char *path) return find_subtree(it, path, pathlen, 1); } +struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path) +{ + const char *slash; + int namelen; + struct cache_tree_sub it_sub = { + .cache_tree = it, + }; + struct cache_tree_sub *down = &it_sub; + + while (down) { + slash = strchrnul(path, '/'); + namelen = slash - path; + down->cache_tree->entry_count = -1; + if (!*slash) { + int pos; + pos = cache_tree_subtree_pos(down->cache_tree, path, namelen); + if (0 <= pos) + return down->cache_tree->down[pos]->cache_tree; + return NULL; + } + down = find_subtree(it, path, namelen, 0); + path = slash + 1; + } + + return NULL; +} + static int do_invalidate_path(struct cache_tree *it, const char *path) { /* a/b/c @@ -474,8 +502,10 @@ int cache_tree_update(struct index_state *istate, int flags) trace_performance_enter(); trace2_region_enter("cache_tree", "update", the_repository); + begin_odb_transaction(); i = update_one(istate->cache_tree, istate->cache, istate->cache_nr, "", 0, &skip, flags); + end_odb_transaction(); trace2_region_leave("cache_tree", "update", the_repository); trace_performance_leave("cache_tree_update"); if (i < 0) @@ -692,14 +722,14 @@ struct tree* write_in_core_index_as_tree(struct repository *repo) { ret = write_index_as_tree_internal(&o, index_state, was_valid, 0, NULL); if (ret == WRITE_TREE_UNMERGED_INDEX) { int i; - fprintf(stderr, "BUG: There are unmerged index entries:\n"); + bug("there are unmerged index entries:"); for (i = 0; i < index_state->cache_nr; i++) { const struct cache_entry *ce = index_state->cache[i]; if (ce_stage(ce)) - fprintf(stderr, "BUG: %d %.*s\n", ce_stage(ce), - (int)ce_namelen(ce), ce->name); + bug("%d %.*s", ce_stage(ce), + (int)ce_namelen(ce), ce->name); } - BUG("unmerged index entries when writing inmemory index"); + BUG("unmerged index entries when writing in-core index"); } return lookup_tree(repo, &index_state->cache_tree->oid); diff --git a/cache-tree.h b/cache-tree.h index 8efeccebfc..f75f8e74dc 100644 --- a/cache-tree.h +++ b/cache-tree.h @@ -29,6 +29,8 @@ struct cache_tree_sub *cache_tree_sub(struct cache_tree *, const char *); int cache_tree_subtree_pos(struct cache_tree *it, const char *path, int pathlen); +struct cache_tree *cache_tree_find_path(struct cache_tree *it, const char *path); + void cache_tree_write(struct strbuf *, struct cache_tree *root); struct cache_tree *cache_tree_read(const char *buffer, unsigned long size); @@ -310,6 +310,29 @@ struct untracked_cache; struct progress; struct pattern_list; +enum sparse_index_mode { + /* + * There are no sparse directories in the index at all. + * + * Repositories that don't use cone-mode sparse-checkout will + * always have their indexes in this mode. + */ + INDEX_EXPANDED = 0, + + /* + * The index has already been collapsed to sparse directories + * whereever possible. + */ + INDEX_COLLAPSED, + + /* + * The sparse directories that exist are outside the + * sparse-checkout boundary, but it is possible that some file + * entries could collapse to sparse directory entries. + */ + INDEX_PARTIALLY_SPARSE, +}; + struct index_state { struct cache_entry **cache; unsigned int version; @@ -323,14 +346,8 @@ struct index_state { drop_cache_tree : 1, updated_workdir : 1, updated_skipworktree : 1, - fsmonitor_has_run_once : 1, - - /* - * sparse_index == 1 when sparse-directory - * entries exist. Requires sparse-checkout - * in cone mode. - */ - sparse_index : 1; + fsmonitor_has_run_once : 1; + enum sparse_index_mode sparse_index; struct hashmap name_hash; struct hashmap dir_hash; struct object_id oid; @@ -1031,6 +1048,10 @@ enum fsync_component { FSYNC_COMPONENT_INDEX | \ FSYNC_COMPONENT_REFERENCE) +#ifndef FSYNC_COMPONENTS_PLATFORM_DEFAULT +#define FSYNC_COMPONENTS_PLATFORM_DEFAULT FSYNC_COMPONENTS_DEFAULT +#endif + /* * A bitmask indicating which components of the repo should be fsynced. */ @@ -1040,7 +1061,8 @@ extern int use_fsync; enum fsync_method { FSYNC_METHOD_FSYNC, - FSYNC_METHOD_WRITEOUT_ONLY + FSYNC_METHOD_WRITEOUT_ONLY, + FSYNC_METHOD_BATCH, }; extern enum fsync_method fsync_method; @@ -1766,6 +1788,11 @@ void fsync_or_die(int fd, const char *); int fsync_component(enum fsync_component component, int fd); void fsync_component_or_die(enum fsync_component component, int fd, const char *msg); +static inline int batch_fsync_enabled(enum fsync_component component) +{ + return (fsync_components & component) && (fsync_method == FSYNC_METHOD_BATCH); +} + ssize_t read_in_full(int fd, void *buf, size_t count); ssize_t write_in_full(int fd, const void *buf, size_t count); ssize_t pread_in_full(int fd, void *buf, size_t count, off_t offset); diff --git a/chunk-format.c b/chunk-format.c index 1c3dca62e2..0275b74a89 100644 --- a/chunk-format.c +++ b/chunk-format.c @@ -181,3 +181,15 @@ int read_chunk(struct chunkfile *cf, return CHUNK_NOT_FOUND; } + +uint8_t oid_version(const struct git_hash_algo *algop) +{ + switch (hash_algo_by_ptr(algop)) { + case GIT_HASH_SHA1: + return 1; + case GIT_HASH_SHA256: + return 2; + default: + die(_("invalid hash version")); + } +} diff --git a/chunk-format.h b/chunk-format.h index 9ccbe00377..7885aa0848 100644 --- a/chunk-format.h +++ b/chunk-format.h @@ -2,6 +2,7 @@ #define CHUNK_FORMAT_H #include "git-compat-util.h" +#include "hash.h" struct hashfile; struct chunkfile; @@ -65,4 +66,6 @@ int read_chunk(struct chunkfile *cf, chunk_read_fn fn, void *data); +uint8_t oid_version(const struct git_hash_algo *algop); + #endif @@ -1,5 +1,50 @@ # Library of functions shared by all CI scripts +if test true != "$GITHUB_ACTIONS" +then + begin_group () { :; } + end_group () { :; } + + group () { + shift + "$@" + } + set -x +else + begin_group () { + need_to_end_group=t + echo "::group::$1" >&2 + set -x + } + + end_group () { + test -n "$need_to_end_group" || return 0 + set +x + need_to_end_group= + echo '::endgroup::' >&2 + } + trap end_group EXIT + + group () { + set +x + begin_group "$1" + shift + "$@" + res=$? + end_group + return $res + } + + begin_group "CI setup" +fi + +# Set 'exit on error' for all CI scripts to let the caller know that +# something went wrong. +# +# We already enabled tracing executed commands earlier. This helps by showing +# how # environment variables are set and and dependencies are installed. +set -e + skip_branch_tip_with_tag () { # Sometimes, a branch is pushed at the same time the tag that points # at the same commit as the tip of the branch is pushed, and building @@ -69,8 +114,7 @@ skip_good_tree () { exit 0 } -check_unignored_build_artifacts () -{ +check_unignored_build_artifacts () { ! git ls-files --other --exclude-standard --error-unmatch \ -- ':/*' 2>/dev/null || { @@ -79,18 +123,16 @@ check_unignored_build_artifacts () } } +handle_failed_tests () { + return 1 +} + # GitHub Action doesn't set TERM, which is required by tput export TERM=${TERM:-dumb} # Clear MAKEFLAGS that may come from the outside world. export MAKEFLAGS= -# Set 'exit on error' for all CI scripts to let the caller know that -# something went wrong. -# Set tracing executed commands, primarily setting environment variables -# and installing dependencies. -set -ex - if test -n "$SYSTEM_COLLECTIONURI" || test -n "$SYSTEM_TASKDEFINITIONSURI" then CI_TYPE=azure-pipelines @@ -124,11 +166,31 @@ then CI_JOB_ID="$GITHUB_RUN_ID" CC="${CC_PACKAGE:-${CC:-gcc}}" DONT_SKIP_TAGS=t + handle_failed_tests () { + mkdir -p t/failed-test-artifacts + echo "FAILED_TEST_ARTIFACTS=t/failed-test-artifacts" >>$GITHUB_ENV + + for test_exit in t/test-results/*.exit + do + test 0 != "$(cat "$test_exit")" || continue + + test_name="${test_exit%.exit}" + test_name="${test_name##*/}" + printf "\\e[33m\\e[1m=== Failed test: ${test_name} ===\\e[m\\n" + echo "The full logs are in the artifacts attached to this run." + cat "t/test-results/$test_name.markup" + + trash_dir="t/trash directory.$test_name" + cp "t/test-results/$test_name.out" t/failed-test-artifacts/ + tar czf t/failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir" + done + return 1 + } cache_dir="$HOME/none" export GIT_PROVE_OPTS="--timer --jobs 10" - export GIT_TEST_OPTS="--verbose-log -x" + export GIT_TEST_OPTS="--verbose-log -x --github-workflow-markup" MAKEFLAGS="$MAKEFLAGS --jobs=10" test windows != "$CI_OS_NAME" || GIT_TEST_OPTS="--no-chain-lint --no-bin-wrappers $GIT_TEST_OPTS" @@ -211,3 +273,6 @@ linux-leaks) esac MAKEFLAGS="$MAKEFLAGS CC=${CC:-cc}" + +end_group +set -x diff --git a/ci/run-build-and-tests.sh b/ci/run-build-and-tests.sh index d671f40278..8ebff42596 100755 --- a/ci/run-build-and-tests.sh +++ b/ci/run-build-and-tests.sh @@ -10,7 +10,7 @@ windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; *) ln -s "$cache_dir/.prove" t/.prove;; esac -export MAKE_TARGETS="all test" +run_tests=t case "$jobname" in linux-gcc) @@ -41,14 +41,16 @@ pedantic) # Don't run the tests; we only care about whether Git can be # built. export DEVOPTS=pedantic - export MAKE_TARGETS=all + run_tests= ;; esac -# Any new "test" targets should not go after this "make", but should -# adjust $MAKE_TARGETS. Otherwise compilation-only targets above will -# start running tests. -make $MAKE_TARGETS +group Build make +if test -n "$run_tests" +then + group "Run tests" make test || + handle_failed_tests +fi check_unignored_build_artifacts save_good_tree diff --git a/ci/run-static-analysis.sh b/ci/run-static-analysis.sh index 65bcebda41..0d51e5ce0e 100755 --- a/ci/run-static-analysis.sh +++ b/ci/run-static-analysis.sh @@ -29,4 +29,6 @@ fi make hdr-check || exit 1 +make check-pot + save_good_tree diff --git a/ci/run-test-slice.sh b/ci/run-test-slice.sh index f8c2c3106a..a3c67956a8 100755 --- a/ci/run-test-slice.sh +++ b/ci/run-test-slice.sh @@ -10,8 +10,9 @@ windows*) cmd //c mklink //j t\\.prove "$(cygpath -aw "$cache_dir/.prove")";; *) ln -s "$cache_dir/.prove" t/.prove;; esac -make --quiet -C t T="$(cd t && +group "Run tests" make --quiet -C t T="$(cd t && ./helper/test-tool path-utils slice-tests "$1" "$2" t[0-9]*.sh | - tr '\n' ' ')" + tr '\n' ' ')" || +handle_failed_tests check_unignored_build_artifacts diff --git a/commit-graph.c b/commit-graph.c index 7943da3848..92d4503336 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -193,18 +193,6 @@ char *get_commit_graph_chain_filename(struct object_directory *odb) return xstrfmt("%s/info/commit-graphs/commit-graph-chain", odb->path); } -static uint8_t oid_version(void) -{ - switch (hash_algo_by_ptr(the_hash_algo)) { - case GIT_HASH_SHA1: - return 1; - case GIT_HASH_SHA256: - return 2; - default: - die(_("invalid hash version")); - } -} - static struct commit_graph *alloc_commit_graph(void) { struct commit_graph *g = xcalloc(1, sizeof(*g)); @@ -365,9 +353,9 @@ struct commit_graph *parse_commit_graph(struct repository *r, } hash_version = *(unsigned char*)(data + 5); - if (hash_version != oid_version()) { + if (hash_version != oid_version(the_hash_algo)) { error(_("commit-graph hash version %X does not match version %X"), - hash_version, oid_version()); + hash_version, oid_version(the_hash_algo)); return NULL; } @@ -1924,7 +1912,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) hashwrite_be32(f, GRAPH_SIGNATURE); hashwrite_u8(f, GRAPH_VERSION); - hashwrite_u8(f, oid_version()); + hashwrite_u8(f, oid_version(the_hash_algo)); hashwrite_u8(f, get_num_chunks(cf)); hashwrite_u8(f, ctx->num_commit_graphs_after - 1); @@ -421,17 +421,14 @@ int parse_commit_buffer(struct repository *r, struct commit *item, const void *b if (item->object.parsed) return 0; - - if (item->parents) { - /* - * Presumably this is leftover from an earlier failed parse; - * clear it out in preparation for us re-parsing (we'll hit the - * same error, but that's good, since it lets our caller know - * the result cannot be trusted. - */ - free_commit_list(item->parents); - item->parents = NULL; - } + /* + * Presumably this is leftover from an earlier failed parse; + * clear it out in preparation for us re-parsing (we'll hit the + * same error, but that's good, since it lets our caller know + * the result cannot be trusted. + */ + free_commit_list(item->parents); + item->parents = NULL; tail += size; if (tail <= bufptr + tree_entry_len + 1 || memcmp(bufptr, "tree ", 5) || diff --git a/common-main.c b/common-main.c index 29fb7452f8..c531372f3f 100644 --- a/common-main.c +++ b/common-main.c @@ -55,10 +55,30 @@ int main(int argc, const char **argv) result = cmd_main(argc, argv); + /* Not exit(3), but a wrapper calling our common_exit() */ + exit(result); +} + +static void check_bug_if_BUG(void) +{ + if (!bug_called_must_BUG) + return; + BUG("on exit(): had bug() call(s) in this process without explicit BUG_if_bug()"); +} + +/* We wrap exit() to call common_exit() in git-compat-util.h */ +int common_exit(const char *file, int line, int code) +{ /* - * We define exit() to call trace2_cmd_exit_fl() in - * git-compat-util.h. Whether we reach this or exit() - * elsewhere we'll always run our trace2 exit handler. + * For non-POSIX systems: Take the lowest 8 bits of the "code" + * to e.g. turn -1 into 255. On a POSIX system this is + * redundant, see exit(3) and wait(2), but as it doesn't harm + * anything there we don't need to guard this with an "ifdef". */ - exit(result); + code &= 0xff; + + check_bug_if_BUG(); + trace2_cmd_exit_fl(file, line, code); + + return code; } diff --git a/compat/fsmonitor/fsm-health-darwin.c b/compat/fsmonitor/fsm-health-darwin.c new file mode 100644 index 0000000000..b9f709e854 --- /dev/null +++ b/compat/fsmonitor/fsm-health-darwin.c @@ -0,0 +1,24 @@ +#include "cache.h" +#include "config.h" +#include "fsmonitor.h" +#include "fsm-health.h" +#include "fsmonitor--daemon.h" + +int fsm_health__ctor(struct fsmonitor_daemon_state *state) +{ + return 0; +} + +void fsm_health__dtor(struct fsmonitor_daemon_state *state) +{ + return; +} + +void fsm_health__loop(struct fsmonitor_daemon_state *state) +{ + return; +} + +void fsm_health__stop_async(struct fsmonitor_daemon_state *state) +{ +} diff --git a/compat/fsmonitor/fsm-health-win32.c b/compat/fsmonitor/fsm-health-win32.c new file mode 100644 index 0000000000..2ea08c1d4e --- /dev/null +++ b/compat/fsmonitor/fsm-health-win32.c @@ -0,0 +1,278 @@ +#include "cache.h" +#include "config.h" +#include "fsmonitor.h" +#include "fsm-health.h" +#include "fsmonitor--daemon.h" + +/* + * Every minute wake up and test our health. + */ +#define WAIT_FREQ_MS (60 * 1000) + +/* + * State machine states for each of the interval functions + * used for polling our health. + */ +enum interval_fn_ctx { + CTX_INIT = 0, + CTX_TERM, + CTX_TIMER +}; + +typedef int (interval_fn)(struct fsmonitor_daemon_state *state, + enum interval_fn_ctx ctx); + +struct fsm_health_data +{ + HANDLE hEventShutdown; + + HANDLE hHandles[1]; /* the array does not own these handles */ +#define HEALTH_SHUTDOWN 0 + int nr_handles; /* number of active event handles */ + + struct wt_moved + { + wchar_t wpath[MAX_PATH + 1]; + BY_HANDLE_FILE_INFORMATION bhfi; + } wt_moved; +}; + +/* + * Lookup the system unique ID for the path. This is as close as + * we get to an inode number, but this also contains volume info, + * so it is a little stronger. + */ +static int lookup_bhfi(wchar_t *wpath, + BY_HANDLE_FILE_INFORMATION *bhfi) +{ + DWORD desired_access = FILE_LIST_DIRECTORY; + DWORD share_mode = + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; + HANDLE hDir; + + hDir = CreateFileW(wpath, desired_access, share_mode, NULL, + OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); + if (hDir == INVALID_HANDLE_VALUE) { + error(_("[GLE %ld] health thread could not open '%ls'"), + GetLastError(), wpath); + return -1; + } + + if (!GetFileInformationByHandle(hDir, bhfi)) { + error(_("[GLE %ld] health thread getting BHFI for '%ls'"), + GetLastError(), wpath); + CloseHandle(hDir); + return -1; + } + + CloseHandle(hDir); + return 0; +} + +/* + * Compare the relevant fields from two system unique IDs. + * We use this to see if two different handles to the same + * path actually refer to the same *instance* of the file + * or directory. + */ +static int bhfi_eq(const BY_HANDLE_FILE_INFORMATION *bhfi_1, + const BY_HANDLE_FILE_INFORMATION *bhfi_2) +{ + return (bhfi_1->dwVolumeSerialNumber == bhfi_2->dwVolumeSerialNumber && + bhfi_1->nFileIndexHigh == bhfi_2->nFileIndexHigh && + bhfi_1->nFileIndexLow == bhfi_2->nFileIndexLow); +} + +/* + * Shutdown if the original worktree root directory been deleted, + * moved, or renamed? + * + * Since the main thread did a "chdir(getenv($HOME))" and our CWD + * is not in the worktree root directory and because the listener + * thread added FILE_SHARE_DELETE to the watch handle, it is possible + * for the root directory to be moved or deleted while we are still + * watching it. We want to detect that here and force a shutdown. + * + * Granted, a delete MAY cause some operations to fail, such as + * GetOverlappedResult(), but it is not guaranteed. And because + * ReadDirectoryChangesW() only reports on changes *WITHIN* the + * directory, not changes *ON* the directory, our watch will not + * receive a delete event for it. + * + * A move/rename of the worktree root will also not generate an event. + * And since the listener thread already has an open handle, it may + * continue to receive events for events within the directory. + * However, the pathname of the named-pipe was constructed using the + * original location of the worktree root. (Remember named-pipes are + * stored in the NPFS and not in the actual file system.) Clients + * trying to talk to the worktree after the move/rename will not + * reach our daemon process, since we're still listening on the + * pipe with original path. + * + * Furthermore, if the user does something like: + * + * $ mv repo repo.old + * $ git init repo + * + * A new daemon cannot be started in the new instance of "repo" + * because the named-pipe is still being used by the daemon on + * the original instance. + * + * So, detect move/rename/delete and shutdown. This should also + * handle unsafe drive removal. + * + * We use the file system unique ID to distinguish the original + * directory instance from a new instance and force a shutdown + * if the unique ID changes. + * + * Since a worktree move/rename/delete/unmount doesn't happen + * that often (and we can't get an immediate event anyway), we + * use a timeout and periodically poll it. + */ +static int has_worktree_moved(struct fsmonitor_daemon_state *state, + enum interval_fn_ctx ctx) +{ + struct fsm_health_data *data = state->health_data; + BY_HANDLE_FILE_INFORMATION bhfi; + int r; + + switch (ctx) { + case CTX_TERM: + return 0; + + case CTX_INIT: + if (xutftowcs_path(data->wt_moved.wpath, + state->path_worktree_watch.buf) < 0) { + error(_("could not convert to wide characters: '%s'"), + state->path_worktree_watch.buf); + return -1; + } + + /* + * On the first call we lookup the unique sequence ID for + * the worktree root directory. + */ + return lookup_bhfi(data->wt_moved.wpath, &data->wt_moved.bhfi); + + case CTX_TIMER: + r = lookup_bhfi(data->wt_moved.wpath, &bhfi); + if (r) + return r; + if (!bhfi_eq(&data->wt_moved.bhfi, &bhfi)) { + error(_("BHFI changed '%ls'"), data->wt_moved.wpath); + return -1; + } + return 0; + + default: + die(_("unhandled case in 'has_worktree_moved': %d"), + (int)ctx); + } + + return 0; +} + + +int fsm_health__ctor(struct fsmonitor_daemon_state *state) +{ + struct fsm_health_data *data; + + CALLOC_ARRAY(data, 1); + + data->hEventShutdown = CreateEvent(NULL, TRUE, FALSE, NULL); + + data->hHandles[HEALTH_SHUTDOWN] = data->hEventShutdown; + data->nr_handles++; + + state->health_data = data; + return 0; +} + +void fsm_health__dtor(struct fsmonitor_daemon_state *state) +{ + struct fsm_health_data *data; + + if (!state || !state->health_data) + return; + + data = state->health_data; + + CloseHandle(data->hEventShutdown); + + FREE_AND_NULL(state->health_data); +} + +/* + * A table of the polling functions. + */ +static interval_fn *table[] = { + has_worktree_moved, + NULL, /* must be last */ +}; + +/* + * Call all of the polling functions in the table. + * Shortcut and return first error. + * + * Return 0 if all succeeded. + */ +static int call_all(struct fsmonitor_daemon_state *state, + enum interval_fn_ctx ctx) +{ + int k; + + for (k = 0; table[k]; k++) { + int r = table[k](state, ctx); + if (r) + return r; + } + + return 0; +} + +void fsm_health__loop(struct fsmonitor_daemon_state *state) +{ + struct fsm_health_data *data = state->health_data; + int r; + + r = call_all(state, CTX_INIT); + if (r < 0) + goto force_error_stop; + if (r > 0) + goto force_shutdown; + + for (;;) { + DWORD dwWait = WaitForMultipleObjects(data->nr_handles, + data->hHandles, + FALSE, WAIT_FREQ_MS); + + if (dwWait == WAIT_OBJECT_0 + HEALTH_SHUTDOWN) + goto clean_shutdown; + + if (dwWait == WAIT_TIMEOUT) { + r = call_all(state, CTX_TIMER); + if (r < 0) + goto force_error_stop; + if (r > 0) + goto force_shutdown; + continue; + } + + error(_("health thread wait failed [GLE %ld]"), + GetLastError()); + goto force_error_stop; + } + +force_error_stop: + state->health_error_code = -1; +force_shutdown: + ipc_server_stop_async(state->ipc_server_data); +clean_shutdown: + call_all(state, CTX_TERM); + return; +} + +void fsm_health__stop_async(struct fsmonitor_daemon_state *state) +{ + SetEvent(state->health_data->hHandles[HEALTH_SHUTDOWN]); +} diff --git a/compat/fsmonitor/fsm-health.h b/compat/fsmonitor/fsm-health.h new file mode 100644 index 0000000000..45547ba938 --- /dev/null +++ b/compat/fsmonitor/fsm-health.h @@ -0,0 +1,47 @@ +#ifndef FSM_HEALTH_H +#define FSM_HEALTH_H + +/* This needs to be implemented by each backend */ + +#ifdef HAVE_FSMONITOR_DAEMON_BACKEND + +struct fsmonitor_daemon_state; + +/* + * Initialize platform-specific data for the fsmonitor health thread. + * This will be called from the main thread PRIOR to staring the + * thread. + * + * Returns 0 if successful. + * Returns -1 otherwise. + */ +int fsm_health__ctor(struct fsmonitor_daemon_state *state); + +/* + * Cleanup platform-specific data for the health thread. + * This will be called from the main thread AFTER joining the thread. + */ +void fsm_health__dtor(struct fsmonitor_daemon_state *state); + +/* + * The main body of the platform-specific event loop to monitor the + * health of the daemon process. This will run in the health thread. + * + * The health thread should call `ipc_server_stop_async()` if it needs + * to cause a shutdown. (It should NOT do so if it receives a shutdown + * shutdown signal.) + * + * It should set `state->health_error_code` to -1 if the daemon should exit + * with an error. + */ +void fsm_health__loop(struct fsmonitor_daemon_state *state); + +/* + * Gently request that the health thread shutdown. + * It does not wait for it to stop. The caller should do a JOIN + * to wait for it. + */ +void fsm_health__stop_async(struct fsmonitor_daemon_state *state); + +#endif /* HAVE_FSMONITOR_DAEMON_BACKEND */ +#endif /* FSM_HEALTH_H */ diff --git a/compat/fsmonitor/fsm-listen-darwin.c b/compat/fsmonitor/fsm-listen-darwin.c index dc8a33130a..8e208e8289 100644 --- a/compat/fsmonitor/fsm-listen-darwin.c +++ b/compat/fsmonitor/fsm-listen-darwin.c @@ -27,7 +27,7 @@ #include "fsm-listen.h" #include "fsmonitor--daemon.h" -struct fsmonitor_daemon_backend_data +struct fsm_listen_data { CFStringRef cfsr_worktree_path; CFStringRef cfsr_gitdir_path; @@ -100,12 +100,17 @@ static void log_flags_set(const char *path, const FSEventStreamEventFlags flag) if (flag & kFSEventStreamEventFlagItemCloned) strbuf_addstr(&msg, "ItemCloned|"); - trace_printf_key(&trace_fsmonitor, "fsevent: '%s', flags=%u %s", + trace_printf_key(&trace_fsmonitor, "fsevent: '%s', flags=0x%x %s", path, flag, msg.buf); strbuf_release(&msg); } +static int ef_is_root_changed(const FSEventStreamEventFlags ef) +{ + return (ef & kFSEventStreamEventFlagRootChanged); +} + static int ef_is_root_delete(const FSEventStreamEventFlags ef) { return (ef & kFSEventStreamEventFlagItemIsDir && @@ -125,6 +130,60 @@ static int ef_is_dropped(const FSEventStreamEventFlags ef) ef & kFSEventStreamEventFlagUserDropped); } +/* + * If an `xattr` change is the only reason we received this event, + * then silently ignore it. Git doesn't care about xattr's. We + * have to be careful here because the kernel can combine multiple + * events for a single path. And because events always have certain + * bits set, such as `ItemIsFile` or `ItemIsDir`. + * + * Return 1 if we should ignore it. + */ +static int ef_ignore_xattr(const FSEventStreamEventFlags ef) +{ + static const FSEventStreamEventFlags mask = + kFSEventStreamEventFlagItemChangeOwner | + kFSEventStreamEventFlagItemCreated | + kFSEventStreamEventFlagItemFinderInfoMod | + kFSEventStreamEventFlagItemInodeMetaMod | + kFSEventStreamEventFlagItemModified | + kFSEventStreamEventFlagItemRemoved | + kFSEventStreamEventFlagItemRenamed | + kFSEventStreamEventFlagItemXattrMod | + kFSEventStreamEventFlagItemCloned; + + return ((ef & mask) == kFSEventStreamEventFlagItemXattrMod); +} + +/* + * On MacOS we have to adjust for Unicode composition insensitivity + * (where NFC and NFD spellings are not respected). The different + * spellings are essentially aliases regardless of how the path is + * actually stored on the disk. + * + * This is related to "core.precomposeUnicode" (which wants to try + * to hide NFD completely and treat everything as NFC). Here, we + * don't know what the value the client has (or will have) for this + * config setting when they make a query, so assume the worst and + * emit both when the OS gives us an NFD path. + */ +static void my_add_path(struct fsmonitor_batch *batch, const char *path) +{ + char *composed; + + /* add the NFC or NFD path as received from the OS */ + fsmonitor_batch__add_path(batch, path); + + /* if NFD, also add the corresponding NFC spelling */ + composed = (char *)precompose_string_if_needed(path); + if (!composed || composed == path) + return; + + fsmonitor_batch__add_path(batch, composed); + free(composed); +} + + static void fsevent_callback(ConstFSEventStreamRef streamRef, void *ctx, size_t num_of_events, @@ -133,7 +192,7 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, const FSEventStreamEventId event_ids[]) { struct fsmonitor_daemon_state *state = ctx; - struct fsmonitor_daemon_backend_data *data = state->backend_data; + struct fsm_listen_data *data = state->listen_data; char **paths = (char **)event_paths; struct fsmonitor_batch *batch = NULL; struct string_list cookie_list = STRING_LIST_INIT_DUP; @@ -190,6 +249,33 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, continue; } + if (ef_is_root_changed(event_flags[k])) { + /* + * The spelling of the pathname of the root directory + * has changed. This includes the name of the root + * directory itself or of any parent directory in the + * path. + * + * (There may be other conditions that throw this, + * but I couldn't find any information on it.) + * + * Force a shutdown now and avoid things getting + * out of sync. The Unix domain socket is inside + * the .git directory and a spelling change will make + * it hard for clients to rendezvous with us. + */ + trace_printf_key(&trace_fsmonitor, + "event: root changed"); + goto force_shutdown; + } + + if (ef_ignore_xattr(event_flags[k])) { + trace_printf_key(&trace_fsmonitor, + "ignore-xattr: '%s', flags=0x%x", + path_k, event_flags[k]); + continue; + } + switch (fsmonitor_classify_path_absolute(state, path_k)) { case IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX: @@ -248,7 +334,7 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, if (!batch) batch = fsmonitor_batch__new(); - fsmonitor_batch__add_path(batch, rel); + my_add_path(batch, rel); } if (event_flags[k] & kFSEventStreamEventFlagItemIsDir) { @@ -261,7 +347,7 @@ static void fsevent_callback(ConstFSEventStreamRef streamRef, if (!batch) batch = fsmonitor_batch__new(); - fsmonitor_batch__add_path(batch, tmp.buf); + my_add_path(batch, tmp.buf); } break; @@ -318,11 +404,11 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state) NULL, NULL }; - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; const void *dir_array[2]; CALLOC_ARRAY(data, 1); - state->backend_data = data; + state->listen_data = data; data->cfsr_worktree_path = CFStringCreateWithCString( NULL, state->path_worktree_watch.buf, kCFStringEncodingUTF8); @@ -354,18 +440,18 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state) failed: error(_("Unable to create FSEventStream.")); - FREE_AND_NULL(state->backend_data); + FREE_AND_NULL(state->listen_data); return -1; } void fsm_listen__dtor(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; - if (!state || !state->backend_data) + if (!state || !state->listen_data) return; - data = state->backend_data; + data = state->listen_data; if (data->stream) { if (data->stream_started) @@ -375,14 +461,14 @@ void fsm_listen__dtor(struct fsmonitor_daemon_state *state) FSEventStreamRelease(data->stream); } - FREE_AND_NULL(state->backend_data); + FREE_AND_NULL(state->listen_data); } void fsm_listen__stop_async(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; - data = state->backend_data; + data = state->listen_data; data->shutdown_style = SHUTDOWN_EVENT; CFRunLoopStop(data->rl); @@ -390,9 +476,9 @@ void fsm_listen__stop_async(struct fsmonitor_daemon_state *state) void fsm_listen__loop(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; - data = state->backend_data; + data = state->listen_data; data->rl = CFRunLoopGetCurrent(); @@ -409,7 +495,7 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) switch (data->shutdown_style) { case FORCE_ERROR_STOP: - state->error_code = -1; + state->listen_error_code = -1; /* fall thru */ case FORCE_SHUTDOWN: ipc_server_stop_async(state->ipc_server_data); @@ -421,7 +507,7 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) return; force_error_stop_without_loop: - state->error_code = -1; + state->listen_error_code = -1; ipc_server_stop_async(state->ipc_server_data); return; } diff --git a/compat/fsmonitor/fsm-listen-win32.c b/compat/fsmonitor/fsm-listen-win32.c index 5b928ab66e..03df8d951b 100644 --- a/compat/fsmonitor/fsm-listen-win32.c +++ b/compat/fsmonitor/fsm-listen-win32.c @@ -25,6 +25,9 @@ struct one_watch DWORD count; struct strbuf path; + wchar_t wpath_longname[MAX_PATH + 1]; + DWORD wpath_longname_len; + HANDLE hDir; HANDLE hEvent; OVERLAPPED overlapped; @@ -34,9 +37,24 @@ struct one_watch * need to later call GetOverlappedResult() and possibly CancelIoEx(). */ BOOL is_active; + + /* + * Are shortnames enabled on the containing drive? This is + * always true for "C:/" drives and usually never true for + * other drives. + * + * We only set this for the worktree because we only need to + * convert shortname paths to longname paths for items we send + * to clients. (We don't care about shortname expansion for + * paths inside a GITDIR because we never send them to + * clients.) + */ + BOOL has_shortnames; + BOOL has_tilde; + wchar_t dotgit_shortname[16]; /* for 8.3 name */ }; -struct fsmonitor_daemon_backend_data +struct fsm_listen_data { struct one_watch *watch_worktree; struct one_watch *watch_gitdir; @@ -51,17 +69,18 @@ struct fsmonitor_daemon_backend_data }; /* - * Convert the WCHAR path from the notification into UTF8 and - * then normalize it. + * Convert the WCHAR path from the event into UTF8 and normalize it. + * + * `wpath_len` is in WCHARS not bytes. */ -static int normalize_path_in_utf8(FILE_NOTIFY_INFORMATION *info, +static int normalize_path_in_utf8(wchar_t *wpath, DWORD wpath_len, struct strbuf *normalized_path) { int reserve; int len = 0; strbuf_reset(normalized_path); - if (!info->FileNameLength) + if (!wpath_len) goto normalize; /* @@ -70,12 +89,12 @@ static int normalize_path_in_utf8(FILE_NOTIFY_INFORMATION *info, * sequence of 2 UTF8 characters. That should let us * avoid ERROR_INSUFFICIENT_BUFFER 99.9+% of the time. */ - reserve = info->FileNameLength + 1; + reserve = 2 * wpath_len + 1; strbuf_grow(normalized_path, reserve); for (;;) { - len = WideCharToMultiByte(CP_UTF8, 0, info->FileName, - info->FileNameLength / sizeof(WCHAR), + len = WideCharToMultiByte(CP_UTF8, 0, + wpath, wpath_len, normalized_path->buf, strbuf_avail(normalized_path) - 1, NULL, NULL); @@ -83,9 +102,7 @@ static int normalize_path_in_utf8(FILE_NOTIFY_INFORMATION *info, goto normalize; if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { error(_("[GLE %ld] could not convert path to UTF-8: '%.*ls'"), - GetLastError(), - (int)(info->FileNameLength / sizeof(WCHAR)), - info->FileName); + GetLastError(), (int)wpath_len, wpath); return -1; } @@ -98,9 +115,176 @@ normalize: return strbuf_normalize_path(normalized_path); } +/* + * See if the worktree root directory has shortnames enabled. + * This will help us decide if we need to do an expensive shortname + * to longname conversion on every notification event. + * + * We do not want to create a file to test this, so we assume that the + * root directory contains a ".git" file or directory. (Our caller + * only calls us for the worktree root, so this should be fine.) + * + * Remember the spelling of the shortname for ".git" if it exists. + */ +static void check_for_shortnames(struct one_watch *watch) +{ + wchar_t buf_in[MAX_PATH + 1]; + wchar_t buf_out[MAX_PATH + 1]; + wchar_t *last; + wchar_t *p; + + /* build L"<wt-root-path>/.git" */ + swprintf(buf_in, ARRAY_SIZE(buf_in) - 1, L"%ls.git", + watch->wpath_longname); + + if (!GetShortPathNameW(buf_in, buf_out, ARRAY_SIZE(buf_out))) + return; + + /* + * Get the final filename component of the shortpath. + * We know that the path does not have a final slash. + */ + for (last = p = buf_out; *p; p++) + if (*p == L'/' || *p == '\\') + last = p + 1; + + if (!wcscmp(last, L".git")) + return; + + watch->has_shortnames = 1; + wcsncpy(watch->dotgit_shortname, last, + ARRAY_SIZE(watch->dotgit_shortname)); + + /* + * The shortname for ".git" is usually of the form "GIT~1", so + * we should be able to avoid shortname to longname mapping on + * every notification event if the source string does not + * contain a "~". + * + * However, the documentation for GetLongPathNameW() says + * that there are filesystems that don't follow that pattern + * and warns against this optimization. + * + * Lets test this. + */ + if (wcschr(watch->dotgit_shortname, L'~')) + watch->has_tilde = 1; +} + +enum get_relative_result { + GRR_NO_CONVERSION_NEEDED, + GRR_HAVE_CONVERSION, + GRR_SHUTDOWN, +}; + +/* + * Info notification paths are relative to the root of the watch. + * If our CWD is still at the root, then we can use relative paths + * to convert from shortnames to longnames. If our process has a + * different CWD, then we need to construct an absolute path, do + * the conversion, and then return the root-relative portion. + * + * We use the longname form of the root as our basis and assume that + * it already has a trailing slash. + * + * `wpath_len` is in WCHARS not bytes. + */ +static enum get_relative_result get_relative_longname( + struct one_watch *watch, + const wchar_t *wpath, DWORD wpath_len, + wchar_t *wpath_longname, size_t bufsize_wpath_longname) +{ + wchar_t buf_in[2 * MAX_PATH + 1]; + wchar_t buf_out[MAX_PATH + 1]; + DWORD root_len; + DWORD out_len; + + /* + * Build L"<wt-root-path>/<event-rel-path>" + * Note that the <event-rel-path> might not be null terminated + * so we avoid swprintf() constructions. + */ + root_len = watch->wpath_longname_len; + if (root_len + wpath_len >= ARRAY_SIZE(buf_in)) { + /* + * This should not happen. We cannot append the observed + * relative path onto the end of the worktree root path + * without overflowing the buffer. Just give up. + */ + return GRR_SHUTDOWN; + } + wcsncpy(buf_in, watch->wpath_longname, root_len); + wcsncpy(buf_in + root_len, wpath, wpath_len); + buf_in[root_len + wpath_len] = 0; + + /* + * We don't actually know if the source pathname is a + * shortname or a longname. This Windows routine allows + * either to be given as input. + */ + out_len = GetLongPathNameW(buf_in, buf_out, ARRAY_SIZE(buf_out)); + if (!out_len) { + /* + * The shortname to longname conversion can fail for + * various reasons, for example if the file has been + * deleted. (That is, if we just received a + * delete-file notification event and the file is + * already gone, we can't ask the file system to + * lookup the longname for it. Likewise, for moves + * and renames where we are given the old name.) + * + * Since deleting or moving a file or directory by its + * shortname is rather obscure, I'm going ignore the + * failure and ask the caller to report the original + * relative path. This seems kinder than failing here + * and forcing a resync. Besides, forcing a resync on + * every file/directory delete would effectively + * cripple monitoring. + * + * We might revisit this in the future. + */ + return GRR_NO_CONVERSION_NEEDED; + } + + if (!wcscmp(buf_in, buf_out)) { + /* + * The path does not have a shortname alias. + */ + return GRR_NO_CONVERSION_NEEDED; + } + + if (wcsncmp(buf_in, buf_out, root_len)) { + /* + * The spelling of the root directory portion of the computed + * longname has changed. This should not happen. Basically, + * it means that we don't know where (without recomputing the + * longname of just the root directory) to split out the + * relative path. Since this should not happen, I'm just + * going to let this fail and force a shutdown (because all + * subsequent events are probably going to see the same + * mismatch). + */ + return GRR_SHUTDOWN; + } + + if (out_len - root_len >= bufsize_wpath_longname) { + /* + * This should not happen. We cannot copy the root-relative + * portion of the path into the provided buffer without an + * overrun. Just give up. + */ + return GRR_SHUTDOWN; + } + + /* Return the worktree root-relative portion of the longname. */ + + wcscpy(wpath_longname, buf_out + root_len); + return GRR_HAVE_CONVERSION; +} + void fsm_listen__stop_async(struct fsmonitor_daemon_state *state) { - SetEvent(state->backend_data->hListener[LISTENER_SHUTDOWN]); + SetEvent(state->listen_data->hListener[LISTENER_SHUTDOWN]); } static struct one_watch *create_watch(struct fsmonitor_daemon_state *state, @@ -111,7 +295,9 @@ static struct one_watch *create_watch(struct fsmonitor_daemon_state *state, DWORD share_mode = FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE; HANDLE hDir; - wchar_t wpath[MAX_PATH]; + DWORD len_longname; + wchar_t wpath[MAX_PATH + 1]; + wchar_t wpath_longname[MAX_PATH + 1]; if (xutftowcs_path(wpath, path) < 0) { error(_("could not convert to wide characters: '%s'"), path); @@ -128,6 +314,21 @@ static struct one_watch *create_watch(struct fsmonitor_daemon_state *state, return NULL; } + len_longname = GetLongPathNameW(wpath, wpath_longname, + ARRAY_SIZE(wpath_longname)); + if (!len_longname) { + error(_("[GLE %ld] could not get longname of '%s'"), + GetLastError(), path); + CloseHandle(hDir); + return NULL; + } + + if (wpath_longname[len_longname - 1] != L'/' && + wpath_longname[len_longname - 1] != L'\\') { + wpath_longname[len_longname++] = L'/'; + wpath_longname[len_longname] = 0; + } + CALLOC_ARRAY(watch, 1); watch->buf_len = sizeof(watch->buffer); /* assume full MAX_RDCW_BUF */ @@ -135,6 +336,9 @@ static struct one_watch *create_watch(struct fsmonitor_daemon_state *state, strbuf_init(&watch->path, 0); strbuf_addstr(&watch->path, path); + wcscpy(watch->wpath_longname, wpath_longname); + watch->wpath_longname_len = len_longname; + watch->hDir = hDir; watch->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); @@ -155,7 +359,7 @@ static void destroy_watch(struct one_watch *watch) free(watch); } -static int start_rdcw_watch(struct fsmonitor_daemon_backend_data *data, +static int start_rdcw_watch(struct fsm_listen_data *data, struct one_watch *watch) { DWORD dwNotifyFilter = @@ -220,12 +424,22 @@ static int recv_rdcw_watch(struct one_watch *watch) } /* - * NEEDSWORK: If an external <gitdir> is deleted, the above - * returns an error. I'm not sure that there's anything that - * we can do here other than failing -- the <worktree>/.git - * link file would be broken anyway. We might try to check - * for that and return a better error message, but I'm not - * sure it is worth it. + * GetOverlappedResult() fails if the watched directory is + * deleted while we were waiting for an overlapped IO to + * complete. The documentation did not list specific errors, + * but I observed ERROR_ACCESS_DENIED (0x05) errors during + * testing. + * + * Note that we only get notificaiton events for events + * *within* the directory, not *on* the directory itself. + * (These might be properies of the parent directory, for + * example). + * + * NEEDSWORK: We might try to check for the deleted directory + * case and return a better error message, but I'm not sure it + * is worth it. + * + * Shutdown if we get any error. */ error(_("GetOverlappedResult failed on '%s' [GLE %ld]"), @@ -259,6 +473,62 @@ static void cancel_rdcw_watch(struct one_watch *watch) } /* + * Process a single relative pathname event. + * Return 1 if we should shutdown. + */ +static int process_1_worktree_event( + struct string_list *cookie_list, + struct fsmonitor_batch **batch, + const struct strbuf *path, + enum fsmonitor_path_type t, + DWORD info_action) +{ + const char *slash; + + switch (t) { + case IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX: + /* special case cookie files within .git */ + + /* Use just the filename of the cookie file. */ + slash = find_last_dir_sep(path->buf); + string_list_append(cookie_list, + slash ? slash + 1 : path->buf); + break; + + case IS_INSIDE_DOT_GIT: + /* ignore everything inside of "<worktree>/.git/" */ + break; + + case IS_DOT_GIT: + /* "<worktree>/.git" was deleted (or renamed away) */ + if ((info_action == FILE_ACTION_REMOVED) || + (info_action == FILE_ACTION_RENAMED_OLD_NAME)) { + trace2_data_string("fsmonitor", NULL, + "fsm-listen/dotgit", + "removed"); + return 1; + } + break; + + case IS_WORKDIR_PATH: + /* queue normal pathname */ + if (!*batch) + *batch = fsmonitor_batch__new(); + fsmonitor_batch__add_path(*batch, path->buf); + break; + + case IS_GITDIR: + case IS_INSIDE_GITDIR: + case IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX: + default: + BUG("unexpected path classification '%d' for '%s'", + t, path->buf); + } + + return 0; +} + +/* * Process filesystem events that happen anywhere (recursively) under the * <worktree> root directory. For a normal working directory, this includes * both version controlled files and the contents of the .git/ directory. @@ -268,12 +538,13 @@ static void cancel_rdcw_watch(struct one_watch *watch) */ static int process_worktree_events(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data = state->backend_data; + struct fsm_listen_data *data = state->listen_data; struct one_watch *watch = data->watch_worktree; struct strbuf path = STRBUF_INIT; struct string_list cookie_list = STRING_LIST_INIT_DUP; struct fsmonitor_batch *batch = NULL; const char *p = watch->buffer; + wchar_t wpath_longname[MAX_PATH + 1]; /* * If the kernel gets more events than will fit in the kernel @@ -306,54 +577,64 @@ static int process_worktree_events(struct fsmonitor_daemon_state *state) */ for (;;) { FILE_NOTIFY_INFORMATION *info = (void *)p; - const char *slash; + wchar_t *wpath = info->FileName; + DWORD wpath_len = info->FileNameLength / sizeof(WCHAR); enum fsmonitor_path_type t; + enum get_relative_result grr; + + if (watch->has_shortnames) { + if (!wcscmp(wpath, watch->dotgit_shortname)) { + /* + * This event exactly matches the + * spelling of the shortname of + * ".git", so we can skip some steps. + * + * (This case is odd because the user + * can "rm -rf GIT~1" and we cannot + * use the filesystem to map it back + * to ".git".) + */ + strbuf_reset(&path); + strbuf_addstr(&path, ".git"); + t = IS_DOT_GIT; + goto process_it; + } - strbuf_reset(&path); - if (normalize_path_in_utf8(info, &path) == -1) - goto skip_this_path; - - t = fsmonitor_classify_path_workdir_relative(path.buf); - - switch (t) { - case IS_INSIDE_DOT_GIT_WITH_COOKIE_PREFIX: - /* special case cookie files within .git */ - - /* Use just the filename of the cookie file. */ - slash = find_last_dir_sep(path.buf); - string_list_append(&cookie_list, - slash ? slash + 1 : path.buf); - break; - - case IS_INSIDE_DOT_GIT: - /* ignore everything inside of "<worktree>/.git/" */ - break; + if (watch->has_tilde && !wcschr(wpath, L'~')) { + /* + * Shortnames on this filesystem have tildes + * and the notification path does not have + * one, so we assume that it is a longname. + */ + goto normalize_it; + } - case IS_DOT_GIT: - /* "<worktree>/.git" was deleted (or renamed away) */ - if ((info->Action == FILE_ACTION_REMOVED) || - (info->Action == FILE_ACTION_RENAMED_OLD_NAME)) { - trace2_data_string("fsmonitor", NULL, - "fsm-listen/dotgit", - "removed"); + grr = get_relative_longname(watch, wpath, wpath_len, + wpath_longname, + ARRAY_SIZE(wpath_longname)); + switch (grr) { + case GRR_NO_CONVERSION_NEEDED: /* use info buffer as is */ + break; + case GRR_HAVE_CONVERSION: + wpath = wpath_longname; + wpath_len = wcslen(wpath); + break; + default: + case GRR_SHUTDOWN: goto force_shutdown; } - break; + } - case IS_WORKDIR_PATH: - /* queue normal pathname */ - if (!batch) - batch = fsmonitor_batch__new(); - fsmonitor_batch__add_path(batch, path.buf); - break; +normalize_it: + if (normalize_path_in_utf8(wpath, wpath_len, &path) == -1) + goto skip_this_path; - case IS_GITDIR: - case IS_INSIDE_GITDIR: - case IS_INSIDE_GITDIR_WITH_COOKIE_PREFIX: - default: - BUG("unexpected path classification '%d' for '%s'", - t, path.buf); - } + t = fsmonitor_classify_path_workdir_relative(path.buf); + +process_it: + if (process_1_worktree_event(&cookie_list, &batch, &path, t, + info->Action)) + goto force_shutdown; skip_this_path: if (!info->NextEntryOffset) @@ -382,10 +663,13 @@ force_shutdown: * Note that we DO NOT get filesystem events on the external <gitdir> * itself (it is not inside something that we are watching). In particular, * we do not get an event if the external <gitdir> is deleted. + * + * Also, we do not care about shortnames within the external <gitdir>, since + * we never send these paths to clients. */ static int process_gitdir_events(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data = state->backend_data; + struct fsm_listen_data *data = state->listen_data; struct one_watch *watch = data->watch_gitdir; struct strbuf path = STRBUF_INIT; struct string_list cookie_list = STRING_LIST_INIT_DUP; @@ -403,8 +687,10 @@ static int process_gitdir_events(struct fsmonitor_daemon_state *state) const char *slash; enum fsmonitor_path_type t; - strbuf_reset(&path); - if (normalize_path_in_utf8(info, &path) == -1) + if (normalize_path_in_utf8( + info->FileName, + info->FileNameLength / sizeof(WCHAR), + &path) == -1) goto skip_this_path; t = fsmonitor_classify_path_gitdir_relative(path.buf); @@ -441,11 +727,11 @@ skip_this_path: void fsm_listen__loop(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data = state->backend_data; + struct fsm_listen_data *data = state->listen_data; DWORD dwWait; int result; - state->error_code = 0; + state->listen_error_code = 0; if (start_rdcw_watch(data, data->watch_worktree) == -1) goto force_error_stop; @@ -510,7 +796,7 @@ void fsm_listen__loop(struct fsmonitor_daemon_state *state) } force_error_stop: - state->error_code = -1; + state->listen_error_code = -1; force_shutdown: /* @@ -527,7 +813,7 @@ clean_shutdown: int fsm_listen__ctor(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; CALLOC_ARRAY(data, 1); @@ -538,6 +824,8 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state) if (!data->watch_worktree) goto failed; + check_for_shortnames(data->watch_worktree); + if (state->nr_paths_watching > 1) { data->watch_gitdir = create_watch(state, state->path_gitdir_watch.buf); @@ -558,7 +846,7 @@ int fsm_listen__ctor(struct fsmonitor_daemon_state *state) data->nr_listener_handles++; } - state->backend_data = data; + state->listen_data = data; return 0; failed: @@ -571,16 +859,16 @@ failed: void fsm_listen__dtor(struct fsmonitor_daemon_state *state) { - struct fsmonitor_daemon_backend_data *data; + struct fsm_listen_data *data; - if (!state || !state->backend_data) + if (!state || !state->listen_data) return; - data = state->backend_data; + data = state->listen_data; CloseHandle(data->hEventShutdown); destroy_watch(data->watch_worktree); destroy_watch(data->watch_gitdir); - FREE_AND_NULL(state->backend_data); + FREE_AND_NULL(state->listen_data); } diff --git a/compat/fsmonitor/fsm-listen.h b/compat/fsmonitor/fsm-listen.h index f0539349ba..41650bf897 100644 --- a/compat/fsmonitor/fsm-listen.h +++ b/compat/fsmonitor/fsm-listen.h @@ -33,7 +33,7 @@ void fsm_listen__dtor(struct fsmonitor_daemon_state *state); * do so if the listener thread receives a normal shutdown signal from * the IPC layer.) * - * It should set `state->error_code` to -1 if the daemon should exit + * It should set `state->listen_error_code` to -1 if the daemon should exit * with an error. */ void fsm_listen__loop(struct fsmonitor_daemon_state *state); diff --git a/compat/fsmonitor/fsm-settings-darwin.c b/compat/fsmonitor/fsm-settings-darwin.c new file mode 100644 index 0000000000..efc732c0f3 --- /dev/null +++ b/compat/fsmonitor/fsm-settings-darwin.c @@ -0,0 +1,89 @@ +#include "cache.h" +#include "config.h" +#include "repository.h" +#include "fsmonitor-settings.h" +#include "fsmonitor.h" +#include <sys/param.h> +#include <sys/mount.h> + +/* + * [1] Remote working directories are problematic for FSMonitor. + * + * The underlying file system on the server machine and/or the remote + * mount type (NFS, SAMBA, etc.) dictates whether notification events + * are available at all to remote client machines. + * + * Kernel differences between the server and client machines also + * dictate the how (buffering, frequency, de-dup) the events are + * delivered to client machine processes. + * + * A client machine (such as a laptop) may choose to suspend/resume + * and it is unclear (without lots of testing) whether the watcher can + * resync after a resume. We might be able to treat this as a normal + * "events were dropped by the kernel" event and do our normal "flush + * and resync" --or-- we might need to close the existing (zombie?) + * notification fd and create a new one. + * + * In theory, the above issues need to be addressed whether we are + * using the Hook or IPC API. + * + * For the builtin FSMonitor, we create the Unix domain socket for the + * IPC in the .git directory. If the working directory is remote, + * then the socket will be created on the remote file system. This + * can fail if the remote file system does not support UDS file types + * (e.g. smbfs to a Windows server) or if the remote kernel does not + * allow a non-local process to bind() the socket. (These problems + * could be fixed by moving the UDS out of the .git directory and to a + * well-known local directory on the client machine, but care should + * be taken to ensure that $HOME is actually local and not a managed + * file share.) + * + * So (for now at least), mark remote working directories as + * incompatible. + * + * + * [2] FAT32 and NTFS working directories are problematic too. + * + * The builtin FSMonitor uses a Unix domain socket in the .git + * directory for IPC. These Windows drive formats do not support + * Unix domain sockets, so mark them as incompatible for the daemon. + * + */ +static enum fsmonitor_reason check_volume(struct repository *r) +{ + struct statfs fs; + + if (statfs(r->worktree, &fs) == -1) { + int saved_errno = errno; + trace_printf_key(&trace_fsmonitor, "statfs('%s') failed: %s", + r->worktree, strerror(saved_errno)); + errno = saved_errno; + return FSMONITOR_REASON_ERROR; + } + + trace_printf_key(&trace_fsmonitor, + "statfs('%s') [type 0x%08x][flags 0x%08x] '%s'", + r->worktree, fs.f_type, fs.f_flags, fs.f_fstypename); + + if (!(fs.f_flags & MNT_LOCAL)) + return FSMONITOR_REASON_REMOTE; + + if (!strcmp(fs.f_fstypename, "msdos")) /* aka FAT32 */ + return FSMONITOR_REASON_NOSOCKETS; + + if (!strcmp(fs.f_fstypename, "ntfs")) + return FSMONITOR_REASON_NOSOCKETS; + + return FSMONITOR_REASON_OK; +} + +enum fsmonitor_reason fsm_os__incompatible(struct repository *r) +{ + enum fsmonitor_reason reason; + + reason = check_volume(r); + if (reason != FSMONITOR_REASON_OK) + return reason; + + return FSMONITOR_REASON_OK; +} diff --git a/compat/fsmonitor/fsm-settings-win32.c b/compat/fsmonitor/fsm-settings-win32.c new file mode 100644 index 0000000000..907655720b --- /dev/null +++ b/compat/fsmonitor/fsm-settings-win32.c @@ -0,0 +1,137 @@ +#include "cache.h" +#include "config.h" +#include "repository.h" +#include "fsmonitor-settings.h" +#include "fsmonitor.h" + +/* + * VFS for Git is incompatible with FSMonitor. + * + * Granted, core Git does not know anything about VFS for Git and we + * shouldn't make assumptions about a downstream feature, but users + * can install both versions. And this can lead to incorrect results + * from core Git commands. So, without bringing in any of the VFS for + * Git code, do a simple config test for a published config setting. + * (We do not look at the various *_TEST_* environment variables.) + */ +static enum fsmonitor_reason check_vfs4git(struct repository *r) +{ + const char *const_str; + + if (!repo_config_get_value(r, "core.virtualfilesystem", &const_str)) + return FSMONITOR_REASON_VFS4GIT; + + return FSMONITOR_REASON_OK; +} + +/* + * Remote working directories are problematic for FSMonitor. + * + * The underlying file system on the server machine and/or the remote + * mount type dictates whether notification events are available at + * all to remote client machines. + * + * Kernel differences between the server and client machines also + * dictate the how (buffering, frequency, de-dup) the events are + * delivered to client machine processes. + * + * A client machine (such as a laptop) may choose to suspend/resume + * and it is unclear (without lots of testing) whether the watcher can + * resync after a resume. We might be able to treat this as a normal + * "events were dropped by the kernel" event and do our normal "flush + * and resync" --or-- we might need to close the existing (zombie?) + * notification fd and create a new one. + * + * In theory, the above issues need to be addressed whether we are + * using the Hook or IPC API. + * + * So (for now at least), mark remote working directories as + * incompatible. + * + * Notes for testing: + * + * (a) Windows allows a network share to be mapped to a drive letter. + * (This is the normal method to access it.) + * + * $ NET USE Z: \\server\share + * $ git -C Z:/repo status + * + * (b) Windows allows a network share to be referenced WITHOUT mapping + * it to drive letter. + * + * $ NET USE \\server\share\dir + * $ git -C //server/share/repo status + * + * (c) Windows allows "SUBST" to create a fake drive mapping to an + * arbitrary path (which may be remote) + * + * $ SUBST Q: Z:\repo + * $ git -C Q:/ status + * + * (d) Windows allows a directory symlink to be created on a local + * file system that points to a remote repo. + * + * $ mklink /d ./link //server/share/repo + * $ git -C ./link status + */ +static enum fsmonitor_reason check_remote(struct repository *r) +{ + wchar_t wpath[MAX_PATH]; + wchar_t wfullpath[MAX_PATH]; + size_t wlen; + UINT driveType; + + /* + * Do everything in wide chars because the drive letter might be + * a multi-byte sequence. See win32_has_dos_drive_prefix(). + */ + if (xutftowcs_path(wpath, r->worktree) < 0) + return FSMONITOR_REASON_ERROR; + + /* + * GetDriveTypeW() requires a final slash. We assume that the + * worktree pathname points to an actual directory. + */ + wlen = wcslen(wpath); + if (wpath[wlen - 1] != L'\\' && wpath[wlen - 1] != L'/') { + wpath[wlen++] = L'\\'; + wpath[wlen] = 0; + } + + /* + * Normalize the path. If nothing else, this converts forward + * slashes to backslashes. This is essential to get GetDriveTypeW() + * correctly handle some UNC "\\server\share\..." paths. + */ + if (!GetFullPathNameW(wpath, MAX_PATH, wfullpath, NULL)) + return FSMONITOR_REASON_ERROR; + + driveType = GetDriveTypeW(wfullpath); + trace_printf_key(&trace_fsmonitor, + "DriveType '%s' L'%ls' (%u)", + r->worktree, wfullpath, driveType); + + if (driveType == DRIVE_REMOTE) { + trace_printf_key(&trace_fsmonitor, + "check_remote('%s') true", + r->worktree); + return FSMONITOR_REASON_REMOTE; + } + + return FSMONITOR_REASON_OK; +} + +enum fsmonitor_reason fsm_os__incompatible(struct repository *r) +{ + enum fsmonitor_reason reason; + + reason = check_vfs4git(r); + if (reason != FSMONITOR_REASON_OK) + return reason; + + reason = check_remote(r); + if (reason != FSMONITOR_REASON_OK) + return reason; + + return FSMONITOR_REASON_OK; +} diff --git a/compat/mingw.c b/compat/mingw.c index 5772692a0a..2607de93af 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -2830,7 +2830,7 @@ not_a_reserved_name: } c = path[i]; - if (c && c != '.' && c != ':' && c != '/' && c != '\\') + if (c && c != '.' && c != ':' && !is_xplatform_dir_sep(c)) goto not_a_reserved_name; /* contains reserved name */ diff --git a/compat/mingw.h b/compat/mingw.h index 494cc8de92..a74da68f31 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -332,6 +332,9 @@ int mingw_getpagesize(void); int win32_fsync_no_flush(int fd); #define fsync_no_flush win32_fsync_no_flush +#define FSYNC_COMPONENTS_PLATFORM_DEFAULT (FSYNC_COMPONENTS_DEFAULT | FSYNC_COMPONENT_LOOSE_OBJECT) +#define FSYNC_METHOD_DEFAULT (FSYNC_METHOD_BATCH) + struct rlimit { unsigned int rlim_cur; }; diff --git a/compat/win32/path-utils.h b/compat/win32/path-utils.h index bba2b64408..65fa3b9263 100644 --- a/compat/win32/path-utils.h +++ b/compat/win32/path-utils.h @@ -6,11 +6,7 @@ int win32_has_dos_drive_prefix(const char *path); int win32_skip_dos_drive_prefix(char **path); #define skip_dos_drive_prefix win32_skip_dos_drive_prefix -static inline int win32_is_dir_sep(int c) -{ - return c == '/' || c == '\\'; -} -#define is_dir_sep win32_is_dir_sep +#define is_dir_sep is_xplatform_dir_sep static inline char *win32_find_last_dir_sep(const char *path) { char *ret = NULL; @@ -1342,7 +1342,7 @@ static const struct fsync_component_name { static enum fsync_component parse_fsync_components(const char *var, const char *string) { - enum fsync_component current = FSYNC_COMPONENTS_DEFAULT; + enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT; enum fsync_component positive = 0, negative = 0; while (string) { @@ -1688,6 +1688,8 @@ static int git_default_core_config(const char *var, const char *value, void *cb) fsync_method = FSYNC_METHOD_FSYNC; else if (!strcmp(value, "writeout-only")) fsync_method = FSYNC_METHOD_WRITEOUT_ONLY; + else if (!strcmp(value, "batch")) + fsync_method = FSYNC_METHOD_BATCH; else warning(_("ignoring unknown core.fsyncMethod value '%s'"), value); diff --git a/config.mak.dev b/config.mak.dev index c3104f400b..335efd4620 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -68,7 +68,6 @@ endif # https://bugzilla.redhat.com/show_bug.cgi?id=2075786 ifneq ($(filter gcc12,$(COMPILER_FEATURES)),) DEVELOPER_CFLAGS += -Wno-error=stringop-overread -DEVELOPER_CFLAGS += -Wno-error=dangling-pointer endif GIT_TEST_PERL_FATAL_WARNINGS = YesPlease diff --git a/config.mak.uname b/config.mak.uname index 259d1511ca..ce83cad47a 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -164,6 +164,7 @@ ifeq ($(uname_S),Darwin) ifndef NO_PTHREADS ifndef NO_UNIX_SOCKETS FSMONITOR_DAEMON_BACKEND = darwin + FSMONITOR_OS_SETTINGS = darwin endif endif @@ -451,6 +452,8 @@ ifeq ($(uname_S),Windows) # These are always available, so we do not have to conditionally # support it. FSMONITOR_DAEMON_BACKEND = win32 + FSMONITOR_OS_SETTINGS = win32 + NO_SVN_TESTS = YesPlease RUNTIME_PREFIX = YesPlease HAVE_WPGMPTR = YesWeDo @@ -641,6 +644,8 @@ ifeq ($(uname_S),MINGW) # These are always available, so we do not have to conditionally # support it. FSMONITOR_DAEMON_BACKEND = win32 + FSMONITOR_OS_SETTINGS = win32 + RUNTIME_PREFIX = YesPlease HAVE_WPGMPTR = YesWeDo NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease @@ -473,6 +473,24 @@ void check_stateless_delimiter(int stateless_rpc, die("%s", error); } +static void send_capabilities(int fd_out, struct packet_reader *reader) +{ + const char *hash_name; + + if (server_supports_v2("agent", 0)) + packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); + + if (server_feature_v2("object-format", &hash_name)) { + int hash_algo = hash_algo_by_name(hash_name); + if (hash_algo == GIT_HASH_UNKNOWN) + die(_("unknown object format '%s' specified by server"), hash_name); + reader->hash_algo = &hash_algos[hash_algo]; + packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name); + } else { + reader->hash_algo = &hash_algos[GIT_HASH_SHA1]; + } +} + struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, struct ref **list, int for_push, struct transport_ls_refs_options *transport_options, @@ -480,7 +498,6 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, int stateless_rpc) { int i; - const char *hash_name; struct strvec *ref_prefixes = transport_options ? &transport_options->ref_prefixes : NULL; const char **unborn_head_target = transport_options ? @@ -490,18 +507,8 @@ struct ref **get_remote_refs(int fd_out, struct packet_reader *reader, if (server_supports_v2("ls-refs", 1)) packet_write_fmt(fd_out, "command=ls-refs\n"); - if (server_supports_v2("agent", 0)) - packet_write_fmt(fd_out, "agent=%s", git_user_agent_sanitized()); - - if (server_feature_v2("object-format", &hash_name)) { - int hash_algo = hash_algo_by_name(hash_name); - if (hash_algo == GIT_HASH_UNKNOWN) - die(_("unknown object format '%s' specified by server"), hash_name); - reader->hash_algo = &hash_algos[hash_algo]; - packet_write_fmt(fd_out, "object-format=%s", reader->hash_algo->name); - } else { - reader->hash_algo = &hash_algos[GIT_HASH_SHA1]; - } + /* Send capabilities */ + send_capabilities(fd_out, reader); if (server_options && server_options->nr && server_supports_v2("server-option", 1)) @@ -1327,7 +1334,7 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host, strvec_push(&detect.args, ssh); strvec_push(&detect.args, "-G"); - push_ssh_options(&detect.args, &detect.env_array, + push_ssh_options(&detect.args, &detect.env, VARIANT_SSH, port, version, flags); strvec_push(&detect.args, ssh_host); @@ -1335,7 +1342,8 @@ static void fill_ssh_args(struct child_process *conn, const char *ssh_host, } strvec_push(&conn->args, ssh); - push_ssh_options(&conn->args, &conn->env_array, variant, port, version, flags); + push_ssh_options(&conn->args, &conn->env, variant, port, version, + flags); strvec_push(&conn->args, ssh_host); } @@ -1397,7 +1405,7 @@ struct child_process *git_connect(int fd[2], const char *url, /* remove repo-local variables from the environment */ for (var = local_repo_env; *var; var++) - strvec_push(&conn->env_array, *var); + strvec_push(&conn->env, *var); conn->use_shell = 1; conn->in = conn->out = -1; @@ -1429,7 +1437,7 @@ struct child_process *git_connect(int fd[2], const char *url, transport_check_allowed("file"); conn->trace2_child_class = "transport/file"; if (version > 0) { - strvec_pushf(&conn->env_array, + strvec_pushf(&conn->env, GIT_PROTOCOL_ENVIRONMENT "=version=%d", version); } diff --git a/connected.c b/connected.c index ed3025e7a2..74a20cb32e 100644 --- a/connected.c +++ b/connected.c @@ -110,7 +110,7 @@ no_promisor_pack_found: rev_list.git_cmd = 1; if (opt->env) - strvec_pushv(&rev_list.env_array, opt->env); + strvec_pushv(&rev_list.env, opt->env); rev_list.in = -1; rev_list.no_stdout = 1; if (opt->err_fd) diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 185f56f414..1b23f2440d 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -54,7 +54,7 @@ set(CMAKE_SOURCE_DIR ${CMAKE_CURRENT_LIST_DIR}/../..) option(USE_VCPKG "Whether or not to use vcpkg for obtaining dependencies. Only applicable to Windows platforms" ON) if(NOT WIN32) - set(USE_VCPKG OFF CACHE BOOL FORCE) + set(USE_VCPKG OFF CACHE BOOL "" FORCE) endif() if(NOT DEFINED CMAKE_EXPORT_COMPILE_COMMANDS) @@ -108,7 +108,6 @@ project(git #TODO gitk git-gui gitweb #TODO Enable NLS on windows natively -#TODO Add pcre support #macros for parsing the Makefile for sources and scripts macro(parse_makefile_for_sources list_var regex) @@ -160,6 +159,14 @@ if(NOT (WIN32 AND (CMAKE_C_COMPILER_ID STREQUAL "MSVC" OR CMAKE_C_COMPILER_ID ST find_package(Intl) endif() +find_package(PkgConfig) +if(PkgConfig_FOUND) + pkg_check_modules(PCRE2 libpcre2-8) + if(PCRE2_FOUND) + add_compile_definitions(USE_LIBPCRE2) + endif() +endif() + if(NOT Intl_FOUND) add_compile_definitions(NO_GETTEXT) if(NOT Iconv_FOUND) @@ -180,6 +187,9 @@ endif() if(Intl_FOUND) include_directories(SYSTEM ${Intl_INCLUDE_DIRS}) endif() +if(PCRE2_FOUND) + include_directories(SYSTEM ${PCRE2_INCLUDE_DIRS}) +endif() if(WIN32 AND NOT MSVC)#not required for visual studio builds @@ -260,7 +270,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") _CONSOLE DETECT_MSYS_TTY STRIP_EXTENSION=".exe" NO_SYMLINK_HEAD UNRELIABLE_FSTAT NOGDI OBJECT_CREATION_MODE=1 __USE_MINGW_ANSI_STDIO=0 USE_NED_ALLOCATOR OVERRIDE_STRDUP MMAP_PREVENTS_DELETE USE_WIN32_MMAP - UNICODE _UNICODE HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM) + HAVE_WPGMPTR ENSURE_MSYSTEM_IS_SET HAVE_RTLGENRANDOM) list(APPEND compat_SOURCES compat/mingw.c compat/winansi.c @@ -277,7 +287,7 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows") elseif(CMAKE_SYSTEM_NAME STREQUAL "Linux") add_compile_definitions(PROCFS_EXECUTABLE_PATH="/proc/self/exe" HAVE_DEV_TTY ) - list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c) + list(APPEND compat_SOURCES unix-socket.c unix-stream-server.c compat/linux/procinfo.c) endif() if(CMAKE_SYSTEM_NAME STREQUAL "Windows") @@ -297,9 +307,17 @@ if(SUPPORTS_SIMPLE_IPC) if(CMAKE_SYSTEM_NAME STREQUAL "Windows") add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-win32.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-win32.c) + + add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-win32.c) elseif(CMAKE_SYSTEM_NAME STREQUAL "Darwin") add_compile_definitions(HAVE_FSMONITOR_DAEMON_BACKEND) list(APPEND compat_SOURCES compat/fsmonitor/fsm-listen-darwin.c) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-health-darwin.c) + + add_compile_definitions(HAVE_FSMONITOR_OS_SETTINGS) + list(APPEND compat_SOURCES compat/fsmonitor/fsm-settings-darwin.c) endif() endif() @@ -700,6 +718,10 @@ endif() if(Iconv_FOUND) target_link_libraries(common-main ${Iconv_LIBRARIES}) endif() +if(PCRE2_FOUND) + target_link_libraries(common-main ${PCRE2_LIBRARIES}) + target_link_directories(common-main PUBLIC ${PCRE2_LIBRARY_DIRS}) +endif() if(WIN32) target_link_libraries(common-main ws2_32 ntdll ${CMAKE_BINARY_DIR}/git.res) add_dependencies(common-main git-rc) diff --git a/contrib/coccinelle/free.cocci b/contrib/coccinelle/free.cocci index 4490069df9..6fb9eb6e88 100644 --- a/contrib/coccinelle/free.cocci +++ b/contrib/coccinelle/free.cocci @@ -2,13 +2,21 @@ expression E; @@ - if (E) +( free(E); +| + free_commit_list(E); +) @@ expression E; @@ - if (!E) +( free(E); +| + free_commit_list(E); +) @@ expression E; @@ -16,3 +24,22 @@ expression E; - free(E); + FREE_AND_NULL(E); - E = NULL; + +@@ +expression E; +@@ +- if (E) +- { + free_commit_list(E); + E = NULL; +- } + +@@ +expression E; +statement S; +@@ +- if (E) { ++ if (E) + S + free_commit_list(E); +- } diff --git a/contrib/scalar/scalar.c b/contrib/scalar/scalar.c index 58ca0e56f1..28176914e5 100644 --- a/contrib/scalar/scalar.c +++ b/contrib/scalar/scalar.c @@ -11,6 +11,8 @@ #include "dir.h" #include "packfile.h" #include "help.h" +#include "archive.h" +#include "object-store.h" /* * Remove the deepest subdirectory in the provided path string. Path must not @@ -43,9 +45,11 @@ static void setup_enlistment_directory(int argc, const char **argv, usage_with_options(usagestr, options); /* find the worktree, determine its corresponding root */ - if (argc == 1) + if (argc == 1) { strbuf_add_absolute_path(&path, argv[0]); - else if (strbuf_getcwd(&path) < 0) + if (!is_directory(path.buf)) + die(_("'%s' does not exist"), path.buf); + } else if (strbuf_getcwd(&path) < 0) die(_("need a working directory")); strbuf_trim_trailing_dir_sep(&path); @@ -258,6 +262,99 @@ static int unregister_dir(void) return res; } +static int add_directory_to_archiver(struct strvec *archiver_args, + const char *path, int recurse) +{ + int at_root = !*path; + DIR *dir = opendir(at_root ? "." : path); + struct dirent *e; + struct strbuf buf = STRBUF_INIT; + size_t len; + int res = 0; + + if (!dir) + return error_errno(_("could not open directory '%s'"), path); + + if (!at_root) + strbuf_addf(&buf, "%s/", path); + len = buf.len; + strvec_pushf(archiver_args, "--prefix=%s", buf.buf); + + while (!res && (e = readdir(dir))) { + if (!strcmp(".", e->d_name) || !strcmp("..", e->d_name)) + continue; + + strbuf_setlen(&buf, len); + strbuf_addstr(&buf, e->d_name); + + if (e->d_type == DT_REG) + strvec_pushf(archiver_args, "--add-file=%s", buf.buf); + else if (e->d_type != DT_DIR) + warning(_("skipping '%s', which is neither file nor " + "directory"), buf.buf); + else if (recurse && + add_directory_to_archiver(archiver_args, + buf.buf, recurse) < 0) + res = -1; + } + + closedir(dir); + strbuf_release(&buf); + return res; +} + +#ifndef WIN32 +#include <sys/statvfs.h> +#endif + +static int get_disk_info(struct strbuf *out) +{ +#ifdef WIN32 + struct strbuf buf = STRBUF_INIT; + char volume_name[MAX_PATH], fs_name[MAX_PATH]; + DWORD serial_number, component_length, flags; + ULARGE_INTEGER avail2caller, total, avail; + + strbuf_realpath(&buf, ".", 1); + if (!GetDiskFreeSpaceExA(buf.buf, &avail2caller, &total, &avail)) { + error(_("could not determine free disk size for '%s'"), + buf.buf); + strbuf_release(&buf); + return -1; + } + + strbuf_setlen(&buf, offset_1st_component(buf.buf)); + if (!GetVolumeInformationA(buf.buf, volume_name, sizeof(volume_name), + &serial_number, &component_length, &flags, + fs_name, sizeof(fs_name))) { + error(_("could not get info for '%s'"), buf.buf); + strbuf_release(&buf); + return -1; + } + strbuf_addf(out, "Available space on '%s': ", buf.buf); + strbuf_humanise_bytes(out, avail2caller.QuadPart); + strbuf_addch(out, '\n'); + strbuf_release(&buf); +#else + struct strbuf buf = STRBUF_INIT; + struct statvfs stat; + + strbuf_realpath(&buf, ".", 1); + if (statvfs(buf.buf, &stat) < 0) { + error_errno(_("could not determine free disk size for '%s'"), + buf.buf); + strbuf_release(&buf); + return -1; + } + + strbuf_addf(out, "Available space on '%s': ", buf.buf); + strbuf_humanise_bytes(out, st_mult(stat.f_bsize, stat.f_bavail)); + strbuf_addf(out, " (mount flags 0x%lx)\n", stat.f_flag); + strbuf_release(&buf); +#endif + return 0; +} + /* printf-style interface, expects `<key>=<value>` argument */ static int set_config(const char *fmt, ...) { @@ -498,6 +595,196 @@ cleanup: return res; } +static void dir_file_stats_objects(const char *full_path, size_t full_path_len, + const char *file_name, void *data) +{ + struct strbuf *buf = data; + struct stat st; + + if (!stat(full_path, &st)) + strbuf_addf(buf, "%-70s %16" PRIuMAX "\n", file_name, + (uintmax_t)st.st_size); +} + +static int dir_file_stats(struct object_directory *object_dir, void *data) +{ + struct strbuf *buf = data; + + strbuf_addf(buf, "Contents of %s:\n", object_dir->path); + + for_each_file_in_pack_dir(object_dir->path, dir_file_stats_objects, + data); + + return 0; +} + +static int count_files(char *path) +{ + DIR *dir = opendir(path); + struct dirent *e; + int count = 0; + + if (!dir) + return 0; + + while ((e = readdir(dir)) != NULL) + if (!is_dot_or_dotdot(e->d_name) && e->d_type == DT_REG) + count++; + + closedir(dir); + return count; +} + +static void loose_objs_stats(struct strbuf *buf, const char *path) +{ + DIR *dir = opendir(path); + struct dirent *e; + int count; + int total = 0; + unsigned char c; + struct strbuf count_path = STRBUF_INIT; + size_t base_path_len; + + if (!dir) + return; + + strbuf_addstr(buf, "Object directory stats for "); + strbuf_add_absolute_path(buf, path); + strbuf_addstr(buf, ":\n"); + + strbuf_add_absolute_path(&count_path, path); + strbuf_addch(&count_path, '/'); + base_path_len = count_path.len; + + while ((e = readdir(dir)) != NULL) + if (!is_dot_or_dotdot(e->d_name) && + e->d_type == DT_DIR && strlen(e->d_name) == 2 && + !hex_to_bytes(&c, e->d_name, 1)) { + strbuf_setlen(&count_path, base_path_len); + strbuf_addstr(&count_path, e->d_name); + total += (count = count_files(count_path.buf)); + strbuf_addf(buf, "%s : %7d files\n", e->d_name, count); + } + + strbuf_addf(buf, "Total: %d loose objects", total); + + strbuf_release(&count_path); + closedir(dir); +} + +static int cmd_diagnose(int argc, const char **argv) +{ + struct option options[] = { + OPT_END(), + }; + const char * const usage[] = { + N_("scalar diagnose [<enlistment>]"), + NULL + }; + struct strbuf zip_path = STRBUF_INIT; + struct strvec archiver_args = STRVEC_INIT; + char **argv_copy = NULL; + int stdout_fd = -1, archiver_fd = -1; + time_t now = time(NULL); + struct tm tm; + struct strbuf path = STRBUF_INIT, buf = STRBUF_INIT; + int res = 0; + + argc = parse_options(argc, argv, NULL, options, + usage, 0); + + setup_enlistment_directory(argc, argv, usage, options, &zip_path); + + strbuf_addstr(&zip_path, "/.scalarDiagnostics/scalar_"); + strbuf_addftime(&zip_path, + "%Y%m%d_%H%M%S", localtime_r(&now, &tm), 0, 0); + strbuf_addstr(&zip_path, ".zip"); + switch (safe_create_leading_directories(zip_path.buf)) { + case SCLD_EXISTS: + case SCLD_OK: + break; + default: + error_errno(_("could not create directory for '%s'"), + zip_path.buf); + goto diagnose_cleanup; + } + stdout_fd = dup(1); + if (stdout_fd < 0) { + res = error_errno(_("could not duplicate stdout")); + goto diagnose_cleanup; + } + + archiver_fd = xopen(zip_path.buf, O_CREAT | O_WRONLY | O_TRUNC, 0666); + if (archiver_fd < 0 || dup2(archiver_fd, 1) < 0) { + res = error_errno(_("could not redirect output")); + goto diagnose_cleanup; + } + + init_zip_archiver(); + strvec_pushl(&archiver_args, "scalar-diagnose", "--format=zip", NULL); + + strbuf_reset(&buf); + strbuf_addstr(&buf, "Collecting diagnostic info\n\n"); + get_version_info(&buf, 1); + + strbuf_addf(&buf, "Enlistment root: %s\n", the_repository->worktree); + get_disk_info(&buf); + write_or_die(stdout_fd, buf.buf, buf.len); + strvec_pushf(&archiver_args, + "--add-virtual-file=diagnostics.log:%.*s", + (int)buf.len, buf.buf); + + strbuf_reset(&buf); + strbuf_addstr(&buf, "--add-virtual-file=packs-local.txt:"); + dir_file_stats(the_repository->objects->odb, &buf); + foreach_alt_odb(dir_file_stats, &buf); + strvec_push(&archiver_args, buf.buf); + + strbuf_reset(&buf); + strbuf_addstr(&buf, "--add-virtual-file=objects-local.txt:"); + loose_objs_stats(&buf, ".git/objects"); + strvec_push(&archiver_args, buf.buf); + + if ((res = add_directory_to_archiver(&archiver_args, ".git", 0)) || + (res = add_directory_to_archiver(&archiver_args, ".git/hooks", 0)) || + (res = add_directory_to_archiver(&archiver_args, ".git/info", 0)) || + (res = add_directory_to_archiver(&archiver_args, ".git/logs", 1)) || + (res = add_directory_to_archiver(&archiver_args, ".git/objects/info", 0))) + goto diagnose_cleanup; + + strvec_pushl(&archiver_args, "--prefix=", + oid_to_hex(the_hash_algo->empty_tree), "--", NULL); + + /* `write_archive()` modifies the `argv` passed to it. Let it. */ + argv_copy = xmemdupz(archiver_args.v, + sizeof(char *) * archiver_args.nr); + res = write_archive(archiver_args.nr, (const char **)argv_copy, NULL, + the_repository, NULL, 0); + if (res) { + error(_("failed to write archive")); + goto diagnose_cleanup; + } + + if (!res) + fprintf(stderr, "\n" + "Diagnostics complete.\n" + "All of the gathered info is captured in '%s'\n", + zip_path.buf); + +diagnose_cleanup: + if (archiver_fd >= 0) { + close(1); + dup2(stdout_fd, 1); + } + free(argv_copy); + strvec_clear(&archiver_args); + strbuf_release(&zip_path); + strbuf_release(&path); + strbuf_release(&buf); + + return res; +} + static int cmd_list(int argc, const char **argv) { if (argc != 1) @@ -799,6 +1086,7 @@ static struct { { "reconfigure", cmd_reconfigure }, { "delete", cmd_delete }, { "version", cmd_version }, + { "diagnose", cmd_diagnose }, { NULL, NULL}, }; diff --git a/contrib/scalar/scalar.txt b/contrib/scalar/scalar.txt index cf4e5b889c..c0425e0653 100644 --- a/contrib/scalar/scalar.txt +++ b/contrib/scalar/scalar.txt @@ -14,6 +14,7 @@ scalar register [<enlistment>] scalar unregister [<enlistment>] scalar run ( all | config | commit-graph | fetch | loose-objects | pack-files ) [<enlistment>] scalar reconfigure [ --all | <enlistment> ] +scalar diagnose [<enlistment>] scalar delete <enlistment> DESCRIPTION @@ -139,6 +140,17 @@ reconfigure the enlistment. With the `--all` option, all enlistments currently registered with Scalar will be reconfigured. Use this option after each Scalar upgrade. +Diagnose +~~~~~~~~ + +diagnose [<enlistment>]:: + When reporting issues with Scalar, it is often helpful to provide the + information gathered by this command, including logs and certain + statistics describing the data shape of the current enlistment. ++ +The output of this command is a `.zip` file that is written into +a directory adjacent to the worktree in the `src` directory. + Delete ~~~~~~ diff --git a/contrib/scalar/t/t9099-scalar.sh b/contrib/scalar/t/t9099-scalar.sh index 89781568f4..10b1172a8a 100755 --- a/contrib/scalar/t/t9099-scalar.sh +++ b/contrib/scalar/t/t9099-scalar.sh @@ -93,4 +93,31 @@ test_expect_success 'scalar supports -c/-C' ' test true = "$(git -C sub config core.preloadIndex)" ' +test_expect_success '`scalar [...] <dir>` errors out when dir is missing' ' + ! scalar run config cloned 2>err && + grep "cloned. does not exist" err +' + +SQ="'" +test_expect_success UNZIP 'scalar diagnose' ' + scalar clone "file://$(pwd)" cloned --single-branch && + git repack && + echo "$(pwd)/.git/objects/" >>cloned/src/.git/objects/info/alternates && + test_commit -C cloned/src loose && + scalar diagnose cloned >out 2>err && + grep "Available space" out && + sed -n "s/.*$SQ\\(.*\\.zip\\)$SQ.*/\\1/p" <err >zip_path && + zip_path=$(cat zip_path) && + test -n "$zip_path" && + unzip -v "$zip_path" && + folder=${zip_path%.zip} && + test_path_is_missing "$folder" && + unzip -p "$zip_path" diagnostics.log >out && + test_file_not_empty out && + unzip -p "$zip_path" packs-local.txt >out && + grep "$(pwd)/.git/objects" out && + unzip -p "$zip_path" objects-local.txt >out && + grep "^Total: [1-9]" out +' + test_done @@ -484,7 +484,7 @@ static int upload_pack(const struct strvec *env) strvec_pushl(&cld.args, "upload-pack", "--strict", NULL); strvec_pushf(&cld.args, "--timeout=%u", timeout); - strvec_pushv(&cld.env_array, env->v); + strvec_pushv(&cld.env, env->v); return run_service_command(&cld); } @@ -494,7 +494,7 @@ static int upload_archive(const struct strvec *env) struct child_process cld = CHILD_PROCESS_INIT; strvec_push(&cld.args, "upload-archive"); - strvec_pushv(&cld.env_array, env->v); + strvec_pushv(&cld.env, env->v); return run_service_command(&cld); } @@ -504,7 +504,7 @@ static int receive_pack(const struct strvec *env) struct child_process cld = CHILD_PROCESS_INIT; strvec_push(&cld.args, "receive-pack"); - strvec_pushv(&cld.env_array, env->v); + strvec_pushv(&cld.env, env->v); return run_service_command(&cld); } @@ -904,16 +904,16 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) char buf[128] = ""; struct sockaddr_in *sin_addr = (void *) addr; inet_ntop(addr->sa_family, &sin_addr->sin_addr, buf, sizeof(buf)); - strvec_pushf(&cld.env_array, "REMOTE_ADDR=%s", buf); - strvec_pushf(&cld.env_array, "REMOTE_PORT=%d", + strvec_pushf(&cld.env, "REMOTE_ADDR=%s", buf); + strvec_pushf(&cld.env, "REMOTE_PORT=%d", ntohs(sin_addr->sin_port)); #ifndef NO_IPV6 } else if (addr->sa_family == AF_INET6) { char buf[128] = ""; struct sockaddr_in6 *sin6_addr = (void *) addr; inet_ntop(AF_INET6, &sin6_addr->sin6_addr, buf, sizeof(buf)); - strvec_pushf(&cld.env_array, "REMOTE_ADDR=[%s]", buf); - strvec_pushf(&cld.env_array, "REMOTE_PORT=%d", + strvec_pushf(&cld.env, "REMOTE_ADDR=[%s]", buf); + strvec_pushf(&cld.env, "REMOTE_PORT=%d", ntohs(sin6_addr->sin6_port)); #endif } diff --git a/diff-lib.c b/diff-lib.c index ca085a03ef..7eb66a417a 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -641,7 +641,7 @@ int do_diff_cache(const struct object_id *tree_oid, struct diff_options *opt) if (diff_cache(&revs, tree_oid, NULL, 1)) exit(128); - clear_pathspec(&revs.prune_data); + release_revisions(&revs); return 0; } @@ -651,6 +651,7 @@ int index_differs_from(struct repository *r, { struct rev_info rev; struct setup_revision_opt opt; + unsigned has_changes; repo_init_revisions(r, &rev, NULL); memset(&opt, 0, sizeof(opt)); @@ -662,8 +663,9 @@ int index_differs_from(struct repository *r, diff_flags_or(&rev.diffopt.flags, flags); rev.diffopt.ita_invisible_in_index = ita_invisible_in_index; run_diff_index(&rev, 1); - object_array_clear(&rev.pending); - return (rev.diffopt.flags.has_changes != 0); + has_changes = rev.diffopt.flags.has_changes; + release_revisions(&rev); + return (has_changes != 0); } static struct strbuf *idiff_prefix_cb(struct diff_options *opt, void *data) @@ -3955,3 +3955,32 @@ void relocate_gitdir(const char *path, const char *old_git_dir, const char *new_ connect_work_tree_and_git_dir(path, new_git_dir, 0); } + +int path_match_flags(const char *const str, const enum path_match_flags flags) +{ + const char *p = str; + + if (flags & PATH_MATCH_NATIVE && + flags & PATH_MATCH_XPLATFORM) + BUG("path_match_flags() must get one match kind, not multiple!"); + else if (!(flags & PATH_MATCH_KINDS_MASK)) + BUG("path_match_flags() must get at least one match kind!"); + + if (flags & PATH_MATCH_STARTS_WITH_DOT_SLASH && + flags & PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH) + BUG("path_match_flags() must get one platform kind, not multiple!"); + else if (!(flags & PATH_MATCH_PLATFORM_MASK)) + BUG("path_match_flags() must get at least one platform kind!"); + + if (*p++ != '.') + return 0; + if (flags & PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH && + *p++ != '.') + return 0; + + if (flags & PATH_MATCH_NATIVE) + return is_dir_sep(*p); + else if (flags & PATH_MATCH_XPLATFORM) + return is_xplatform_dir_sep(*p); + BUG("unreachable"); +} @@ -578,4 +578,67 @@ void connect_work_tree_and_git_dir(const char *work_tree, void relocate_gitdir(const char *path, const char *old_git_dir, const char *new_git_dir); + +/** + * The "enum path_matches_kind" determines how path_match_flags() will + * behave. The flags come in sets, and one (and only one) must be + * provided out of each "set": + * + * PATH_MATCH_NATIVE: + * Path separator is is_dir_sep() + * PATH_MATCH_XPLATFORM: + * Path separator is is_xplatform_dir_sep() + * + * Do we use is_dir_sep() to check for a directory separator + * (*_NATIVE), or do we always check for '/' or '\' (*_XPLATFORM). The + * "*_NATIVE" version on Windows is the same as "*_XPLATFORM", + * everywhere else "*_NATIVE" means "only /". + * + * PATH_MATCH_STARTS_WITH_DOT_SLASH: + * Match a path starting with "./" + * PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH: + * Match a path starting with "../" + * + * The "/" in the above is adjusted based on the "*_NATIVE" and + * "*_XPLATFORM" flags. + */ +enum path_match_flags { + PATH_MATCH_NATIVE = 1 << 0, + PATH_MATCH_XPLATFORM = 1 << 1, + PATH_MATCH_STARTS_WITH_DOT_SLASH = 1 << 2, + PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH = 1 << 3, +}; +#define PATH_MATCH_KINDS_MASK (PATH_MATCH_STARTS_WITH_DOT_SLASH | \ + PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH) +#define PATH_MATCH_PLATFORM_MASK (PATH_MATCH_NATIVE | PATH_MATCH_XPLATFORM) + +/** + * path_match_flags() checks if a given "path" matches a given "enum + * path_match_flags" criteria. + */ +int path_match_flags(const char *const path, const enum path_match_flags f); + +/** + * starts_with_dot_slash_native(): convenience wrapper for + * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_SLASH and + * PATH_MATCH_NATIVE. + */ +static inline int starts_with_dot_slash_native(const char *const path) +{ + const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_SLASH; + + return path_match_flags(path, what | PATH_MATCH_NATIVE); +} + +/** + * starts_with_dot_slash_native(): convenience wrapper for + * path_match_flags() with PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH and + * PATH_MATCH_NATIVE. + */ +static inline int starts_with_dot_dot_slash_native(const char *const path) +{ + const enum path_match_flags what = PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH; + + return path_match_flags(path, what | PATH_MATCH_NATIVE); +} #endif @@ -80,7 +80,7 @@ static int launch_specified_editor(const char *editor, const char *path, strvec_pushl(&p.args, editor, realpath.buf, NULL); if (env) - strvec_pushv(&p.env_array, (const char **)env); + strvec_pushv(&p.env, (const char **)env); p.use_shell = 1; p.trace2_child_class = "editor"; if (start_command(&p) < 0) { diff --git a/fetch-pack.c b/fetch-pack.c index 6d0d271259..cb6647d657 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -115,11 +115,12 @@ static void for_each_cached_alternate(struct fetch_negotiator *negotiator, cb(negotiator, cache.items[i]); } -static struct commit *deref_without_lazy_fetch(const struct object_id *oid, - int mark_tags_complete) +static struct commit *deref_without_lazy_fetch_extended(const struct object_id *oid, + int mark_tags_complete, + enum object_type *type, + unsigned int oi_flags) { - enum object_type type; - struct object_info info = { .typep = &type }; + struct object_info info = { .typep = type }; struct commit *commit; commit = lookup_commit_in_graph(the_repository, oid); @@ -128,9 +129,9 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid, while (1) { if (oid_object_info_extended(the_repository, oid, &info, - OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK)) + oi_flags)) return NULL; - if (type == OBJ_TAG) { + if (*type == OBJ_TAG) { struct tag *tag = (struct tag *) parse_object(the_repository, oid); @@ -144,7 +145,7 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid, } } - if (type == OBJ_COMMIT) { + if (*type == OBJ_COMMIT) { struct commit *commit = lookup_commit(the_repository, oid); if (!commit || repo_parse_commit(the_repository, commit)) return NULL; @@ -154,6 +155,16 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid, return NULL; } + +static struct commit *deref_without_lazy_fetch(const struct object_id *oid, + int mark_tags_complete) +{ + enum object_type type; + unsigned flags = OBJECT_INFO_SKIP_FETCH_OBJECT | OBJECT_INFO_QUICK; + return deref_without_lazy_fetch_extended(oid, mark_tags_complete, + &type, flags); +} + static int rev_list_insert_ref(struct fetch_negotiator *negotiator, const struct object_id *oid) { @@ -836,6 +847,16 @@ static void parse_gitmodules_oids(int fd, struct oidset *gitmodules_oids) } while (1); } +static void add_index_pack_keep_option(struct strvec *args) +{ + char hostname[HOST_NAME_MAX + 1]; + + if (xgethostname(hostname, sizeof(hostname))) + xsnprintf(hostname, sizeof(hostname), "localhost"); + strvec_pushf(args, "--keep=fetch-pack %"PRIuMAX " on %s", + (uintmax_t)getpid(), hostname); +} + /* * If packfile URIs were provided, pass a non-NULL pointer to index_pack_args. * The strings to pass as the --index-pack-arg arguments to http-fetch will be @@ -905,14 +926,8 @@ static int get_pack(struct fetch_pack_args *args, strvec_push(&cmd.args, "-v"); if (args->use_thin_pack) strvec_push(&cmd.args, "--fix-thin"); - if ((do_keep || index_pack_args) && (args->lock_pack || unpack_limit)) { - char hostname[HOST_NAME_MAX + 1]; - if (xgethostname(hostname, sizeof(hostname))) - xsnprintf(hostname, sizeof(hostname), "localhost"); - strvec_pushf(&cmd.args, - "--keep=fetch-pack %"PRIuMAX " on %s", - (uintmax_t)getpid(), hostname); - } + if ((do_keep || index_pack_args) && (args->lock_pack || unpack_limit)) + add_index_pack_keep_option(&cmd.args); if (!index_pack_args && args->check_self_contained_and_connected) strvec_push(&cmd.args, "--check-self-contained-and-connected"); else diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index baca57d5b6..f48f44f9cd 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -699,6 +699,7 @@ int fmt_merge_msg(struct strbuf *in, struct strbuf *out, shortlog(origins.items[i].string, origins.items[i].util, head, &rev, opts, out); + release_revisions(&rev); } strbuf_complete_line(out); @@ -975,27 +975,16 @@ done: return ret; } -/* - * Like builtin/submodule--helper.c's starts_with_dot_slash, but without - * relying on the platform-dependent is_dir_sep helper. - * - * This is for use in checking whether a submodule URL is interpreted as - * relative to the current directory on any platform, since \ is a - * directory separator on Windows but not on other platforms. - */ -static int starts_with_dot_slash(const char *str) +static int starts_with_dot_slash(const char *const path) { - return str[0] == '.' && (str[1] == '/' || str[1] == '\\'); + return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_SLASH | + PATH_MATCH_XPLATFORM); } -/* - * Like starts_with_dot_slash, this is a variant of submodule--helper's - * helper of the same name with the twist that it accepts backslash as a - * directory separator even on non-Windows platforms. - */ -static int starts_with_dot_dot_slash(const char *str) +static int starts_with_dot_dot_slash(const char *const path) { - return str[0] == '.' && starts_with_dot_slash(str + 1); + return path_match_flags(path, PATH_MATCH_STARTS_WITH_DOT_DOT_SLASH | + PATH_MATCH_XPLATFORM); } static int submodule_url_is_relative(const char *url) diff --git a/fsmonitor--daemon.h b/fsmonitor--daemon.h index bd09fffc17..2102a5c9ff 100644 --- a/fsmonitor--daemon.h +++ b/fsmonitor--daemon.h @@ -33,10 +33,12 @@ void fsmonitor_batch__free_list(struct fsmonitor_batch *batch); */ void fsmonitor_batch__add_path(struct fsmonitor_batch *batch, const char *path); -struct fsmonitor_daemon_backend_data; /* opaque platform-specific data */ +struct fsm_listen_data; /* opaque platform-specific data for listener thread */ +struct fsm_health_data; /* opaque platform-specific data for health thread */ struct fsmonitor_daemon_state { pthread_t listener_thread; + pthread_t health_thread; pthread_mutex_t main_lock; struct strbuf path_worktree_watch; @@ -50,10 +52,13 @@ struct fsmonitor_daemon_state { int cookie_seq; struct hashmap cookies; - int error_code; - struct fsmonitor_daemon_backend_data *backend_data; + int listen_error_code; + int health_error_code; + struct fsm_listen_data *listen_data; + struct fsm_health_data *health_data; struct ipc_server_data *ipc_server_data; + struct strbuf path_ipc; }; /* diff --git a/fsmonitor-settings.c b/fsmonitor-settings.c index 757d230d53..658cb79da0 100644 --- a/fsmonitor-settings.c +++ b/fsmonitor-settings.c @@ -9,23 +9,52 @@ */ struct fsmonitor_settings { enum fsmonitor_mode mode; + enum fsmonitor_reason reason; char *hook_path; }; -static void lookup_fsmonitor_settings(struct repository *r) +static enum fsmonitor_reason check_for_incompatible(struct repository *r) +{ + if (!r->worktree) { + /* + * Bare repositories don't have a working directory and + * therefore have nothing to watch. + */ + return FSMONITOR_REASON_BARE; + } + +#ifdef HAVE_FSMONITOR_OS_SETTINGS + { + enum fsmonitor_reason reason; + + reason = fsm_os__incompatible(r); + if (reason != FSMONITOR_REASON_OK) + return reason; + } +#endif + + return FSMONITOR_REASON_OK; +} + +static struct fsmonitor_settings *alloc_settings(void) { struct fsmonitor_settings *s; + + CALLOC_ARRAY(s, 1); + s->mode = FSMONITOR_MODE_DISABLED; + s->reason = FSMONITOR_REASON_UNTESTED; + + return s; +} + +static void lookup_fsmonitor_settings(struct repository *r) +{ const char *const_str; int bool_value; if (r->settings.fsmonitor) return; - CALLOC_ARRAY(s, 1); - s->mode = FSMONITOR_MODE_DISABLED; - - r->settings.fsmonitor = s; - /* * Overload the existing "core.fsmonitor" config setting (which * has historically been either unset or a hook pathname) to @@ -38,6 +67,8 @@ static void lookup_fsmonitor_settings(struct repository *r) case 0: /* config value was set to <bool> */ if (bool_value) fsm_settings__set_ipc(r); + else + fsm_settings__set_disabled(r); return; case 1: /* config value was unset */ @@ -53,18 +84,18 @@ static void lookup_fsmonitor_settings(struct repository *r) return; } - if (!const_str || !*const_str) - return; - - fsm_settings__set_hook(r, const_str); + if (const_str && *const_str) + fsm_settings__set_hook(r, const_str); + else + fsm_settings__set_disabled(r); } enum fsmonitor_mode fsm_settings__get_mode(struct repository *r) { if (!r) r = the_repository; - - lookup_fsmonitor_settings(r); + if (!r->settings.fsmonitor) + lookup_fsmonitor_settings(r); return r->settings.fsmonitor->mode; } @@ -73,31 +104,55 @@ const char *fsm_settings__get_hook_path(struct repository *r) { if (!r) r = the_repository; - - lookup_fsmonitor_settings(r); + if (!r->settings.fsmonitor) + lookup_fsmonitor_settings(r); return r->settings.fsmonitor->hook_path; } void fsm_settings__set_ipc(struct repository *r) { + enum fsmonitor_reason reason = check_for_incompatible(r); + + if (reason != FSMONITOR_REASON_OK) { + fsm_settings__set_incompatible(r, reason); + return; + } + + /* + * Caller requested IPC explicitly, so avoid (possibly + * recursive) config lookup. + */ if (!r) r = the_repository; - - lookup_fsmonitor_settings(r); + if (!r->settings.fsmonitor) + r->settings.fsmonitor = alloc_settings(); r->settings.fsmonitor->mode = FSMONITOR_MODE_IPC; + r->settings.fsmonitor->reason = reason; FREE_AND_NULL(r->settings.fsmonitor->hook_path); } void fsm_settings__set_hook(struct repository *r, const char *path) { + enum fsmonitor_reason reason = check_for_incompatible(r); + + if (reason != FSMONITOR_REASON_OK) { + fsm_settings__set_incompatible(r, reason); + return; + } + + /* + * Caller requested hook explicitly, so avoid (possibly + * recursive) config lookup. + */ if (!r) r = the_repository; - - lookup_fsmonitor_settings(r); + if (!r->settings.fsmonitor) + r->settings.fsmonitor = alloc_settings(); r->settings.fsmonitor->mode = FSMONITOR_MODE_HOOK; + r->settings.fsmonitor->reason = reason; FREE_AND_NULL(r->settings.fsmonitor->hook_path); r->settings.fsmonitor->hook_path = strdup(path); } @@ -106,9 +161,81 @@ void fsm_settings__set_disabled(struct repository *r) { if (!r) r = the_repository; - - lookup_fsmonitor_settings(r); + if (!r->settings.fsmonitor) + r->settings.fsmonitor = alloc_settings(); r->settings.fsmonitor->mode = FSMONITOR_MODE_DISABLED; + r->settings.fsmonitor->reason = FSMONITOR_REASON_OK; FREE_AND_NULL(r->settings.fsmonitor->hook_path); } + +void fsm_settings__set_incompatible(struct repository *r, + enum fsmonitor_reason reason) +{ + if (!r) + r = the_repository; + if (!r->settings.fsmonitor) + r->settings.fsmonitor = alloc_settings(); + + r->settings.fsmonitor->mode = FSMONITOR_MODE_INCOMPATIBLE; + r->settings.fsmonitor->reason = reason; + FREE_AND_NULL(r->settings.fsmonitor->hook_path); +} + +enum fsmonitor_reason fsm_settings__get_reason(struct repository *r) +{ + if (!r) + r = the_repository; + if (!r->settings.fsmonitor) + lookup_fsmonitor_settings(r); + + return r->settings.fsmonitor->reason; +} + +char *fsm_settings__get_incompatible_msg(const struct repository *r, + enum fsmonitor_reason reason) +{ + struct strbuf msg = STRBUF_INIT; + + switch (reason) { + case FSMONITOR_REASON_UNTESTED: + case FSMONITOR_REASON_OK: + goto done; + + case FSMONITOR_REASON_BARE: + strbuf_addf(&msg, + _("bare repository '%s' is incompatible with fsmonitor"), + xgetcwd()); + goto done; + + case FSMONITOR_REASON_ERROR: + strbuf_addf(&msg, + _("repository '%s' is incompatible with fsmonitor due to errors"), + r->worktree); + goto done; + + case FSMONITOR_REASON_REMOTE: + strbuf_addf(&msg, + _("remote repository '%s' is incompatible with fsmonitor"), + r->worktree); + goto done; + + case FSMONITOR_REASON_VFS4GIT: + strbuf_addf(&msg, + _("virtual repository '%s' is incompatible with fsmonitor"), + r->worktree); + goto done; + + case FSMONITOR_REASON_NOSOCKETS: + strbuf_addf(&msg, + _("repository '%s' is incompatible with fsmonitor due to lack of Unix sockets"), + r->worktree); + goto done; + } + + BUG("Unhandled case in fsm_settings__get_incompatible_msg: '%d'", + reason); + +done: + return strbuf_detach(&msg, NULL); +} diff --git a/fsmonitor-settings.h b/fsmonitor-settings.h index a4c5d7b488..d9c2605197 100644 --- a/fsmonitor-settings.h +++ b/fsmonitor-settings.h @@ -4,18 +4,51 @@ struct repository; enum fsmonitor_mode { + FSMONITOR_MODE_INCOMPATIBLE = -1, /* see _reason */ FSMONITOR_MODE_DISABLED = 0, FSMONITOR_MODE_HOOK = 1, /* core.fsmonitor=<hook_path> */ FSMONITOR_MODE_IPC = 2, /* core.fsmonitor=<true> */ }; +/* + * Incompatibility reasons. + */ +enum fsmonitor_reason { + FSMONITOR_REASON_UNTESTED = 0, + FSMONITOR_REASON_OK, /* no incompatibility or when disabled */ + FSMONITOR_REASON_BARE, + FSMONITOR_REASON_ERROR, /* FS error probing for compatibility */ + FSMONITOR_REASON_REMOTE, + FSMONITOR_REASON_VFS4GIT, /* VFS for Git virtualization */ + FSMONITOR_REASON_NOSOCKETS, /* NTFS,FAT32 do not support Unix sockets */ +}; + void fsm_settings__set_ipc(struct repository *r); void fsm_settings__set_hook(struct repository *r, const char *path); void fsm_settings__set_disabled(struct repository *r); +void fsm_settings__set_incompatible(struct repository *r, + enum fsmonitor_reason reason); enum fsmonitor_mode fsm_settings__get_mode(struct repository *r); const char *fsm_settings__get_hook_path(struct repository *r); +enum fsmonitor_reason fsm_settings__get_reason(struct repository *r); +char *fsm_settings__get_incompatible_msg(const struct repository *r, + enum fsmonitor_reason reason); + struct fsmonitor_settings; +#ifdef HAVE_FSMONITOR_OS_SETTINGS +/* + * Ask platform-specific code whether the repository is incompatible + * with fsmonitor (both hook and ipc modes). For example, if the working + * directory is on a remote volume and mounted via a technology that does + * not support notification events, then we should not pretend to watch it. + * + * fsm_os__* routines should considered private to fsm_settings__ + * routines. + */ +enum fsmonitor_reason fsm_os__incompatible(struct repository *r); +#endif /* HAVE_FSMONITOR_OS_SETTINGS */ + #endif /* FSMONITOR_SETTINGS_H */ diff --git a/fsmonitor.c b/fsmonitor.c index 292a6742b4..57d6a483be 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -184,30 +184,68 @@ static int query_fsmonitor_hook(struct repository *r, static void fsmonitor_refresh_callback(struct index_state *istate, char *name) { int i, len = strlen(name); - if (name[len - 1] == '/') { + int pos = index_name_pos(istate, name, len); + + trace_printf_key(&trace_fsmonitor, + "fsmonitor_refresh_callback '%s' (pos %d)", + name, pos); + if (name[len - 1] == '/') { /* - * TODO We should binary search to find the first path with - * TODO this directory prefix. Then linearly update entries - * TODO while the prefix matches. Taking care to search without - * TODO the trailing slash -- because '/' sorts after a few - * TODO interesting special chars, like '.' and ' '. + * The daemon can decorate directory events, such as + * moves or renames, with a trailing slash if the OS + * FS Event contains sufficient information, such as + * MacOS. + * + * Use this to invalidate the entire cone under that + * directory. + * + * We do not expect an exact match because the index + * does not normally contain directory entries, so we + * start at the insertion point and scan. */ + if (pos < 0) + pos = -pos - 1; /* Mark all entries for the folder invalid */ - for (i = 0; i < istate->cache_nr; i++) { - if (istate->cache[i]->ce_flags & CE_FSMONITOR_VALID && - starts_with(istate->cache[i]->name, name)) - istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; + for (i = pos; i < istate->cache_nr; i++) { + if (!starts_with(istate->cache[i]->name, name)) + break; + istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; } - /* Need to remove the / from the path for the untracked cache */ + + /* + * We need to remove the traling "/" from the path + * for the untracked cache. + */ name[len - 1] = '\0'; + } else if (pos >= 0) { + /* + * We have an exact match for this path and can just + * invalidate it. + */ + istate->cache[pos]->ce_flags &= ~CE_FSMONITOR_VALID; } else { - int pos = index_name_pos(istate, name, strlen(name)); - - if (pos >= 0) { - struct cache_entry *ce = istate->cache[pos]; - ce->ce_flags &= ~CE_FSMONITOR_VALID; + /* + * The path is not a tracked file -or- it is a + * directory event on a platform that cannot + * distinguish between file and directory events in + * the event handler, such as Windows. + * + * Scan as if it is a directory and invalidate the + * cone under it. (But remember to ignore items + * between "name" and "name/", such as "name-" and + * "name.". + */ + pos = -pos - 1; + + for (i = pos; i < istate->cache_nr; i++) { + if (!starts_with(istate->cache[i]->name, name)) + break; + if ((unsigned char)istate->cache[i]->name[len] > '/') + break; + if (istate->cache[i]->name[len] == '/') + istate->cache[i]->ce_flags &= ~CE_FSMONITOR_VALID; } } @@ -215,7 +253,6 @@ static void fsmonitor_refresh_callback(struct index_state *istate, char *name) * Mark the untracked cache dirty even if it wasn't found in the index * as it could be a new untracked file. */ - trace_printf_key(&trace_fsmonitor, "fsmonitor_refresh_callback '%s'", name); untracked_cache_invalidate_path(istate, name, 0); } @@ -543,6 +580,8 @@ void tweak_fsmonitor(struct index_state *istate) if (fsmonitor_enabled) { /* Mark all entries valid */ for (i = 0; i < istate->cache_nr; i++) { + if (S_ISGITLINK(istate->cache[i]->ce_mode)) + continue; istate->cache[i]->ce_flags |= CE_FSMONITOR_VALID; } diff --git a/fsmonitor.h b/fsmonitor.h index 3f41f65369..edf7ce5203 100644 --- a/fsmonitor.h +++ b/fsmonitor.h @@ -68,6 +68,15 @@ static inline int is_fsmonitor_refreshed(const struct index_state *istate) * Set the given cache entries CE_FSMONITOR_VALID bit. This should be * called any time the cache entry has been updated to reflect the * current state of the file on disk. + * + * However, never mark submodules as valid. When commands like "git + * status" run they might need to recurse into the submodule (using a + * child process) to get a summary of the submodule state. We don't + * have (and don't want to create) the facility to translate every + * FS event that we receive and that happens to be deep inside of a + * submodule back to the submodule root, so we cannot correctly keep + * track of this bit on the gitlink directory. Therefore, we never + * set it on submodules. */ static inline void mark_fsmonitor_valid(struct index_state *istate, struct cache_entry *ce) { @@ -75,6 +84,8 @@ static inline void mark_fsmonitor_valid(struct index_state *istate, struct cache if (fsm_mode > FSMONITOR_MODE_DISABLED && !(ce->ce_flags & CE_FSMONITOR_VALID)) { + if (S_ISGITLINK(ce->ce_mode)) + return; istate->cache_changed = 1; ce->ce_flags |= CE_FSMONITOR_VALID; trace_printf_key(&trace_fsmonitor, "mark_fsmonitor_clean '%s'", ce->name); diff --git a/git-compat-util.h b/git-compat-util.h index 96293b6c43..fd36d3bfdc 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -236,6 +236,12 @@ #include <sys/sysctl.h> #endif +/* Used by compat/win32/path-utils.h, and more */ +static inline int is_xplatform_dir_sep(int c) +{ + return c == '/' || c == '\\'; +} + #if defined(__CYGWIN__) #include "compat/win32/path-utils.h" #endif @@ -416,11 +422,11 @@ static inline int git_skip_dos_drive_prefix(char **path) #define skip_dos_drive_prefix git_skip_dos_drive_prefix #endif -#ifndef is_dir_sep static inline int git_is_dir_sep(int c) { return c == '/'; } +#ifndef is_dir_sep #define is_dir_sep git_is_dir_sep #endif @@ -1320,15 +1326,27 @@ static inline int regexec_buf(const regex_t *preg, const char *buf, size_t size, /* usage.c: only to be used for testing BUG() implementation (see test-tool) */ extern int BUG_exit_code; +/* usage.c: if bug() is called we should have a BUG_if_bug() afterwards */ +extern int bug_called_must_BUG; + __attribute__((format (printf, 3, 4))) NORETURN void BUG_fl(const char *file, int line, const char *fmt, ...); #define BUG(...) BUG_fl(__FILE__, __LINE__, __VA_ARGS__) +__attribute__((format (printf, 3, 4))) +void bug_fl(const char *file, int line, const char *fmt, ...); +#define bug(...) bug_fl(__FILE__, __LINE__, __VA_ARGS__) +#define BUG_if_bug(...) do { \ + if (bug_called_must_BUG) \ + BUG_fl(__FILE__, __LINE__, __VA_ARGS__); \ +} while (0) +#ifndef FSYNC_METHOD_DEFAULT #ifdef __APPLE__ #define FSYNC_METHOD_DEFAULT FSYNC_METHOD_WRITEOUT_ONLY #else #define FSYNC_METHOD_DEFAULT FSYNC_METHOD_FSYNC #endif +#endif enum fsync_action { FSYNC_WRITEOUT_ONLY, @@ -1451,8 +1469,8 @@ int cmd_main(int, const char **); * Intercept all calls to exit() and route them to trace2 to * optionally emit a message before calling the real exit(). */ -int trace2_cmd_exit_fl(const char *file, int line, int code); -#define exit(code) exit(trace2_cmd_exit_fl(__FILE__, __LINE__, (code))) +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 @@ -538,7 +538,7 @@ static struct cmd_struct commands[] = { { "format-patch", cmd_format_patch, RUN_SETUP }, { "fsck", cmd_fsck, RUN_SETUP }, { "fsck-objects", cmd_fsck, RUN_SETUP }, - { "fsmonitor--daemon", cmd_fsmonitor__daemon, RUN_SETUP }, + { "fsmonitor--daemon", cmd_fsmonitor__daemon, SUPPORT_SUPER_PREFIX | RUN_SETUP }, { "gc", cmd_gc, RUN_SETUP }, { "get-tar-commit-id", cmd_get_tar_commit_id, NO_PARSEOPT }, { "grep", cmd_grep, RUN_SETUP_GENTLY }, diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 606b50104c..1835487ab2 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -4219,7 +4219,10 @@ sub git_header_html { my $mod_perl_version = $ENV{'MOD_PERL'} ? " $ENV{'MOD_PERL'}" : ''; print <<EOF; <?xml version="1.0" encoding="utf-8"?> -<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<!DOCTYPE html [ + <!ENTITY nbsp " "> + <!ENTITY sdot "⋅"> +]> <html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> <!-- git web interface version $version, (C) 2005-2006, Kay Sievers <kay.sievers\@vrfy.org>, Christian Gierke --> <!-- git core binaries version $git_version --> @@ -54,7 +54,7 @@ static int pick_next_hook(struct child_process *cp, return 0; cp->no_stdin = 1; - strvec_pushv(&cp->env_array, hook_cb->options->env.v); + strvec_pushv(&cp->env, hook_cb->options->env.v); cp->stdout_to_stderr = 1; cp->trace2_hook_name = hook_cb->hook_name; cp->dir = hook_cb->options->dir; @@ -144,6 +144,7 @@ int run_hooks_opt(const char *hook_name, struct run_hooks_opt *options) cb_data.hook_path = abs_path.buf; } + run_processes_parallel_ungroup = 1; run_processes_parallel_tr2(jobs, pick_next_hook, notify_start_failure, diff --git a/http-backend.c b/http-backend.c index 81a7229ece..58b83a9f66 100644 --- a/http-backend.c +++ b/http-backend.c @@ -476,9 +476,9 @@ static void run_service(const char **argv, int buffer_input) host = "(none)"; if (!getenv("GIT_COMMITTER_NAME")) - strvec_pushf(&cld.env_array, "GIT_COMMITTER_NAME=%s", user); + strvec_pushf(&cld.env, "GIT_COMMITTER_NAME=%s", user); if (!getenv("GIT_COMMITTER_EMAIL")) - strvec_pushf(&cld.env_array, + strvec_pushf(&cld.env, "GIT_COMMITTER_EMAIL=%s@http.%s", user, host); strvec_pushv(&cld.args, argv); diff --git a/http-push.c b/http-push.c index 7dafb1331a..5f4340a36e 100644 --- a/http-push.c +++ b/http-push.c @@ -1689,7 +1689,6 @@ int cmd_main(int argc, const char **argv) struct refspec rs = REFSPEC_INIT_PUSH; struct remote_lock *ref_lock = NULL; struct remote_lock *info_ref_lock = NULL; - struct rev_info revs; int delete_branch = 0; int force_delete = 0; int objects_to_send; @@ -1825,6 +1824,7 @@ int cmd_main(int argc, const char **argv) new_refs = 0; for (ref = remote_refs; ref; ref = ref->next) { + struct rev_info revs; struct strvec commit_argv = STRVEC_INIT; if (!ref->peer_ref) @@ -1941,6 +1941,7 @@ int cmd_main(int argc, const char **argv) unlock_remote(ref_lock); check_locks(); strvec_clear(&commit_argv); + release_revisions(&revs); } /* Update remote server info if appropriate */ @@ -1989,8 +1989,8 @@ int http_get_strbuf(const char *url, * If a previous interrupted download is detected (i.e. a previous temporary * file is still around) the download is resumed. */ -static int http_get_file(const char *url, const char *filename, - struct http_get_options *options) +int http_get_file(const char *url, const char *filename, + struct http_get_options *options) { int ret; struct strbuf tmpfile = STRBUF_INIT; @@ -163,6 +163,15 @@ struct http_get_options { */ int http_get_strbuf(const char *url, struct strbuf *result, struct http_get_options *options); +/* + * Downloads a URL and stores the result in the given file. + * + * If a previous interrupted download is detected (i.e. a previous temporary + * file is still around) the download is resumed. + */ +int http_get_file(const char *url, const char *filename, + struct http_get_options *options); + int http_fetch_ref(const char *base, struct ref *ref); /* Helpers for fetching packs */ diff --git a/merge-ort.c b/merge-ort.c index 0d3f42592f..b5015b9afd 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -1594,6 +1594,7 @@ static int find_first_merges(struct repository *repo, } object_array_clear(&merges); + release_revisions(&revs); return result->nr; } diff --git a/merge-recursive.c b/merge-recursive.c index fd1bbde061..b83a129b43 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -522,10 +522,10 @@ static struct stage_data *insert_stage_data(struct repository *r, */ static struct string_list *get_unmerged(struct index_state *istate) { - struct string_list *unmerged = xcalloc(1, sizeof(struct string_list)); + struct string_list *unmerged = xmalloc(sizeof(struct string_list)); int i; - unmerged->strdup_strings = 1; + string_list_init_dup(unmerged); /* TODO: audit for interaction with sparse-index. */ ensure_full_index(istate); @@ -1160,6 +1160,7 @@ static int find_first_merges(struct repository *repo, } object_array_clear(&merges); + release_revisions(&revs); return result->nr; } @@ -41,18 +41,6 @@ #define PACK_EXPIRED UINT_MAX -static uint8_t oid_version(void) -{ - switch (hash_algo_by_ptr(the_hash_algo)) { - case GIT_HASH_SHA1: - return 1; - case GIT_HASH_SHA256: - return 2; - default: - die(_("invalid hash version")); - } -} - const unsigned char *get_midx_checksum(struct multi_pack_index *m) { return m->data + m->data_len - the_hash_algo->rawsz; @@ -134,9 +122,9 @@ struct multi_pack_index *load_multi_pack_index(const char *object_dir, int local m->version); hash_version = m->data[MIDX_BYTE_HASH_VERSION]; - if (hash_version != oid_version()) { + if (hash_version != oid_version(the_hash_algo)) { error(_("multi-pack-index hash version %u does not match version %u"), - hash_version, oid_version()); + hash_version, oid_version(the_hash_algo)); goto cleanup_fail; } m->hash_len = the_hash_algo->rawsz; @@ -420,7 +408,7 @@ static size_t write_midx_header(struct hashfile *f, { hashwrite_be32(f, MIDX_SIGNATURE); hashwrite_u8(f, MIDX_VERSION); - hashwrite_u8(f, oid_version()); + hashwrite_u8(f, oid_version(the_hash_algo)); hashwrite_u8(f, num_chunks); hashwrite_u8(f, 0); /* unused */ hashwrite_be32(f, num_packs); @@ -1061,6 +1049,7 @@ static struct commit **find_commits_for_midx_bitmap(uint32_t *indexed_commits_nr if (indexed_commits_nr_p) *indexed_commits_nr_p = cb.commits_nr; + release_revisions(&revs); return cb.commits; } diff --git a/object-file.c b/object-file.c index d35c1820e7..6c8e3b1660 100644 --- a/object-file.c +++ b/object-file.c @@ -838,7 +838,7 @@ static void fill_alternate_refs_command(struct child_process *cmd, } } - strvec_pushv(&cmd->env_array, (const char **)local_repo_env); + strvec_pushv(&cmd->env, (const char **)local_repo_env); cmd->out = -1; } @@ -997,7 +997,7 @@ int has_loose_object_nonlocal(const struct object_id *oid) return check_and_freshen_nonlocal(oid, 0); } -static int has_loose_object(const struct object_id *oid) +int has_loose_object(const struct object_id *oid) { return check_and_freshen(oid, 0); } @@ -1893,7 +1893,9 @@ static void close_loose_object(int fd, const char *filename) if (the_repository->objects->odb->will_destroy) goto out; - if (fsync_object_files > 0) + if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) + fsync_loose_object_bulk_checkin(fd, filename); + else if (fsync_object_files > 0) fsync_or_die(fd, filename); else fsync_component_or_die(FSYNC_COMPONENT_LOOSE_OBJECT, fd, @@ -1961,6 +1963,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr, static struct strbuf tmp_file = STRBUF_INIT; static struct strbuf filename = STRBUF_INIT; + if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) + prepare_loose_object_bulk_checkin(); + loose_object_path(the_repository, &filename, oid); fd = create_tmpfile(&tmp_file, filename.buf); @@ -2035,6 +2040,8 @@ static int freshen_packed_object(const struct object_id *oid) struct pack_entry e; if (!find_pack_entry(the_repository, oid, &e)) return 0; + if (e.p->is_cruft) + return 0; if (e.p->freshened) return 1; if (!freshen_file(e.p->pack_name)) @@ -2623,12 +2630,8 @@ int read_loose_object(const char *path, goto out; } - switch (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr), - NULL)) { - case ULHR_OK: - break; - case ULHR_BAD: - case ULHR_TOO_LONG: + if (unpack_loose_header(&stream, map, mapsize, hdr, sizeof(hdr), + NULL) != ULHR_OK) { error(_("unable to unpack header of %s"), path); goto out; } diff --git a/object-store.h b/object-store.h index 53996018c1..539ea43904 100644 --- a/object-store.h +++ b/object-store.h @@ -115,12 +115,20 @@ struct packed_git { freshened:1, do_not_close:1, pack_promisor:1, - multi_pack_index:1; + multi_pack_index:1, + is_cruft:1; unsigned char hash[GIT_MAX_RAWSZ]; struct revindex_entry *revindex; const uint32_t *revindex_data; const uint32_t *revindex_map; size_t revindex_size; + /* + * mtimes_map points at the beginning of the memory mapped region of + * this pack's corresponding .mtimes file, and mtimes_size is the size + * of that .mtimes file + */ + const uint32_t *mtimes_map; + size_t mtimes_size; /* something like ".git/objects/pack/xxxxx.pack" */ char pack_name[FLEX_ARRAY]; /* more */ }; @@ -327,6 +335,8 @@ int repo_has_object_file_with_flags(struct repository *r, */ int has_loose_object_nonlocal(const struct object_id *); +int has_loose_object(const struct object_id *); + /** * format_object_header() is a thin wrapper around s xsnprintf() that * writes the initial "<type> <obj-len>" part of the loose object diff --git a/pack-bitmap-write.c b/pack-bitmap-write.c index cf681547f2..c43375bd34 100644 --- a/pack-bitmap-write.c +++ b/pack-bitmap-write.c @@ -326,6 +326,7 @@ next: trace2_data_intmax("pack-bitmap-write", the_repository, "num_maximal_commits", num_maximal); + release_revisions(&revs); free_commit_list(reusable); } diff --git a/pack-bitmap.c b/pack-bitmap.c index 6a7cdca231..36134222d7 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -315,6 +315,8 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, struct stat st; char *idx_name = midx_bitmap_filename(midx); int fd = git_open(idx_name); + uint32_t i; + struct packed_git *preferred; free(idx_name); @@ -353,6 +355,20 @@ static int open_midx_bitmap_1(struct bitmap_index *bitmap_git, warning(_("multi-pack bitmap is missing required reverse index")); goto cleanup; } + + for (i = 0; i < bitmap_git->midx->num_packs; i++) { + if (prepare_midx_pack(the_repository, bitmap_git->midx, i)) + die(_("could not open pack %s"), + bitmap_git->midx->pack_names[i]); + } + + preferred = bitmap_git->midx->packs[midx_preferred_pack(bitmap_git)]; + if (!is_pack_valid(preferred)) { + warning(_("preferred pack (%s) is invalid"), + preferred->pack_name); + goto cleanup; + } + return 0; cleanup: @@ -429,8 +445,6 @@ static int load_reverse_index(struct bitmap_index *bitmap_git) * since we will need to make use of them in pack-objects. */ for (i = 0; i < bitmap_git->midx->num_packs; i++) { - if (prepare_midx_pack(the_repository, bitmap_git->midx, i)) - die(_("load_reverse_index: could not open pack")); ret = load_pack_revindex(bitmap_git->midx->packs[i]); if (ret) return ret; diff --git a/pack-mtimes.c b/pack-mtimes.c new file mode 100644 index 0000000000..0e0aafdcb0 --- /dev/null +++ b/pack-mtimes.c @@ -0,0 +1,129 @@ +#include "git-compat-util.h" +#include "pack-mtimes.h" +#include "object-store.h" +#include "packfile.h" + +static char *pack_mtimes_filename(struct packed_git *p) +{ + size_t len; + if (!strip_suffix(p->pack_name, ".pack", &len)) + BUG("pack_name does not end in .pack"); + return xstrfmt("%.*s.mtimes", (int)len, p->pack_name); +} + +#define MTIMES_HEADER_SIZE (12) + +struct mtimes_header { + uint32_t signature; + uint32_t version; + uint32_t hash_id; +}; + +static int load_pack_mtimes_file(char *mtimes_file, + uint32_t num_objects, + const uint32_t **data_p, size_t *len_p) +{ + int fd, ret = 0; + struct stat st; + uint32_t *data = NULL; + size_t mtimes_size, expected_size; + struct mtimes_header header; + + fd = git_open(mtimes_file); + + if (fd < 0) { + ret = -1; + goto cleanup; + } + if (fstat(fd, &st)) { + ret = error_errno(_("failed to read %s"), mtimes_file); + goto cleanup; + } + + mtimes_size = xsize_t(st.st_size); + + if (mtimes_size < MTIMES_HEADER_SIZE) { + ret = error(_("mtimes file %s is too small"), mtimes_file); + goto cleanup; + } + + data = xmmap(NULL, mtimes_size, PROT_READ, MAP_PRIVATE, fd, 0); + + header.signature = ntohl(data[0]); + header.version = ntohl(data[1]); + header.hash_id = ntohl(data[2]); + + if (header.signature != MTIMES_SIGNATURE) { + ret = error(_("mtimes file %s has unknown signature"), mtimes_file); + goto cleanup; + } + + if (header.version != 1) { + ret = error(_("mtimes file %s has unsupported version %"PRIu32), + mtimes_file, header.version); + goto cleanup; + } + + if (!(header.hash_id == 1 || header.hash_id == 2)) { + ret = error(_("mtimes file %s has unsupported hash id %"PRIu32), + mtimes_file, header.hash_id); + goto cleanup; + } + + + expected_size = MTIMES_HEADER_SIZE; + expected_size = st_add(expected_size, st_mult(sizeof(uint32_t), num_objects)); + expected_size = st_add(expected_size, 2 * (header.hash_id == 1 ? GIT_SHA1_RAWSZ : GIT_SHA256_RAWSZ)); + + if (mtimes_size != expected_size) { + ret = error(_("mtimes file %s is corrupt"), mtimes_file); + goto cleanup; + } + +cleanup: + if (ret) { + if (data) + munmap(data, mtimes_size); + } else { + *len_p = mtimes_size; + *data_p = data; + } + + close(fd); + return ret; +} + +int load_pack_mtimes(struct packed_git *p) +{ + char *mtimes_name = NULL; + int ret = 0; + + if (!p->is_cruft) + return ret; /* not a cruft pack */ + if (p->mtimes_map) + return ret; /* already loaded */ + + ret = open_pack_index(p); + if (ret < 0) + goto cleanup; + + mtimes_name = pack_mtimes_filename(p); + ret = load_pack_mtimes_file(mtimes_name, + p->num_objects, + &p->mtimes_map, + &p->mtimes_size); +cleanup: + free(mtimes_name); + return ret; +} + +uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos) +{ + if (!p->mtimes_map) + BUG("pack .mtimes file not loaded for %s", p->pack_name); + if (p->num_objects <= pos) + BUG("pack .mtimes out-of-bounds (%"PRIu32" vs %"PRIu32")", + pos, p->num_objects); + + return get_be32(p->mtimes_map + pos + 3); +} diff --git a/pack-mtimes.h b/pack-mtimes.h new file mode 100644 index 0000000000..cc957b3e85 --- /dev/null +++ b/pack-mtimes.h @@ -0,0 +1,26 @@ +#ifndef PACK_MTIMES_H +#define PACK_MTIMES_H + +#include "git-compat-util.h" + +#define MTIMES_SIGNATURE 0x4d544d45 /* "MTME" */ +#define MTIMES_VERSION 1 + +struct packed_git; + +/* + * Loads the .mtimes file corresponding to "p", if any, returning zero + * on success. + */ +int load_pack_mtimes(struct packed_git *p); + +/* Returns the mtime associated with the object at position "pos" (in + * lexicographic/index order) in pack "p". + * + * Note that it is a BUG() to call this function if either (a) "p" does + * not have a corresponding .mtimes file, or (b) it does, but it hasn't + * been loaded + */ +uint32_t nth_packed_mtime(struct packed_git *p, uint32_t pos); + +#endif diff --git a/pack-objects.c b/pack-objects.c index fe2a4eace9..272e8d4517 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -170,6 +170,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata, if (pdata->layer) REALLOC_ARRAY(pdata->layer, pdata->nr_alloc); + + if (pdata->cruft_mtime) + REALLOC_ARRAY(pdata->cruft_mtime, pdata->nr_alloc); } new_entry = pdata->objects + pdata->nr_objects++; @@ -198,6 +201,9 @@ struct object_entry *packlist_alloc(struct packing_data *pdata, if (pdata->layer) pdata->layer[pdata->nr_objects - 1] = 0; + if (pdata->cruft_mtime) + pdata->cruft_mtime[pdata->nr_objects - 1] = 0; + return new_entry; } diff --git a/pack-objects.h b/pack-objects.h index dca2351ef9..393b9db546 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -168,6 +168,14 @@ struct packing_data { /* delta islands */ unsigned int *tree_depth; unsigned char *layer; + + /* + * Used when writing cruft packs. + * + * Object mtimes are stored in pack order when writing, but + * written out in lexicographic (index) order. + */ + uint32_t *cruft_mtime; }; void prepare_packing_data(struct repository *r, struct packing_data *pdata); @@ -289,4 +297,21 @@ static inline void oe_set_layer(struct packing_data *pack, pack->layer[e - pack->objects] = layer; } +static inline uint32_t oe_cruft_mtime(struct packing_data *pack, + struct object_entry *e) +{ + if (!pack->cruft_mtime) + return 0; + return pack->cruft_mtime[e - pack->objects]; +} + +static inline void oe_set_cruft_mtime(struct packing_data *pack, + struct object_entry *e, + uint32_t mtime) +{ + if (!pack->cruft_mtime) + CALLOC_ARRAY(pack->cruft_mtime, pack->nr_alloc); + pack->cruft_mtime[e - pack->objects] = mtime; +} + #endif diff --git a/pack-write.c b/pack-write.c index 51812cb129..23c0342018 100644 --- a/pack-write.c +++ b/pack-write.c @@ -2,6 +2,11 @@ #include "pack.h" #include "csum-file.h" #include "remote.h" +#include "chunk-format.h" +#include "pack-mtimes.h" +#include "oidmap.h" +#include "chunk-format.h" +#include "pack-objects.h" void reset_pack_idx_option(struct pack_idx_option *opts) { @@ -181,21 +186,9 @@ static int pack_order_cmp(const void *va, const void *vb, void *ctx) static void write_rev_header(struct hashfile *f) { - uint32_t oid_version; - switch (hash_algo_by_ptr(the_hash_algo)) { - case GIT_HASH_SHA1: - oid_version = 1; - break; - case GIT_HASH_SHA256: - oid_version = 2; - break; - default: - die("write_rev_header: unknown hash version"); - } - hashwrite_be32(f, RIDX_SIGNATURE); hashwrite_be32(f, RIDX_VERSION); - hashwrite_be32(f, oid_version); + hashwrite_be32(f, oid_version(the_hash_algo)); } static void write_rev_index_positions(struct hashfile *f, @@ -288,6 +281,70 @@ const char *write_rev_file_order(const char *rev_name, return rev_name; } +static void write_mtimes_header(struct hashfile *f) +{ + hashwrite_be32(f, MTIMES_SIGNATURE); + hashwrite_be32(f, MTIMES_VERSION); + hashwrite_be32(f, oid_version(the_hash_algo)); +} + +/* + * Writes the object mtimes of "objects" for use in a .mtimes file. + * Note that objects must be in lexicographic (index) order, which is + * the expected ordering of these values in the .mtimes file. + */ +static void write_mtimes_objects(struct hashfile *f, + struct packing_data *to_pack, + struct pack_idx_entry **objects, + uint32_t nr_objects) +{ + uint32_t i; + for (i = 0; i < nr_objects; i++) { + struct object_entry *e = (struct object_entry*)objects[i]; + hashwrite_be32(f, oe_cruft_mtime(to_pack, e)); + } +} + +static void write_mtimes_trailer(struct hashfile *f, const unsigned char *hash) +{ + hashwrite(f, hash, the_hash_algo->rawsz); +} + +static const char *write_mtimes_file(const char *mtimes_name, + struct packing_data *to_pack, + struct pack_idx_entry **objects, + uint32_t nr_objects, + const unsigned char *hash) +{ + struct hashfile *f; + int fd; + + if (!to_pack) + BUG("cannot call write_mtimes_file with NULL packing_data"); + + if (!mtimes_name) { + struct strbuf tmp_file = STRBUF_INIT; + fd = odb_mkstemp(&tmp_file, "pack/tmp_mtimes_XXXXXX"); + mtimes_name = strbuf_detach(&tmp_file, NULL); + } else { + unlink(mtimes_name); + fd = xopen(mtimes_name, O_CREAT|O_EXCL|O_WRONLY, 0600); + } + f = hashfd(fd, mtimes_name); + + write_mtimes_header(f); + write_mtimes_objects(f, to_pack, objects, nr_objects); + write_mtimes_trailer(f, hash); + + if (adjust_shared_perm(mtimes_name) < 0) + die(_("failed to make %s readable"), mtimes_name); + + finalize_hashfile(f, NULL, FSYNC_COMPONENT_PACK_METADATA, + CSUM_HASH_IN_STREAM | CSUM_CLOSE | CSUM_FSYNC); + + return mtimes_name; +} + off_t write_pack_header(struct hashfile *f, uint32_t nr_entries) { struct pack_header hdr; @@ -484,11 +541,13 @@ void stage_tmp_packfiles(struct strbuf *name_buffer, const char *pack_tmp_name, struct pack_idx_entry **written_list, uint32_t nr_written, + struct packing_data *to_pack, struct pack_idx_option *pack_idx_opts, unsigned char hash[], char **idx_tmp_name) { const char *rev_tmp_name = NULL; + const char *mtimes_tmp_name = NULL; if (adjust_shared_perm(pack_tmp_name)) die_errno("unable to make temporary pack file readable"); @@ -501,9 +560,17 @@ void stage_tmp_packfiles(struct strbuf *name_buffer, rev_tmp_name = write_rev_file(NULL, written_list, nr_written, hash, pack_idx_opts->flags); + if (pack_idx_opts->flags & WRITE_MTIMES) { + mtimes_tmp_name = write_mtimes_file(NULL, to_pack, written_list, + nr_written, + hash); + } + rename_tmp_packfile(name_buffer, pack_tmp_name, "pack"); if (rev_tmp_name) rename_tmp_packfile(name_buffer, rev_tmp_name, "rev"); + if (mtimes_tmp_name) + rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes"); } void write_promisor_file(const char *promisor_name, struct ref **sought, int nr_sought) @@ -44,6 +44,7 @@ struct pack_idx_option { #define WRITE_IDX_STRICT 02 #define WRITE_REV 04 #define WRITE_REV_VERIFY 010 +#define WRITE_MTIMES 020 uint32_t version; uint32_t off32_limit; @@ -109,11 +110,14 @@ int encode_in_pack_object_header(unsigned char *hdr, int hdr_len, #define PH_ERROR_PROTOCOL (-3) int read_pack_header(int fd, struct pack_header *); +struct packing_data; + struct hashfile *create_tmp_packfile(char **pack_tmp_name); void stage_tmp_packfiles(struct strbuf *name_buffer, const char *pack_tmp_name, struct pack_idx_entry **written_list, uint32_t nr_written, + struct packing_data *to_pack, struct pack_idx_option *pack_idx_opts, unsigned char hash[], char **idx_tmp_name); diff --git a/packfile.c b/packfile.c index 6b88a56025..8e812a84a3 100644 --- a/packfile.c +++ b/packfile.c @@ -334,12 +334,22 @@ static void close_pack_revindex(struct packed_git *p) p->revindex_data = NULL; } +static void close_pack_mtimes(struct packed_git *p) +{ + if (!p->mtimes_map) + return; + + munmap((void *)p->mtimes_map, p->mtimes_size); + p->mtimes_map = NULL; +} + void close_pack(struct packed_git *p) { close_pack_windows(p); close_pack_fd(p); close_pack_index(p); close_pack_revindex(p); + close_pack_mtimes(p); oidset_clear(&p->bad_objects); } @@ -363,7 +373,7 @@ void close_object_store(struct raw_object_store *o) void unlink_pack_path(const char *pack_name, int force_delete) { - static const char *exts[] = {".pack", ".idx", ".rev", ".keep", ".bitmap", ".promisor"}; + static const char *exts[] = {".pack", ".idx", ".rev", ".keep", ".bitmap", ".promisor", ".mtimes"}; int i; struct strbuf buf = STRBUF_INIT; size_t plen; @@ -718,6 +728,10 @@ struct packed_git *add_packed_git(const char *path, size_t path_len, int local) if (!access(p->pack_name, F_OK)) p->pack_promisor = 1; + xsnprintf(p->pack_name + path_len, alloc - path_len, ".mtimes"); + if (!access(p->pack_name, F_OK)) + p->is_cruft = 1; + xsnprintf(p->pack_name + path_len, alloc - path_len, ".pack"); if (stat(p->pack_name, &st) || !S_ISREG(st.st_mode)) { free(p); @@ -869,7 +883,8 @@ static void prepare_pack(const char *full_name, size_t full_name_len, ends_with(file_name, ".pack") || ends_with(file_name, ".bitmap") || ends_with(file_name, ".keep") || - ends_with(file_name, ".promisor")) + ends_with(file_name, ".promisor") || + ends_with(file_name, ".mtimes")) string_list_append(data->garbage, full_name); else report_garbage(PACKDIR_FILE_GARBAGE, full_name); @@ -99,7 +99,7 @@ void prepare_pager_args(struct child_process *pager_process, const char *pager) { strvec_push(&pager_process->args, pager); pager_process->use_shell = 1; - setup_pager_env(&pager_process->env_array); + setup_pager_env(&pager_process->env); pager_process->trace2_child_class = "pager"; } @@ -129,7 +129,7 @@ void setup_pager(void) /* spawn the pager */ prepare_pager_args(&pager_process, pager); pager_process.in = -1; - strvec_push(&pager_process.env_array, "GIT_PAGER_IN_USE"); + strvec_push(&pager_process.env, "GIT_PAGER_IN_USE"); if (start_command(&pager_process)) return; diff --git a/parse-options.c b/parse-options.c index 6e57744fd2..edf55d3ef5 100644 --- a/parse-options.c +++ b/parse-options.c @@ -14,15 +14,15 @@ enum opt_parsed { OPT_UNSET = 1<<1, }; -static int optbug(const struct option *opt, const char *reason) +static void optbug(const struct option *opt, const char *reason) { - if (opt->long_name) { - if (opt->short_name) - return error("BUG: switch '%c' (--%s) %s", - opt->short_name, opt->long_name, reason); - return error("BUG: option '%s' %s", opt->long_name, reason); - } - return error("BUG: switch '%c' %s", opt->short_name, reason); + if (opt->long_name && opt->short_name) + bug("switch '%c' (--%s) %s", opt->short_name, + opt->long_name, reason); + else if (opt->long_name) + bug("option '%s' %s", opt->long_name, reason); + else + bug("switch '%c' %s", opt->short_name, reason); } static const char *optname(const struct option *opt, enum opt_parsed flags) @@ -441,28 +441,27 @@ static void check_typos(const char *arg, const struct option *options) static void parse_options_check(const struct option *opts) { - int err = 0; char short_opts[128]; memset(short_opts, '\0', sizeof(short_opts)); for (; opts->type != OPTION_END; opts++) { if ((opts->flags & PARSE_OPT_LASTARG_DEFAULT) && (opts->flags & PARSE_OPT_OPTARG)) - err |= optbug(opts, "uses incompatible flags " - "LASTARG_DEFAULT and OPTARG"); + optbug(opts, "uses incompatible flags " + "LASTARG_DEFAULT and OPTARG"); if (opts->short_name) { if (0x7F <= opts->short_name) - err |= optbug(opts, "invalid short name"); + optbug(opts, "invalid short name"); else if (short_opts[opts->short_name]++) - err |= optbug(opts, "short name already used"); + optbug(opts, "short name already used"); } if (opts->flags & PARSE_OPT_NODASH && ((opts->flags & PARSE_OPT_OPTARG) || !(opts->flags & PARSE_OPT_NOARG) || !(opts->flags & PARSE_OPT_NONEG) || opts->long_name)) - err |= optbug(opts, "uses feature " - "not supported for dashless options"); + optbug(opts, "uses feature " + "not supported for dashless options"); switch (opts->type) { case OPTION_COUNTUP: case OPTION_BIT: @@ -471,33 +470,33 @@ static void parse_options_check(const struct option *opts) case OPTION_NUMBER: if ((opts->flags & PARSE_OPT_OPTARG) || !(opts->flags & PARSE_OPT_NOARG)) - err |= optbug(opts, "should not accept an argument"); + optbug(opts, "should not accept an argument"); break; case OPTION_CALLBACK: if (!opts->callback && !opts->ll_callback) - BUG("OPTION_CALLBACK needs one callback"); - if (opts->callback && opts->ll_callback) - BUG("OPTION_CALLBACK can't have two callbacks"); + optbug(opts, "OPTION_CALLBACK needs one callback"); + else if (opts->callback && opts->ll_callback) + optbug(opts, "OPTION_CALLBACK can't have two callbacks"); break; case OPTION_LOWLEVEL_CALLBACK: if (!opts->ll_callback) - BUG("OPTION_LOWLEVEL_CALLBACK needs a callback"); + optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs a callback"); if (opts->callback) - BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback"); + optbug(opts, "OPTION_LOWLEVEL_CALLBACK needs no high level callback"); break; case OPTION_ALIAS: - BUG("OPT_ALIAS() should not remain at this point. " - "Are you using parse_options_step() directly?\n" - "That case is not supported yet."); + optbug(opts, "OPT_ALIAS() should not remain at this point. " + "Are you using parse_options_step() directly?\n" + "That case is not supported yet."); + break; default: ; /* ok. (usually accepts an argument) */ } if (opts->argh && strcspn(opts->argh, " _") != strlen(opts->argh)) - err |= optbug(opts, "multi-word argh should use dash to separate words"); + optbug(opts, "multi-word argh should use dash to separate words"); } - if (err) - exit(128); + BUG_if_bug("invalid 'struct option'"); } static void parse_options_start_1(struct parse_opt_ctx_t *ctx, @@ -1413,7 +1413,7 @@ int is_ntfs_dotgit(const char *name) for (;;) { c = *(name++); - if (!c || c == '\\' || c == '/' || c == ':') + if (!c || is_xplatform_dir_sep(c) || c == ':') return 1; if (c != '.' && c != ' ') return 0; diff --git a/pathspec.c b/pathspec.c index ddeeba7911..84ad9c73cf 100644 --- a/pathspec.c +++ b/pathspec.c @@ -629,7 +629,7 @@ void parse_pathspec(struct pathspec *pathspec, */ if (nr_exclude == n) { int plen = (!(flags & PATHSPEC_PREFER_CWD)) ? 0 : prefixlen; - init_pathspec_item(item + n, 0, prefix, plen, ""); + init_pathspec_item(item + n, 0, prefix, plen, "."); pathspec->nr++; } diff --git a/po/.gitignore b/po/.gitignore index 796b96d1c4..ff0e5176a6 100644 --- a/po/.gitignore +++ b/po/.gitignore @@ -1 +1,3 @@ /build +/git.pot +/git-core.pot diff --git a/po/README.md b/po/README.md index 19fabb4acf..74856ca5bf 100644 --- a/po/README.md +++ b/po/README.md @@ -9,8 +9,14 @@ coordinates our localization effort in the l10 coordinator repository: https://github.com/git-l10n/git-po/ -The two character language translation codes are defined by ISO\_639-1, as -stated in the gettext(1) full manual, appendix A.1, Usual Language Codes. +We will use XX as an alias to refer to the language translation code in +the following paragraphs, for example we use "po/XX.po" to refer to the +translation file for a specific language. But this doesn't mean that +the language code has only two letters. The language code can be in one +of two forms: "ll" or "ll\_CC". Here "ll" is the ISO 639 two-letter +language code and "CC" is the ISO 3166 two-letter code for country names +and subdivisions. For example: "de" for German language code, "zh\_CN" +for Simplified Chinese language code. ## Contributing to an existing translation @@ -39,72 +45,74 @@ language, so that the l10n coordinator only needs to interact with one person per language. -## Core translation +## Translation Process Flow -The core translation is the smallest set of work that must be completed -for a new language translation. Because there are more than 5000 messages -in the template message file "po/git.pot" that need to be translated, -this is not a piece of cake for the contributor for a new language. +The overall data-flow looks like this: -The core template message file which contains a small set of messages -will be generated in "po-core/core.pot" automatically by running a helper -program named "git-po-helper" (described later). + +-------------------+ +------------------+ + | Git source code | ----(2)---> | L10n coordinator | + | repository | <---(5)---- | repository | + +-------------------+ +------------------+ + | | ^ + (1) (3) (4) + V v | + +----------------------------------+ + | Language Team XX | + +----------------------------------+ -```shell -git-po-helper init --core XX.po -``` +- Translatable strings are marked in the source file. +- Language teams can start translation iterations at any time, even + before the l10n window opens: -After translating the generated "po-core/XX.po", you can merge it to -"po/XX.po" using the following commands: + + Pull from the master branch of the source (1) + + Update the message file by running "make po-update PO\_FILE=po/XX.po" + + Translate the message file "po/XX.po" -```shell -msgcat po-core/XX.po po/XX.po -s -o /tmp/XX.po -mv /tmp/XX.po po/XX.po -git-po-helper update XX.po -``` +- The L10n coordinator pulls from source and announces the l10n window + open (2) +- Language team pulls from the l10n coordinator, starts another + translation iteration against the l10n coordinator's tree (3) -Edit "po/XX.po" by hand to fix "fuzzy" messages, which may have misplaced -translated messages and duplicate messages. + + Run "git pull --rebase" from the l10n coordinator + + Update the message file by running "make po-update PO\_FILE=po/XX.po" + + Translate the message file "po/XX.po" + + Squash trivial l10n git commits using "git rebase -i" +- Language team sends pull request to the l10n coordinator (4) +- L10n coordinator checks and merges +- L10n coordinator asks the result to be pulled (5). -## Translation Process Flow -The overall data-flow looks like this: +## Dynamically generated POT files - +-------------------+ +------------------+ - | Git source code | ---(1)---> | L10n coordinator | - | repository | <---(4)--- | repository | - +-------------------+ +------------------+ - | ^ - (2) (3) - V | - +------------------+ - | Language Team XX | - +------------------+ +POT files are templates for l10n contributors to create or update their +translation files. We used to have the "po/git.pot" file which was +generated by the l10n coordinator, but this file had been removed from +the tree. -- Translatable strings are marked in the source file. -- L10n coordinator pulls from the source (1) -- L10n coordinator updates the message template "po/git.pot" -- Language team pulls from L10n coordinator (2) -- Language team updates the message file "po/XX.po" -- L10n coordinator pulls from Language team (3) -- L10n coordinator asks the result to be pulled (4). +The two POT files "po/git.pot" and "po/git-core.pot" can be created +dynamically when necessary. +L10n contributors use "po/git.pot" to prepare translations for their +languages, but they are not expected to modify it. The "po/git.pot" file +can be generated manually with the following command: -## Maintaining the "po/git.pot" file +```shell +make po/git.pot +``` -(This is done by the l10n coordinator). +The "po/git-core.pot" file is the template for core translations. A core +translation is the minimum set of work necessary to complete a +translation of a new language. Since there are more than 5000 messages +in the full set of template message file "po/git.pot" that need to be +translated, this is not a piece of cake for new language contributors. -The "po/git.pot" file contains a message catalog extracted from Git's -sources. The l10n coordinator maintains it by adding new translations with -msginit(1), or update existing ones with msgmerge(1). In order to update -the Git sources to extract the messages from, the l10n coordinator is -expected to pull from the main git repository at strategic point in -history (e.g. when a major release and release candidates are tagged), -and then run "make pot" at the top-level directory. +The "core" template file "po/git-core.pot" can be generated manually +by running: -Language contributors use this file to prepare translations for their -language, but they are not expected to modify it. +```shell +make po/git-core.pot +``` ## Initializing a "XX.po" file @@ -115,32 +123,14 @@ If your language XX does not have translated message file "po/XX.po" yet, you add a translation for the first time by running: ```shell -msginit --locale=XX +make po-init PO_FILE=po/XX.po ``` -in the "po/" directory, where XX is the locale, e.g. "de", "is", "pt\_BR", -"zh\_CN", etc. - -Then edit the automatically generated copyright info in your new "XX.po" -to be correct, e.g. for Icelandic: - -```diff -@@ -1,6 +1,6 @@ --# Icelandic translations for PACKAGE package. --# Copyright (C) 2010 THE PACKAGE'S COPYRIGHT HOLDER --# This file is distributed under the same license as the PACKAGE package. -+# Icelandic translations for Git. -+# Copyright (C) 2010 Ævar Arnfjörð Bjarmason <avarab@gmail.com> -+# This file is distributed under the same license as the Git package. - # Ævar Arnfjörð Bjarmason <avarab@gmail.com>, 2010. -``` - -And change references to PACKAGE VERSION in the PO Header Entry to -just "Git": +where XX is the locale, e.g. "de", "is", "pt\_BR", "zh\_CN", etc. -```shell -perl -pi -e 's/(?<="Project-Id-Version: )PACKAGE VERSION/Git/' XX.po -``` +The newly generated message file "po/XX.po" is based on the core pot +file "po/git-core.pot", so it contains only a minimal set of messages +and it's a good start for a new language contribution. Once you are done testing the translation (see below), commit the result and ask the l10n coordinator to pull from you. @@ -153,19 +143,53 @@ and ask the l10n coordinator to pull from you. If you are replacing translation strings in an existing "XX.po" file to improve the translation, just edit the file. -If there's an existing "XX.po" file for your language, but the repository -of the l10n coordinator has newer "po/git.pot" file, you would need to first -pull from the l10n coordinator (see the beginning of this document for its -URL), and then update the existing translation by running: +If you want to find new translatable strings in source files of upstream +repository and propagate them to your "po/XX.po", run command: ```shell -msgmerge --add-location --backup=off -U XX.po git.pot +make po-update PO_FILE=po/XX.po ``` -in the "po/" directory, where "XX.po" is the file you want to update. +It will: -Once you are done testing the translation (see below), commit the result -and ask the l10n coordinator to pull from you. +- Call "make po/git.pot" to generate new "po/git.pot" file +- Call "msgmerge --add-location --backup=off -U po/XX.po po/git.pot" + to update your "po/XX.po" +- The "--add-location" option for msgmerge will add location lines, + and these location lines will help translation tools to locate + translation context easily. + +Once you are done testing the translation (see below), it's better +to commit a location-less "po/XX.po" file to save repository space +and make a user-friendly patch for review. + +To save a location-less "po/XX.po" automatically in repository, you +can: + +First define a new attribute for "po/XX.po" by appending the following +line in ".git/info/attributes": + +``` +/po/XX.po filter=gettext-no-location +``` + +Then define the driver for the "gettext-no-location" clean filter to +strip out both filenames and locations from the contents as follows: + +```shell +git config --global filter.gettext-no-location.clean \ + "msgcat --no-location -" +``` + +For users who have gettext version 0.20 or higher, it is also possible +to define a clean filter to preserve filenames but not locations: + +```shell +git config --global filter.gettext-no-location.clean \ + "msgcat --add-location=file -" +``` + +You're now ready to ask the l10n coordinator to pull from you. ## Fuzzy translation @@ -196,6 +220,14 @@ common errors, e.g. missing printf format strings, or translated messages that deviate from the originals in whether they begin/end with a newline or not. +L10n coordinator will check your contributions using a helper program +(see "PO helper" section below): + +```shell +git-po-helper check-po po/XX.po +git-po-helper check-commits <rev-list-opts> +``` + ## Marking strings for translation @@ -370,29 +402,6 @@ l10n workflow. To build and install the helper program from source, see [git-po-helper/README][]. -Usage for git-po-helper: - -- To start a new language translation: - - ```shell - git-po-helper init XX.po - ``` - -- To update your "XX.po" file: - - ```shell - git-po-helper update XX.po - ``` - -- To check commit log and syntax of "XX.po": - - ```shell - git-po-helper check-po XX.po - git-po-helper check-commits - ``` - -Run "git-po-helper" without arguments to show usage. - ## Conventions @@ -436,13 +445,8 @@ additional conventions: - Initialize proper filename of the "XX.po" file conforming to iso-639 and iso-3166. -- Must complete a minimal translation based on the "po-core/core.pot" - template. Using the following command to initialize the minimal - "po-core/XX.po" file: - - ```shell - git-po-helper init --core <your-language> - ``` +- Must complete a minimal translation based on the "Core + translation". See that section above. - Add a new entry in the "po/TEAMS" file with proper format, and check the syntax of "po/TEAMS" by running the following command: diff --git a/po/git.pot b/po/git.pot deleted file mode 100644 index 054cb99c06..0000000000 --- a/po/git.pot +++ /dev/null @@ -1,25151 +0,0 @@ -# SOME DESCRIPTIVE TITLE. -# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER -# This file is distributed under the same license as the PACKAGE package. -# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR. -# -#, fuzzy -msgid "" -msgstr "" -"Project-Id-Version: PACKAGE VERSION\n" -"Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2022-04-13 14:52+0800\n" -"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" -"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" -"Language-Team: LANGUAGE <LL@li.org>\n" -"Language: \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" -"Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" - -#: add-interactive.c:382 -#, c-format -msgid "Huh (%s)?" -msgstr "" - -#: add-interactive.c:535 add-interactive.c:836 reset.c:136 sequencer.c:3505 -#: sequencer.c:3970 sequencer.c:4127 builtin/rebase.c:1261 -#: builtin/rebase.c:1671 -msgid "could not read index" -msgstr "" - -#: add-interactive.c:590 git-add--interactive.perl:269 -#: git-add--interactive.perl:294 -msgid "binary" -msgstr "" - -#: add-interactive.c:648 git-add--interactive.perl:278 -#: git-add--interactive.perl:332 -msgid "nothing" -msgstr "" - -#: add-interactive.c:649 git-add--interactive.perl:314 -#: git-add--interactive.perl:329 -msgid "unchanged" -msgstr "" - -#: add-interactive.c:686 git-add--interactive.perl:641 -msgid "Update" -msgstr "" - -#: add-interactive.c:703 add-interactive.c:891 -#, c-format -msgid "could not stage '%s'" -msgstr "" - -#: add-interactive.c:709 add-interactive.c:898 reset.c:160 sequencer.c:3709 -msgid "could not write index" -msgstr "" - -#: add-interactive.c:712 git-add--interactive.perl:626 -#, c-format, perl-format -msgid "updated %d path\n" -msgid_plural "updated %d paths\n" -msgstr[0] "" -msgstr[1] "" - -#: add-interactive.c:730 git-add--interactive.perl:676 -#, c-format, perl-format -msgid "note: %s is untracked now.\n" -msgstr "" - -#: add-interactive.c:735 apply.c:4133 builtin/checkout.c:311 -#: builtin/reset.c:167 -#, c-format -msgid "make_cache_entry failed for path '%s'" -msgstr "" - -#: add-interactive.c:765 git-add--interactive.perl:653 -msgid "Revert" -msgstr "" - -#: add-interactive.c:781 -msgid "Could not parse HEAD^{tree}" -msgstr "" - -#: add-interactive.c:819 git-add--interactive.perl:629 -#, c-format, perl-format -msgid "reverted %d path\n" -msgid_plural "reverted %d paths\n" -msgstr[0] "" -msgstr[1] "" - -#: add-interactive.c:870 git-add--interactive.perl:693 -#, c-format -msgid "No untracked files.\n" -msgstr "" - -#: add-interactive.c:874 git-add--interactive.perl:687 -msgid "Add untracked" -msgstr "" - -#: add-interactive.c:901 git-add--interactive.perl:623 -#, c-format, perl-format -msgid "added %d path\n" -msgid_plural "added %d paths\n" -msgstr[0] "" -msgstr[1] "" - -#: add-interactive.c:931 -#, c-format -msgid "ignoring unmerged: %s" -msgstr "" - -#: add-interactive.c:943 add-patch.c:1758 git-add--interactive.perl:1371 -#, c-format -msgid "Only binary files changed.\n" -msgstr "" - -#: add-interactive.c:945 add-patch.c:1756 git-add--interactive.perl:1373 -#, c-format -msgid "No changes.\n" -msgstr "" - -#: add-interactive.c:949 git-add--interactive.perl:1381 -msgid "Patch update" -msgstr "" - -#: add-interactive.c:988 git-add--interactive.perl:1794 -msgid "Review diff" -msgstr "" - -#: add-interactive.c:1016 -msgid "show paths with changes" -msgstr "" - -#: add-interactive.c:1018 -msgid "add working tree state to the staged set of changes" -msgstr "" - -#: add-interactive.c:1020 -msgid "revert staged set of changes back to the HEAD version" -msgstr "" - -#: add-interactive.c:1022 -msgid "pick hunks and update selectively" -msgstr "" - -#: add-interactive.c:1024 -msgid "view diff between HEAD and index" -msgstr "" - -#: add-interactive.c:1026 -msgid "add contents of untracked files to the staged set of changes" -msgstr "" - -#: add-interactive.c:1034 add-interactive.c:1083 -msgid "Prompt help:" -msgstr "" - -#: add-interactive.c:1036 -msgid "select a single item" -msgstr "" - -#: add-interactive.c:1038 -msgid "select a range of items" -msgstr "" - -#: add-interactive.c:1040 -msgid "select multiple ranges" -msgstr "" - -#: add-interactive.c:1042 add-interactive.c:1087 -msgid "select item based on unique prefix" -msgstr "" - -#: add-interactive.c:1044 -msgid "unselect specified items" -msgstr "" - -#: add-interactive.c:1046 -msgid "choose all items" -msgstr "" - -#: add-interactive.c:1048 -msgid "(empty) finish selecting" -msgstr "" - -#: add-interactive.c:1085 -msgid "select a numbered item" -msgstr "" - -#: add-interactive.c:1089 -msgid "(empty) select nothing" -msgstr "" - -#: add-interactive.c:1097 builtin/clean.c:839 git-add--interactive.perl:1898 -msgid "*** Commands ***" -msgstr "" - -#: add-interactive.c:1098 builtin/clean.c:840 git-add--interactive.perl:1895 -msgid "What now" -msgstr "" - -#: add-interactive.c:1150 git-add--interactive.perl:213 -msgid "staged" -msgstr "" - -#: add-interactive.c:1150 git-add--interactive.perl:213 -msgid "unstaged" -msgstr "" - -#: add-interactive.c:1150 apply.c:5002 apply.c:5005 builtin/am.c:2370 -#: builtin/am.c:2373 builtin/bugreport.c:107 builtin/clone.c:132 -#: builtin/fetch.c:154 builtin/merge.c:287 builtin/pull.c:194 -#: builtin/submodule--helper.c:412 builtin/submodule--helper.c:1872 -#: builtin/submodule--helper.c:1875 builtin/submodule--helper.c:2709 -#: builtin/submodule--helper.c:2712 builtin/submodule--helper.c:2891 -#: git-add--interactive.perl:213 -msgid "path" -msgstr "" - -#: add-interactive.c:1157 -msgid "could not refresh index" -msgstr "" - -#: add-interactive.c:1171 builtin/clean.c:804 git-add--interactive.perl:1805 -#, c-format -msgid "Bye.\n" -msgstr "" - -#: add-patch.c:34 git-add--interactive.perl:1433 -#, c-format, perl-format -msgid "Stage mode change [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:35 git-add--interactive.perl:1434 -#, c-format, perl-format -msgid "Stage deletion [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:36 git-add--interactive.perl:1435 -#, c-format, perl-format -msgid "Stage addition [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:37 git-add--interactive.perl:1436 -#, c-format, perl-format -msgid "Stage this hunk [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:39 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be marked for " -"staging." -msgstr "" - -#: add-patch.c:42 -msgid "" -"y - stage this hunk\n" -"n - do not stage this hunk\n" -"q - quit; do not stage this hunk or any of the remaining ones\n" -"a - stage this hunk and all later hunks in the file\n" -"d - do not stage this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:56 git-add--interactive.perl:1439 -#, c-format, perl-format -msgid "Stash mode change [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:57 git-add--interactive.perl:1440 -#, c-format, perl-format -msgid "Stash deletion [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:58 git-add--interactive.perl:1441 -#, c-format, perl-format -msgid "Stash addition [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:59 git-add--interactive.perl:1442 -#, c-format, perl-format -msgid "Stash this hunk [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:61 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be marked for " -"stashing." -msgstr "" - -#: add-patch.c:64 -msgid "" -"y - stash this hunk\n" -"n - do not stash this hunk\n" -"q - quit; do not stash this hunk or any of the remaining ones\n" -"a - stash this hunk and all later hunks in the file\n" -"d - do not stash this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:80 git-add--interactive.perl:1445 -#, c-format, perl-format -msgid "Unstage mode change [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:81 git-add--interactive.perl:1446 -#, c-format, perl-format -msgid "Unstage deletion [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:82 git-add--interactive.perl:1447 -#, c-format, perl-format -msgid "Unstage addition [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:83 git-add--interactive.perl:1448 -#, c-format, perl-format -msgid "Unstage this hunk [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:85 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be marked for " -"unstaging." -msgstr "" - -#: add-patch.c:88 -msgid "" -"y - unstage this hunk\n" -"n - do not unstage this hunk\n" -"q - quit; do not unstage this hunk or any of the remaining ones\n" -"a - unstage this hunk and all later hunks in the file\n" -"d - do not unstage this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:103 git-add--interactive.perl:1451 -#, c-format, perl-format -msgid "Apply mode change to index [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:104 git-add--interactive.perl:1452 -#, c-format, perl-format -msgid "Apply deletion to index [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:105 git-add--interactive.perl:1453 -#, c-format, perl-format -msgid "Apply addition to index [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:106 git-add--interactive.perl:1454 -#, c-format, perl-format -msgid "Apply this hunk to index [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:108 add-patch.c:176 add-patch.c:221 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be marked for " -"applying." -msgstr "" - -#: add-patch.c:111 -msgid "" -"y - apply this hunk to index\n" -"n - do not apply this hunk to index\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:126 git-add--interactive.perl:1457 -#: git-add--interactive.perl:1475 -#, c-format, perl-format -msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:127 git-add--interactive.perl:1458 -#: git-add--interactive.perl:1476 -#, c-format, perl-format -msgid "Discard deletion from worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:128 git-add--interactive.perl:1459 -#: git-add--interactive.perl:1477 -#, c-format, perl-format -msgid "Discard addition from worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:129 git-add--interactive.perl:1460 -#: git-add--interactive.perl:1478 -#, c-format, perl-format -msgid "Discard this hunk from worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:131 add-patch.c:154 add-patch.c:199 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be marked for " -"discarding." -msgstr "" - -#: add-patch.c:134 add-patch.c:202 -msgid "" -"y - discard this hunk from worktree\n" -"n - do not discard this hunk from worktree\n" -"q - quit; do not discard this hunk or any of the remaining ones\n" -"a - discard this hunk and all later hunks in the file\n" -"d - do not discard this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:149 add-patch.c:194 git-add--interactive.perl:1463 -#, c-format, perl-format -msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:150 add-patch.c:195 git-add--interactive.perl:1464 -#, c-format, perl-format -msgid "Discard deletion from index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:151 add-patch.c:196 git-add--interactive.perl:1465 -#, c-format, perl-format -msgid "Discard addition from index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:152 add-patch.c:197 git-add--interactive.perl:1466 -#, c-format, perl-format -msgid "Discard this hunk from index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:157 -msgid "" -"y - discard this hunk from index and worktree\n" -"n - do not discard this hunk from index and worktree\n" -"q - quit; do not discard this hunk or any of the remaining ones\n" -"a - discard this hunk and all later hunks in the file\n" -"d - do not discard this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:171 add-patch.c:216 git-add--interactive.perl:1469 -#, c-format, perl-format -msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:172 add-patch.c:217 git-add--interactive.perl:1470 -#, c-format, perl-format -msgid "Apply deletion to index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:173 add-patch.c:218 git-add--interactive.perl:1471 -#, c-format, perl-format -msgid "Apply addition to index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:174 add-patch.c:219 git-add--interactive.perl:1472 -#, c-format, perl-format -msgid "Apply this hunk to index and worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: add-patch.c:179 -msgid "" -"y - apply this hunk to index and worktree\n" -"n - do not apply this hunk to index and worktree\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:224 -msgid "" -"y - apply this hunk to worktree\n" -"n - do not apply this hunk to worktree\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file\n" -msgstr "" - -#: add-patch.c:343 -#, c-format -msgid "could not parse hunk header '%.*s'" -msgstr "" - -#: add-patch.c:362 add-patch.c:366 -#, c-format -msgid "could not parse colored hunk header '%.*s'" -msgstr "" - -#: add-patch.c:431 -msgid "could not parse diff" -msgstr "" - -#: add-patch.c:450 -msgid "could not parse colored diff" -msgstr "" - -#: add-patch.c:464 -#, c-format -msgid "failed to run '%s'" -msgstr "" - -#: add-patch.c:618 -msgid "mismatched output from interactive.diffFilter" -msgstr "" - -#: add-patch.c:619 -msgid "" -"Your filter must maintain a one-to-one correspondence\n" -"between its input and output lines." -msgstr "" - -#: add-patch.c:797 -#, c-format -msgid "" -"expected context line #%d in\n" -"%.*s" -msgstr "" - -#: add-patch.c:812 -#, c-format -msgid "" -"hunks do not overlap:\n" -"%.*s\n" -"\tdoes not end with:\n" -"%.*s" -msgstr "" - -#: add-patch.c:1088 git-add--interactive.perl:1115 -msgid "Manual hunk edit mode -- see bottom for a quick guide.\n" -msgstr "" - -#: add-patch.c:1092 -#, c-format -msgid "" -"---\n" -"To remove '%c' lines, make them ' ' lines (context).\n" -"To remove '%c' lines, delete them.\n" -"Lines starting with %c will be removed.\n" -msgstr "" - -#. TRANSLATORS: 'it' refers to the patch mentioned in the previous messages. -#: add-patch.c:1106 git-add--interactive.perl:1129 -msgid "" -"If it does not apply cleanly, you will be given an opportunity to\n" -"edit again. If all lines of the hunk are removed, then the edit is\n" -"aborted and the hunk is left unchanged.\n" -msgstr "" - -#: add-patch.c:1139 -msgid "could not parse hunk header" -msgstr "" - -#: add-patch.c:1184 -msgid "'git apply --cached' failed" -msgstr "" - -#. TRANSLATORS: do not translate [y/n] -#. The program will only accept that input at this point. -#. Consider translating (saying "no" discards!) as -#. (saying "n" for "no" discards!) if the translation -#. of the word "no" does not start with n. -#. -#. TRANSLATORS: do not translate [y/n] -#. The program will only accept that input -#. at this point. -#. Consider translating (saying "no" discards!) as -#. (saying "n" for "no" discards!) if the translation -#. of the word "no" does not start with n. -#: add-patch.c:1253 git-add--interactive.perl:1244 -msgid "" -"Your edited hunk does not apply. Edit again (saying \"no\" discards!) [y/n]? " -msgstr "" - -#: add-patch.c:1296 -msgid "The selected hunks do not apply to the index!" -msgstr "" - -#: add-patch.c:1297 git-add--interactive.perl:1348 -msgid "Apply them to the worktree anyway? " -msgstr "" - -#: add-patch.c:1304 git-add--interactive.perl:1351 -msgid "Nothing was applied.\n" -msgstr "" - -#: add-patch.c:1361 -msgid "" -"j - leave this hunk undecided, see next undecided hunk\n" -"J - leave this hunk undecided, see next hunk\n" -"k - leave this hunk undecided, see previous undecided hunk\n" -"K - leave this hunk undecided, see previous hunk\n" -"g - select a hunk to go to\n" -"/ - search for a hunk matching the given regex\n" -"s - split the current hunk into smaller hunks\n" -"e - manually edit the current hunk\n" -"? - print help\n" -msgstr "" - -#: add-patch.c:1523 add-patch.c:1533 -msgid "No previous hunk" -msgstr "" - -#: add-patch.c:1528 add-patch.c:1538 -msgid "No next hunk" -msgstr "" - -#: add-patch.c:1544 -msgid "No other hunks to goto" -msgstr "" - -#: add-patch.c:1555 git-add--interactive.perl:1608 -msgid "go to which hunk (<ret> to see more)? " -msgstr "" - -#: add-patch.c:1556 git-add--interactive.perl:1610 -msgid "go to which hunk? " -msgstr "" - -#: add-patch.c:1567 -#, c-format -msgid "Invalid number: '%s'" -msgstr "" - -#: add-patch.c:1572 -#, c-format -msgid "Sorry, only %d hunk available." -msgid_plural "Sorry, only %d hunks available." -msgstr[0] "" -msgstr[1] "" - -#: add-patch.c:1581 -msgid "No other hunks to search" -msgstr "" - -#: add-patch.c:1587 git-add--interactive.perl:1663 -msgid "search for regex? " -msgstr "" - -#: add-patch.c:1602 -#, c-format -msgid "Malformed search regexp %s: %s" -msgstr "" - -#: add-patch.c:1619 -msgid "No hunk matches the given pattern" -msgstr "" - -#: add-patch.c:1626 -msgid "Sorry, cannot split this hunk" -msgstr "" - -#: add-patch.c:1630 -#, c-format -msgid "Split into %d hunks." -msgstr "" - -#: add-patch.c:1634 -msgid "Sorry, cannot edit this hunk" -msgstr "" - -#: add-patch.c:1686 -msgid "'git apply' failed" -msgstr "" - -#: advice.c:81 -#, c-format -msgid "" -"\n" -"Disable this message with \"git config advice.%s false\"" -msgstr "" - -#: advice.c:97 -#, c-format -msgid "%shint: %.*s%s\n" -msgstr "" - -#: advice.c:181 -msgid "Cherry-picking is not possible because you have unmerged files." -msgstr "" - -#: advice.c:183 -msgid "Committing is not possible because you have unmerged files." -msgstr "" - -#: advice.c:185 -msgid "Merging is not possible because you have unmerged files." -msgstr "" - -#: advice.c:187 -msgid "Pulling is not possible because you have unmerged files." -msgstr "" - -#: advice.c:189 -msgid "Reverting is not possible because you have unmerged files." -msgstr "" - -#: advice.c:191 -#, c-format -msgid "It is not possible to %s because you have unmerged files." -msgstr "" - -#: advice.c:199 -msgid "" -"Fix them up in the work tree, and then use 'git add/rm <file>'\n" -"as appropriate to mark resolution and make a commit." -msgstr "" - -#: advice.c:207 -msgid "Exiting because of an unresolved conflict." -msgstr "" - -#: advice.c:212 builtin/merge.c:1388 -msgid "You have not concluded your merge (MERGE_HEAD exists)." -msgstr "" - -#: advice.c:214 -msgid "Please, commit your changes before merging." -msgstr "" - -#: advice.c:215 -msgid "Exiting because of unfinished merge." -msgstr "" - -#: advice.c:220 -msgid "Not possible to fast-forward, aborting." -msgstr "" - -#: advice.c:230 -#, c-format -msgid "" -"The following paths and/or pathspecs matched paths that exist\n" -"outside of your sparse-checkout definition, so will not be\n" -"updated in the index:\n" -msgstr "" - -#: advice.c:237 -msgid "" -"If you intend to update such entries, try one of the following:\n" -"* Use the --sparse option.\n" -"* Disable or modify the sparsity rules." -msgstr "" - -#: advice.c:245 -#, c-format -msgid "" -"Note: switching to '%s'.\n" -"\n" -"You are in 'detached HEAD' state. You can look around, make experimental\n" -"changes and commit them, and you can discard any commits you make in this\n" -"state without impacting any branches by switching back to a branch.\n" -"\n" -"If you want to create a new branch to retain commits you create, you may\n" -"do so (now or later) by using -c with the switch command. Example:\n" -"\n" -" git switch -c <new-branch-name>\n" -"\n" -"Or undo this operation with:\n" -"\n" -" git switch -\n" -"\n" -"Turn off this advice by setting config variable advice.detachedHead to " -"false\n" -"\n" -msgstr "" - -#: alias.c:50 -msgid "cmdline ends with \\" -msgstr "" - -#: alias.c:51 -msgid "unclosed quote" -msgstr "" - -#: apply.c:70 -#, c-format -msgid "unrecognized whitespace option '%s'" -msgstr "" - -#: apply.c:86 -#, c-format -msgid "unrecognized whitespace ignore option '%s'" -msgstr "" - -#: apply.c:138 archive.c:584 parse-options.c:1122 range-diff.c:555 -#: revision.c:2314 revision.c:2318 revision.c:2327 revision.c:2332 -#: revision.c:2560 revision.c:2895 revision.c:2899 revision.c:2907 -#: revision.c:2910 revision.c:2912 builtin/add.c:507 builtin/add.c:509 -#: builtin/add.c:515 builtin/add.c:527 builtin/branch.c:755 -#: builtin/checkout.c:472 builtin/checkout.c:475 builtin/checkout.c:1663 -#: builtin/checkout.c:1773 builtin/checkout.c:1776 builtin/clone.c:921 -#: builtin/commit.c:359 builtin/commit.c:362 builtin/commit.c:1200 -#: builtin/commit.c:1256 builtin/commit.c:1273 builtin/describe.c:593 -#: builtin/diff-tree.c:155 builtin/difftool.c:733 builtin/fast-export.c:1245 -#: builtin/fetch.c:2141 builtin/fetch.c:2162 builtin/fetch.c:2167 -#: builtin/help.c:602 builtin/index-pack.c:1858 builtin/init-db.c:560 -#: builtin/log.c:1968 builtin/log.c:1970 builtin/ls-files.c:778 -#: builtin/merge-base.c:163 builtin/merge-base.c:169 builtin/merge.c:1409 -#: builtin/merge.c:1411 builtin/pack-objects.c:4098 builtin/push.c:592 -#: builtin/push.c:630 builtin/push.c:636 builtin/push.c:641 -#: builtin/rebase.c:1221 builtin/rebase.c:1223 builtin/rebase.c:1227 -#: builtin/repack.c:688 builtin/repack.c:719 builtin/reset.c:433 -#: builtin/reset.c:469 builtin/rev-list.c:537 builtin/show-branch.c:711 -#: builtin/stash.c:1696 builtin/stash.c:1699 builtin/submodule--helper.c:1328 -#: builtin/submodule--helper.c:3054 builtin/tag.c:527 builtin/tag.c:573 -#: builtin/worktree.c:779 -#, c-format -msgid "options '%s' and '%s' cannot be used together" -msgstr "" - -#: apply.c:141 apply.c:152 apply.c:155 -#, c-format -msgid "'%s' outside a repository" -msgstr "" - -#: apply.c:807 -#, c-format -msgid "Cannot prepare timestamp regexp %s" -msgstr "" - -#: apply.c:816 -#, c-format -msgid "regexec returned %d for input: %s" -msgstr "" - -#: apply.c:890 -#, c-format -msgid "unable to find filename in patch at line %d" -msgstr "" - -#: apply.c:928 -#, c-format -msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" -msgstr "" - -#: apply.c:934 -#, c-format -msgid "git apply: bad git-diff - inconsistent new filename on line %d" -msgstr "" - -#: apply.c:935 -#, c-format -msgid "git apply: bad git-diff - inconsistent old filename on line %d" -msgstr "" - -#: apply.c:940 -#, c-format -msgid "git apply: bad git-diff - expected /dev/null on line %d" -msgstr "" - -#: apply.c:969 -#, c-format -msgid "invalid mode on line %d: %s" -msgstr "" - -#: apply.c:1288 -#, c-format -msgid "inconsistent header lines %d and %d" -msgstr "" - -#: apply.c:1378 -#, c-format -msgid "" -"git diff header lacks filename information when removing %d leading pathname " -"component (line %d)" -msgid_plural "" -"git diff header lacks filename information when removing %d leading pathname " -"components (line %d)" -msgstr[0] "" -msgstr[1] "" - -#: apply.c:1391 -#, c-format -msgid "git diff header lacks filename information (line %d)" -msgstr "" - -#: apply.c:1487 -#, c-format -msgid "recount: unexpected line: %.*s" -msgstr "" - -#: apply.c:1556 -#, c-format -msgid "patch fragment without header at line %d: %.*s" -msgstr "" - -#: apply.c:1759 -msgid "new file depends on old contents" -msgstr "" - -#: apply.c:1761 -msgid "deleted file still has contents" -msgstr "" - -#: apply.c:1795 -#, c-format -msgid "corrupt patch at line %d" -msgstr "" - -#: apply.c:1832 -#, c-format -msgid "new file %s depends on old contents" -msgstr "" - -#: apply.c:1834 -#, c-format -msgid "deleted file %s still has contents" -msgstr "" - -#: apply.c:1837 -#, c-format -msgid "** warning: file %s becomes empty but is not deleted" -msgstr "" - -#: apply.c:1985 -#, c-format -msgid "corrupt binary patch at line %d: %.*s" -msgstr "" - -#: apply.c:2022 -#, c-format -msgid "unrecognized binary patch at line %d" -msgstr "" - -#: apply.c:2184 -#, c-format -msgid "patch with only garbage at line %d" -msgstr "" - -#: apply.c:2270 -#, c-format -msgid "unable to read symlink %s" -msgstr "" - -#: apply.c:2274 -#, c-format -msgid "unable to open or read %s" -msgstr "" - -#: apply.c:2943 -#, c-format -msgid "invalid start of line: '%c'" -msgstr "" - -#: apply.c:3064 -#, c-format -msgid "Hunk #%d succeeded at %d (offset %d line)." -msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." -msgstr[0] "" -msgstr[1] "" - -#: apply.c:3076 -#, c-format -msgid "Context reduced to (%ld/%ld) to apply fragment at %d" -msgstr "" - -#: apply.c:3082 -#, c-format -msgid "" -"while searching for:\n" -"%.*s" -msgstr "" - -#: apply.c:3104 -#, c-format -msgid "missing binary patch data for '%s'" -msgstr "" - -#: apply.c:3112 -#, c-format -msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'" -msgstr "" - -#: apply.c:3159 -#, c-format -msgid "cannot apply binary patch to '%s' without full index line" -msgstr "" - -#: apply.c:3170 -#, c-format -msgid "" -"the patch applies to '%s' (%s), which does not match the current contents." -msgstr "" - -#: apply.c:3178 -#, c-format -msgid "the patch applies to an empty '%s' but it is not empty" -msgstr "" - -#: apply.c:3196 -#, c-format -msgid "the necessary postimage %s for '%s' cannot be read" -msgstr "" - -#: apply.c:3209 -#, c-format -msgid "binary patch does not apply to '%s'" -msgstr "" - -#: apply.c:3216 -#, c-format -msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" -msgstr "" - -#: apply.c:3237 -#, c-format -msgid "patch failed: %s:%ld" -msgstr "" - -#: apply.c:3360 -#, c-format -msgid "cannot checkout %s" -msgstr "" - -#: apply.c:3412 apply.c:3423 apply.c:3469 midx.c:105 pack-revindex.c:214 -#: setup.c:310 -#, c-format -msgid "failed to read %s" -msgstr "" - -#: apply.c:3420 -#, c-format -msgid "reading from '%s' beyond a symbolic link" -msgstr "" - -#: apply.c:3449 apply.c:3721 -#, c-format -msgid "path %s has been renamed/deleted" -msgstr "" - -#: apply.c:3559 apply.c:3736 -#, c-format -msgid "%s: does not exist in index" -msgstr "" - -#: apply.c:3568 apply.c:3744 apply.c:3960 -#, c-format -msgid "%s: does not match index" -msgstr "" - -#: apply.c:3605 -msgid "repository lacks the necessary blob to perform 3-way merge." -msgstr "" - -#: apply.c:3608 -#, c-format -msgid "Performing three-way merge...\n" -msgstr "" - -#: apply.c:3624 apply.c:3628 -#, c-format -msgid "cannot read the current contents of '%s'" -msgstr "" - -#: apply.c:3640 -#, c-format -msgid "Failed to perform three-way merge...\n" -msgstr "" - -#: apply.c:3654 -#, c-format -msgid "Applied patch to '%s' with conflicts.\n" -msgstr "" - -#: apply.c:3659 -#, c-format -msgid "Applied patch to '%s' cleanly.\n" -msgstr "" - -#: apply.c:3676 -#, c-format -msgid "Falling back to direct application...\n" -msgstr "" - -#: apply.c:3688 -msgid "removal patch leaves file contents" -msgstr "" - -#: apply.c:3761 -#, c-format -msgid "%s: wrong type" -msgstr "" - -#: apply.c:3763 -#, c-format -msgid "%s has type %o, expected %o" -msgstr "" - -#: apply.c:3900 apply.c:3902 read-cache.c:903 read-cache.c:932 -#: read-cache.c:1399 -#, c-format -msgid "invalid path '%s'" -msgstr "" - -#: apply.c:3958 -#, c-format -msgid "%s: already exists in index" -msgstr "" - -#: apply.c:3962 -#, c-format -msgid "%s: already exists in working directory" -msgstr "" - -#: apply.c:3982 -#, c-format -msgid "new mode (%o) of %s does not match old mode (%o)" -msgstr "" - -#: apply.c:3987 -#, c-format -msgid "new mode (%o) of %s does not match old mode (%o) of %s" -msgstr "" - -#: apply.c:4007 -#, c-format -msgid "affected file '%s' is beyond a symbolic link" -msgstr "" - -#: apply.c:4011 -#, c-format -msgid "%s: patch does not apply" -msgstr "" - -#: apply.c:4026 -#, c-format -msgid "Checking patch %s..." -msgstr "" - -#: apply.c:4118 -#, c-format -msgid "sha1 information is lacking or useless for submodule %s" -msgstr "" - -#: apply.c:4125 -#, c-format -msgid "mode change for %s, which is not in current HEAD" -msgstr "" - -#: apply.c:4128 -#, c-format -msgid "sha1 information is lacking or useless (%s)." -msgstr "" - -#: apply.c:4137 -#, c-format -msgid "could not add %s to temporary index" -msgstr "" - -#: apply.c:4147 -#, c-format -msgid "could not write temporary index to %s" -msgstr "" - -#: apply.c:4285 -#, c-format -msgid "unable to remove %s from index" -msgstr "" - -#: apply.c:4319 -#, c-format -msgid "corrupt patch for submodule %s" -msgstr "" - -#: apply.c:4325 -#, c-format -msgid "unable to stat newly created file '%s'" -msgstr "" - -#: apply.c:4333 -#, c-format -msgid "unable to create backing store for newly created file %s" -msgstr "" - -#: apply.c:4339 apply.c:4484 -#, c-format -msgid "unable to add cache entry for %s" -msgstr "" - -#: apply.c:4382 builtin/bisect--helper.c:540 builtin/gc.c:2258 -#: builtin/gc.c:2293 -#, c-format -msgid "failed to write to '%s'" -msgstr "" - -#: apply.c:4386 -#, c-format -msgid "closing file '%s'" -msgstr "" - -#: apply.c:4456 -#, c-format -msgid "unable to write file '%s' mode %o" -msgstr "" - -#: apply.c:4554 -#, c-format -msgid "Applied patch %s cleanly." -msgstr "" - -#: apply.c:4562 -msgid "internal error" -msgstr "" - -#: apply.c:4565 -#, c-format -msgid "Applying patch %%s with %d reject..." -msgid_plural "Applying patch %%s with %d rejects..." -msgstr[0] "" -msgstr[1] "" - -#: apply.c:4576 -#, c-format -msgid "truncating .rej filename to %.*s.rej" -msgstr "" - -#: apply.c:4584 -#, c-format -msgid "cannot open %s" -msgstr "" - -#: apply.c:4598 -#, c-format -msgid "Hunk #%d applied cleanly." -msgstr "" - -#: apply.c:4602 -#, c-format -msgid "Rejected hunk #%d." -msgstr "" - -#: apply.c:4731 -#, c-format -msgid "Skipped patch '%s'." -msgstr "" - -#: apply.c:4740 -msgid "No valid patches in input (allow with \"--allow-empty\")" -msgstr "" - -#: apply.c:4761 -msgid "unable to read index file" -msgstr "" - -#: apply.c:4918 -#, c-format -msgid "can't open patch '%s': %s" -msgstr "" - -#: apply.c:4945 -#, c-format -msgid "squelched %d whitespace error" -msgid_plural "squelched %d whitespace errors" -msgstr[0] "" -msgstr[1] "" - -#: apply.c:4951 apply.c:4966 -#, c-format -msgid "%d line adds whitespace errors." -msgid_plural "%d lines add whitespace errors." -msgstr[0] "" -msgstr[1] "" - -#: apply.c:4959 -#, c-format -msgid "%d line applied after fixing whitespace errors." -msgid_plural "%d lines applied after fixing whitespace errors." -msgstr[0] "" -msgstr[1] "" - -#: apply.c:4975 builtin/add.c:690 builtin/mv.c:338 builtin/rm.c:430 -msgid "Unable to write new index file" -msgstr "" - -#: apply.c:5003 -msgid "don't apply changes matching the given path" -msgstr "" - -#: apply.c:5006 -msgid "apply changes matching the given path" -msgstr "" - -#: apply.c:5008 builtin/am.c:2379 -msgid "num" -msgstr "" - -#: apply.c:5009 -msgid "remove <num> leading slashes from traditional diff paths" -msgstr "" - -#: apply.c:5012 -msgid "ignore additions made by the patch" -msgstr "" - -#: apply.c:5014 -msgid "instead of applying the patch, output diffstat for the input" -msgstr "" - -#: apply.c:5018 -msgid "show number of added and deleted lines in decimal notation" -msgstr "" - -#: apply.c:5020 -msgid "instead of applying the patch, output a summary for the input" -msgstr "" - -#: apply.c:5022 -msgid "instead of applying the patch, see if the patch is applicable" -msgstr "" - -#: apply.c:5024 -msgid "make sure the patch is applicable to the current index" -msgstr "" - -#: apply.c:5026 -msgid "mark new files with `git add --intent-to-add`" -msgstr "" - -#: apply.c:5028 -msgid "apply a patch without touching the working tree" -msgstr "" - -#: apply.c:5030 -msgid "accept a patch that touches outside the working area" -msgstr "" - -#: apply.c:5033 -msgid "also apply the patch (use with --stat/--summary/--check)" -msgstr "" - -#: apply.c:5035 -msgid "attempt three-way merge, fall back on normal patch if that fails" -msgstr "" - -#: apply.c:5037 -msgid "build a temporary index based on embedded index information" -msgstr "" - -#: apply.c:5040 builtin/checkout-index.c:230 -msgid "paths are separated with NUL character" -msgstr "" - -#: apply.c:5042 -msgid "ensure at least <n> lines of context match" -msgstr "" - -#: apply.c:5043 builtin/am.c:2355 builtin/am.c:2358 -#: builtin/interpret-trailers.c:98 builtin/interpret-trailers.c:100 -#: builtin/interpret-trailers.c:102 builtin/pack-objects.c:3983 -#: builtin/rebase.c:1079 -msgid "action" -msgstr "" - -#: apply.c:5044 -msgid "detect new or modified lines that have whitespace errors" -msgstr "" - -#: apply.c:5047 apply.c:5050 -msgid "ignore changes in whitespace when finding context" -msgstr "" - -#: apply.c:5053 -msgid "apply the patch in reverse" -msgstr "" - -#: apply.c:5055 -msgid "don't expect at least one line of context" -msgstr "" - -#: apply.c:5057 -msgid "leave the rejected hunks in corresponding *.rej files" -msgstr "" - -#: apply.c:5059 -msgid "allow overlapping hunks" -msgstr "" - -#: apply.c:5062 -msgid "tolerate incorrectly detected missing new-line at the end of file" -msgstr "" - -#: apply.c:5065 -msgid "do not trust the line counts in the hunk headers" -msgstr "" - -#: apply.c:5067 builtin/am.c:2367 -msgid "root" -msgstr "" - -#: apply.c:5068 -msgid "prepend <root> to all filenames" -msgstr "" - -#: apply.c:5071 -msgid "don't return error for empty patches" -msgstr "" - -#: archive-tar.c:125 archive-zip.c:346 -#, c-format -msgid "cannot stream blob %s" -msgstr "" - -#: archive-tar.c:265 archive-zip.c:359 -#, c-format -msgid "unsupported file mode: 0%o (SHA1: %s)" -msgstr "" - -#: archive-tar.c:447 -#, c-format -msgid "unable to start '%s' filter" -msgstr "" - -#: archive-tar.c:450 -msgid "unable to redirect descriptor" -msgstr "" - -#: archive-tar.c:457 -#, c-format -msgid "'%s' filter reported error" -msgstr "" - -#: archive-zip.c:319 -#, c-format -msgid "path is not valid UTF-8: %s" -msgstr "" - -#: archive-zip.c:323 -#, c-format -msgid "path too long (%d chars, SHA1: %s): %s" -msgstr "" - -#: archive-zip.c:470 builtin/pack-objects.c:363 builtin/pack-objects.c:366 -#, c-format -msgid "deflate error (%d)" -msgstr "" - -#: archive-zip.c:604 -#, c-format -msgid "timestamp too large for this system: %<PRIuMAX>" -msgstr "" - -#: archive.c:14 -msgid "git archive [<options>] <tree-ish> [<path>...]" -msgstr "" - -#: archive.c:16 -msgid "" -"git archive --remote <repo> [--exec <cmd>] [<options>] <tree-ish> [<path>...]" -msgstr "" - -#: archive.c:17 -msgid "git archive --remote <repo> [--exec <cmd>] --list" -msgstr "" - -#: archive.c:188 archive.c:341 builtin/gc.c:497 builtin/notes.c:238 -#: builtin/tag.c:579 -#, c-format -msgid "cannot read '%s'" -msgstr "" - -#: archive.c:426 builtin/add.c:214 builtin/add.c:657 builtin/rm.c:334 -#, c-format -msgid "pathspec '%s' did not match any files" -msgstr "" - -#: archive.c:450 -#, c-format -msgid "no such ref: %.*s" -msgstr "" - -#: archive.c:456 -#, c-format -msgid "not a valid object name: %s" -msgstr "" - -#: archive.c:469 -#, c-format -msgid "not a tree object: %s" -msgstr "" - -#: archive.c:481 -msgid "current working directory is untracked" -msgstr "" - -#: archive.c:522 -#, c-format -msgid "File not found: %s" -msgstr "" - -#: archive.c:524 -#, c-format -msgid "Not a regular file: %s" -msgstr "" - -#: archive.c:551 -msgid "fmt" -msgstr "" - -#: archive.c:551 -msgid "archive format" -msgstr "" - -#: archive.c:552 builtin/log.c:1809 -msgid "prefix" -msgstr "" - -#: archive.c:553 -msgid "prepend prefix to each pathname in the archive" -msgstr "" - -#: archive.c:554 archive.c:557 builtin/blame.c:881 builtin/blame.c:885 -#: builtin/blame.c:886 builtin/commit-tree.c:115 builtin/config.c:135 -#: builtin/fast-export.c:1181 builtin/fast-export.c:1183 -#: builtin/fast-export.c:1187 builtin/grep.c:936 builtin/hash-object.c:104 -#: builtin/ls-files.c:654 builtin/ls-files.c:657 builtin/notes.c:410 -#: builtin/notes.c:576 builtin/read-tree.c:115 parse-options.h:195 -msgid "file" -msgstr "" - -#: archive.c:555 -msgid "add untracked file to archive" -msgstr "" - -#: archive.c:558 builtin/archive.c:88 -msgid "write the archive to this file" -msgstr "" - -#: archive.c:560 -msgid "read .gitattributes in working directory" -msgstr "" - -#: archive.c:561 -msgid "report archived files on stderr" -msgstr "" - -#: archive.c:563 -msgid "set compression level" -msgstr "" - -#: archive.c:566 -msgid "list supported archive formats" -msgstr "" - -#: archive.c:568 builtin/archive.c:89 builtin/clone.c:122 builtin/clone.c:125 -#: builtin/submodule--helper.c:1884 builtin/submodule--helper.c:2718 -msgid "repo" -msgstr "" - -#: archive.c:569 builtin/archive.c:90 -msgid "retrieve the archive from remote repository <repo>" -msgstr "" - -#: archive.c:570 builtin/archive.c:91 builtin/difftool.c:708 -#: builtin/notes.c:496 -msgid "command" -msgstr "" - -#: archive.c:571 builtin/archive.c:92 -msgid "path to the remote git-upload-archive command" -msgstr "" - -#: archive.c:578 -msgid "Unexpected option --remote" -msgstr "" - -#: archive.c:580 fetch-pack.c:300 revision.c:2914 builtin/add.c:530 -#: builtin/add.c:562 builtin/checkout.c:1782 builtin/clone.c:1099 -#: builtin/clone.c:1102 builtin/commit.c:371 builtin/fast-export.c:1230 -#: builtin/index-pack.c:1854 builtin/log.c:2140 builtin/reset.c:442 -#: builtin/reset.c:500 builtin/rm.c:281 builtin/stash.c:1708 -#: builtin/worktree.c:580 builtin/worktree.c:781 http-fetch.c:144 -#: http-fetch.c:153 -#, c-format -msgid "the option '%s' requires '%s'" -msgstr "" - -#: archive.c:582 -msgid "Unexpected option --output" -msgstr "" - -#: archive.c:606 -#, c-format -msgid "Unknown archive format '%s'" -msgstr "" - -#: archive.c:615 -#, c-format -msgid "Argument not supported for format '%s': -%d" -msgstr "" - -#: attr.c:202 -#, c-format -msgid "%.*s is not a valid attribute name" -msgstr "" - -#: attr.c:363 -#, c-format -msgid "%s not allowed: %s:%d" -msgstr "" - -#: attr.c:403 -msgid "" -"Negative patterns are ignored in git attributes\n" -"Use '\\!' for literal leading exclamation." -msgstr "" - -#: bisect.c:488 -#, c-format -msgid "Badly quoted content in file '%s': %s" -msgstr "" - -#: bisect.c:698 -#, c-format -msgid "We cannot bisect more!\n" -msgstr "" - -#: bisect.c:765 -#, c-format -msgid "Not a valid commit name %s" -msgstr "" - -#: bisect.c:790 -#, c-format -msgid "" -"The merge base %s is bad.\n" -"This means the bug has been fixed between %s and [%s].\n" -msgstr "" - -#: bisect.c:795 -#, c-format -msgid "" -"The merge base %s is new.\n" -"The property has changed between %s and [%s].\n" -msgstr "" - -#: bisect.c:800 -#, c-format -msgid "" -"The merge base %s is %s.\n" -"This means the first '%s' commit is between %s and [%s].\n" -msgstr "" - -#: bisect.c:808 -#, c-format -msgid "" -"Some %s revs are not ancestors of the %s rev.\n" -"git bisect cannot work properly in this case.\n" -"Maybe you mistook %s and %s revs?\n" -msgstr "" - -#: bisect.c:821 -#, c-format -msgid "" -"the merge base between %s and [%s] must be skipped.\n" -"So we cannot be sure the first %s commit is between %s and %s.\n" -"We continue anyway." -msgstr "" - -#: bisect.c:860 -#, c-format -msgid "Bisecting: a merge base must be tested\n" -msgstr "" - -#: bisect.c:910 -#, c-format -msgid "a %s revision is needed" -msgstr "" - -#: bisect.c:940 -#, c-format -msgid "could not create file '%s'" -msgstr "" - -#: bisect.c:986 builtin/merge.c:155 -#, c-format -msgid "could not read file '%s'" -msgstr "" - -#: bisect.c:1026 -msgid "reading bisect refs failed" -msgstr "" - -#: bisect.c:1056 -#, c-format -msgid "%s was both %s and %s\n" -msgstr "" - -#: bisect.c:1065 -#, c-format -msgid "" -"No testable commit found.\n" -"Maybe you started with bad path arguments?\n" -msgstr "" - -#: bisect.c:1094 -#, c-format -msgid "(roughly %d step)" -msgid_plural "(roughly %d steps)" -msgstr[0] "" -msgstr[1] "" - -#. TRANSLATORS: the last %s will be replaced with "(roughly %d -#. steps)" translation. -#. -#: bisect.c:1100 -#, c-format -msgid "Bisecting: %d revision left to test after this %s\n" -msgid_plural "Bisecting: %d revisions left to test after this %s\n" -msgstr[0] "" -msgstr[1] "" - -#: blame.c:2773 -msgid "--contents and --reverse do not blend well." -msgstr "" - -#: blame.c:2787 -msgid "cannot use --contents with final commit object name" -msgstr "" - -#: blame.c:2808 -msgid "--reverse and --first-parent together require specified latest commit" -msgstr "" - -#: blame.c:2817 bundle.c:231 midx.c:1058 ref-filter.c:2371 remote.c:2157 -#: sequencer.c:2348 sequencer.c:4872 submodule.c:913 builtin/commit.c:1118 -#: builtin/log.c:437 builtin/log.c:1055 builtin/log.c:1663 builtin/log.c:2096 -#: builtin/log.c:2387 builtin/merge.c:431 builtin/pack-objects.c:3381 -#: builtin/pack-objects.c:3781 builtin/pack-objects.c:3796 -#: builtin/shortlog.c:255 -msgid "revision walk setup failed" -msgstr "" - -#: blame.c:2835 -msgid "" -"--reverse --first-parent together require range along first-parent chain" -msgstr "" - -#: blame.c:2846 -#, c-format -msgid "no such path %s in %s" -msgstr "" - -#: blame.c:2857 -#, c-format -msgid "cannot read blob %s for path %s" -msgstr "" - -#: branch.c:93 -msgid "" -"cannot inherit upstream tracking configuration of multiple refs when " -"rebasing is requested" -msgstr "" - -#: branch.c:104 -#, c-format -msgid "not setting branch '%s' as its own upstream" -msgstr "" - -#: branch.c:160 -#, c-format -msgid "branch '%s' set up to track '%s' by rebasing." -msgstr "" - -#: branch.c:161 -#, c-format -msgid "branch '%s' set up to track '%s'." -msgstr "" - -#: branch.c:164 -#, c-format -msgid "branch '%s' set up to track:" -msgstr "" - -#: branch.c:176 -msgid "unable to write upstream branch configuration" -msgstr "" - -#: branch.c:178 -msgid "" -"\n" -"After fixing the error cause you may try to fix up\n" -"the remote tracking information by invoking:" -msgstr "" - -#: branch.c:219 -#, c-format -msgid "asked to inherit tracking from '%s', but no remote is set" -msgstr "" - -#: branch.c:225 -#, c-format -msgid "asked to inherit tracking from '%s', but no merge configuration is set" -msgstr "" - -#: branch.c:277 -#, c-format -msgid "not tracking: ambiguous information for ref '%s'" -msgstr "" - -#. TRANSLATORS: This is a line listing a remote with duplicate -#. refspecs in the advice message below. For RTL languages you'll -#. probably want to swap the "%s" and leading " " space around. -#. -#. TRANSLATORS: This is line item of ambiguous object output -#. from describe_ambiguous_object() above. For RTL languages -#. you'll probably want to swap the "%s" and leading " " space -#. around. -#. -#: branch.c:289 object-name.c:464 -#, c-format -msgid " %s\n" -msgstr "" - -#. TRANSLATORS: The second argument is a \n-delimited list of -#. duplicate refspecs, composed above. -#. -#: branch.c:295 -#, c-format -msgid "" -"There are multiple remotes whose fetch refspecs map to the remote\n" -"tracking ref '%s':\n" -"%s\n" -"This is typically a configuration error.\n" -"\n" -"To support setting up tracking branches, ensure that\n" -"different remotes' fetch refspecs map into different\n" -"tracking namespaces." -msgstr "" - -#: branch.c:344 -#, c-format -msgid "'%s' is not a valid branch name" -msgstr "" - -#: branch.c:364 -#, c-format -msgid "a branch named '%s' already exists" -msgstr "" - -#: branch.c:370 -#, c-format -msgid "cannot force update the branch '%s' checked out at '%s'" -msgstr "" - -#: branch.c:393 -#, c-format -msgid "cannot set up tracking information; starting point '%s' is not a branch" -msgstr "" - -#: branch.c:395 -#, c-format -msgid "the requested upstream branch '%s' does not exist" -msgstr "" - -#: branch.c:397 -msgid "" -"\n" -"If you are planning on basing your work on an upstream\n" -"branch that already exists at the remote, you may need to\n" -"run \"git fetch\" to retrieve it.\n" -"\n" -"If you are planning to push out a new local branch that\n" -"will track its remote counterpart, you may want to use\n" -"\"git push -u\" to set the upstream config as you push." -msgstr "" - -#: branch.c:445 builtin/replace.c:321 builtin/replace.c:377 -#: builtin/replace.c:423 builtin/replace.c:453 -#, c-format -msgid "not a valid object name: '%s'" -msgstr "" - -#: branch.c:465 -#, c-format -msgid "ambiguous object name: '%s'" -msgstr "" - -#: branch.c:470 -#, c-format -msgid "not a valid branch point: '%s'" -msgstr "" - -#: branch.c:658 -#, c-format -msgid "submodule '%s': unable to find submodule" -msgstr "" - -#: branch.c:661 -#, c-format -msgid "" -"You may try updating the submodules using 'git checkout %s && git submodule " -"update --init'" -msgstr "" - -#: branch.c:672 branch.c:698 -#, c-format -msgid "submodule '%s': cannot create branch '%s'" -msgstr "" - -#: branch.c:730 -#, c-format -msgid "'%s' is already checked out at '%s'" -msgstr "" - -#: branch.c:755 -#, c-format -msgid "HEAD of working tree %s is not updated" -msgstr "" - -#: bundle.c:45 -#, c-format -msgid "unrecognized bundle hash algorithm: %s" -msgstr "" - -#: bundle.c:53 -#, c-format -msgid "unknown capability '%s'" -msgstr "" - -#: bundle.c:79 -#, c-format -msgid "'%s' does not look like a v2 or v3 bundle file" -msgstr "" - -#: bundle.c:118 -#, c-format -msgid "unrecognized header: %s%s (%d)" -msgstr "" - -#: bundle.c:145 rerere.c:464 rerere.c:675 sequencer.c:2616 sequencer.c:3402 -#: builtin/commit.c:865 -#, c-format -msgid "could not open '%s'" -msgstr "" - -#: bundle.c:203 -msgid "Repository lacks these prerequisite commits:" -msgstr "" - -#: bundle.c:206 -msgid "need a repository to verify a bundle" -msgstr "" - -#: bundle.c:264 -#, c-format -msgid "The bundle contains this ref:" -msgid_plural "The bundle contains these %<PRIuMAX> refs:" -msgstr[0] "" -msgstr[1] "" - -#: bundle.c:272 -msgid "The bundle records a complete history." -msgstr "" - -#: bundle.c:274 -#, c-format -msgid "The bundle requires this ref:" -msgid_plural "The bundle requires these %<PRIuMAX> refs:" -msgstr[0] "" -msgstr[1] "" - -#: bundle.c:350 -msgid "unable to dup bundle descriptor" -msgstr "" - -#: bundle.c:357 -msgid "Could not spawn pack-objects" -msgstr "" - -#: bundle.c:368 -msgid "pack-objects died" -msgstr "" - -#: bundle.c:417 -#, c-format -msgid "ref '%s' is excluded by the rev-list options" -msgstr "" - -#: bundle.c:533 builtin/log.c:211 builtin/log.c:1975 builtin/shortlog.c:400 -#, c-format -msgid "unrecognized argument: %s" -msgstr "" - -#: bundle.c:548 -#, c-format -msgid "unsupported bundle version %d" -msgstr "" - -#: bundle.c:550 -#, c-format -msgid "cannot write bundle version %d with algorithm %s" -msgstr "" - -#: bundle.c:600 -msgid "Refusing to create empty bundle." -msgstr "" - -#: bundle.c:610 -#, c-format -msgid "cannot create '%s'" -msgstr "" - -#: bundle.c:639 -msgid "index-pack died" -msgstr "" - -#: chunk-format.c:117 -msgid "terminating chunk id appears earlier than expected" -msgstr "" - -#: chunk-format.c:126 -#, c-format -msgid "improper chunk offset(s) %<PRIx64> and %<PRIx64>" -msgstr "" - -#: chunk-format.c:133 -#, c-format -msgid "duplicate chunk ID %<PRIx32> found" -msgstr "" - -#: chunk-format.c:147 -#, c-format -msgid "final chunk has non-zero id %<PRIx32>" -msgstr "" - -#: color.c:354 -#, c-format -msgid "invalid color value: %.*s" -msgstr "" - -#: commit-graph.c:204 midx.c:52 -msgid "invalid hash version" -msgstr "" - -#: commit-graph.c:262 -msgid "commit-graph file is too small" -msgstr "" - -#: commit-graph.c:355 -#, c-format -msgid "commit-graph signature %X does not match signature %X" -msgstr "" - -#: commit-graph.c:362 -#, c-format -msgid "commit-graph version %X does not match version %X" -msgstr "" - -#: commit-graph.c:369 -#, c-format -msgid "commit-graph hash version %X does not match version %X" -msgstr "" - -#: commit-graph.c:386 -#, c-format -msgid "commit-graph file is too small to hold %u chunks" -msgstr "" - -#: commit-graph.c:485 -msgid "commit-graph has no base graphs chunk" -msgstr "" - -#: commit-graph.c:495 -msgid "commit-graph chain does not match" -msgstr "" - -#: commit-graph.c:543 -#, c-format -msgid "invalid commit-graph chain: line '%s' not a hash" -msgstr "" - -#: commit-graph.c:567 -msgid "unable to find all commit-graph files" -msgstr "" - -#: commit-graph.c:752 commit-graph.c:789 -msgid "invalid commit position. commit-graph is likely corrupt" -msgstr "" - -#: commit-graph.c:773 -#, c-format -msgid "could not find commit %s" -msgstr "" - -#: commit-graph.c:806 -msgid "commit-graph requires overflow generation data but has none" -msgstr "" - -#: commit-graph.c:1111 builtin/am.c:1370 builtin/checkout.c:775 -#: builtin/clone.c:705 -#, c-format -msgid "unable to parse commit %s" -msgstr "" - -#: commit-graph.c:1373 builtin/pack-objects.c:3078 -#, c-format -msgid "unable to get type of object %s" -msgstr "" - -#: commit-graph.c:1404 -msgid "Loading known commits in commit graph" -msgstr "" - -#: commit-graph.c:1421 -msgid "Expanding reachable commits in commit graph" -msgstr "" - -#: commit-graph.c:1441 -msgid "Clearing commit marks in commit graph" -msgstr "" - -#: commit-graph.c:1460 -msgid "Computing commit graph topological levels" -msgstr "" - -#: commit-graph.c:1513 -msgid "Computing commit graph generation numbers" -msgstr "" - -#: commit-graph.c:1598 -msgid "Computing commit changed paths Bloom filters" -msgstr "" - -#: commit-graph.c:1675 -msgid "Collecting referenced commits" -msgstr "" - -#: commit-graph.c:1701 -#, c-format -msgid "Finding commits for commit graph in %<PRIuMAX> pack" -msgid_plural "Finding commits for commit graph in %<PRIuMAX> packs" -msgstr[0] "" -msgstr[1] "" - -#: commit-graph.c:1714 -#, c-format -msgid "error adding pack %s" -msgstr "" - -#: commit-graph.c:1718 -#, c-format -msgid "error opening index for %s" -msgstr "" - -#: commit-graph.c:1756 -msgid "Finding commits for commit graph among packed objects" -msgstr "" - -#: commit-graph.c:1774 -msgid "Finding extra edges in commit graph" -msgstr "" - -#: commit-graph.c:1823 -msgid "failed to write correct number of base graph ids" -msgstr "" - -#: commit-graph.c:1854 midx.c:1168 builtin/sparse-checkout.c:475 -#, c-format -msgid "unable to create leading directories of %s" -msgstr "" - -#: commit-graph.c:1868 -msgid "unable to create temporary graph layer" -msgstr "" - -#: commit-graph.c:1873 -#, c-format -msgid "unable to adjust shared permissions for '%s'" -msgstr "" - -#: commit-graph.c:1930 -#, c-format -msgid "Writing out commit graph in %d pass" -msgid_plural "Writing out commit graph in %d passes" -msgstr[0] "" -msgstr[1] "" - -#: commit-graph.c:1967 -msgid "unable to open commit-graph chain file" -msgstr "" - -#: commit-graph.c:1983 -msgid "failed to rename base commit-graph file" -msgstr "" - -#: commit-graph.c:2004 -msgid "failed to rename temporary commit-graph file" -msgstr "" - -#: commit-graph.c:2137 -msgid "Scanning merged commits" -msgstr "" - -#: commit-graph.c:2181 -msgid "Merging commit-graph" -msgstr "" - -#: commit-graph.c:2289 -msgid "attempting to write a commit-graph, but 'core.commitGraph' is disabled" -msgstr "" - -#: commit-graph.c:2396 -msgid "too many commits to write graph" -msgstr "" - -#: commit-graph.c:2494 -msgid "the commit-graph file has incorrect checksum and is likely corrupt" -msgstr "" - -#: commit-graph.c:2504 -#, c-format -msgid "commit-graph has incorrect OID order: %s then %s" -msgstr "" - -#: commit-graph.c:2514 commit-graph.c:2529 -#, c-format -msgid "commit-graph has incorrect fanout value: fanout[%d] = %u != %u" -msgstr "" - -#: commit-graph.c:2521 -#, c-format -msgid "failed to parse commit %s from commit-graph" -msgstr "" - -#: commit-graph.c:2539 -msgid "Verifying commits in commit graph" -msgstr "" - -#: commit-graph.c:2554 -#, c-format -msgid "failed to parse commit %s from object database for commit-graph" -msgstr "" - -#: commit-graph.c:2561 -#, c-format -msgid "root tree OID for commit %s in commit-graph is %s != %s" -msgstr "" - -#: commit-graph.c:2571 -#, c-format -msgid "commit-graph parent list for commit %s is too long" -msgstr "" - -#: commit-graph.c:2580 -#, c-format -msgid "commit-graph parent for %s is %s != %s" -msgstr "" - -#: commit-graph.c:2594 -#, c-format -msgid "commit-graph parent list for commit %s terminates early" -msgstr "" - -#: commit-graph.c:2599 -#, c-format -msgid "" -"commit-graph has generation number zero for commit %s, but non-zero elsewhere" -msgstr "" - -#: commit-graph.c:2603 -#, c-format -msgid "" -"commit-graph has non-zero generation number for commit %s, but zero elsewhere" -msgstr "" - -#: commit-graph.c:2620 -#, c-format -msgid "commit-graph generation for commit %s is %<PRIuMAX> < %<PRIuMAX>" -msgstr "" - -#: commit-graph.c:2626 -#, c-format -msgid "commit date for commit %s in commit-graph is %<PRIuMAX> != %<PRIuMAX>" -msgstr "" - -#: commit.c:54 sequencer.c:3105 builtin/am.c:400 builtin/am.c:445 -#: builtin/am.c:450 builtin/am.c:1449 builtin/am.c:2124 builtin/replace.c:456 -#, c-format -msgid "could not parse %s" -msgstr "" - -#: commit.c:56 -#, c-format -msgid "%s %s is not a commit!" -msgstr "" - -#: commit.c:197 -msgid "" -"Support for <GIT_DIR>/info/grafts is deprecated\n" -"and will be removed in a future Git version.\n" -"\n" -"Please use \"git replace --convert-graft-file\"\n" -"to convert the grafts into replace refs.\n" -"\n" -"Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" -msgstr "" - -#: commit.c:1252 -#, c-format -msgid "Commit %s has an untrusted GPG signature, allegedly by %s." -msgstr "" - -#: commit.c:1256 -#, c-format -msgid "Commit %s has a bad GPG signature allegedly by %s." -msgstr "" - -#: commit.c:1259 -#, c-format -msgid "Commit %s does not have a GPG signature." -msgstr "" - -#: commit.c:1262 -#, c-format -msgid "Commit %s has a good GPG signature by %s\n" -msgstr "" - -#: commit.c:1516 -msgid "" -"Warning: commit message did not conform to UTF-8.\n" -"You may want to amend it after fixing the message, or set the config\n" -"variable i18n.commitencoding to the encoding your project uses.\n" -msgstr "" - -#: compat/obstack.c:406 compat/obstack.c:408 -msgid "memory exhausted" -msgstr "" - -#: compat/terminal.c:167 -msgid "cannot resume in the background, please use 'fg' to resume" -msgstr "" - -#: compat/terminal.c:168 -msgid "cannot restore terminal settings" -msgstr "" - -#: config.c:143 -#, c-format -msgid "" -"exceeded maximum include depth (%d) while including\n" -"\t%s\n" -"from\n" -"\t%s\n" -"This might be due to circular includes." -msgstr "" - -#: config.c:159 -#, c-format -msgid "could not expand include path '%s'" -msgstr "" - -#: config.c:170 -msgid "relative config includes must come from files" -msgstr "" - -#: config.c:219 -msgid "relative config include conditionals must come from files" -msgstr "" - -#: config.c:364 -msgid "" -"remote URLs cannot be configured in file directly or indirectly included by " -"includeIf.hasconfig:remote.*.url" -msgstr "" - -#: config.c:508 -#, c-format -msgid "invalid config format: %s" -msgstr "" - -#: config.c:512 -#, c-format -msgid "missing environment variable name for configuration '%.*s'" -msgstr "" - -#: config.c:517 -#, c-format -msgid "missing environment variable '%s' for configuration '%.*s'" -msgstr "" - -#: config.c:553 -#, c-format -msgid "key does not contain a section: %s" -msgstr "" - -#: config.c:558 -#, c-format -msgid "key does not contain variable name: %s" -msgstr "" - -#: config.c:580 sequencer.c:2802 -#, c-format -msgid "invalid key: %s" -msgstr "" - -#: config.c:585 -#, c-format -msgid "invalid key (newline): %s" -msgstr "" - -#: config.c:605 -msgid "empty config key" -msgstr "" - -#: config.c:623 config.c:635 -#, c-format -msgid "bogus config parameter: %s" -msgstr "" - -#: config.c:649 config.c:666 config.c:673 config.c:682 -#, c-format -msgid "bogus format in %s" -msgstr "" - -#: config.c:716 -#, c-format -msgid "bogus count in %s" -msgstr "" - -#: config.c:720 -#, c-format -msgid "too many entries in %s" -msgstr "" - -#: config.c:730 -#, c-format -msgid "missing config key %s" -msgstr "" - -#: config.c:738 -#, c-format -msgid "missing config value %s" -msgstr "" - -#: config.c:1089 -#, c-format -msgid "bad config line %d in blob %s" -msgstr "" - -#: config.c:1093 -#, c-format -msgid "bad config line %d in file %s" -msgstr "" - -#: config.c:1097 -#, c-format -msgid "bad config line %d in standard input" -msgstr "" - -#: config.c:1101 -#, c-format -msgid "bad config line %d in submodule-blob %s" -msgstr "" - -#: config.c:1105 -#, c-format -msgid "bad config line %d in command line %s" -msgstr "" - -#: config.c:1109 -#, c-format -msgid "bad config line %d in %s" -msgstr "" - -#: config.c:1246 -msgid "out of range" -msgstr "" - -#: config.c:1246 -msgid "invalid unit" -msgstr "" - -#: config.c:1247 -#, c-format -msgid "bad numeric config value '%s' for '%s': %s" -msgstr "" - -#: config.c:1257 -#, c-format -msgid "bad numeric config value '%s' for '%s' in blob %s: %s" -msgstr "" - -#: config.c:1260 -#, c-format -msgid "bad numeric config value '%s' for '%s' in file %s: %s" -msgstr "" - -#: config.c:1263 -#, c-format -msgid "bad numeric config value '%s' for '%s' in standard input: %s" -msgstr "" - -#: config.c:1266 -#, c-format -msgid "bad numeric config value '%s' for '%s' in submodule-blob %s: %s" -msgstr "" - -#: config.c:1269 -#, c-format -msgid "bad numeric config value '%s' for '%s' in command line %s: %s" -msgstr "" - -#: config.c:1272 -#, c-format -msgid "bad numeric config value '%s' for '%s' in %s: %s" -msgstr "" - -#: config.c:1368 -#, c-format -msgid "invalid value for variable %s" -msgstr "" - -#: config.c:1389 -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "" - -#: config.c:1425 -#, c-format -msgid "bad boolean config value '%s' for '%s'" -msgstr "" - -#: config.c:1443 -#, c-format -msgid "failed to expand user dir in: '%s'" -msgstr "" - -#: config.c:1452 -#, c-format -msgid "'%s' for '%s' is not a valid timestamp" -msgstr "" - -#: config.c:1545 -#, c-format -msgid "abbrev length out of range: %d" -msgstr "" - -#: config.c:1559 config.c:1570 -#, c-format -msgid "bad zlib compression level %d" -msgstr "" - -#: config.c:1660 -msgid "core.commentChar should only be one character" -msgstr "" - -#: config.c:1692 -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "" - -#: config.c:1698 -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "" - -#: config.c:1714 -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "" - -#: config.c:1800 -#, c-format -msgid "malformed value for %s" -msgstr "" - -#: config.c:1826 -#, c-format -msgid "malformed value for %s: %s" -msgstr "" - -#: config.c:1827 -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "" - -#: config.c:1888 builtin/pack-objects.c:4078 -#, c-format -msgid "bad pack compression level %d" -msgstr "" - -#: config.c:2014 -#, c-format -msgid "unable to load config blob object '%s'" -msgstr "" - -#: config.c:2017 -#, c-format -msgid "reference '%s' does not point to a blob" -msgstr "" - -#: config.c:2035 -#, c-format -msgid "unable to resolve config blob '%s'" -msgstr "" - -#: config.c:2080 -#, c-format -msgid "failed to parse %s" -msgstr "" - -#: config.c:2136 -msgid "unable to parse command-line config" -msgstr "" - -#: config.c:2512 -msgid "unknown error occurred while reading the configuration files" -msgstr "" - -#: config.c:2686 -#, c-format -msgid "Invalid %s: '%s'" -msgstr "" - -#: config.c:2731 -#, c-format -msgid "splitIndex.maxPercentChange value '%d' should be between 0 and 100" -msgstr "" - -#: config.c:2763 -#, c-format -msgid "unable to parse '%s' from command-line config" -msgstr "" - -#: config.c:2765 -#, c-format -msgid "bad config variable '%s' in file '%s' at line %d" -msgstr "" - -#: config.c:2850 -#, c-format -msgid "invalid section name '%s'" -msgstr "" - -#: config.c:2882 -#, c-format -msgid "%s has multiple values" -msgstr "" - -#: config.c:2911 -#, c-format -msgid "failed to write new configuration file %s" -msgstr "" - -#: config.c:3177 config.c:3518 -#, c-format -msgid "could not lock config file %s" -msgstr "" - -#: config.c:3188 -#, c-format -msgid "opening %s" -msgstr "" - -#: config.c:3225 builtin/config.c:361 -#, c-format -msgid "invalid pattern: %s" -msgstr "" - -#: config.c:3250 -#, c-format -msgid "invalid config file %s" -msgstr "" - -#: config.c:3263 config.c:3531 -#, c-format -msgid "fstat on %s failed" -msgstr "" - -#: config.c:3274 -#, c-format -msgid "unable to mmap '%s'%s" -msgstr "" - -#: config.c:3284 config.c:3536 -#, c-format -msgid "chmod on %s failed" -msgstr "" - -#: config.c:3369 config.c:3633 -#, c-format -msgid "could not write config file %s" -msgstr "" - -#: config.c:3403 -#, c-format -msgid "could not set '%s' to '%s'" -msgstr "" - -#: config.c:3405 builtin/remote.c:666 builtin/remote.c:885 builtin/remote.c:893 -#, c-format -msgid "could not unset '%s'" -msgstr "" - -#: config.c:3509 -#, c-format -msgid "invalid section name: %s" -msgstr "" - -#: config.c:3676 -#, c-format -msgid "missing value for '%s'" -msgstr "" - -#: connect.c:61 -msgid "the remote end hung up upon initial contact" -msgstr "" - -#: connect.c:63 -msgid "" -"Could not read from remote repository.\n" -"\n" -"Please make sure you have the correct access rights\n" -"and the repository exists." -msgstr "" - -#: connect.c:81 -#, c-format -msgid "server doesn't support '%s'" -msgstr "" - -#: connect.c:118 -#, c-format -msgid "server doesn't support feature '%s'" -msgstr "" - -#: connect.c:129 -msgid "expected flush after capabilities" -msgstr "" - -#: connect.c:265 -#, c-format -msgid "ignoring capabilities after first line '%s'" -msgstr "" - -#: connect.c:286 -msgid "protocol error: unexpected capabilities^{}" -msgstr "" - -#: connect.c:308 -#, c-format -msgid "protocol error: expected shallow sha-1, got '%s'" -msgstr "" - -#: connect.c:310 -msgid "repository on the other end cannot be shallow" -msgstr "" - -#: connect.c:349 -msgid "invalid packet" -msgstr "" - -#: connect.c:369 -#, c-format -msgid "protocol error: unexpected '%s'" -msgstr "" - -#: connect.c:499 -#, c-format -msgid "unknown object format '%s' specified by server" -msgstr "" - -#: connect.c:528 -#, c-format -msgid "invalid ls-refs response: %s" -msgstr "" - -#: connect.c:532 -msgid "expected flush after ref listing" -msgstr "" - -#: connect.c:535 -msgid "expected response end packet after ref listing" -msgstr "" - -#: connect.c:670 -#, c-format -msgid "protocol '%s' is not supported" -msgstr "" - -#: connect.c:721 -msgid "unable to set SO_KEEPALIVE on socket" -msgstr "" - -#: connect.c:761 connect.c:824 -#, c-format -msgid "Looking up %s ... " -msgstr "" - -#: connect.c:765 -#, c-format -msgid "unable to look up %s (port %s) (%s)" -msgstr "" - -#. TRANSLATORS: this is the end of "Looking up %s ... " -#: connect.c:769 connect.c:840 -#, c-format -msgid "" -"done.\n" -"Connecting to %s (port %s) ... " -msgstr "" - -#: connect.c:791 connect.c:868 -#, c-format -msgid "" -"unable to connect to %s:\n" -"%s" -msgstr "" - -#. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " -#: connect.c:797 connect.c:874 -msgid "done." -msgstr "" - -#: connect.c:828 -#, c-format -msgid "unable to look up %s (%s)" -msgstr "" - -#: connect.c:834 -#, c-format -msgid "unknown port %s" -msgstr "" - -#: connect.c:971 connect.c:1303 -#, c-format -msgid "strange hostname '%s' blocked" -msgstr "" - -#: connect.c:973 -#, c-format -msgid "strange port '%s' blocked" -msgstr "" - -#: connect.c:983 -#, c-format -msgid "cannot start proxy %s" -msgstr "" - -#: connect.c:1054 -msgid "no path specified; see 'git help pull' for valid url syntax" -msgstr "" - -#: connect.c:1194 -msgid "newline is forbidden in git:// hosts and repo paths" -msgstr "" - -#: connect.c:1251 -msgid "ssh variant 'simple' does not support -4" -msgstr "" - -#: connect.c:1263 -msgid "ssh variant 'simple' does not support -6" -msgstr "" - -#: connect.c:1280 -msgid "ssh variant 'simple' does not support setting port" -msgstr "" - -#: connect.c:1392 -#, c-format -msgid "strange pathname '%s' blocked" -msgstr "" - -#: connect.c:1440 -msgid "unable to fork" -msgstr "" - -#: connected.c:109 builtin/fsck.c:189 builtin/prune.c:57 -msgid "Checking connectivity" -msgstr "" - -#: connected.c:122 -msgid "Could not run 'git rev-list'" -msgstr "" - -#: connected.c:146 -msgid "failed write to rev-list" -msgstr "" - -#: connected.c:151 -msgid "failed to close rev-list's stdin" -msgstr "" - -#: convert.c:183 -#, c-format -msgid "illegal crlf_action %d" -msgstr "" - -#: convert.c:196 -#, c-format -msgid "CRLF would be replaced by LF in %s" -msgstr "" - -#: convert.c:198 -#, c-format -msgid "" -"CRLF will be replaced by LF in %s.\n" -"The file will have its original line endings in your working directory" -msgstr "" - -#: convert.c:206 -#, c-format -msgid "LF would be replaced by CRLF in %s" -msgstr "" - -#: convert.c:208 -#, c-format -msgid "" -"LF will be replaced by CRLF in %s.\n" -"The file will have its original line endings in your working directory" -msgstr "" - -#: convert.c:273 -#, c-format -msgid "BOM is prohibited in '%s' if encoded as %s" -msgstr "" - -#: convert.c:280 -#, c-format -msgid "" -"The file '%s' contains a byte order mark (BOM). Please use UTF-%.*s as " -"working-tree-encoding." -msgstr "" - -#: convert.c:293 -#, c-format -msgid "BOM is required in '%s' if encoded as %s" -msgstr "" - -#: convert.c:295 -#, c-format -msgid "" -"The file '%s' is missing a byte order mark (BOM). Please use UTF-%sBE or UTF-" -"%sLE (depending on the byte order) as working-tree-encoding." -msgstr "" - -#: convert.c:408 convert.c:479 -#, c-format -msgid "failed to encode '%s' from %s to %s" -msgstr "" - -#: convert.c:451 -#, c-format -msgid "encoding '%s' from %s to %s and back is not the same" -msgstr "" - -#: convert.c:654 -#, c-format -msgid "cannot fork to run external filter '%s'" -msgstr "" - -#: convert.c:674 -#, c-format -msgid "cannot feed the input to external filter '%s'" -msgstr "" - -#: convert.c:681 -#, c-format -msgid "external filter '%s' failed %d" -msgstr "" - -#: convert.c:716 convert.c:719 -#, c-format -msgid "read from external filter '%s' failed" -msgstr "" - -#: convert.c:722 convert.c:777 -#, c-format -msgid "external filter '%s' failed" -msgstr "" - -#: convert.c:826 -msgid "unexpected filter type" -msgstr "" - -#: convert.c:837 -msgid "path name too long for external filter" -msgstr "" - -#: convert.c:935 -#, c-format -msgid "" -"external filter '%s' is not available anymore although not all paths have " -"been filtered" -msgstr "" - -#: convert.c:1236 -msgid "true/false are no valid working-tree-encodings" -msgstr "" - -#: convert.c:1416 convert.c:1449 -#, c-format -msgid "%s: clean filter '%s' failed" -msgstr "" - -#: convert.c:1492 -#, c-format -msgid "%s: smudge filter %s failed" -msgstr "" - -#: credential.c:96 -#, c-format -msgid "skipping credential lookup for key: credential.%s" -msgstr "" - -#: credential.c:112 -msgid "refusing to work with credential missing host field" -msgstr "" - -#: credential.c:114 -msgid "refusing to work with credential missing protocol field" -msgstr "" - -#: credential.c:396 -#, c-format -msgid "url contains a newline in its %s component: %s" -msgstr "" - -#: credential.c:440 -#, c-format -msgid "url has no scheme: %s" -msgstr "" - -#: credential.c:513 -#, c-format -msgid "credential url cannot be parsed: %s" -msgstr "" - -#: date.c:139 -msgid "in the future" -msgstr "" - -#: date.c:145 -#, c-format -msgid "%<PRIuMAX> second ago" -msgid_plural "%<PRIuMAX> seconds ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:152 -#, c-format -msgid "%<PRIuMAX> minute ago" -msgid_plural "%<PRIuMAX> minutes ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:159 -#, c-format -msgid "%<PRIuMAX> hour ago" -msgid_plural "%<PRIuMAX> hours ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:166 -#, c-format -msgid "%<PRIuMAX> day ago" -msgid_plural "%<PRIuMAX> days ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:172 -#, c-format -msgid "%<PRIuMAX> week ago" -msgid_plural "%<PRIuMAX> weeks ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:179 -#, c-format -msgid "%<PRIuMAX> month ago" -msgid_plural "%<PRIuMAX> months ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:190 -#, c-format -msgid "%<PRIuMAX> year" -msgid_plural "%<PRIuMAX> years" -msgstr[0] "" -msgstr[1] "" - -#. TRANSLATORS: "%s" is "<n> years" -#: date.c:193 -#, c-format -msgid "%s, %<PRIuMAX> month ago" -msgid_plural "%s, %<PRIuMAX> months ago" -msgstr[0] "" -msgstr[1] "" - -#: date.c:198 date.c:203 -#, c-format -msgid "%<PRIuMAX> year ago" -msgid_plural "%<PRIuMAX> years ago" -msgstr[0] "" -msgstr[1] "" - -#: delta-islands.c:272 -msgid "Propagating island marks" -msgstr "" - -#: delta-islands.c:290 -#, c-format -msgid "bad tree object %s" -msgstr "" - -#: delta-islands.c:334 -#, c-format -msgid "failed to load island regex for '%s': %s" -msgstr "" - -#: delta-islands.c:390 -#, c-format -msgid "island regex from config has too many capture groups (max=%d)" -msgstr "" - -#: delta-islands.c:467 -#, c-format -msgid "Marked %d islands, done.\n" -msgstr "" - -#: diff-merges.c:81 gpg-interface.c:719 gpg-interface.c:734 ls-refs.c:37 -#: parallel-checkout.c:42 sequencer.c:2805 setup.c:563 builtin/am.c:203 -#: builtin/am.c:2243 builtin/am.c:2287 builtin/blame.c:724 builtin/blame.c:742 -#: builtin/fetch.c:792 builtin/pack-objects.c:3515 builtin/pull.c:45 -#: builtin/pull.c:47 builtin/pull.c:321 -#, c-format -msgid "invalid value for '%s': '%s'" -msgstr "" - -#: diff-lib.c:561 -msgid "--merge-base does not work with ranges" -msgstr "" - -#: diff-lib.c:563 -msgid "--merge-base only works with commits" -msgstr "" - -#: diff-lib.c:580 -msgid "unable to get HEAD" -msgstr "" - -#: diff-lib.c:587 -msgid "no merge base found" -msgstr "" - -#: diff-lib.c:589 -msgid "multiple merge bases found" -msgstr "" - -#: diff-no-index.c:237 -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "" - -#: diff-no-index.c:262 -msgid "" -"Not a git repository. Use --no-index to compare two paths outside a working " -"tree" -msgstr "" - -#: diff.c:159 -#, c-format -msgid " Failed to parse dirstat cut-off percentage '%s'\n" -msgstr "" - -#: diff.c:164 -#, c-format -msgid " Unknown dirstat parameter '%s'\n" -msgstr "" - -#: diff.c:300 -msgid "" -"color moved setting must be one of 'no', 'default', 'blocks', 'zebra', " -"'dimmed-zebra', 'plain'" -msgstr "" - -#: diff.c:328 -#, c-format -msgid "" -"unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', " -"'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'" -msgstr "" - -#: diff.c:336 -msgid "" -"color-moved-ws: allow-indentation-change cannot be combined with other " -"whitespace modes" -msgstr "" - -#: diff.c:413 -#, c-format -msgid "Unknown value for 'diff.submodule' config variable: '%s'" -msgstr "" - -#: diff.c:473 -#, c-format -msgid "" -"Found errors in 'diff.dirstat' config variable:\n" -"%s" -msgstr "" - -#: diff.c:4282 -#, c-format -msgid "external diff died, stopping at %s" -msgstr "" - -#: diff.c:4677 parse-options.c:1114 -#, c-format -msgid "options '%s', '%s', '%s', and '%s' cannot be used together" -msgstr "" - -#: diff.c:4681 parse-options.c:1118 builtin/worktree.c:578 -#, c-format -msgid "options '%s', '%s', and '%s' cannot be used together" -msgstr "" - -#: diff.c:4685 -#, c-format -msgid "options '%s' and '%s' cannot be used together, use '%s' with '%s'" -msgstr "" - -#: diff.c:4689 -#, c-format -msgid "" -"options '%s' and '%s' cannot be used together, use '%s' with '%s' and '%s'" -msgstr "" - -#: diff.c:4769 -msgid "--follow requires exactly one pathspec" -msgstr "" - -#: diff.c:4823 -#, c-format -msgid "invalid --stat value: %s" -msgstr "" - -#: diff.c:4828 diff.c:4833 diff.c:4838 diff.c:4843 diff.c:5319 -#: parse-options.c:217 parse-options.c:221 -#, c-format -msgid "%s expects a numerical value" -msgstr "" - -#: diff.c:4860 -#, c-format -msgid "" -"Failed to parse --dirstat/-X option parameter:\n" -"%s" -msgstr "" - -#: diff.c:4893 -#, c-format -msgid "unknown change class '%c' in --diff-filter=%s" -msgstr "" - -#: diff.c:4917 -#, c-format -msgid "unknown value after ws-error-highlight=%.*s" -msgstr "" - -#: diff.c:4931 -#, c-format -msgid "unable to resolve '%s'" -msgstr "" - -#: diff.c:4981 diff.c:4987 -#, c-format -msgid "%s expects <n>/<m> form" -msgstr "" - -#: diff.c:4999 -#, c-format -msgid "%s expects a character, got '%s'" -msgstr "" - -#: diff.c:5020 -#, c-format -msgid "bad --color-moved argument: %s" -msgstr "" - -#: diff.c:5039 -#, c-format -msgid "invalid mode '%s' in --color-moved-ws" -msgstr "" - -#: diff.c:5079 -msgid "" -"option diff-algorithm accepts \"myers\", \"minimal\", \"patience\" and " -"\"histogram\"" -msgstr "" - -#: diff.c:5115 diff.c:5135 -#, c-format -msgid "invalid argument to %s" -msgstr "" - -#: diff.c:5239 -#, c-format -msgid "invalid regex given to -I: '%s'" -msgstr "" - -#: diff.c:5288 -#, c-format -msgid "failed to parse --submodule option parameter: '%s'" -msgstr "" - -#: diff.c:5344 -#, c-format -msgid "bad --word-diff argument: %s" -msgstr "" - -#: diff.c:5380 -msgid "Diff output format options" -msgstr "" - -#: diff.c:5382 diff.c:5388 -msgid "generate patch" -msgstr "" - -#: diff.c:5385 builtin/log.c:180 -msgid "suppress diff output" -msgstr "" - -#: diff.c:5390 diff.c:5504 diff.c:5511 -msgid "<n>" -msgstr "" - -#: diff.c:5391 diff.c:5394 -msgid "generate diffs with <n> lines context" -msgstr "" - -#: diff.c:5396 -msgid "generate the diff in raw format" -msgstr "" - -#: diff.c:5399 -msgid "synonym for '-p --raw'" -msgstr "" - -#: diff.c:5403 -msgid "synonym for '-p --stat'" -msgstr "" - -#: diff.c:5407 -msgid "machine friendly --stat" -msgstr "" - -#: diff.c:5410 -msgid "output only the last line of --stat" -msgstr "" - -#: diff.c:5412 diff.c:5420 -msgid "<param1,param2>..." -msgstr "" - -#: diff.c:5413 -msgid "" -"output the distribution of relative amount of changes for each sub-directory" -msgstr "" - -#: diff.c:5417 -msgid "synonym for --dirstat=cumulative" -msgstr "" - -#: diff.c:5421 -msgid "synonym for --dirstat=files,param1,param2..." -msgstr "" - -#: diff.c:5425 -msgid "warn if changes introduce conflict markers or whitespace errors" -msgstr "" - -#: diff.c:5428 -msgid "condensed summary such as creations, renames and mode changes" -msgstr "" - -#: diff.c:5431 -msgid "show only names of changed files" -msgstr "" - -#: diff.c:5434 -msgid "show only names and status of changed files" -msgstr "" - -#: diff.c:5436 -msgid "<width>[,<name-width>[,<count>]]" -msgstr "" - -#: diff.c:5437 -msgid "generate diffstat" -msgstr "" - -#: diff.c:5439 diff.c:5442 diff.c:5445 -msgid "<width>" -msgstr "" - -#: diff.c:5440 -msgid "generate diffstat with a given width" -msgstr "" - -#: diff.c:5443 -msgid "generate diffstat with a given name width" -msgstr "" - -#: diff.c:5446 -msgid "generate diffstat with a given graph width" -msgstr "" - -#: diff.c:5448 -msgid "<count>" -msgstr "" - -#: diff.c:5449 -msgid "generate diffstat with limited lines" -msgstr "" - -#: diff.c:5452 -msgid "generate compact summary in diffstat" -msgstr "" - -#: diff.c:5455 -msgid "output a binary diff that can be applied" -msgstr "" - -#: diff.c:5458 -msgid "show full pre- and post-image object names on the \"index\" lines" -msgstr "" - -#: diff.c:5460 -msgid "show colored diff" -msgstr "" - -#: diff.c:5461 -msgid "<kind>" -msgstr "" - -#: diff.c:5462 -msgid "" -"highlight whitespace errors in the 'context', 'old' or 'new' lines in the " -"diff" -msgstr "" - -#: diff.c:5465 -msgid "" -"do not munge pathnames and use NULs as output field terminators in --raw or " -"--numstat" -msgstr "" - -#: diff.c:5468 diff.c:5471 diff.c:5474 diff.c:5583 -msgid "<prefix>" -msgstr "" - -#: diff.c:5469 -msgid "show the given source prefix instead of \"a/\"" -msgstr "" - -#: diff.c:5472 -msgid "show the given destination prefix instead of \"b/\"" -msgstr "" - -#: diff.c:5475 -msgid "prepend an additional prefix to every line of output" -msgstr "" - -#: diff.c:5478 -msgid "do not show any source or destination prefix" -msgstr "" - -#: diff.c:5481 -msgid "show context between diff hunks up to the specified number of lines" -msgstr "" - -#: diff.c:5485 diff.c:5490 diff.c:5495 -msgid "<char>" -msgstr "" - -#: diff.c:5486 -msgid "specify the character to indicate a new line instead of '+'" -msgstr "" - -#: diff.c:5491 -msgid "specify the character to indicate an old line instead of '-'" -msgstr "" - -#: diff.c:5496 -msgid "specify the character to indicate a context instead of ' '" -msgstr "" - -#: diff.c:5499 -msgid "Diff rename options" -msgstr "" - -#: diff.c:5500 -msgid "<n>[/<m>]" -msgstr "" - -#: diff.c:5501 -msgid "break complete rewrite changes into pairs of delete and create" -msgstr "" - -#: diff.c:5505 -msgid "detect renames" -msgstr "" - -#: diff.c:5509 -msgid "omit the preimage for deletes" -msgstr "" - -#: diff.c:5512 -msgid "detect copies" -msgstr "" - -#: diff.c:5516 -msgid "use unmodified files as source to find copies" -msgstr "" - -#: diff.c:5518 -msgid "disable rename detection" -msgstr "" - -#: diff.c:5521 -msgid "use empty blobs as rename source" -msgstr "" - -#: diff.c:5523 -msgid "continue listing the history of a file beyond renames" -msgstr "" - -#: diff.c:5526 -msgid "" -"prevent rename/copy detection if the number of rename/copy targets exceeds " -"given limit" -msgstr "" - -#: diff.c:5528 -msgid "Diff algorithm options" -msgstr "" - -#: diff.c:5530 -msgid "produce the smallest possible diff" -msgstr "" - -#: diff.c:5533 -msgid "ignore whitespace when comparing lines" -msgstr "" - -#: diff.c:5536 -msgid "ignore changes in amount of whitespace" -msgstr "" - -#: diff.c:5539 -msgid "ignore changes in whitespace at EOL" -msgstr "" - -#: diff.c:5542 -msgid "ignore carrier-return at the end of line" -msgstr "" - -#: diff.c:5545 -msgid "ignore changes whose lines are all blank" -msgstr "" - -#: diff.c:5547 diff.c:5569 diff.c:5572 diff.c:5617 -msgid "<regex>" -msgstr "" - -#: diff.c:5548 -msgid "ignore changes whose all lines match <regex>" -msgstr "" - -#: diff.c:5551 -msgid "heuristic to shift diff hunk boundaries for easy reading" -msgstr "" - -#: diff.c:5554 -msgid "generate diff using the \"patience diff\" algorithm" -msgstr "" - -#: diff.c:5558 -msgid "generate diff using the \"histogram diff\" algorithm" -msgstr "" - -#: diff.c:5560 -msgid "<algorithm>" -msgstr "" - -#: diff.c:5561 -msgid "choose a diff algorithm" -msgstr "" - -#: diff.c:5563 -msgid "<text>" -msgstr "" - -#: diff.c:5564 -msgid "generate diff using the \"anchored diff\" algorithm" -msgstr "" - -#: diff.c:5566 diff.c:5575 diff.c:5578 -msgid "<mode>" -msgstr "" - -#: diff.c:5567 -msgid "show word diff, using <mode> to delimit changed words" -msgstr "" - -#: diff.c:5570 -msgid "use <regex> to decide what a word is" -msgstr "" - -#: diff.c:5573 -msgid "equivalent to --word-diff=color --word-diff-regex=<regex>" -msgstr "" - -#: diff.c:5576 -msgid "moved lines of code are colored differently" -msgstr "" - -#: diff.c:5579 -msgid "how white spaces are ignored in --color-moved" -msgstr "" - -#: diff.c:5582 -msgid "Other diff options" -msgstr "" - -#: diff.c:5584 -msgid "when run from subdir, exclude changes outside and show relative paths" -msgstr "" - -#: diff.c:5588 -msgid "treat all files as text" -msgstr "" - -#: diff.c:5590 -msgid "swap two inputs, reverse the diff" -msgstr "" - -#: diff.c:5592 -msgid "exit with 1 if there were differences, 0 otherwise" -msgstr "" - -#: diff.c:5594 -msgid "disable all output of the program" -msgstr "" - -#: diff.c:5596 -msgid "allow an external diff helper to be executed" -msgstr "" - -#: diff.c:5598 -msgid "run external text conversion filters when comparing binary files" -msgstr "" - -#: diff.c:5600 -msgid "<when>" -msgstr "" - -#: diff.c:5601 -msgid "ignore changes to submodules in the diff generation" -msgstr "" - -#: diff.c:5604 -msgid "<format>" -msgstr "" - -#: diff.c:5605 -msgid "specify how differences in submodules are shown" -msgstr "" - -#: diff.c:5609 -msgid "hide 'git add -N' entries from the index" -msgstr "" - -#: diff.c:5612 -msgid "treat 'git add -N' entries as real in the index" -msgstr "" - -#: diff.c:5614 -msgid "<string>" -msgstr "" - -#: diff.c:5615 -msgid "" -"look for differences that change the number of occurrences of the specified " -"string" -msgstr "" - -#: diff.c:5618 -msgid "" -"look for differences that change the number of occurrences of the specified " -"regex" -msgstr "" - -#: diff.c:5621 -msgid "show all changes in the changeset with -S or -G" -msgstr "" - -#: diff.c:5624 -msgid "treat <string> in -S as extended POSIX regular expression" -msgstr "" - -#: diff.c:5627 -msgid "control the order in which files appear in the output" -msgstr "" - -#: diff.c:5628 diff.c:5631 -msgid "<path>" -msgstr "" - -#: diff.c:5629 -msgid "show the change in the specified path first" -msgstr "" - -#: diff.c:5632 -msgid "skip the output to the specified path" -msgstr "" - -#: diff.c:5634 -msgid "<object-id>" -msgstr "" - -#: diff.c:5635 -msgid "" -"look for differences that change the number of occurrences of the specified " -"object" -msgstr "" - -#: diff.c:5637 -msgid "[(A|C|D|M|R|T|U|X|B)...[*]]" -msgstr "" - -#: diff.c:5638 -msgid "select files by diff type" -msgstr "" - -#: diff.c:5640 -msgid "<file>" -msgstr "" - -#: diff.c:5641 -msgid "output to a specific file" -msgstr "" - -#: diff.c:6321 -msgid "exhaustive rename detection was skipped due to too many files." -msgstr "" - -#: diff.c:6324 -msgid "only found copies from modified paths due to too many files." -msgstr "" - -#: diff.c:6327 -#, c-format -msgid "" -"you may want to set your %s variable to at least %d and retry the command." -msgstr "" - -#: diffcore-order.c:24 -#, c-format -msgid "failed to read orderfile '%s'" -msgstr "" - -#: diffcore-rename.c:1564 -msgid "Performing inexact rename detection" -msgstr "" - -#: diffcore-rotate.c:29 -#, c-format -msgid "No such path '%s' in the diff" -msgstr "" - -#: dir.c:593 -#, c-format -msgid "pathspec '%s' did not match any file(s) known to git" -msgstr "" - -#: dir.c:733 dir.c:762 dir.c:775 -#, c-format -msgid "unrecognized pattern: '%s'" -msgstr "" - -#: dir.c:790 dir.c:804 -#, c-format -msgid "unrecognized negative pattern: '%s'" -msgstr "" - -#: dir.c:820 -#, c-format -msgid "your sparse-checkout file may have issues: pattern '%s' is repeated" -msgstr "" - -#: dir.c:828 -msgid "disabling cone pattern matching" -msgstr "" - -#: dir.c:1212 -#, c-format -msgid "cannot use %s as an exclude file" -msgstr "" - -#: dir.c:2419 -#, c-format -msgid "could not open directory '%s'" -msgstr "" - -#: dir.c:2721 -msgid "failed to get kernel name and information" -msgstr "" - -#: dir.c:2846 -msgid "untracked cache is disabled on this system or location" -msgstr "" - -#: dir.c:3119 -msgid "" -"No directory name could be guessed.\n" -"Please specify a directory on the command line" -msgstr "" - -#: dir.c:3807 -#, c-format -msgid "index file corrupt in repo %s" -msgstr "" - -#: dir.c:3854 dir.c:3859 -#, c-format -msgid "could not create directories for %s" -msgstr "" - -#: dir.c:3888 -#, c-format -msgid "could not migrate git directory from '%s' to '%s'" -msgstr "" - -#: editor.c:74 -#, c-format -msgid "hint: Waiting for your editor to close the file...%c" -msgstr "" - -#: entry.c:179 -msgid "Filtering content" -msgstr "" - -#: entry.c:500 -#, c-format -msgid "could not stat file '%s'" -msgstr "" - -#: environment.c:147 -#, c-format -msgid "bad git namespace path \"%s\"" -msgstr "" - -#: exec-cmd.c:363 -#, c-format -msgid "too many args to run %s" -msgstr "" - -#: fetch-pack.c:194 -msgid "git fetch-pack: expected shallow list" -msgstr "" - -#: fetch-pack.c:197 -msgid "git fetch-pack: expected a flush packet after shallow list" -msgstr "" - -#: fetch-pack.c:208 -msgid "git fetch-pack: expected ACK/NAK, got a flush packet" -msgstr "" - -#: fetch-pack.c:228 -#, c-format -msgid "git fetch-pack: expected ACK/NAK, got '%s'" -msgstr "" - -#: fetch-pack.c:239 -msgid "unable to write to remote" -msgstr "" - -#: fetch-pack.c:397 fetch-pack.c:1460 -#, c-format -msgid "invalid shallow line: %s" -msgstr "" - -#: fetch-pack.c:403 fetch-pack.c:1466 -#, c-format -msgid "invalid unshallow line: %s" -msgstr "" - -#: fetch-pack.c:405 fetch-pack.c:1468 -#, c-format -msgid "object not found: %s" -msgstr "" - -#: fetch-pack.c:408 fetch-pack.c:1471 -#, c-format -msgid "error in object: %s" -msgstr "" - -#: fetch-pack.c:410 fetch-pack.c:1473 -#, c-format -msgid "no shallow found: %s" -msgstr "" - -#: fetch-pack.c:413 fetch-pack.c:1477 -#, c-format -msgid "expected shallow/unshallow, got %s" -msgstr "" - -#: fetch-pack.c:453 -#, c-format -msgid "got %s %d %s" -msgstr "" - -#: fetch-pack.c:470 -#, c-format -msgid "invalid commit %s" -msgstr "" - -#: fetch-pack.c:501 -msgid "giving up" -msgstr "" - -#: fetch-pack.c:514 progress.h:25 -msgid "done" -msgstr "" - -#: fetch-pack.c:526 -#, c-format -msgid "got %s (%d) %s" -msgstr "" - -#: fetch-pack.c:562 -#, c-format -msgid "Marking %s as complete" -msgstr "" - -#: fetch-pack.c:784 -#, c-format -msgid "already have %s (%s)" -msgstr "" - -#: fetch-pack.c:870 -msgid "fetch-pack: unable to fork off sideband demultiplexer" -msgstr "" - -#: fetch-pack.c:878 -msgid "protocol error: bad pack header" -msgstr "" - -#: fetch-pack.c:974 -#, c-format -msgid "fetch-pack: unable to fork off %s" -msgstr "" - -#: fetch-pack.c:980 -msgid "fetch-pack: invalid index-pack output" -msgstr "" - -#: fetch-pack.c:997 -#, c-format -msgid "%s failed" -msgstr "" - -#: fetch-pack.c:999 -msgid "error in sideband demultiplexer" -msgstr "" - -#: fetch-pack.c:1048 -#, c-format -msgid "Server version is %.*s" -msgstr "" - -#: fetch-pack.c:1056 fetch-pack.c:1062 fetch-pack.c:1065 fetch-pack.c:1071 -#: fetch-pack.c:1075 fetch-pack.c:1079 fetch-pack.c:1083 fetch-pack.c:1087 -#: fetch-pack.c:1091 fetch-pack.c:1095 fetch-pack.c:1099 fetch-pack.c:1103 -#: fetch-pack.c:1109 fetch-pack.c:1115 fetch-pack.c:1120 fetch-pack.c:1125 -#, c-format -msgid "Server supports %s" -msgstr "" - -#: fetch-pack.c:1058 -msgid "Server does not support shallow clients" -msgstr "" - -#: fetch-pack.c:1118 -msgid "Server does not support --shallow-since" -msgstr "" - -#: fetch-pack.c:1123 -msgid "Server does not support --shallow-exclude" -msgstr "" - -#: fetch-pack.c:1127 -msgid "Server does not support --deepen" -msgstr "" - -#: fetch-pack.c:1129 -msgid "Server does not support this repository's object format" -msgstr "" - -#: fetch-pack.c:1142 -msgid "no common commits" -msgstr "" - -#: fetch-pack.c:1151 fetch-pack.c:1506 builtin/clone.c:1166 -msgid "source repository is shallow, reject to clone." -msgstr "" - -#: fetch-pack.c:1157 fetch-pack.c:1705 -msgid "git fetch-pack: fetch failed." -msgstr "" - -#: fetch-pack.c:1271 -#, c-format -msgid "mismatched algorithms: client %s; server %s" -msgstr "" - -#: fetch-pack.c:1275 -#, c-format -msgid "the server does not support algorithm '%s'" -msgstr "" - -#: fetch-pack.c:1308 -msgid "Server does not support shallow requests" -msgstr "" - -#: fetch-pack.c:1315 -msgid "Server supports filter" -msgstr "" - -#: fetch-pack.c:1358 fetch-pack.c:2087 -msgid "unable to write request to remote" -msgstr "" - -#: fetch-pack.c:1376 -#, c-format -msgid "error reading section header '%s'" -msgstr "" - -#: fetch-pack.c:1382 -#, c-format -msgid "expected '%s', received '%s'" -msgstr "" - -#: fetch-pack.c:1416 -#, c-format -msgid "unexpected acknowledgment line: '%s'" -msgstr "" - -#: fetch-pack.c:1421 -#, c-format -msgid "error processing acks: %d" -msgstr "" - -#. TRANSLATORS: The parameter will be 'ready', a protocol -#. keyword. -#. -#: fetch-pack.c:1435 -#, c-format -msgid "expected packfile to be sent after '%s'" -msgstr "" - -#. TRANSLATORS: The parameter will be 'ready', a protocol -#. keyword. -#. -#: fetch-pack.c:1441 -#, c-format -msgid "expected no other sections to be sent after no '%s'" -msgstr "" - -#: fetch-pack.c:1482 -#, c-format -msgid "error processing shallow info: %d" -msgstr "" - -#: fetch-pack.c:1531 -#, c-format -msgid "expected wanted-ref, got '%s'" -msgstr "" - -#: fetch-pack.c:1536 -#, c-format -msgid "unexpected wanted-ref: '%s'" -msgstr "" - -#: fetch-pack.c:1541 -#, c-format -msgid "error processing wanted refs: %d" -msgstr "" - -#: fetch-pack.c:1571 -msgid "git fetch-pack: expected response end packet" -msgstr "" - -#: fetch-pack.c:1983 -msgid "no matching remote head" -msgstr "" - -#: fetch-pack.c:2006 builtin/clone.c:587 -msgid "remote did not send all necessary objects" -msgstr "" - -#: fetch-pack.c:2109 -msgid "unexpected 'ready' from remote" -msgstr "" - -#: fetch-pack.c:2132 -#, c-format -msgid "no such remote ref %s" -msgstr "" - -#: fetch-pack.c:2135 -#, c-format -msgid "Server does not allow request for unadvertised object %s" -msgstr "" - -#: fsmonitor-ipc.c:119 -#, c-format -msgid "fsmonitor_ipc__send_query: invalid path '%s'" -msgstr "" - -#: fsmonitor-ipc.c:125 -#, c-format -msgid "fsmonitor_ipc__send_query: unspecified error on '%s'" -msgstr "" - -#: fsmonitor-ipc.c:155 -msgid "fsmonitor--daemon is not running" -msgstr "" - -#: fsmonitor-ipc.c:164 -#, c-format -msgid "could not send '%s' command to fsmonitor--daemon" -msgstr "" - -#: gpg-interface.c:329 gpg-interface.c:456 gpg-interface.c:995 -#: gpg-interface.c:1011 -msgid "could not create temporary file" -msgstr "" - -#: gpg-interface.c:332 gpg-interface.c:459 -#, c-format -msgid "failed writing detached signature to '%s'" -msgstr "" - -#: gpg-interface.c:450 -msgid "" -"gpg.ssh.allowedSignersFile needs to be configured and exist for ssh " -"signature verification" -msgstr "" - -#: gpg-interface.c:479 -msgid "" -"ssh-keygen -Y find-principals/verify is needed for ssh signature " -"verification (available in openssh version 8.2p1+)" -msgstr "" - -#: gpg-interface.c:550 -#, c-format -msgid "ssh signing revocation file configured but not found: %s" -msgstr "" - -#: gpg-interface.c:638 -#, c-format -msgid "bad/incompatible signature '%s'" -msgstr "" - -#: gpg-interface.c:815 gpg-interface.c:820 -#, c-format -msgid "failed to get the ssh fingerprint for key '%s'" -msgstr "" - -#: gpg-interface.c:843 -msgid "" -"either user.signingkey or gpg.ssh.defaultKeyCommand needs to be configured" -msgstr "" - -#: gpg-interface.c:865 -#, c-format -msgid "gpg.ssh.defaultKeyCommand succeeded but returned no keys: %s %s" -msgstr "" - -#: gpg-interface.c:871 -#, c-format -msgid "gpg.ssh.defaultKeyCommand failed: %s %s" -msgstr "" - -#: gpg-interface.c:966 -msgid "gpg failed to sign the data" -msgstr "" - -#: gpg-interface.c:988 -msgid "user.signingkey needs to be set for ssh signing" -msgstr "" - -#: gpg-interface.c:999 -#, c-format -msgid "failed writing ssh signing key to '%s'" -msgstr "" - -#: gpg-interface.c:1017 -#, c-format -msgid "failed writing ssh signing key buffer to '%s'" -msgstr "" - -#: gpg-interface.c:1035 -msgid "" -"ssh-keygen -Y sign is needed for ssh signing (available in openssh version " -"8.2p1+)" -msgstr "" - -#: gpg-interface.c:1047 -#, c-format -msgid "failed reading ssh signing data buffer from '%s'" -msgstr "" - -#: graph.c:98 -#, c-format -msgid "ignored invalid color '%.*s' in log.graphColors" -msgstr "" - -#: grep.c:446 -msgid "" -"given pattern contains NULL byte (via -f <file>). This is only supported " -"with -P under PCRE v2" -msgstr "" - -#: grep.c:1859 -#, c-format -msgid "'%s': unable to read %s" -msgstr "" - -#: grep.c:1876 setup.c:178 builtin/clone.c:308 builtin/diff.c:90 -#: builtin/rm.c:136 -#, c-format -msgid "failed to stat '%s'" -msgstr "" - -#: grep.c:1887 -#, c-format -msgid "'%s': short read" -msgstr "" - -#: help.c:25 -msgid "start a working area (see also: git help tutorial)" -msgstr "" - -#: help.c:26 -msgid "work on the current change (see also: git help everyday)" -msgstr "" - -#: help.c:27 -msgid "examine the history and state (see also: git help revisions)" -msgstr "" - -#: help.c:28 -msgid "grow, mark and tweak your common history" -msgstr "" - -#: help.c:29 -msgid "collaborate (see also: git help workflows)" -msgstr "" - -#: help.c:33 -msgid "Main Porcelain Commands" -msgstr "" - -#: help.c:34 -msgid "Ancillary Commands / Manipulators" -msgstr "" - -#: help.c:35 -msgid "Ancillary Commands / Interrogators" -msgstr "" - -#: help.c:36 -msgid "Interacting with Others" -msgstr "" - -#: help.c:37 -msgid "Low-level Commands / Manipulators" -msgstr "" - -#: help.c:38 -msgid "Low-level Commands / Interrogators" -msgstr "" - -#: help.c:39 -msgid "Low-level Commands / Syncing Repositories" -msgstr "" - -#: help.c:40 -msgid "Low-level Commands / Internal Helpers" -msgstr "" - -#: help.c:316 -#, c-format -msgid "available git commands in '%s'" -msgstr "" - -#: help.c:323 -msgid "git commands available from elsewhere on your $PATH" -msgstr "" - -#: help.c:332 -msgid "These are common Git commands used in various situations:" -msgstr "" - -#: help.c:382 git.c:100 -#, c-format -msgid "unsupported command listing type '%s'" -msgstr "" - -#: help.c:422 -msgid "The Git concept guides are:" -msgstr "" - -#: help.c:446 -msgid "External commands" -msgstr "" - -#: help.c:468 -msgid "Command aliases" -msgstr "" - -#: help.c:486 -msgid "See 'git help <command>' to read about a specific subcommand" -msgstr "" - -#: help.c:563 -#, c-format -msgid "" -"'%s' appears to be a git command, but we were not\n" -"able to execute it. Maybe git-%s is broken?" -msgstr "" - -#: help.c:585 help.c:682 -#, c-format -msgid "git: '%s' is not a git command. See 'git --help'." -msgstr "" - -#: help.c:633 -msgid "Uh oh. Your system reports no Git commands at all." -msgstr "" - -#: help.c:655 -#, c-format -msgid "WARNING: You called a Git command named '%s', which does not exist." -msgstr "" - -#: help.c:660 -#, c-format -msgid "Continuing under the assumption that you meant '%s'." -msgstr "" - -#: help.c:666 -#, c-format -msgid "Run '%s' instead [y/N]? " -msgstr "" - -#: help.c:674 -#, c-format -msgid "Continuing in %0.1f seconds, assuming that you meant '%s'." -msgstr "" - -#: help.c:686 -msgid "" -"\n" -"The most similar command is" -msgid_plural "" -"\n" -"The most similar commands are" -msgstr[0] "" -msgstr[1] "" - -#: help.c:729 -msgid "git version [<options>]" -msgstr "" - -#: help.c:784 -#, c-format -msgid "%s: %s - %s" -msgstr "" - -#: help.c:788 -msgid "" -"\n" -"Did you mean this?" -msgid_plural "" -"\n" -"Did you mean one of these?" -msgstr[0] "" -msgstr[1] "" - -#: hook.c:28 -#, c-format -msgid "" -"The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." -msgstr "" - -#: hook.c:87 -#, c-format -msgid "Couldn't start hook '%s'\n" -msgstr "" - -#: ident.c:354 -msgid "Author identity unknown\n" -msgstr "" - -#: ident.c:357 -msgid "Committer identity unknown\n" -msgstr "" - -#: ident.c:363 -msgid "" -"\n" -"*** Please tell me who you are.\n" -"\n" -"Run\n" -"\n" -" git config --global user.email \"you@example.com\"\n" -" git config --global user.name \"Your Name\"\n" -"\n" -"to set your account's default identity.\n" -"Omit --global to set the identity only in this repository.\n" -"\n" -msgstr "" - -#: ident.c:398 -msgid "no email was given and auto-detection is disabled" -msgstr "" - -#: ident.c:403 -#, c-format -msgid "unable to auto-detect email address (got '%s')" -msgstr "" - -#: ident.c:420 -msgid "no name was given and auto-detection is disabled" -msgstr "" - -#: ident.c:426 -#, c-format -msgid "unable to auto-detect name (got '%s')" -msgstr "" - -#: ident.c:434 -#, c-format -msgid "empty ident name (for <%s>) not allowed" -msgstr "" - -#: ident.c:440 -#, c-format -msgid "name consists only of disallowed characters: %s" -msgstr "" - -#: ident.c:455 builtin/commit.c:649 -#, c-format -msgid "invalid date format: %s" -msgstr "" - -#: list-objects-filter-options.c:68 -msgid "expected 'tree:<depth>'" -msgstr "" - -#: list-objects-filter-options.c:83 -msgid "sparse:path filters support has been dropped" -msgstr "" - -#: list-objects-filter-options.c:90 -#, c-format -msgid "'%s' for 'object:type=<type>' is not a valid object type" -msgstr "" - -#: list-objects-filter-options.c:109 -#, c-format -msgid "invalid filter-spec '%s'" -msgstr "" - -#: list-objects-filter-options.c:125 -#, c-format -msgid "must escape char in sub-filter-spec: '%c'" -msgstr "" - -#: list-objects-filter-options.c:167 -msgid "expected something after combine:" -msgstr "" - -#: list-objects-filter-options.c:249 -msgid "multiple filter-specs cannot be combined" -msgstr "" - -#: list-objects-filter-options.c:365 -msgid "unable to upgrade repository format to support partial clone" -msgstr "" - -#: list-objects-filter.c:532 -#, c-format -msgid "unable to access sparse blob in '%s'" -msgstr "" - -#: list-objects-filter.c:535 -#, c-format -msgid "unable to parse sparse filter data in %s" -msgstr "" - -#: list-objects.c:144 -#, c-format -msgid "entry '%s' in tree %s has tree mode, but is not a tree" -msgstr "" - -#: list-objects.c:157 -#, c-format -msgid "entry '%s' in tree %s has blob mode, but is not a blob" -msgstr "" - -#: list-objects.c:415 -#, c-format -msgid "unable to load root tree for commit %s" -msgstr "" - -#: lockfile.c:152 -#, c-format -msgid "" -"Unable to create '%s.lock': %s.\n" -"\n" -"Another git process seems to be running in this repository, e.g.\n" -"an editor opened by 'git commit'. Please make sure all processes\n" -"are terminated then try again. If it still fails, a git process\n" -"may have crashed in this repository earlier:\n" -"remove the file manually to continue." -msgstr "" - -#: lockfile.c:160 -#, c-format -msgid "Unable to create '%s.lock': %s" -msgstr "" - -#: ls-refs.c:175 -#, c-format -msgid "unexpected line: '%s'" -msgstr "" - -#: ls-refs.c:179 -msgid "expected flush after ls-refs arguments" -msgstr "" - -#: mailinfo.c:1050 -msgid "quoted CRLF detected" -msgstr "" - -#: mailinfo.c:1254 builtin/am.c:185 builtin/mailinfo.c:46 -#, c-format -msgid "bad action '%s' for '%s'" -msgstr "" - -#: merge-ort.c:1630 merge-recursive.c:1214 -#, c-format -msgid "Failed to merge submodule %s (not checked out)" -msgstr "" - -#: merge-ort.c:1639 merge-recursive.c:1221 -#, c-format -msgid "Failed to merge submodule %s (commits not present)" -msgstr "" - -#: merge-ort.c:1648 merge-recursive.c:1228 -#, c-format -msgid "Failed to merge submodule %s (commits don't follow merge-base)" -msgstr "" - -#: merge-ort.c:1658 merge-ort.c:1666 -#, c-format -msgid "Note: Fast-forwarding submodule %s to %s" -msgstr "" - -#: merge-ort.c:1688 -#, c-format -msgid "Failed to merge submodule %s" -msgstr "" - -#: merge-ort.c:1695 -#, c-format -msgid "" -"Failed to merge submodule %s, but a possible merge resolution exists:\n" -"%s\n" -msgstr "" - -#: merge-ort.c:1699 merge-recursive.c:1284 -#, c-format -msgid "" -"If this is correct simply add it to the index for example\n" -"by using:\n" -"\n" -" git update-index --cacheinfo 160000 %s \"%s\"\n" -"\n" -"which will accept this suggestion.\n" -msgstr "" - -#: merge-ort.c:1712 -#, c-format -msgid "" -"Failed to merge submodule %s, but multiple possible merges exist:\n" -"%s" -msgstr "" - -#: merge-ort.c:1937 merge-recursive.c:1375 -msgid "Failed to execute internal merge" -msgstr "" - -#: merge-ort.c:1942 merge-recursive.c:1380 -#, c-format -msgid "Unable to add %s to database" -msgstr "" - -#: merge-ort.c:1949 merge-recursive.c:1413 -#, c-format -msgid "Auto-merging %s" -msgstr "" - -#: merge-ort.c:2088 merge-recursive.c:2135 -#, c-format -msgid "" -"CONFLICT (implicit dir rename): Existing file/dir at %s in the way of " -"implicit directory rename(s) putting the following path(s) there: %s." -msgstr "" - -#: merge-ort.c:2098 merge-recursive.c:2145 -#, c-format -msgid "" -"CONFLICT (implicit dir rename): Cannot map more than one path to %s; " -"implicit directory renames tried to put these paths there: %s" -msgstr "" - -#: merge-ort.c:2156 -#, c-format -msgid "" -"CONFLICT (directory rename split): Unclear where to rename %s to; it was " -"renamed to multiple other directories, with no destination getting a " -"majority of the files." -msgstr "" - -#: merge-ort.c:2310 merge-recursive.c:2481 -#, c-format -msgid "" -"WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was " -"renamed." -msgstr "" - -#: merge-ort.c:2450 merge-recursive.c:3264 -#, c-format -msgid "" -"Path updated: %s added in %s inside a directory that was renamed in %s; " -"moving it to %s." -msgstr "" - -#: merge-ort.c:2457 merge-recursive.c:3271 -#, c-format -msgid "" -"Path updated: %s renamed to %s in %s, inside a directory that was renamed in " -"%s; moving it to %s." -msgstr "" - -#: merge-ort.c:2470 merge-recursive.c:3267 -#, c-format -msgid "" -"CONFLICT (file location): %s added in %s inside a directory that was renamed " -"in %s, suggesting it should perhaps be moved to %s." -msgstr "" - -#: merge-ort.c:2478 merge-recursive.c:3274 -#, c-format -msgid "" -"CONFLICT (file location): %s renamed to %s in %s, inside a directory that " -"was renamed in %s, suggesting it should perhaps be moved to %s." -msgstr "" - -#: merge-ort.c:2634 -#, c-format -msgid "CONFLICT (rename/rename): %s renamed to %s in %s and to %s in %s." -msgstr "" - -#: merge-ort.c:2729 -#, c-format -msgid "" -"CONFLICT (rename involved in collision): rename of %s -> %s has content " -"conflicts AND collides with another path; this may result in nested conflict " -"markers." -msgstr "" - -#: merge-ort.c:2748 merge-ort.c:2772 -#, c-format -msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s." -msgstr "" - -#: merge-ort.c:3261 merge-recursive.c:3025 -#, c-format -msgid "cannot read object %s" -msgstr "" - -#: merge-ort.c:3264 merge-recursive.c:3028 -#, c-format -msgid "object %s is not a blob" -msgstr "" - -#: merge-ort.c:3693 -#, c-format -msgid "" -"CONFLICT (file/directory): directory in the way of %s from %s; moving it to " -"%s instead." -msgstr "" - -#: merge-ort.c:3770 -#, c-format -msgid "" -"CONFLICT (distinct types): %s had different types on each side; renamed both " -"of them so each can be recorded somewhere." -msgstr "" - -#: merge-ort.c:3777 -#, c-format -msgid "" -"CONFLICT (distinct types): %s had different types on each side; renamed one " -"of them so each can be recorded somewhere." -msgstr "" - -#: merge-ort.c:3866 merge-recursive.c:3104 -msgid "content" -msgstr "" - -#: merge-ort.c:3868 merge-recursive.c:3108 -msgid "add/add" -msgstr "" - -#: merge-ort.c:3870 merge-recursive.c:3153 -msgid "submodule" -msgstr "" - -#: merge-ort.c:3872 merge-recursive.c:3154 -#, c-format -msgid "CONFLICT (%s): Merge conflict in %s" -msgstr "" - -#: merge-ort.c:3916 -#, c-format -msgid "" -"CONFLICT (modify/delete): %s deleted in %s and modified in %s. Version %s " -"of %s left in tree." -msgstr "" - -#: merge-ort.c:4212 -#, c-format -msgid "" -"Note: %s not up to date and in way of checking out conflicted version; old " -"copy renamed to %s" -msgstr "" - -#. TRANSLATORS: The %s arguments are: 1) tree hash of a merge -#. base, and 2-3) the trees for the two trees we're merging. -#. -#: merge-ort.c:4586 -#, c-format -msgid "collecting merge info failed for trees %s, %s, %s" -msgstr "" - -#: merge-ort-wrappers.c:13 merge-recursive.c:3723 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by merge:\n" -" %s" -msgstr "" - -#: merge-ort-wrappers.c:33 merge-recursive.c:3485 builtin/merge.c:405 -msgid "Already up to date." -msgstr "" - -#: merge-recursive.c:353 -msgid "(bad commit)\n" -msgstr "" - -#: merge-recursive.c:381 -#, c-format -msgid "add_cacheinfo failed for path '%s'; merge aborting." -msgstr "" - -#: merge-recursive.c:390 -#, c-format -msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." -msgstr "" - -#: merge-recursive.c:881 -#, c-format -msgid "failed to create path '%s'%s" -msgstr "" - -#: merge-recursive.c:892 -#, c-format -msgid "Removing %s to make room for subdirectory\n" -msgstr "" - -#: merge-recursive.c:906 merge-recursive.c:925 -msgid ": perhaps a D/F conflict?" -msgstr "" - -#: merge-recursive.c:915 -#, c-format -msgid "refusing to lose untracked file at '%s'" -msgstr "" - -#: merge-recursive.c:956 builtin/cat-file.c:47 -#, c-format -msgid "cannot read object %s '%s'" -msgstr "" - -#: merge-recursive.c:961 -#, c-format -msgid "blob expected for %s '%s'" -msgstr "" - -#: merge-recursive.c:986 -#, c-format -msgid "failed to open '%s': %s" -msgstr "" - -#: merge-recursive.c:997 -#, c-format -msgid "failed to symlink '%s': %s" -msgstr "" - -#: merge-recursive.c:1002 -#, c-format -msgid "do not know what to do with %06o %s '%s'" -msgstr "" - -#: merge-recursive.c:1236 merge-recursive.c:1249 -#, c-format -msgid "Fast-forwarding submodule %s to the following commit:" -msgstr "" - -#: merge-recursive.c:1239 merge-recursive.c:1252 -#, c-format -msgid "Fast-forwarding submodule %s" -msgstr "" - -#: merge-recursive.c:1276 -#, c-format -msgid "Failed to merge submodule %s (merge following commits not found)" -msgstr "" - -#: merge-recursive.c:1280 -#, c-format -msgid "Failed to merge submodule %s (not fast-forward)" -msgstr "" - -#: merge-recursive.c:1281 -msgid "Found a possible merge resolution for the submodule:\n" -msgstr "" - -#: merge-recursive.c:1293 -#, c-format -msgid "Failed to merge submodule %s (multiple merges found)" -msgstr "" - -#: merge-recursive.c:1437 -#, c-format -msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." -msgstr "" - -#: merge-recursive.c:1509 -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree." -msgstr "" - -#: merge-recursive.c:1514 -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree." -msgstr "" - -#: merge-recursive.c:1521 -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree at %s." -msgstr "" - -#: merge-recursive.c:1526 -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree at %s." -msgstr "" - -#: merge-recursive.c:1561 -msgid "rename" -msgstr "" - -#: merge-recursive.c:1561 -msgid "renamed" -msgstr "" - -#: merge-recursive.c:1612 merge-recursive.c:2518 merge-recursive.c:3181 -#, c-format -msgid "Refusing to lose dirty file at %s" -msgstr "" - -#: merge-recursive.c:1622 -#, c-format -msgid "Refusing to lose untracked file at %s, even though it's in the way." -msgstr "" - -#: merge-recursive.c:1680 -#, c-format -msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -msgstr "" - -#: merge-recursive.c:1711 -#, c-format -msgid "%s is a directory in %s adding as %s instead" -msgstr "" - -#: merge-recursive.c:1716 -#, c-format -msgid "Refusing to lose untracked file at %s; adding as %s instead" -msgstr "" - -#: merge-recursive.c:1743 -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" -"\"->\"%s\" in \"%s\"%s" -msgstr "" - -#: merge-recursive.c:1748 -msgid " (left unresolved)" -msgstr "" - -#: merge-recursive.c:1840 -#, c-format -msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -msgstr "" - -#: merge-recursive.c:2103 -#, c-format -msgid "" -"CONFLICT (directory rename split): Unclear where to place %s because " -"directory %s was renamed to multiple other directories, with no destination " -"getting a majority of the files." -msgstr "" - -#: merge-recursive.c:2237 -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" -">%s in %s" -msgstr "" - -#: merge-recursive.c:3092 -msgid "modify" -msgstr "" - -#: merge-recursive.c:3092 -msgid "modified" -msgstr "" - -#: merge-recursive.c:3131 -#, c-format -msgid "Skipped %s (merged same as existing)" -msgstr "" - -#: merge-recursive.c:3184 -#, c-format -msgid "Adding as %s instead" -msgstr "" - -#: merge-recursive.c:3388 -#, c-format -msgid "Removing %s" -msgstr "" - -#: merge-recursive.c:3411 -msgid "file/directory" -msgstr "" - -#: merge-recursive.c:3416 -msgid "directory/file" -msgstr "" - -#: merge-recursive.c:3423 -#, c-format -msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" -msgstr "" - -#: merge-recursive.c:3432 -#, c-format -msgid "Adding %s" -msgstr "" - -#: merge-recursive.c:3441 -#, c-format -msgid "CONFLICT (add/add): Merge conflict in %s" -msgstr "" - -#: merge-recursive.c:3494 -#, c-format -msgid "merging of trees %s and %s failed" -msgstr "" - -#: merge-recursive.c:3588 -msgid "Merging:" -msgstr "" - -#: merge-recursive.c:3601 -#, c-format -msgid "found %u common ancestor:" -msgid_plural "found %u common ancestors:" -msgstr[0] "" -msgstr[1] "" - -#: merge-recursive.c:3651 -msgid "merge returned no commit" -msgstr "" - -#: merge-recursive.c:3823 -#, c-format -msgid "Could not parse object '%s'" -msgstr "" - -#: merge-recursive.c:3841 builtin/merge.c:720 builtin/merge.c:912 -#: builtin/stash.c:489 -msgid "Unable to write index." -msgstr "" - -#: merge.c:41 -msgid "failed to read the cache" -msgstr "" - -#: merge.c:102 rerere.c:705 builtin/am.c:1989 builtin/am.c:2023 -#: builtin/checkout.c:603 builtin/checkout.c:865 builtin/clone.c:714 -#: builtin/stash.c:269 -msgid "unable to write new index file" -msgstr "" - -#: midx.c:79 -msgid "multi-pack-index OID fanout is of the wrong size" -msgstr "" - -#: midx.c:112 -#, c-format -msgid "multi-pack-index file %s is too small" -msgstr "" - -#: midx.c:128 -#, c-format -msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x" -msgstr "" - -#: midx.c:133 -#, c-format -msgid "multi-pack-index version %d not recognized" -msgstr "" - -#: midx.c:138 -#, c-format -msgid "multi-pack-index hash version %u does not match version %u" -msgstr "" - -#: midx.c:155 -msgid "multi-pack-index missing required pack-name chunk" -msgstr "" - -#: midx.c:157 -msgid "multi-pack-index missing required OID fanout chunk" -msgstr "" - -#: midx.c:159 -msgid "multi-pack-index missing required OID lookup chunk" -msgstr "" - -#: midx.c:161 -msgid "multi-pack-index missing required object offsets chunk" -msgstr "" - -#: midx.c:180 -#, c-format -msgid "multi-pack-index pack names out of order: '%s' before '%s'" -msgstr "" - -#: midx.c:228 -#, c-format -msgid "bad pack-int-id: %u (%u total packs)" -msgstr "" - -#: midx.c:278 -msgid "multi-pack-index stores a 64-bit offset, but off_t is too small" -msgstr "" - -#: midx.c:509 -#, c-format -msgid "failed to add packfile '%s'" -msgstr "" - -#: midx.c:515 -#, c-format -msgid "failed to open pack-index '%s'" -msgstr "" - -#: midx.c:583 -#, c-format -msgid "failed to locate object %d in packfile" -msgstr "" - -#: midx.c:911 -msgid "cannot store reverse index file" -msgstr "" - -#: midx.c:1009 -#, c-format -msgid "could not parse line: %s" -msgstr "" - -#: midx.c:1011 -#, c-format -msgid "malformed line: %s" -msgstr "" - -#: midx.c:1181 -msgid "ignoring existing multi-pack-index; checksum mismatch" -msgstr "" - -#: midx.c:1206 -msgid "could not load pack" -msgstr "" - -#: midx.c:1212 -#, c-format -msgid "could not open index for %s" -msgstr "" - -#: midx.c:1223 -msgid "Adding packfiles to multi-pack-index" -msgstr "" - -#: midx.c:1266 -#, c-format -msgid "unknown preferred pack: '%s'" -msgstr "" - -#: midx.c:1311 -#, c-format -msgid "cannot select preferred pack %s with no objects" -msgstr "" - -#: midx.c:1343 -#, c-format -msgid "did not see pack-file %s to drop" -msgstr "" - -#: midx.c:1389 -#, c-format -msgid "preferred pack '%s' is expired" -msgstr "" - -#: midx.c:1402 -msgid "no pack files to index." -msgstr "" - -#: midx.c:1409 -msgid "refusing to write multi-pack .bitmap without any objects" -msgstr "" - -#: midx.c:1451 -msgid "could not write multi-pack bitmap" -msgstr "" - -#: midx.c:1461 -msgid "could not write multi-pack-index" -msgstr "" - -#: midx.c:1520 builtin/clean.c:37 -#, c-format -msgid "failed to remove %s" -msgstr "" - -#: midx.c:1553 -#, c-format -msgid "failed to clear multi-pack-index at %s" -msgstr "" - -#: midx.c:1616 -msgid "multi-pack-index file exists, but failed to parse" -msgstr "" - -#: midx.c:1624 -msgid "incorrect checksum" -msgstr "" - -#: midx.c:1627 -msgid "Looking for referenced packfiles" -msgstr "" - -#: midx.c:1642 -#, c-format -msgid "" -"oid fanout out of order: fanout[%d] = %<PRIx32> > %<PRIx32> = fanout[%d]" -msgstr "" - -#: midx.c:1647 -msgid "the midx contains no oid" -msgstr "" - -#: midx.c:1656 -msgid "Verifying OID order in multi-pack-index" -msgstr "" - -#: midx.c:1665 -#, c-format -msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]" -msgstr "" - -#: midx.c:1685 -msgid "Sorting objects by packfile" -msgstr "" - -#: midx.c:1692 -msgid "Verifying object offsets" -msgstr "" - -#: midx.c:1708 -#, c-format -msgid "failed to load pack entry for oid[%d] = %s" -msgstr "" - -#: midx.c:1714 -#, c-format -msgid "failed to load pack-index for packfile %s" -msgstr "" - -#: midx.c:1723 -#, c-format -msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>" -msgstr "" - -#: midx.c:1750 -msgid "Counting referenced objects" -msgstr "" - -#: midx.c:1760 -msgid "Finding and deleting unreferenced packfiles" -msgstr "" - -#: midx.c:1952 -msgid "could not start pack-objects" -msgstr "" - -#: midx.c:1972 -msgid "could not finish pack-objects" -msgstr "" - -#: name-hash.c:542 -#, c-format -msgid "unable to create lazy_dir thread: %s" -msgstr "" - -#: name-hash.c:564 -#, c-format -msgid "unable to create lazy_name thread: %s" -msgstr "" - -#: name-hash.c:570 -#, c-format -msgid "unable to join lazy_name thread: %s" -msgstr "" - -#: notes-merge.c:276 -#, c-format -msgid "" -"You have not concluded your previous notes merge (%s exists).\n" -"Please, use 'git notes merge --commit' or 'git notes merge --abort' to " -"commit/abort the previous merge before you start a new notes merge." -msgstr "" - -#: notes-merge.c:283 -#, c-format -msgid "You have not concluded your notes merge (%s exists)." -msgstr "" - -#: notes-utils.c:46 -msgid "Cannot commit uninitialized/unreferenced notes tree" -msgstr "" - -#: notes-utils.c:105 -#, c-format -msgid "Bad notes.rewriteMode value: '%s'" -msgstr "" - -#: notes-utils.c:115 -#, c-format -msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" -msgstr "" - -#. TRANSLATORS: The first %s is the name of -#. the environment variable, the second %s is -#. its value. -#. -#: notes-utils.c:145 -#, c-format -msgid "Bad %s value: '%s'" -msgstr "" - -#: object-file.c:457 -#, c-format -msgid "object directory %s does not exist; check .git/objects/info/alternates" -msgstr "" - -#: object-file.c:515 -#, c-format -msgid "unable to normalize alternate object path: %s" -msgstr "" - -#: object-file.c:589 -#, c-format -msgid "%s: ignoring alternate object stores, nesting too deep" -msgstr "" - -#: object-file.c:596 -#, c-format -msgid "unable to normalize object directory: %s" -msgstr "" - -#: object-file.c:639 -msgid "unable to fdopen alternates lockfile" -msgstr "" - -#: object-file.c:657 -msgid "unable to read alternates file" -msgstr "" - -#: object-file.c:664 -msgid "unable to move new alternates file into place" -msgstr "" - -#: object-file.c:742 -#, c-format -msgid "path '%s' does not exist" -msgstr "" - -#: object-file.c:763 -#, c-format -msgid "reference repository '%s' as a linked checkout is not supported yet." -msgstr "" - -#: object-file.c:769 -#, c-format -msgid "reference repository '%s' is not a local repository." -msgstr "" - -#: object-file.c:775 -#, c-format -msgid "reference repository '%s' is shallow" -msgstr "" - -#: object-file.c:783 -#, c-format -msgid "reference repository '%s' is grafted" -msgstr "" - -#: object-file.c:814 -#, c-format -msgid "could not find object directory matching %s" -msgstr "" - -#: object-file.c:864 -#, c-format -msgid "invalid line while parsing alternate refs: %s" -msgstr "" - -#: object-file.c:1014 -#, c-format -msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" -msgstr "" - -#: object-file.c:1049 -#, c-format -msgid "mmap failed%s" -msgstr "" - -#: object-file.c:1230 -#, c-format -msgid "object file %s is empty" -msgstr "" - -#: object-file.c:1349 object-file.c:2588 -#, c-format -msgid "corrupt loose object '%s'" -msgstr "" - -#: object-file.c:1351 object-file.c:2592 -#, c-format -msgid "garbage at end of loose object '%s'" -msgstr "" - -#: object-file.c:1473 -#, c-format -msgid "unable to parse %s header" -msgstr "" - -#: object-file.c:1475 -msgid "invalid object type" -msgstr "" - -#: object-file.c:1486 -#, c-format -msgid "unable to unpack %s header" -msgstr "" - -#: object-file.c:1490 -#, c-format -msgid "header for %s too long, exceeds %d bytes" -msgstr "" - -#: object-file.c:1720 -#, c-format -msgid "failed to read object %s" -msgstr "" - -#: object-file.c:1724 -#, c-format -msgid "replacement %s not found for %s" -msgstr "" - -#: object-file.c:1728 -#, c-format -msgid "loose object %s (stored in %s) is corrupt" -msgstr "" - -#: object-file.c:1732 -#, c-format -msgid "packed object %s (stored in %s) is corrupt" -msgstr "" - -#: object-file.c:1855 -#, c-format -msgid "unable to write file %s" -msgstr "" - -#: object-file.c:1862 -#, c-format -msgid "unable to set permission to '%s'" -msgstr "" - -#: object-file.c:1869 -msgid "file write error" -msgstr "" - -#: object-file.c:1904 -msgid "error when closing loose object file" -msgstr "" - -#: object-file.c:1971 -#, c-format -msgid "insufficient permission for adding an object to repository database %s" -msgstr "" - -#: object-file.c:1973 -msgid "unable to create temporary file" -msgstr "" - -#: object-file.c:1997 -msgid "unable to write loose object file" -msgstr "" - -#: object-file.c:2003 -#, c-format -msgid "unable to deflate new object %s (%d)" -msgstr "" - -#: object-file.c:2007 -#, c-format -msgid "deflateEnd on object %s failed (%d)" -msgstr "" - -#: object-file.c:2011 -#, c-format -msgid "confused by unstable object source data for %s" -msgstr "" - -#: object-file.c:2022 builtin/pack-objects.c:1251 -#, c-format -msgid "failed utime() on %s" -msgstr "" - -#: object-file.c:2100 -#, c-format -msgid "cannot read object for %s" -msgstr "" - -#: object-file.c:2151 -msgid "corrupt commit" -msgstr "" - -#: object-file.c:2159 -msgid "corrupt tag" -msgstr "" - -#: object-file.c:2259 -#, c-format -msgid "read error while indexing %s" -msgstr "" - -#: object-file.c:2262 -#, c-format -msgid "short read while indexing %s" -msgstr "" - -#: object-file.c:2335 object-file.c:2345 -#, c-format -msgid "%s: failed to insert into database" -msgstr "" - -#: object-file.c:2351 -#, c-format -msgid "%s: unsupported file type" -msgstr "" - -#: object-file.c:2375 builtin/fetch.c:1494 -#, c-format -msgid "%s is not a valid object" -msgstr "" - -#: object-file.c:2377 -#, c-format -msgid "%s is not a valid '%s' object" -msgstr "" - -#: object-file.c:2404 -#, c-format -msgid "unable to open %s" -msgstr "" - -#: object-file.c:2599 -#, c-format -msgid "hash mismatch for %s (expected %s)" -msgstr "" - -#: object-file.c:2622 -#, c-format -msgid "unable to mmap %s" -msgstr "" - -#: object-file.c:2628 -#, c-format -msgid "unable to unpack header of %s" -msgstr "" - -#: object-file.c:2633 -#, c-format -msgid "unable to parse header of %s" -msgstr "" - -#: object-file.c:2644 -#, c-format -msgid "unable to unpack contents of %s" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous object -#. output shown when we cannot look up or parse the -#. object in question. E.g. "deadbeef [bad object]". -#. -#: object-name.c:382 -#, c-format -msgid "%s [bad object]" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous commit -#. object output. E.g.: -#. * -#. "deadbeef commit 2021-01-01 - Some Commit Message" -#. -#: object-name.c:407 -#, c-format -msgid "%s commit %s - %s" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous -#. tag object output. E.g.: -#. * -#. "deadbeef tag 2022-01-01 - Some Tag Message" -#. * -#. The second argument is the YYYY-MM-DD found -#. in the tag. -#. * -#. The third argument is the "tag" string -#. from object.c. -#. -#: object-name.c:428 -#, c-format -msgid "%s tag %s - %s" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous -#. tag object output where we couldn't parse -#. the tag itself. E.g.: -#. * -#. "deadbeef [bad tag, could not parse it]" -#. -#: object-name.c:439 -#, c-format -msgid "%s [bad tag, could not parse it]" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous <type> -#. object output. E.g. "deadbeef tree". -#. -#: object-name.c:447 -#, c-format -msgid "%s tree" -msgstr "" - -#. TRANSLATORS: This is a line of ambiguous <type> -#. object output. E.g. "deadbeef blob". -#. -#: object-name.c:453 -#, c-format -msgid "%s blob" -msgstr "" - -#: object-name.c:569 -#, c-format -msgid "short object ID %s is ambiguous" -msgstr "" - -#. TRANSLATORS: The argument is the list of ambiguous -#. objects composed in show_ambiguous_object(). See -#. its "TRANSLATORS" comments for details. -#. -#: object-name.c:591 -#, c-format -msgid "" -"The candidates are:\n" -"%s" -msgstr "" - -#: object-name.c:888 -msgid "" -"Git normally never creates a ref that ends with 40 hex characters\n" -"because it will be ignored when you just specify 40-hex. These refs\n" -"may be created by mistake. For example,\n" -"\n" -" git switch -c $br $(git rev-parse ...)\n" -"\n" -"where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" -"examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" -msgstr "" - -#: object-name.c:1008 -#, c-format -msgid "log for '%.*s' only goes back to %s" -msgstr "" - -#: object-name.c:1016 -#, c-format -msgid "log for '%.*s' only has %d entries" -msgstr "" - -#: object-name.c:1794 -#, c-format -msgid "path '%s' exists on disk, but not in '%.*s'" -msgstr "" - -#: object-name.c:1800 -#, c-format -msgid "" -"path '%s' exists, but not '%s'\n" -"hint: Did you mean '%.*s:%s' aka '%.*s:./%s'?" -msgstr "" - -#: object-name.c:1809 -#, c-format -msgid "path '%s' does not exist in '%.*s'" -msgstr "" - -#: object-name.c:1837 -#, c-format -msgid "" -"path '%s' is in the index, but not at stage %d\n" -"hint: Did you mean ':%d:%s'?" -msgstr "" - -#: object-name.c:1853 -#, c-format -msgid "" -"path '%s' is in the index, but not '%s'\n" -"hint: Did you mean ':%d:%s' aka ':%d:./%s'?" -msgstr "" - -#: object-name.c:1861 -#, c-format -msgid "path '%s' exists on disk, but not in the index" -msgstr "" - -#: object-name.c:1863 -#, c-format -msgid "path '%s' does not exist (neither on disk nor in the index)" -msgstr "" - -#: object-name.c:1876 -msgid "relative path syntax can't be used outside working tree" -msgstr "" - -#: object-name.c:1901 -#, c-format -msgid "<object>:<path> required, only <object> '%s' given" -msgstr "" - -#: object-name.c:2014 -#, c-format -msgid "invalid object name '%.*s'." -msgstr "" - -#: object.c:53 -#, c-format -msgid "invalid object type \"%s\"" -msgstr "" - -#: object.c:173 -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "" - -#: object.c:250 -#, c-format -msgid "object %s has unknown type id %d" -msgstr "" - -#: object.c:263 -#, c-format -msgid "unable to parse object: %s" -msgstr "" - -#: object.c:283 object.c:294 -#, c-format -msgid "hash mismatch %s" -msgstr "" - -#: pack-bitmap.c:353 -msgid "multi-pack bitmap is missing required reverse index" -msgstr "" - -#: pack-bitmap.c:433 -msgid "load_reverse_index: could not open pack" -msgstr "" - -#: pack-bitmap.c:1072 pack-bitmap.c:1078 builtin/pack-objects.c:2432 -#, c-format -msgid "unable to get size of %s" -msgstr "" - -#: pack-bitmap.c:1937 -#, c-format -msgid "could not find %s in pack %s at offset %<PRIuMAX>" -msgstr "" - -#: pack-bitmap.c:1973 builtin/rev-list.c:91 -#, c-format -msgid "unable to get disk usage of %s" -msgstr "" - -#: pack-revindex.c:221 -#, c-format -msgid "reverse-index file %s is too small" -msgstr "" - -#: pack-revindex.c:226 -#, c-format -msgid "reverse-index file %s is corrupt" -msgstr "" - -#: pack-revindex.c:234 -#, c-format -msgid "reverse-index file %s has unknown signature" -msgstr "" - -#: pack-revindex.c:238 -#, c-format -msgid "reverse-index file %s has unsupported version %<PRIu32>" -msgstr "" - -#: pack-revindex.c:243 -#, c-format -msgid "reverse-index file %s has unsupported hash id %<PRIu32>" -msgstr "" - -#: pack-write.c:251 -msgid "cannot both write and verify reverse index" -msgstr "" - -#: pack-write.c:270 -#, c-format -msgid "could not stat: %s" -msgstr "" - -#: pack-write.c:282 -#, c-format -msgid "failed to make %s readable" -msgstr "" - -#: pack-write.c:521 -#, c-format -msgid "could not write '%s' promisor file" -msgstr "" - -#: packfile.c:627 -msgid "offset before end of packfile (broken .idx?)" -msgstr "" - -#: packfile.c:657 -#, c-format -msgid "packfile %s cannot be mapped%s" -msgstr "" - -#: packfile.c:1924 -#, c-format -msgid "offset before start of pack index for %s (corrupt index?)" -msgstr "" - -#: packfile.c:1928 -#, c-format -msgid "offset beyond end of pack index for %s (truncated index?)" -msgstr "" - -#: parse-options-cb.c:21 parse-options-cb.c:25 builtin/commit-graph.c:175 -#, c-format -msgid "option `%s' expects a numerical value" -msgstr "" - -#: parse-options-cb.c:42 -#, c-format -msgid "malformed expiration date '%s'" -msgstr "" - -#: parse-options-cb.c:55 -#, c-format -msgid "option `%s' expects \"always\", \"auto\", or \"never\"" -msgstr "" - -#: parse-options-cb.c:133 parse-options-cb.c:150 -#, c-format -msgid "malformed object name '%s'" -msgstr "" - -#: parse-options-cb.c:307 -#, c-format -msgid "option `%s' expects \"%s\" or \"%s\"" -msgstr "" - -#: parse-options.c:58 -#, c-format -msgid "%s requires a value" -msgstr "" - -#: parse-options.c:93 -#, c-format -msgid "%s is incompatible with %s" -msgstr "" - -#: parse-options.c:98 -#, c-format -msgid "%s : incompatible with something else" -msgstr "" - -#: parse-options.c:112 parse-options.c:116 -#, c-format -msgid "%s takes no value" -msgstr "" - -#: parse-options.c:114 -#, c-format -msgid "%s isn't available" -msgstr "" - -#: parse-options.c:237 -#, c-format -msgid "%s expects a non-negative integer value with an optional k/m/g suffix" -msgstr "" - -#: parse-options.c:393 -#, c-format -msgid "ambiguous option: %s (could be --%s%s or --%s%s)" -msgstr "" - -#: parse-options.c:428 parse-options.c:436 -#, c-format -msgid "did you mean `--%s` (with two dashes)?" -msgstr "" - -#: parse-options.c:678 parse-options.c:1054 -#, c-format -msgid "alias of --%s" -msgstr "" - -#: parse-options.c:892 -#, c-format -msgid "unknown option `%s'" -msgstr "" - -#: parse-options.c:894 -#, c-format -msgid "unknown switch `%c'" -msgstr "" - -#: parse-options.c:896 -#, c-format -msgid "unknown non-ascii option in string: `%s'" -msgstr "" - -#: parse-options.c:920 -msgid "..." -msgstr "" - -#: parse-options.c:934 -#, c-format -msgid "usage: %s" -msgstr "" - -#. TRANSLATORS: the colon here should align with the -#. one in "usage: %s" translation. -#. -#: parse-options.c:949 -#, c-format -msgid " or: %s" -msgstr "" - -#. TRANSLATORS: You should only need to translate this format -#. string if your language is a RTL language (e.g. Arabic, -#. Hebrew etc.), not if it's a LTR language (e.g. German, -#. Russian, Chinese etc.). -#. * -#. When a translated usage string has an embedded "\n" it's -#. because options have wrapped to the next line. The line -#. after the "\n" will then be padded to align with the -#. command name, such as N_("git cmd [opt]\n<8 -#. spaces>[opt2]"), where the 8 spaces are the same length as -#. "git cmd ". -#. * -#. This format string prints out that already-translated -#. line. The "%*s" is whitespace padding to account for the -#. padding at the start of the line that we add in this -#. function. The "%s" is a line in the (hopefully already -#. translated) N_() usage string, which contained embedded -#. newlines before we split it up. -#. -#: parse-options.c:970 -#, c-format -msgid "%*s%s" -msgstr "" - -#: parse-options.c:993 -#, c-format -msgid " %s" -msgstr "" - -#: parse-options.c:1040 -msgid "-NUM" -msgstr "" - -#: path.c:922 -#, c-format -msgid "Could not make %s writable by group" -msgstr "" - -#: pathspec.c:150 -msgid "Escape character '\\' not allowed as last character in attr value" -msgstr "" - -#: pathspec.c:168 -msgid "Only one 'attr:' specification is allowed." -msgstr "" - -#: pathspec.c:171 -msgid "attr spec must not be empty" -msgstr "" - -#: pathspec.c:214 -#, c-format -msgid "invalid attribute name %s" -msgstr "" - -#: pathspec.c:279 -msgid "global 'glob' and 'noglob' pathspec settings are incompatible" -msgstr "" - -#: pathspec.c:286 -msgid "" -"global 'literal' pathspec setting is incompatible with all other global " -"pathspec settings" -msgstr "" - -#: pathspec.c:326 -msgid "invalid parameter for pathspec magic 'prefix'" -msgstr "" - -#: pathspec.c:347 -#, c-format -msgid "Invalid pathspec magic '%.*s' in '%s'" -msgstr "" - -#: pathspec.c:352 -#, c-format -msgid "Missing ')' at the end of pathspec magic in '%s'" -msgstr "" - -#: pathspec.c:390 -#, c-format -msgid "Unimplemented pathspec magic '%c' in '%s'" -msgstr "" - -#: pathspec.c:449 -#, c-format -msgid "%s: 'literal' and 'glob' are incompatible" -msgstr "" - -#: pathspec.c:465 -#, c-format -msgid "%s: '%s' is outside repository at '%s'" -msgstr "" - -#: pathspec.c:541 -#, c-format -msgid "'%s' (mnemonic: '%c')" -msgstr "" - -#: pathspec.c:551 -#, c-format -msgid "%s: pathspec magic not supported by this command: %s" -msgstr "" - -#: pathspec.c:618 -#, c-format -msgid "pathspec '%s' is beyond a symbolic link" -msgstr "" - -#: pathspec.c:663 -#, c-format -msgid "line is badly quoted: %s" -msgstr "" - -#: pkt-line.c:92 -msgid "unable to write flush packet" -msgstr "" - -#: pkt-line.c:99 -msgid "unable to write delim packet" -msgstr "" - -#: pkt-line.c:106 -msgid "unable to write response end packet" -msgstr "" - -#: pkt-line.c:113 -msgid "flush packet write failed" -msgstr "" - -#: pkt-line.c:153 -msgid "protocol error: impossibly long line" -msgstr "" - -#: pkt-line.c:169 pkt-line.c:171 -msgid "packet write with format failed" -msgstr "" - -#: pkt-line.c:204 pkt-line.c:252 -msgid "packet write failed - data exceeds max packet size" -msgstr "" - -#: pkt-line.c:222 -#, c-format -msgid "packet write failed: %s" -msgstr "" - -#: pkt-line.c:349 pkt-line.c:350 -msgid "read error" -msgstr "" - -#: pkt-line.c:360 pkt-line.c:361 -msgid "the remote end hung up unexpectedly" -msgstr "" - -#: pkt-line.c:417 pkt-line.c:419 -#, c-format -msgid "protocol error: bad line length character: %.4s" -msgstr "" - -#: pkt-line.c:434 pkt-line.c:436 pkt-line.c:442 pkt-line.c:444 -#, c-format -msgid "protocol error: bad line length %d" -msgstr "" - -#: pkt-line.c:472 sideband.c:165 -#, c-format -msgid "remote error: %s" -msgstr "" - -#: preload-index.c:125 -msgid "Refreshing index" -msgstr "" - -#: preload-index.c:144 -#, c-format -msgid "unable to create threaded lstat: %s" -msgstr "" - -#: pretty.c:1051 -msgid "unable to parse --pretty format" -msgstr "" - -#: promisor-remote.c:31 -msgid "promisor-remote: unable to fork off fetch subprocess" -msgstr "" - -#: promisor-remote.c:38 promisor-remote.c:40 -msgid "promisor-remote: could not write to fetch subprocess" -msgstr "" - -#: promisor-remote.c:44 -msgid "promisor-remote: could not close stdin to fetch subprocess" -msgstr "" - -#: promisor-remote.c:54 -#, c-format -msgid "promisor remote name cannot begin with '/': %s" -msgstr "" - -#: protocol-caps.c:103 -msgid "object-info: expected flush after arguments" -msgstr "" - -#: prune-packed.c:35 -msgid "Removing duplicate objects" -msgstr "" - -#: range-diff.c:68 -msgid "could not start `log`" -msgstr "" - -#: range-diff.c:70 -msgid "could not read `log` output" -msgstr "" - -#: range-diff.c:98 sequencer.c:5575 -#, c-format -msgid "could not parse commit '%s'" -msgstr "" - -#: range-diff.c:109 -#, c-format -msgid "" -"could not parse first line of `log` output: did not start with 'commit ': " -"'%s'" -msgstr "" - -#: range-diff.c:132 -#, c-format -msgid "could not parse git header '%.*s'" -msgstr "" - -#: range-diff.c:300 -msgid "failed to generate diff" -msgstr "" - -#: range-diff.c:558 range-diff.c:560 -#, c-format -msgid "could not parse log for '%s'" -msgstr "" - -#: read-cache.c:737 -#, c-format -msgid "will not add file alias '%s' ('%s' already exists in index)" -msgstr "" - -#: read-cache.c:753 -msgid "cannot create an empty blob in the object database" -msgstr "" - -#: read-cache.c:775 -#, c-format -msgid "%s: can only add regular files, symbolic links or git-directories" -msgstr "" - -#: read-cache.c:780 builtin/submodule--helper.c:3359 -#, c-format -msgid "'%s' does not have a commit checked out" -msgstr "" - -#: read-cache.c:832 -#, c-format -msgid "unable to index file '%s'" -msgstr "" - -#: read-cache.c:851 -#, c-format -msgid "unable to add '%s' to index" -msgstr "" - -#: read-cache.c:862 -#, c-format -msgid "unable to stat '%s'" -msgstr "" - -#: read-cache.c:1404 -#, c-format -msgid "'%s' appears as both a file and as a directory" -msgstr "" - -#: read-cache.c:1619 -msgid "Refresh index" -msgstr "" - -#: read-cache.c:1751 -#, c-format -msgid "" -"index.version set, but the value is invalid.\n" -"Using version %i" -msgstr "" - -#: read-cache.c:1761 -#, c-format -msgid "" -"GIT_INDEX_VERSION set, but the value is invalid.\n" -"Using version %i" -msgstr "" - -#: read-cache.c:1817 -#, c-format -msgid "bad signature 0x%08x" -msgstr "" - -#: read-cache.c:1820 -#, c-format -msgid "bad index version %d" -msgstr "" - -#: read-cache.c:1829 -msgid "bad index file sha1 signature" -msgstr "" - -#: read-cache.c:1863 -#, c-format -msgid "index uses %.4s extension, which we do not understand" -msgstr "" - -#: read-cache.c:1865 -#, c-format -msgid "ignoring %.4s extension" -msgstr "" - -#: read-cache.c:1902 -#, c-format -msgid "unknown index entry format 0x%08x" -msgstr "" - -#: read-cache.c:1918 -#, c-format -msgid "malformed name field in the index, near path '%s'" -msgstr "" - -#: read-cache.c:1975 -msgid "unordered stage entries in index" -msgstr "" - -#: read-cache.c:1978 -#, c-format -msgid "multiple stage entries for merged file '%s'" -msgstr "" - -#: read-cache.c:1981 -#, c-format -msgid "unordered stage entries for '%s'" -msgstr "" - -#: read-cache.c:2096 read-cache.c:2402 rerere.c:549 rerere.c:583 rerere.c:1096 -#: submodule.c:1831 builtin/add.c:586 builtin/check-ignore.c:183 -#: builtin/checkout.c:532 builtin/checkout.c:724 builtin/clean.c:1016 -#: builtin/commit.c:379 builtin/diff-tree.c:122 builtin/grep.c:521 -#: builtin/mv.c:148 builtin/reset.c:506 builtin/rm.c:293 -#: builtin/submodule--helper.c:335 builtin/submodule--helper.c:3319 -msgid "index file corrupt" -msgstr "" - -#: read-cache.c:2240 -#, c-format -msgid "unable to create load_cache_entries thread: %s" -msgstr "" - -#: read-cache.c:2253 -#, c-format -msgid "unable to join load_cache_entries thread: %s" -msgstr "" - -#: read-cache.c:2286 -#, c-format -msgid "%s: index file open failed" -msgstr "" - -#: read-cache.c:2290 -#, c-format -msgid "%s: cannot stat the open index" -msgstr "" - -#: read-cache.c:2294 -#, c-format -msgid "%s: index file smaller than expected" -msgstr "" - -#: read-cache.c:2298 -#, c-format -msgid "%s: unable to map index file%s" -msgstr "" - -#: read-cache.c:2341 -#, c-format -msgid "unable to create load_index_extensions thread: %s" -msgstr "" - -#: read-cache.c:2368 -#, c-format -msgid "unable to join load_index_extensions thread: %s" -msgstr "" - -#: read-cache.c:2414 -#, c-format -msgid "could not freshen shared index '%s'" -msgstr "" - -#: read-cache.c:2473 -#, c-format -msgid "broken index, expect %s in %s, got %s" -msgstr "" - -#: read-cache.c:3032 -msgid "cannot write split index for a sparse index" -msgstr "" - -#: read-cache.c:3114 strbuf.c:1192 wrapper.c:717 builtin/merge.c:1156 -#, c-format -msgid "could not close '%s'" -msgstr "" - -#: read-cache.c:3157 -msgid "failed to convert to a sparse-index" -msgstr "" - -#: read-cache.c:3228 -#, c-format -msgid "could not stat '%s'" -msgstr "" - -#: read-cache.c:3241 -#, c-format -msgid "unable to open git dir: %s" -msgstr "" - -#: read-cache.c:3253 -#, c-format -msgid "unable to unlink: %s" -msgstr "" - -#: read-cache.c:3282 -#, c-format -msgid "cannot fix permission bits on '%s'" -msgstr "" - -#: read-cache.c:3439 -#, c-format -msgid "%s: cannot drop to stage #0" -msgstr "" - -#: rebase-interactive.c:11 -msgid "" -"You can fix this with 'git rebase --edit-todo' and then run 'git rebase --" -"continue'.\n" -"Or you can abort the rebase with 'git rebase --abort'.\n" -msgstr "" - -#: rebase-interactive.c:33 -#, c-format -msgid "" -"unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring." -msgstr "" - -#: rebase-interactive.c:42 -msgid "" -"\n" -"Commands:\n" -"p, pick <commit> = use commit\n" -"r, reword <commit> = use commit, but edit the commit message\n" -"e, edit <commit> = use commit, but stop for amending\n" -"s, squash <commit> = use commit, but meld into previous commit\n" -"f, fixup [-C | -c] <commit> = like \"squash\" but keep only the previous\n" -" commit's log message, unless -C is used, in which case\n" -" keep only this commit's message; -c is same as -C but\n" -" opens the editor\n" -"x, exec <command> = run command (the rest of the line) using shell\n" -"b, break = stop here (continue rebase later with 'git rebase --continue')\n" -"d, drop <commit> = remove commit\n" -"l, label <label> = label current HEAD with a name\n" -"t, reset <label> = reset HEAD to a label\n" -"m, merge [-C <commit> | -c <commit>] <label> [# <oneline>]\n" -". create a merge commit using the original merge commit's\n" -". message (or the oneline, if no original merge commit was\n" -". specified); use -c <commit> to reword the commit message\n" -"\n" -"These lines can be re-ordered; they are executed from top to bottom.\n" -msgstr "" - -#: rebase-interactive.c:66 -#, c-format -msgid "Rebase %s onto %s (%d command)" -msgid_plural "Rebase %s onto %s (%d commands)" -msgstr[0] "" -msgstr[1] "" - -#: rebase-interactive.c:75 -msgid "" -"\n" -"Do not remove any line. Use 'drop' explicitly to remove a commit.\n" -msgstr "" - -#: rebase-interactive.c:78 -msgid "" -"\n" -"If you remove a line here THAT COMMIT WILL BE LOST.\n" -msgstr "" - -#: rebase-interactive.c:84 -msgid "" -"\n" -"You are editing the todo file of an ongoing interactive rebase.\n" -"To continue rebase after editing, run:\n" -" git rebase --continue\n" -"\n" -msgstr "" - -#: rebase-interactive.c:89 -msgid "" -"\n" -"However, if you remove everything, the rebase will be aborted.\n" -"\n" -msgstr "" - -#: rebase-interactive.c:113 rerere.c:469 rerere.c:677 sequencer.c:3879 -#: sequencer.c:3905 sequencer.c:5681 builtin/fsck.c:328 builtin/gc.c:1791 -#: builtin/rebase.c:191 -#, c-format -msgid "could not write '%s'" -msgstr "" - -#: rebase-interactive.c:119 -#, c-format -msgid "could not write '%s'." -msgstr "" - -#: rebase-interactive.c:196 -#, c-format -msgid "" -"Warning: some commits may have been dropped accidentally.\n" -"Dropped commits (newer to older):\n" -msgstr "" - -#: rebase-interactive.c:203 -#, c-format -msgid "" -"To avoid this message, use \"drop\" to explicitly remove a commit.\n" -"\n" -"Use 'git config rebase.missingCommitsCheck' to change the level of " -"warnings.\n" -"The possible behaviours are: ignore, warn, error.\n" -"\n" -msgstr "" - -#: rebase.c:29 -#, c-format -msgid "%s: 'preserve' superseded by 'merges'" -msgstr "" - -#: ref-filter.c:42 wt-status.c:2057 -msgid "gone" -msgstr "" - -#: ref-filter.c:43 -#, c-format -msgid "ahead %d" -msgstr "" - -#: ref-filter.c:44 -#, c-format -msgid "behind %d" -msgstr "" - -#: ref-filter.c:45 -#, c-format -msgid "ahead %d, behind %d" -msgstr "" - -#: ref-filter.c:235 -#, c-format -msgid "expected format: %%(color:<color>)" -msgstr "" - -#: ref-filter.c:237 -#, c-format -msgid "unrecognized color: %%(color:%s)" -msgstr "" - -#: ref-filter.c:259 -#, c-format -msgid "Integer value expected refname:lstrip=%s" -msgstr "" - -#: ref-filter.c:263 -#, c-format -msgid "Integer value expected refname:rstrip=%s" -msgstr "" - -#: ref-filter.c:265 ref-filter.c:344 ref-filter.c:377 ref-filter.c:431 -#: ref-filter.c:443 ref-filter.c:462 ref-filter.c:534 ref-filter.c:560 -#, c-format -msgid "unrecognized %%(%s) argument: %s" -msgstr "" - -#: ref-filter.c:320 -#, c-format -msgid "%%(objecttype) does not take arguments" -msgstr "" - -#: ref-filter.c:352 -#, c-format -msgid "%%(deltabase) does not take arguments" -msgstr "" - -#: ref-filter.c:364 -#, c-format -msgid "%%(body) does not take arguments" -msgstr "" - -#: ref-filter.c:396 -#, c-format -msgid "expected %%(trailers:key=<value>)" -msgstr "" - -#: ref-filter.c:398 -#, c-format -msgid "unknown %%(trailers) argument: %s" -msgstr "" - -#: ref-filter.c:429 -#, c-format -msgid "positive value expected contents:lines=%s" -msgstr "" - -#: ref-filter.c:458 -#, c-format -msgid "positive value expected '%s' in %%(%s)" -msgstr "" - -#: ref-filter.c:476 -#, c-format -msgid "unrecognized email option: %s" -msgstr "" - -#: ref-filter.c:506 -#, c-format -msgid "expected format: %%(align:<width>,<position>)" -msgstr "" - -#: ref-filter.c:518 -#, c-format -msgid "unrecognized position:%s" -msgstr "" - -#: ref-filter.c:525 -#, c-format -msgid "unrecognized width:%s" -msgstr "" - -#: ref-filter.c:542 -#, c-format -msgid "positive width expected with the %%(align) atom" -msgstr "" - -#: ref-filter.c:568 -#, c-format -msgid "%%(rest) does not take arguments" -msgstr "" - -#: ref-filter.c:680 -#, c-format -msgid "malformed field name: %.*s" -msgstr "" - -#: ref-filter.c:707 -#, c-format -msgid "unknown field name: %.*s" -msgstr "" - -#: ref-filter.c:711 -#, c-format -msgid "" -"not a git repository, but the field '%.*s' requires access to object data" -msgstr "" - -#: ref-filter.c:844 ref-filter.c:910 ref-filter.c:946 ref-filter.c:948 -#, c-format -msgid "format: %%(%s) atom used without a %%(%s) atom" -msgstr "" - -#: ref-filter.c:912 -#, c-format -msgid "format: %%(then) atom used more than once" -msgstr "" - -#: ref-filter.c:914 -#, c-format -msgid "format: %%(then) atom used after %%(else)" -msgstr "" - -#: ref-filter.c:950 -#, c-format -msgid "format: %%(else) atom used more than once" -msgstr "" - -#: ref-filter.c:965 -#, c-format -msgid "format: %%(end) atom used without corresponding atom" -msgstr "" - -#: ref-filter.c:1027 -#, c-format -msgid "malformed format string %s" -msgstr "" - -#: ref-filter.c:1033 -#, c-format -msgid "this command reject atom %%(%.*s)" -msgstr "" - -#: ref-filter.c:1040 -#, c-format -msgid "--format=%.*s cannot be used with --python, --shell, --tcl" -msgstr "" - -#: ref-filter.c:1707 -#, c-format -msgid "(no branch, rebasing %s)" -msgstr "" - -#: ref-filter.c:1710 -#, c-format -msgid "(no branch, rebasing detached HEAD %s)" -msgstr "" - -#: ref-filter.c:1713 -#, c-format -msgid "(no branch, bisect started on %s)" -msgstr "" - -#: ref-filter.c:1717 -#, c-format -msgid "(HEAD detached at %s)" -msgstr "" - -#: ref-filter.c:1720 -#, c-format -msgid "(HEAD detached from %s)" -msgstr "" - -#: ref-filter.c:1723 -msgid "(no branch)" -msgstr "" - -#: ref-filter.c:1755 ref-filter.c:1973 -#, c-format -msgid "missing object %s for %s" -msgstr "" - -#: ref-filter.c:1765 -#, c-format -msgid "parse_object_buffer failed on %s for %s" -msgstr "" - -#: ref-filter.c:2156 -#, c-format -msgid "malformed object at '%s'" -msgstr "" - -#: ref-filter.c:2246 -#, c-format -msgid "ignoring ref with broken name %s" -msgstr "" - -#: ref-filter.c:2251 refs.c:672 -#, c-format -msgid "ignoring broken ref %s" -msgstr "" - -#: ref-filter.c:2630 -#, c-format -msgid "format: %%(end) atom missing" -msgstr "" - -#: ref-filter.c:2741 -#, c-format -msgid "malformed object name %s" -msgstr "" - -#: ref-filter.c:2746 -#, c-format -msgid "option `%s' must point to a commit" -msgstr "" - -#: reflog.c:407 -#, c-format -msgid "not a reflog: %s" -msgstr "" - -#: reflog.c:410 -#, c-format -msgid "no reflog for '%s'" -msgstr "" - -#: refs.c:262 -#, c-format -msgid "%s does not point to a valid object!" -msgstr "" - -#: refs.c:561 -#, c-format -msgid "" -"Using '%s' as the name for the initial branch. This default branch name\n" -"is subject to change. To configure the initial branch name to use in all\n" -"of your new repositories, which will suppress this warning, call:\n" -"\n" -"\tgit config --global init.defaultBranch <name>\n" -"\n" -"Names commonly chosen instead of 'master' are 'main', 'trunk' and\n" -"'development'. The just-created branch can be renamed via this command:\n" -"\n" -"\tgit branch -m <name>\n" -msgstr "" - -#: refs.c:583 -#, c-format -msgid "could not retrieve `%s`" -msgstr "" - -#: refs.c:593 -#, c-format -msgid "invalid branch name: %s = %s" -msgstr "" - -#: refs.c:670 -#, c-format -msgid "ignoring dangling symref %s" -msgstr "" - -#: refs.c:919 -#, c-format -msgid "log for ref %s has gap after %s" -msgstr "" - -#: refs.c:926 -#, c-format -msgid "log for ref %s unexpectedly ended on %s" -msgstr "" - -#: refs.c:991 -#, c-format -msgid "log for %s is empty" -msgstr "" - -#: refs.c:1086 -#, c-format -msgid "refusing to update ref with bad name '%s'" -msgstr "" - -#: refs.c:1164 -#, c-format -msgid "update_ref failed for ref '%s': %s" -msgstr "" - -#: refs.c:2059 -#, c-format -msgid "multiple updates for ref '%s' not allowed" -msgstr "" - -#: refs.c:2145 -msgid "ref updates forbidden inside quarantine environment" -msgstr "" - -#: refs.c:2156 -msgid "ref updates aborted by hook" -msgstr "" - -#: refs.c:2264 refs.c:2294 -#, c-format -msgid "'%s' exists; cannot create '%s'" -msgstr "" - -#: refs.c:2270 refs.c:2305 -#, c-format -msgid "cannot process '%s' and '%s' at the same time" -msgstr "" - -#: refs/files-backend.c:1295 -#, c-format -msgid "could not remove reference %s" -msgstr "" - -#: refs/files-backend.c:1310 refs/packed-backend.c:1565 -#: refs/packed-backend.c:1575 -#, c-format -msgid "could not delete reference %s: %s" -msgstr "" - -#: refs/files-backend.c:1313 refs/packed-backend.c:1578 -#, c-format -msgid "could not delete references: %s" -msgstr "" - -#: refspec.c:170 -#, c-format -msgid "invalid refspec '%s'" -msgstr "" - -#: remote.c:402 -#, c-format -msgid "config remote shorthand cannot begin with '/': %s" -msgstr "" - -#: remote.c:450 -msgid "more than one receivepack given, using the first" -msgstr "" - -#: remote.c:458 -msgid "more than one uploadpack given, using the first" -msgstr "" - -#: remote.c:698 -#, c-format -msgid "Cannot fetch both %s and %s to %s" -msgstr "" - -#: remote.c:702 -#, c-format -msgid "%s usually tracks %s, not %s" -msgstr "" - -#: remote.c:706 -#, c-format -msgid "%s tracks both %s and %s" -msgstr "" - -#: remote.c:774 -#, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "" - -#: remote.c:784 -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "" - -#: remote.c:1191 -#, c-format -msgid "src refspec %s does not match any" -msgstr "" - -#: remote.c:1196 -#, c-format -msgid "src refspec %s matches more than one" -msgstr "" - -#. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push -#. <remote> <src>:<dst>" push, and "being pushed ('%s')" is -#. the <src>. -#. -#: remote.c:1211 -#, c-format -msgid "" -"The destination you provided is not a full refname (i.e.,\n" -"starting with \"refs/\"). We tried to guess what you meant by:\n" -"\n" -"- Looking for a ref that matches '%s' on the remote side.\n" -"- Checking if the <src> being pushed ('%s')\n" -" is a ref in \"refs/{heads,tags}/\". If so we add a corresponding\n" -" refs/{heads,tags}/ prefix on the remote side.\n" -"\n" -"Neither worked, so we gave up. You must fully qualify the ref." -msgstr "" - -#: remote.c:1231 -#, c-format -msgid "" -"The <src> part of the refspec is a commit object.\n" -"Did you mean to create a new branch by pushing to\n" -"'%s:refs/heads/%s'?" -msgstr "" - -#: remote.c:1236 -#, c-format -msgid "" -"The <src> part of the refspec is a tag object.\n" -"Did you mean to create a new tag by pushing to\n" -"'%s:refs/tags/%s'?" -msgstr "" - -#: remote.c:1241 -#, c-format -msgid "" -"The <src> part of the refspec is a tree object.\n" -"Did you mean to tag a new tree by pushing to\n" -"'%s:refs/tags/%s'?" -msgstr "" - -#: remote.c:1246 -#, c-format -msgid "" -"The <src> part of the refspec is a blob object.\n" -"Did you mean to tag a new blob by pushing to\n" -"'%s:refs/tags/%s'?" -msgstr "" - -#: remote.c:1282 -#, c-format -msgid "%s cannot be resolved to branch" -msgstr "" - -#: remote.c:1293 -#, c-format -msgid "unable to delete '%s': remote ref does not exist" -msgstr "" - -#: remote.c:1305 -#, c-format -msgid "dst refspec %s matches more than one" -msgstr "" - -#: remote.c:1312 -#, c-format -msgid "dst ref %s receives from more than one src" -msgstr "" - -#: remote.c:1833 remote.c:1940 -msgid "HEAD does not point to a branch" -msgstr "" - -#: remote.c:1842 -#, c-format -msgid "no such branch: '%s'" -msgstr "" - -#: remote.c:1845 -#, c-format -msgid "no upstream configured for branch '%s'" -msgstr "" - -#: remote.c:1851 -#, c-format -msgid "upstream branch '%s' not stored as a remote-tracking branch" -msgstr "" - -#: remote.c:1866 -#, c-format -msgid "push destination '%s' on remote '%s' has no local tracking branch" -msgstr "" - -#: remote.c:1881 -#, c-format -msgid "branch '%s' has no remote for pushing" -msgstr "" - -#: remote.c:1891 -#, c-format -msgid "push refspecs for '%s' do not include '%s'" -msgstr "" - -#: remote.c:1904 -msgid "push has no destination (push.default is 'nothing')" -msgstr "" - -#: remote.c:1926 -msgid "cannot resolve 'simple' push to a single destination" -msgstr "" - -#: remote.c:2059 -#, c-format -msgid "couldn't find remote ref %s" -msgstr "" - -#: remote.c:2072 -#, c-format -msgid "* Ignoring funny ref '%s' locally" -msgstr "" - -#: remote.c:2235 -#, c-format -msgid "Your branch is based on '%s', but the upstream is gone.\n" -msgstr "" - -#: remote.c:2239 -msgid " (use \"git branch --unset-upstream\" to fixup)\n" -msgstr "" - -#: remote.c:2242 -#, c-format -msgid "Your branch is up to date with '%s'.\n" -msgstr "" - -#: remote.c:2246 -#, c-format -msgid "Your branch and '%s' refer to different commits.\n" -msgstr "" - -#: remote.c:2249 -#, c-format -msgid " (use \"%s\" for details)\n" -msgstr "" - -#: remote.c:2253 -#, c-format -msgid "Your branch is ahead of '%s' by %d commit.\n" -msgid_plural "Your branch is ahead of '%s' by %d commits.\n" -msgstr[0] "" -msgstr[1] "" - -#: remote.c:2259 -msgid " (use \"git push\" to publish your local commits)\n" -msgstr "" - -#: remote.c:2262 -#, c-format -msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" -msgid_plural "" -"Your branch is behind '%s' by %d commits, and can be fast-forwarded.\n" -msgstr[0] "" -msgstr[1] "" - -#: remote.c:2270 -msgid " (use \"git pull\" to update your local branch)\n" -msgstr "" - -#: remote.c:2273 -#, c-format -msgid "" -"Your branch and '%s' have diverged,\n" -"and have %d and %d different commit each, respectively.\n" -msgid_plural "" -"Your branch and '%s' have diverged,\n" -"and have %d and %d different commits each, respectively.\n" -msgstr[0] "" -msgstr[1] "" - -#: remote.c:2283 -msgid " (use \"git pull\" to merge the remote branch into yours)\n" -msgstr "" - -#: remote.c:2475 -#, c-format -msgid "cannot parse expected object name '%s'" -msgstr "" - -#: replace-object.c:21 -#, c-format -msgid "bad replace ref name: %s" -msgstr "" - -#: replace-object.c:30 -#, c-format -msgid "duplicate replace ref: %s" -msgstr "" - -#: replace-object.c:82 -#, c-format -msgid "replace depth too high for object %s" -msgstr "" - -#: rerere.c:201 rerere.c:210 rerere.c:213 -msgid "corrupt MERGE_RR" -msgstr "" - -#: rerere.c:248 rerere.c:253 -msgid "unable to write rerere record" -msgstr "" - -#: rerere.c:479 -#, c-format -msgid "there were errors while writing '%s' (%s)" -msgstr "" - -#: rerere.c:482 builtin/gc.c:2263 builtin/gc.c:2298 -#, c-format -msgid "failed to flush '%s'" -msgstr "" - -#: rerere.c:487 rerere.c:1024 -#, c-format -msgid "could not parse conflict hunks in '%s'" -msgstr "" - -#: rerere.c:669 -#, c-format -msgid "failed utime() on '%s'" -msgstr "" - -#: rerere.c:679 -#, c-format -msgid "writing '%s' failed" -msgstr "" - -#: rerere.c:699 -#, c-format -msgid "Staged '%s' using previous resolution." -msgstr "" - -#: rerere.c:738 -#, c-format -msgid "Recorded resolution for '%s'." -msgstr "" - -#: rerere.c:773 -#, c-format -msgid "Resolved '%s' using previous resolution." -msgstr "" - -#: rerere.c:788 -#, c-format -msgid "cannot unlink stray '%s'" -msgstr "" - -#: rerere.c:792 -#, c-format -msgid "Recorded preimage for '%s'" -msgstr "" - -#: rerere.c:866 submodule.c:2290 builtin/log.c:2042 -#: builtin/submodule--helper.c:1786 builtin/submodule--helper.c:1833 -#, c-format -msgid "could not create directory '%s'" -msgstr "" - -#: rerere.c:1042 -#, c-format -msgid "failed to update conflicted state in '%s'" -msgstr "" - -#: rerere.c:1053 rerere.c:1060 -#, c-format -msgid "no remembered resolution for '%s'" -msgstr "" - -#: rerere.c:1062 -#, c-format -msgid "cannot unlink '%s'" -msgstr "" - -#: rerere.c:1072 -#, c-format -msgid "Updated preimage for '%s'" -msgstr "" - -#: rerere.c:1081 -#, c-format -msgid "Forgot resolution for '%s'\n" -msgstr "" - -#: rerere.c:1192 -msgid "unable to open rr-cache directory" -msgstr "" - -#: reset.c:112 -msgid "could not determine HEAD revision" -msgstr "" - -#: reset.c:141 reset.c:147 sequencer.c:3696 -#, c-format -msgid "failed to find tree of %s" -msgstr "" - -#: revision.c:2358 -msgid "--unpacked=<packfile> no longer supported" -msgstr "" - -#: revision.c:2712 -msgid "your current branch appears to be broken" -msgstr "" - -#: revision.c:2715 -#, c-format -msgid "your current branch '%s' does not have any commits yet" -msgstr "" - -#: revision.c:2901 -msgid "object filtering requires --objects" -msgstr "" - -#: revision.c:2918 -msgid "-L does not yet support diff formats besides -p and -s" -msgstr "" - -#: run-command.c:1262 -#, c-format -msgid "cannot create async thread: %s" -msgstr "" - -#: send-pack.c:150 -msgid "unexpected flush packet while reading remote unpack status" -msgstr "" - -#: send-pack.c:152 -#, c-format -msgid "unable to parse remote unpack status: %s" -msgstr "" - -#: send-pack.c:154 -#, c-format -msgid "remote unpack failed: %s" -msgstr "" - -#: send-pack.c:378 -msgid "failed to sign the push certificate" -msgstr "" - -#: send-pack.c:435 -msgid "send-pack: unable to fork off fetch subprocess" -msgstr "" - -#: send-pack.c:457 -msgid "push negotiation failed; proceeding anyway with push" -msgstr "" - -#: send-pack.c:528 -msgid "the receiving end does not support this repository's hash algorithm" -msgstr "" - -#: send-pack.c:537 -msgid "the receiving end does not support --signed push" -msgstr "" - -#: send-pack.c:539 -msgid "" -"not sending a push certificate since the receiving end does not support --" -"signed push" -msgstr "" - -#: send-pack.c:546 -msgid "the receiving end does not support --atomic push" -msgstr "" - -#: send-pack.c:551 -msgid "the receiving end does not support push options" -msgstr "" - -#: sequencer.c:197 -#, c-format -msgid "invalid commit message cleanup mode '%s'" -msgstr "" - -#: sequencer.c:325 -#, c-format -msgid "could not delete '%s'" -msgstr "" - -#: sequencer.c:345 sequencer.c:4724 builtin/rebase.c:564 builtin/rebase.c:1326 -#: builtin/rm.c:409 -#, c-format -msgid "could not remove '%s'" -msgstr "" - -#: sequencer.c:355 -msgid "revert" -msgstr "" - -#: sequencer.c:357 -msgid "cherry-pick" -msgstr "" - -#: sequencer.c:359 -msgid "rebase" -msgstr "" - -#: sequencer.c:361 -#, c-format -msgid "unknown action: %d" -msgstr "" - -#: sequencer.c:420 -msgid "" -"after resolving the conflicts, mark the corrected paths\n" -"with 'git add <paths>' or 'git rm <paths>'" -msgstr "" - -#: sequencer.c:423 -msgid "" -"After resolving the conflicts, mark them with\n" -"\"git add/rm <pathspec>\", then run\n" -"\"git cherry-pick --continue\".\n" -"You can instead skip this commit with \"git cherry-pick --skip\".\n" -"To abort and get back to the state before \"git cherry-pick\",\n" -"run \"git cherry-pick --abort\"." -msgstr "" - -#: sequencer.c:430 -msgid "" -"After resolving the conflicts, mark them with\n" -"\"git add/rm <pathspec>\", then run\n" -"\"git revert --continue\".\n" -"You can instead skip this commit with \"git revert --skip\".\n" -"To abort and get back to the state before \"git revert\",\n" -"run \"git revert --abort\"." -msgstr "" - -#: sequencer.c:448 sequencer.c:3288 -#, c-format -msgid "could not lock '%s'" -msgstr "" - -#: sequencer.c:450 sequencer.c:3087 sequencer.c:3292 sequencer.c:3306 -#: sequencer.c:3557 sequencer.c:5591 strbuf.c:1189 wrapper.c:715 -#, c-format -msgid "could not write to '%s'" -msgstr "" - -#: sequencer.c:455 -#, c-format -msgid "could not write eol to '%s'" -msgstr "" - -#: sequencer.c:460 sequencer.c:3092 sequencer.c:3294 sequencer.c:3308 -#: sequencer.c:3565 -#, c-format -msgid "failed to finalize '%s'" -msgstr "" - -#: sequencer.c:473 sequencer.c:1930 sequencer.c:3112 sequencer.c:3547 -#: sequencer.c:3675 builtin/am.c:290 builtin/commit.c:837 builtin/merge.c:1154 -#, c-format -msgid "could not read '%s'" -msgstr "" - -#: sequencer.c:499 -#, c-format -msgid "your local changes would be overwritten by %s." -msgstr "" - -#: sequencer.c:503 -msgid "commit your changes or stash them to proceed." -msgstr "" - -#: sequencer.c:535 -#, c-format -msgid "%s: fast-forward" -msgstr "" - -#: sequencer.c:574 builtin/tag.c:615 -#, c-format -msgid "Invalid cleanup mode %s" -msgstr "" - -#. TRANSLATORS: %s will be "revert", "cherry-pick" or -#. "rebase". -#. -#: sequencer.c:685 -#, c-format -msgid "%s: Unable to write new index file" -msgstr "" - -#: sequencer.c:699 -msgid "unable to update cache tree" -msgstr "" - -#: sequencer.c:713 -msgid "could not resolve HEAD commit" -msgstr "" - -#: sequencer.c:793 -#, c-format -msgid "no key present in '%.*s'" -msgstr "" - -#: sequencer.c:804 -#, c-format -msgid "unable to dequote value of '%s'" -msgstr "" - -#: sequencer.c:841 wrapper.c:219 wrapper.c:389 builtin/am.c:757 -#: builtin/am.c:849 builtin/rebase.c:699 -#, c-format -msgid "could not open '%s' for reading" -msgstr "" - -#: sequencer.c:851 -msgid "'GIT_AUTHOR_NAME' already given" -msgstr "" - -#: sequencer.c:856 -msgid "'GIT_AUTHOR_EMAIL' already given" -msgstr "" - -#: sequencer.c:861 -msgid "'GIT_AUTHOR_DATE' already given" -msgstr "" - -#: sequencer.c:865 -#, c-format -msgid "unknown variable '%s'" -msgstr "" - -#: sequencer.c:870 -msgid "missing 'GIT_AUTHOR_NAME'" -msgstr "" - -#: sequencer.c:872 -msgid "missing 'GIT_AUTHOR_EMAIL'" -msgstr "" - -#: sequencer.c:874 -msgid "missing 'GIT_AUTHOR_DATE'" -msgstr "" - -#: sequencer.c:939 -#, c-format -msgid "" -"you have staged changes in your working tree\n" -"If these changes are meant to be squashed into the previous commit, run:\n" -"\n" -" git commit --amend %s\n" -"\n" -"If they are meant to go into a new commit, run:\n" -"\n" -" git commit %s\n" -"\n" -"In both cases, once you're done, continue with:\n" -"\n" -" git rebase --continue\n" -msgstr "" - -#: sequencer.c:1225 -msgid "'prepare-commit-msg' hook failed" -msgstr "" - -#: sequencer.c:1231 -msgid "" -"Your name and email address were configured automatically based\n" -"on your username and hostname. Please check that they are accurate.\n" -"You can suppress this message by setting them explicitly. Run the\n" -"following command and follow the instructions in your editor to edit\n" -"your configuration file:\n" -"\n" -" git config --global --edit\n" -"\n" -"After doing this, you may fix the identity used for this commit with:\n" -"\n" -" git commit --amend --reset-author\n" -msgstr "" - -#: sequencer.c:1244 -msgid "" -"Your name and email address were configured automatically based\n" -"on your username and hostname. Please check that they are accurate.\n" -"You can suppress this message by setting them explicitly:\n" -"\n" -" git config --global user.name \"Your Name\"\n" -" git config --global user.email you@example.com\n" -"\n" -"After doing this, you may fix the identity used for this commit with:\n" -"\n" -" git commit --amend --reset-author\n" -msgstr "" - -#: sequencer.c:1287 -msgid "couldn't look up newly created commit" -msgstr "" - -#: sequencer.c:1289 -msgid "could not parse newly created commit" -msgstr "" - -#: sequencer.c:1336 -msgid "unable to resolve HEAD after creating commit" -msgstr "" - -#: sequencer.c:1338 -msgid "detached HEAD" -msgstr "" - -#: sequencer.c:1342 -msgid " (root-commit)" -msgstr "" - -#: sequencer.c:1363 -msgid "could not parse HEAD" -msgstr "" - -#: sequencer.c:1365 -#, c-format -msgid "HEAD %s is not a commit!" -msgstr "" - -#: sequencer.c:1369 sequencer.c:1447 builtin/commit.c:1707 -msgid "could not parse HEAD commit" -msgstr "" - -#: sequencer.c:1425 sequencer.c:2310 -msgid "unable to parse commit author" -msgstr "" - -#: sequencer.c:1436 builtin/am.c:1644 builtin/merge.c:710 -msgid "git write-tree failed to write a tree" -msgstr "" - -#: sequencer.c:1469 sequencer.c:1589 -#, c-format -msgid "unable to read commit message from '%s'" -msgstr "" - -#: sequencer.c:1500 sequencer.c:1532 -#, c-format -msgid "invalid author identity '%s'" -msgstr "" - -#: sequencer.c:1506 -msgid "corrupt author: missing date information" -msgstr "" - -#: sequencer.c:1545 builtin/am.c:1671 builtin/commit.c:1821 builtin/merge.c:921 -#: builtin/merge.c:946 t/helper/test-fast-rebase.c:78 -msgid "failed to write commit object" -msgstr "" - -#: sequencer.c:1572 sequencer.c:4496 t/helper/test-fast-rebase.c:199 -#: t/helper/test-fast-rebase.c:217 -#, c-format -msgid "could not update %s" -msgstr "" - -#: sequencer.c:1621 -#, c-format -msgid "could not parse commit %s" -msgstr "" - -#: sequencer.c:1626 -#, c-format -msgid "could not parse parent commit %s" -msgstr "" - -#: sequencer.c:1709 sequencer.c:1990 -#, c-format -msgid "unknown command: %d" -msgstr "" - -#: sequencer.c:1751 -msgid "This is the 1st commit message:" -msgstr "" - -#: sequencer.c:1752 -#, c-format -msgid "This is the commit message #%d:" -msgstr "" - -#: sequencer.c:1753 -msgid "The 1st commit message will be skipped:" -msgstr "" - -#: sequencer.c:1754 -#, c-format -msgid "The commit message #%d will be skipped:" -msgstr "" - -#: sequencer.c:1755 -#, c-format -msgid "This is a combination of %d commits." -msgstr "" - -#: sequencer.c:1902 sequencer.c:1959 -#, c-format -msgid "cannot write '%s'" -msgstr "" - -#: sequencer.c:1949 -msgid "need a HEAD to fixup" -msgstr "" - -#: sequencer.c:1951 sequencer.c:3592 -msgid "could not read HEAD" -msgstr "" - -#: sequencer.c:1953 -msgid "could not read HEAD's commit message" -msgstr "" - -#: sequencer.c:1977 -#, c-format -msgid "could not read commit message of %s" -msgstr "" - -#: sequencer.c:2087 -msgid "your index file is unmerged." -msgstr "" - -#: sequencer.c:2094 -msgid "cannot fixup root commit" -msgstr "" - -#: sequencer.c:2113 -#, c-format -msgid "commit %s is a merge but no -m option was given." -msgstr "" - -#: sequencer.c:2121 sequencer.c:2129 -#, c-format -msgid "commit %s does not have parent %d" -msgstr "" - -#: sequencer.c:2135 -#, c-format -msgid "cannot get commit message for %s" -msgstr "" - -#. TRANSLATORS: The first %s will be a "todo" command like -#. "revert" or "pick", the second %s a SHA1. -#: sequencer.c:2154 -#, c-format -msgid "%s: cannot parse parent commit %s" -msgstr "" - -#: sequencer.c:2220 -#, c-format -msgid "could not rename '%s' to '%s'" -msgstr "" - -#: sequencer.c:2280 -#, c-format -msgid "could not revert %s... %s" -msgstr "" - -#: sequencer.c:2281 -#, c-format -msgid "could not apply %s... %s" -msgstr "" - -#: sequencer.c:2302 -#, c-format -msgid "dropping %s %s -- patch contents already upstream\n" -msgstr "" - -#: sequencer.c:2360 -#, c-format -msgid "git %s: failed to read the index" -msgstr "" - -#: sequencer.c:2368 -#, c-format -msgid "git %s: failed to refresh the index" -msgstr "" - -#: sequencer.c:2448 -#, c-format -msgid "%s does not accept arguments: '%s'" -msgstr "" - -#: sequencer.c:2457 -#, c-format -msgid "missing arguments for %s" -msgstr "" - -#: sequencer.c:2500 -#, c-format -msgid "could not parse '%s'" -msgstr "" - -#: sequencer.c:2561 -#, c-format -msgid "invalid line %d: %.*s" -msgstr "" - -#: sequencer.c:2572 -#, c-format -msgid "cannot '%s' without a previous commit" -msgstr "" - -#: sequencer.c:2620 builtin/rebase.c:185 -#, c-format -msgid "could not read '%s'." -msgstr "" - -#: sequencer.c:2658 -msgid "cancelling a cherry picking in progress" -msgstr "" - -#: sequencer.c:2667 -msgid "cancelling a revert in progress" -msgstr "" - -#: sequencer.c:2707 -msgid "please fix this using 'git rebase --edit-todo'." -msgstr "" - -#: sequencer.c:2709 -#, c-format -msgid "unusable instruction sheet: '%s'" -msgstr "" - -#: sequencer.c:2714 -msgid "no commits parsed." -msgstr "" - -#: sequencer.c:2725 -msgid "cannot cherry-pick during a revert." -msgstr "" - -#: sequencer.c:2727 -msgid "cannot revert during a cherry-pick." -msgstr "" - -#: sequencer.c:2914 -msgid "unusable squash-onto" -msgstr "" - -#: sequencer.c:2934 -#, c-format -msgid "malformed options sheet: '%s'" -msgstr "" - -#: sequencer.c:3029 sequencer.c:4875 -msgid "empty commit set passed" -msgstr "" - -#: sequencer.c:3046 -msgid "revert is already in progress" -msgstr "" - -#: sequencer.c:3048 -#, c-format -msgid "try \"git revert (--continue | %s--abort | --quit)\"" -msgstr "" - -#: sequencer.c:3051 -msgid "cherry-pick is already in progress" -msgstr "" - -#: sequencer.c:3053 -#, c-format -msgid "try \"git cherry-pick (--continue | %s--abort | --quit)\"" -msgstr "" - -#: sequencer.c:3067 -#, c-format -msgid "could not create sequencer directory '%s'" -msgstr "" - -#: sequencer.c:3082 -msgid "could not lock HEAD" -msgstr "" - -#: sequencer.c:3142 sequencer.c:4585 -msgid "no cherry-pick or revert in progress" -msgstr "" - -#: sequencer.c:3144 sequencer.c:3155 -msgid "cannot resolve HEAD" -msgstr "" - -#: sequencer.c:3146 sequencer.c:3190 -msgid "cannot abort from a branch yet to be born" -msgstr "" - -#: sequencer.c:3176 builtin/fetch.c:1030 builtin/fetch.c:1457 -#: builtin/grep.c:774 -#, c-format -msgid "cannot open '%s'" -msgstr "" - -#: sequencer.c:3178 -#, c-format -msgid "cannot read '%s': %s" -msgstr "" - -#: sequencer.c:3179 -msgid "unexpected end of file" -msgstr "" - -#: sequencer.c:3185 -#, c-format -msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" -msgstr "" - -#: sequencer.c:3196 -msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!" -msgstr "" - -#: sequencer.c:3237 -msgid "no revert in progress" -msgstr "" - -#: sequencer.c:3246 -msgid "no cherry-pick in progress" -msgstr "" - -#: sequencer.c:3256 -msgid "failed to skip the commit" -msgstr "" - -#: sequencer.c:3263 -msgid "there is nothing to skip" -msgstr "" - -#: sequencer.c:3266 -#, c-format -msgid "" -"have you committed already?\n" -"try \"git %s --continue\"" -msgstr "" - -#: sequencer.c:3428 sequencer.c:4476 -msgid "cannot read HEAD" -msgstr "" - -#: sequencer.c:3445 -#, c-format -msgid "unable to copy '%s' to '%s'" -msgstr "" - -#: sequencer.c:3453 -#, c-format -msgid "" -"You can amend the commit now, with\n" -"\n" -" git commit --amend %s\n" -"\n" -"Once you are satisfied with your changes, run\n" -"\n" -" git rebase --continue\n" -msgstr "" - -#: sequencer.c:3463 -#, c-format -msgid "Could not apply %s... %.*s" -msgstr "" - -#: sequencer.c:3470 -#, c-format -msgid "Could not merge %.*s" -msgstr "" - -#: sequencer.c:3484 sequencer.c:3488 builtin/difftool.c:633 -#, c-format -msgid "could not copy '%s' to '%s'" -msgstr "" - -#: sequencer.c:3499 -#, c-format -msgid "Executing: %s\n" -msgstr "" - -#: sequencer.c:3510 -#, c-format -msgid "" -"execution failed: %s\n" -"%sYou can fix the problem, and then run\n" -"\n" -" git rebase --continue\n" -"\n" -msgstr "" - -#: sequencer.c:3516 -msgid "and made changes to the index and/or the working tree\n" -msgstr "" - -#: sequencer.c:3522 -#, c-format -msgid "" -"execution succeeded: %s\n" -"but left changes to the index and/or the working tree\n" -"Commit or stash your changes, and then run\n" -"\n" -" git rebase --continue\n" -"\n" -msgstr "" - -#: sequencer.c:3582 -#, c-format -msgid "illegal label name: '%.*s'" -msgstr "" - -#: sequencer.c:3655 -msgid "writing fake root commit" -msgstr "" - -#: sequencer.c:3660 -msgid "writing squash-onto" -msgstr "" - -#: sequencer.c:3739 -#, c-format -msgid "could not resolve '%s'" -msgstr "" - -#: sequencer.c:3771 -msgid "cannot merge without a current revision" -msgstr "" - -#: sequencer.c:3793 -#, c-format -msgid "unable to parse '%.*s'" -msgstr "" - -#: sequencer.c:3802 -#, c-format -msgid "nothing to merge: '%.*s'" -msgstr "" - -#: sequencer.c:3814 -msgid "octopus merge cannot be executed on top of a [new root]" -msgstr "" - -#: sequencer.c:3869 -#, c-format -msgid "could not get commit message of '%s'" -msgstr "" - -#: sequencer.c:4013 -#, c-format -msgid "could not even attempt to merge '%.*s'" -msgstr "" - -#: sequencer.c:4029 -msgid "merge: Unable to write new index file" -msgstr "" - -#: sequencer.c:4110 -msgid "Cannot autostash" -msgstr "" - -#: sequencer.c:4113 -#, c-format -msgid "Unexpected stash response: '%s'" -msgstr "" - -#: sequencer.c:4119 -#, c-format -msgid "Could not create directory for '%s'" -msgstr "" - -#: sequencer.c:4122 -#, c-format -msgid "Created autostash: %s\n" -msgstr "" - -#: sequencer.c:4124 -msgid "could not reset --hard" -msgstr "" - -#: sequencer.c:4148 -#, c-format -msgid "Applied autostash.\n" -msgstr "" - -#: sequencer.c:4160 -#, c-format -msgid "cannot store %s" -msgstr "" - -#: sequencer.c:4163 -#, c-format -msgid "" -"%s\n" -"Your changes are safe in the stash.\n" -"You can run \"git stash pop\" or \"git stash drop\" at any time.\n" -msgstr "" - -#: sequencer.c:4168 -msgid "Applying autostash resulted in conflicts." -msgstr "" - -#: sequencer.c:4169 -msgid "Autostash exists; creating a new stash entry." -msgstr "" - -#: sequencer.c:4225 -msgid "could not detach HEAD" -msgstr "" - -#: sequencer.c:4240 -#, c-format -msgid "Stopped at HEAD\n" -msgstr "" - -#: sequencer.c:4242 -#, c-format -msgid "Stopped at %s\n" -msgstr "" - -#: sequencer.c:4274 -#, c-format -msgid "" -"Could not execute the todo command\n" -"\n" -" %.*s\n" -"It has been rescheduled; To edit the command before continuing, please\n" -"edit the todo list first:\n" -"\n" -" git rebase --edit-todo\n" -" git rebase --continue\n" -msgstr "" - -#: sequencer.c:4320 -#, c-format -msgid "Rebasing (%d/%d)%s" -msgstr "" - -#: sequencer.c:4366 -#, c-format -msgid "Stopped at %s... %.*s\n" -msgstr "" - -#: sequencer.c:4436 -#, c-format -msgid "unknown command %d" -msgstr "" - -#: sequencer.c:4484 -msgid "could not read orig-head" -msgstr "" - -#: sequencer.c:4489 -msgid "could not read 'onto'" -msgstr "" - -#: sequencer.c:4503 -#, c-format -msgid "could not update HEAD to %s" -msgstr "" - -#: sequencer.c:4563 -#, c-format -msgid "Successfully rebased and updated %s.\n" -msgstr "" - -#: sequencer.c:4615 -msgid "cannot rebase: You have unstaged changes." -msgstr "" - -#: sequencer.c:4624 -msgid "cannot amend non-existing commit" -msgstr "" - -#: sequencer.c:4626 -#, c-format -msgid "invalid file: '%s'" -msgstr "" - -#: sequencer.c:4628 -#, c-format -msgid "invalid contents: '%s'" -msgstr "" - -#: sequencer.c:4631 -msgid "" -"\n" -"You have uncommitted changes in your working tree. Please, commit them\n" -"first and then run 'git rebase --continue' again." -msgstr "" - -#: sequencer.c:4667 sequencer.c:4706 -#, c-format -msgid "could not write file: '%s'" -msgstr "" - -#: sequencer.c:4722 -msgid "could not remove CHERRY_PICK_HEAD" -msgstr "" - -#: sequencer.c:4732 -msgid "could not commit staged changes." -msgstr "" - -#: sequencer.c:4852 -#, c-format -msgid "%s: can't cherry-pick a %s" -msgstr "" - -#: sequencer.c:4856 -#, c-format -msgid "%s: bad revision" -msgstr "" - -#: sequencer.c:4891 -msgid "can't revert as initial commit" -msgstr "" - -#: sequencer.c:5162 sequencer.c:5391 -#, c-format -msgid "skipped previously applied commit %s" -msgstr "" - -#: sequencer.c:5232 sequencer.c:5407 -msgid "use --reapply-cherry-picks to include skipped commits" -msgstr "" - -#: sequencer.c:5378 -msgid "make_script: unhandled options" -msgstr "" - -#: sequencer.c:5381 -msgid "make_script: error preparing revisions" -msgstr "" - -#: sequencer.c:5639 sequencer.c:5656 -msgid "nothing to do" -msgstr "" - -#: sequencer.c:5675 -msgid "could not skip unnecessary pick commands" -msgstr "" - -#: sequencer.c:5775 -msgid "the script was already rearranged." -msgstr "" - -#: setup.c:135 -#, c-format -msgid "'%s' is outside repository at '%s'" -msgstr "" - -#: setup.c:187 -#, c-format -msgid "" -"%s: no such path in the working tree.\n" -"Use 'git <command> -- <path>...' to specify paths that do not exist locally." -msgstr "" - -#: setup.c:200 -#, c-format -msgid "" -"ambiguous argument '%s': unknown revision or path not in the working tree.\n" -"Use '--' to separate paths from revisions, like this:\n" -"'git <command> [<revision>...] -- [<file>...]'" -msgstr "" - -#: setup.c:266 -#, c-format -msgid "option '%s' must come before non-option arguments" -msgstr "" - -#: setup.c:285 -#, c-format -msgid "" -"ambiguous argument '%s': both revision and filename\n" -"Use '--' to separate paths from revisions, like this:\n" -"'git <command> [<revision>...] -- [<file>...]'" -msgstr "" - -#: setup.c:421 -msgid "unable to set up work tree using invalid config" -msgstr "" - -#: setup.c:425 builtin/rev-parse.c:895 -msgid "this operation must be run in a work tree" -msgstr "" - -#: setup.c:724 -#, c-format -msgid "Expected git repo version <= %d, found %d" -msgstr "" - -#: setup.c:732 -msgid "unknown repository extension found:" -msgid_plural "unknown repository extensions found:" -msgstr[0] "" -msgstr[1] "" - -#: setup.c:746 -msgid "repo version is 0, but v1-only extension found:" -msgid_plural "repo version is 0, but v1-only extensions found:" -msgstr[0] "" -msgstr[1] "" - -#: setup.c:767 -#, c-format -msgid "error opening '%s'" -msgstr "" - -#: setup.c:769 -#, c-format -msgid "too large to be a .git file: '%s'" -msgstr "" - -#: setup.c:771 -#, c-format -msgid "error reading %s" -msgstr "" - -#: setup.c:773 -#, c-format -msgid "invalid gitfile format: %s" -msgstr "" - -#: setup.c:775 -#, c-format -msgid "no path in gitfile: %s" -msgstr "" - -#: setup.c:777 -#, c-format -msgid "not a git repository: %s" -msgstr "" - -#: setup.c:879 -#, c-format -msgid "'$%s' too big" -msgstr "" - -#: setup.c:893 -#, c-format -msgid "not a git repository: '%s'" -msgstr "" - -#: setup.c:922 setup.c:924 setup.c:955 -#, c-format -msgid "cannot chdir to '%s'" -msgstr "" - -#: setup.c:927 setup.c:983 setup.c:993 setup.c:1032 setup.c:1040 -msgid "cannot come back to cwd" -msgstr "" - -#: setup.c:1054 -#, c-format -msgid "failed to stat '%*s%s%s'" -msgstr "" - -#: setup.c:1338 -msgid "Unable to read current working directory" -msgstr "" - -#: setup.c:1347 setup.c:1353 -#, c-format -msgid "cannot change to '%s'" -msgstr "" - -#: setup.c:1358 -#, c-format -msgid "not a git repository (or any of the parent directories): %s" -msgstr "" - -#: setup.c:1364 -#, c-format -msgid "" -"not a git repository (or any parent up to mount point %s)\n" -"Stopping at filesystem boundary (GIT_DISCOVERY_ACROSS_FILESYSTEM not set)." -msgstr "" - -#: setup.c:1374 -#, c-format -msgid "" -"unsafe repository ('%s' is owned by someone else)\n" -"To add an exception for this directory, call:\n" -"\n" -"\tgit config --global --add safe.directory %s" -msgstr "" - -#: setup.c:1502 -#, c-format -msgid "" -"problem with core.sharedRepository filemode value (0%.3o).\n" -"The owner of files must always have read and write permissions." -msgstr "" - -#: setup.c:1564 -msgid "fork failed" -msgstr "" - -#: setup.c:1569 -msgid "setsid failed" -msgstr "" - -#: sparse-index.c:285 -#, c-format -msgid "index entry is a directory, but not sparse (%08x)" -msgstr "" - -#: split-index.c:9 -msgid "cannot use split index with a sparse index" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 gibibyte -#: strbuf.c:851 -#, c-format -msgid "%u.%2.2u GiB" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 gibibyte/second -#: strbuf.c:853 -#, c-format -msgid "%u.%2.2u GiB/s" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 mebibyte -#: strbuf.c:861 -#, c-format -msgid "%u.%2.2u MiB" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 mebibyte/second -#: strbuf.c:863 -#, c-format -msgid "%u.%2.2u MiB/s" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 kibibyte -#: strbuf.c:870 -#, c-format -msgid "%u.%2.2u KiB" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 kibibyte/second -#: strbuf.c:872 -#, c-format -msgid "%u.%2.2u KiB/s" -msgstr "" - -#. TRANSLATORS: IEC 80000-13:2008 byte -#: strbuf.c:878 -#, c-format -msgid "%u byte" -msgid_plural "%u bytes" -msgstr[0] "" -msgstr[1] "" - -#. TRANSLATORS: IEC 80000-13:2008 byte/second -#: strbuf.c:880 -#, c-format -msgid "%u byte/s" -msgid_plural "%u bytes/s" -msgstr[0] "" -msgstr[1] "" - -#: strbuf.c:1187 wrapper.c:217 wrapper.c:387 builtin/am.c:766 -#: builtin/rebase.c:653 -#, c-format -msgid "could not open '%s' for writing" -msgstr "" - -#: strbuf.c:1196 -#, c-format -msgid "could not edit '%s'" -msgstr "" - -#: submodule-config.c:238 -#, c-format -msgid "ignoring suspicious submodule name: %s" -msgstr "" - -#: submodule-config.c:305 -msgid "negative values not allowed for submodule.fetchjobs" -msgstr "" - -#: submodule-config.c:403 -#, c-format -msgid "ignoring '%s' which may be interpreted as a command-line option: %s" -msgstr "" - -#: submodule-config.c:500 builtin/push.c:489 builtin/send-pack.c:148 -#, c-format -msgid "invalid value for '%s'" -msgstr "" - -#: submodule-config.c:828 -#, c-format -msgid "Could not update .gitmodules entry %s" -msgstr "" - -#: submodule.c:115 submodule.c:144 -msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" -msgstr "" - -#: submodule.c:119 submodule.c:148 -#, c-format -msgid "Could not find section in .gitmodules where path=%s" -msgstr "" - -#: submodule.c:155 -#, c-format -msgid "Could not remove .gitmodules entry for %s" -msgstr "" - -#: submodule.c:166 -msgid "staging updated .gitmodules failed" -msgstr "" - -#: submodule.c:346 -#, c-format -msgid "in unpopulated submodule '%s'" -msgstr "" - -#: submodule.c:377 -#, c-format -msgid "Pathspec '%s' is in submodule '%.*s'" -msgstr "" - -#: submodule.c:454 -#, c-format -msgid "bad --ignore-submodules argument: %s" -msgstr "" - -#: submodule.c:866 -#, c-format -msgid "" -"Submodule in commit %s at path: '%s' collides with a submodule named the " -"same. Skipping it." -msgstr "" - -#: submodule.c:987 -#, c-format -msgid "submodule entry '%s' (%s) is a %s, not a commit" -msgstr "" - -#: submodule.c:1069 -#, c-format -msgid "" -"Could not run 'git rev-list <commits> --not --remotes -n 1' command in " -"submodule %s" -msgstr "" - -#: submodule.c:1192 -#, c-format -msgid "process for submodule '%s' failed" -msgstr "" - -#: submodule.c:1221 builtin/branch.c:714 builtin/submodule--helper.c:2827 -msgid "Failed to resolve HEAD as a valid ref." -msgstr "" - -#: submodule.c:1232 -#, c-format -msgid "Pushing submodule '%s'\n" -msgstr "" - -#: submodule.c:1235 -#, c-format -msgid "Unable to push submodule '%s'\n" -msgstr "" - -#: submodule.c:1567 -#, c-format -msgid "Fetching submodule %s%s\n" -msgstr "" - -#: submodule.c:1589 -#, c-format -msgid "Could not access submodule '%s'\n" -msgstr "" - -#: submodule.c:1618 -#, c-format -msgid "Could not access submodule '%s' at commit %s\n" -msgstr "" - -#: submodule.c:1629 -#, c-format -msgid "Fetching submodule %s%s at commit %s\n" -msgstr "" - -#: submodule.c:1849 -#, c-format -msgid "" -"Errors during submodule fetch:\n" -"%s" -msgstr "" - -#: submodule.c:1874 -#, c-format -msgid "'%s' not recognized as a git repository" -msgstr "" - -#: submodule.c:1891 -#, c-format -msgid "Could not run 'git status --porcelain=2' in submodule %s" -msgstr "" - -#: submodule.c:1932 -#, c-format -msgid "'git status --porcelain=2' failed in submodule %s" -msgstr "" - -#: submodule.c:2007 -#, c-format -msgid "could not start 'git status' in submodule '%s'" -msgstr "" - -#: submodule.c:2020 -#, c-format -msgid "could not run 'git status' in submodule '%s'" -msgstr "" - -#: submodule.c:2037 -#, c-format -msgid "Could not unset core.worktree setting in submodule '%s'" -msgstr "" - -#: submodule.c:2064 submodule.c:2379 -#, c-format -msgid "could not recurse into submodule '%s'" -msgstr "" - -#: submodule.c:2086 -msgid "could not reset submodule index" -msgstr "" - -#: submodule.c:2128 -#, c-format -msgid "submodule '%s' has dirty index" -msgstr "" - -#: submodule.c:2182 -#, c-format -msgid "Submodule '%s' could not be updated." -msgstr "" - -#: submodule.c:2250 -#, c-format -msgid "submodule git dir '%s' is inside git dir '%.*s'" -msgstr "" - -#: submodule.c:2271 -#, c-format -msgid "" -"relocate_gitdir for submodule '%s' with more than one worktree not supported" -msgstr "" - -#: submodule.c:2283 submodule.c:2343 -#, c-format -msgid "could not lookup name for submodule '%s'" -msgstr "" - -#: submodule.c:2287 -#, c-format -msgid "refusing to move '%s' into an existing git dir" -msgstr "" - -#: submodule.c:2293 -#, c-format -msgid "" -"Migrating git directory of '%s%s' from\n" -"'%s' to\n" -"'%s'\n" -msgstr "" - -#: submodule.c:2424 -msgid "could not start ls-files in .." -msgstr "" - -#: submodule.c:2464 -#, c-format -msgid "ls-tree returned unexpected return code %d" -msgstr "" - -#: symlinks.c:244 -#, c-format -msgid "failed to lstat '%s'" -msgstr "" - -#: trailer.c:244 -#, c-format -msgid "running trailer command '%s' failed" -msgstr "" - -#: trailer.c:493 trailer.c:498 trailer.c:503 trailer.c:562 trailer.c:566 -#: trailer.c:570 -#, c-format -msgid "unknown value '%s' for key '%s'" -msgstr "" - -#: trailer.c:547 trailer.c:552 trailer.c:557 builtin/remote.c:300 -#: builtin/remote.c:328 -#, c-format -msgid "more than one %s" -msgstr "" - -#: trailer.c:743 -#, c-format -msgid "empty trailer token in trailer '%.*s'" -msgstr "" - -#: trailer.c:763 -#, c-format -msgid "could not read input file '%s'" -msgstr "" - -#: trailer.c:766 builtin/mktag.c:88 imap-send.c:1563 -msgid "could not read from stdin" -msgstr "" - -#: trailer.c:1024 wrapper.c:760 -#, c-format -msgid "could not stat %s" -msgstr "" - -#: trailer.c:1026 -#, c-format -msgid "file %s is not a regular file" -msgstr "" - -#: trailer.c:1028 -#, c-format -msgid "file %s is not writable by user" -msgstr "" - -#: trailer.c:1040 -msgid "could not open temporary file" -msgstr "" - -#: trailer.c:1080 -#, c-format -msgid "could not rename temporary file to %s" -msgstr "" - -#: transport-helper.c:62 transport-helper.c:91 -msgid "full write to remote helper failed" -msgstr "" - -#: transport-helper.c:145 -#, c-format -msgid "unable to find remote helper for '%s'" -msgstr "" - -#: transport-helper.c:161 transport-helper.c:575 -msgid "can't dup helper output fd" -msgstr "" - -#: transport-helper.c:214 -#, c-format -msgid "" -"unknown mandatory capability %s; this remote helper probably needs newer " -"version of Git" -msgstr "" - -#: transport-helper.c:220 -msgid "this remote helper should implement refspec capability" -msgstr "" - -#: transport-helper.c:287 transport-helper.c:429 -#, c-format -msgid "%s unexpectedly said: '%s'" -msgstr "" - -#: transport-helper.c:417 -#, c-format -msgid "%s also locked %s" -msgstr "" - -#: transport-helper.c:497 -msgid "couldn't run fast-import" -msgstr "" - -#: transport-helper.c:520 -msgid "error while running fast-import" -msgstr "" - -#: transport-helper.c:549 transport-helper.c:1254 -#, c-format -msgid "could not read ref %s" -msgstr "" - -#: transport-helper.c:594 -#, c-format -msgid "unknown response to connect: %s" -msgstr "" - -#: transport-helper.c:616 -msgid "setting remote service path not supported by protocol" -msgstr "" - -#: transport-helper.c:618 -msgid "invalid remote service path" -msgstr "" - -#: transport-helper.c:661 transport.c:1496 -msgid "operation not supported by protocol" -msgstr "" - -#: transport-helper.c:664 -#, c-format -msgid "can't connect to subservice %s" -msgstr "" - -#: transport-helper.c:693 transport.c:415 -msgid "--negotiate-only requires protocol v2" -msgstr "" - -#: transport-helper.c:758 -msgid "'option' without a matching 'ok/error' directive" -msgstr "" - -#: transport-helper.c:801 -#, c-format -msgid "expected ok/error, helper said '%s'" -msgstr "" - -#: transport-helper.c:862 -#, c-format -msgid "helper reported unexpected status of %s" -msgstr "" - -#: transport-helper.c:945 -#, c-format -msgid "helper %s does not support dry-run" -msgstr "" - -#: transport-helper.c:948 -#, c-format -msgid "helper %s does not support --signed" -msgstr "" - -#: transport-helper.c:951 -#, c-format -msgid "helper %s does not support --signed=if-asked" -msgstr "" - -#: transport-helper.c:956 -#, c-format -msgid "helper %s does not support --atomic" -msgstr "" - -#: transport-helper.c:960 -#, c-format -msgid "helper %s does not support --%s" -msgstr "" - -#: transport-helper.c:967 -#, c-format -msgid "helper %s does not support 'push-option'" -msgstr "" - -#: transport-helper.c:1067 -msgid "remote-helper doesn't support push; refspec needed" -msgstr "" - -#: transport-helper.c:1072 -#, c-format -msgid "helper %s does not support 'force'" -msgstr "" - -#: transport-helper.c:1119 -msgid "couldn't run fast-export" -msgstr "" - -#: transport-helper.c:1124 -msgid "error while running fast-export" -msgstr "" - -#: transport-helper.c:1149 -#, c-format -msgid "" -"No refs in common and none specified; doing nothing.\n" -"Perhaps you should specify a branch.\n" -msgstr "" - -#: transport-helper.c:1231 -#, c-format -msgid "unsupported object format '%s'" -msgstr "" - -#: transport-helper.c:1240 -#, c-format -msgid "malformed response in ref list: %s" -msgstr "" - -#: transport-helper.c:1392 -#, c-format -msgid "read(%s) failed" -msgstr "" - -#: transport-helper.c:1419 -#, c-format -msgid "write(%s) failed" -msgstr "" - -#: transport-helper.c:1468 -#, c-format -msgid "%s thread failed" -msgstr "" - -#: transport-helper.c:1472 -#, c-format -msgid "%s thread failed to join: %s" -msgstr "" - -#: transport-helper.c:1491 transport-helper.c:1495 -#, c-format -msgid "can't start thread for copying data: %s" -msgstr "" - -#: transport-helper.c:1532 -#, c-format -msgid "%s process failed to wait" -msgstr "" - -#: transport-helper.c:1536 -#, c-format -msgid "%s process failed" -msgstr "" - -#: transport-helper.c:1554 transport-helper.c:1563 -msgid "can't start thread for copying data" -msgstr "" - -#: transport.c:116 -#, c-format -msgid "Would set upstream of '%s' to '%s' of '%s'\n" -msgstr "" - -#: transport.c:138 -#, c-format -msgid "could not read bundle '%s'" -msgstr "" - -#: transport.c:234 -#, c-format -msgid "transport: invalid depth option '%s'" -msgstr "" - -#: transport.c:289 -msgid "see protocol.version in 'git help config' for more details" -msgstr "" - -#: transport.c:290 -msgid "server options require protocol version 2 or later" -msgstr "" - -#: transport.c:418 -msgid "server does not support wait-for-done" -msgstr "" - -#: transport.c:770 -msgid "could not parse transport.color.* config" -msgstr "" - -#: transport.c:845 -msgid "support for protocol v2 not implemented yet" -msgstr "" - -#: transport.c:978 -#, c-format -msgid "unknown value for config '%s': %s" -msgstr "" - -#: transport.c:1044 -#, c-format -msgid "transport '%s' not allowed" -msgstr "" - -#: transport.c:1093 -msgid "git-over-rsync is no longer supported" -msgstr "" - -#: transport.c:1196 -#, c-format -msgid "" -"The following submodule paths contain changes that can\n" -"not be found on any remote:\n" -msgstr "" - -#: transport.c:1200 -#, c-format -msgid "" -"\n" -"Please try\n" -"\n" -"\tgit push --recurse-submodules=on-demand\n" -"\n" -"or cd to the path and use\n" -"\n" -"\tgit push\n" -"\n" -"to push them to a remote.\n" -"\n" -msgstr "" - -#: transport.c:1208 -msgid "Aborting." -msgstr "" - -#: transport.c:1354 -msgid "failed to push all needed submodules" -msgstr "" - -#: tree-walk.c:33 -msgid "too-short tree object" -msgstr "" - -#: tree-walk.c:39 -msgid "malformed mode in tree entry" -msgstr "" - -#: tree-walk.c:43 -msgid "empty filename in tree entry" -msgstr "" - -#: tree-walk.c:118 -msgid "too-short tree file" -msgstr "" - -#: unpack-trees.c:118 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by checkout:\n" -"%%sPlease commit your changes or stash them before you switch branches." -msgstr "" - -#: unpack-trees.c:120 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by checkout:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:123 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by merge:\n" -"%%sPlease commit your changes or stash them before you merge." -msgstr "" - -#: unpack-trees.c:125 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by merge:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:128 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by %s:\n" -"%%sPlease commit your changes or stash them before you %s." -msgstr "" - -#: unpack-trees.c:130 -#, c-format -msgid "" -"Your local changes to the following files would be overwritten by %s:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:135 -#, c-format -msgid "" -"Updating the following directories would lose untracked files in them:\n" -"%s" -msgstr "" - -#: unpack-trees.c:138 -#, c-format -msgid "" -"Refusing to remove the current working directory:\n" -"%s" -msgstr "" - -#: unpack-trees.c:142 -#, c-format -msgid "" -"The following untracked working tree files would be removed by checkout:\n" -"%%sPlease move or remove them before you switch branches." -msgstr "" - -#: unpack-trees.c:144 -#, c-format -msgid "" -"The following untracked working tree files would be removed by checkout:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:147 -#, c-format -msgid "" -"The following untracked working tree files would be removed by merge:\n" -"%%sPlease move or remove them before you merge." -msgstr "" - -#: unpack-trees.c:149 -#, c-format -msgid "" -"The following untracked working tree files would be removed by merge:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:152 -#, c-format -msgid "" -"The following untracked working tree files would be removed by %s:\n" -"%%sPlease move or remove them before you %s." -msgstr "" - -#: unpack-trees.c:154 -#, c-format -msgid "" -"The following untracked working tree files would be removed by %s:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:160 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by " -"checkout:\n" -"%%sPlease move or remove them before you switch branches." -msgstr "" - -#: unpack-trees.c:162 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by " -"checkout:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:165 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by merge:\n" -"%%sPlease move or remove them before you merge." -msgstr "" - -#: unpack-trees.c:167 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by merge:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:170 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by %s:\n" -"%%sPlease move or remove them before you %s." -msgstr "" - -#: unpack-trees.c:172 -#, c-format -msgid "" -"The following untracked working tree files would be overwritten by %s:\n" -"%%s" -msgstr "" - -#: unpack-trees.c:180 -#, c-format -msgid "Entry '%s' overlaps with '%s'. Cannot bind." -msgstr "" - -#: unpack-trees.c:183 -#, c-format -msgid "" -"Cannot update submodule:\n" -"%s" -msgstr "" - -#: unpack-trees.c:186 -#, c-format -msgid "" -"The following paths are not up to date and were left despite sparse " -"patterns:\n" -"%s" -msgstr "" - -#: unpack-trees.c:188 -#, c-format -msgid "" -"The following paths are unmerged and were left despite sparse patterns:\n" -"%s" -msgstr "" - -#: unpack-trees.c:190 -#, c-format -msgid "" -"The following paths were already present and thus not updated despite sparse " -"patterns:\n" -"%s" -msgstr "" - -#: unpack-trees.c:270 -#, c-format -msgid "Aborting\n" -msgstr "" - -#: unpack-trees.c:297 -#, c-format -msgid "" -"After fixing the above paths, you may want to run `git sparse-checkout " -"reapply`.\n" -msgstr "" - -#: unpack-trees.c:358 -msgid "Updating files" -msgstr "" - -#: unpack-trees.c:390 -msgid "" -"the following paths have collided (e.g. case-sensitive paths\n" -"on a case-insensitive filesystem) and only one from the same\n" -"colliding group is in the working tree:\n" -msgstr "" - -#: unpack-trees.c:1664 -msgid "Updating index flags" -msgstr "" - -#: unpack-trees.c:2925 -#, c-format -msgid "worktree and untracked commit have duplicate entries: %s" -msgstr "" - -#: upload-pack.c:1579 -msgid "expected flush after fetch arguments" -msgstr "" - -#: urlmatch.c:163 -msgid "invalid URL scheme name or missing '://' suffix" -msgstr "" - -#: urlmatch.c:187 urlmatch.c:346 urlmatch.c:405 -#, c-format -msgid "invalid %XX escape sequence" -msgstr "" - -#: urlmatch.c:215 -msgid "missing host and scheme is not 'file:'" -msgstr "" - -#: urlmatch.c:232 -msgid "a 'file:' URL may not have a port number" -msgstr "" - -#: urlmatch.c:247 -msgid "invalid characters in host name" -msgstr "" - -#: urlmatch.c:292 urlmatch.c:303 -msgid "invalid port number" -msgstr "" - -#: urlmatch.c:371 -msgid "invalid '..' path segment" -msgstr "" - -#: walker.c:170 -msgid "Fetching objects" -msgstr "" - -#: worktree.c:237 builtin/am.c:2210 builtin/bisect--helper.c:156 -#, c-format -msgid "failed to read '%s'" -msgstr "" - -#: worktree.c:304 -#, c-format -msgid "'%s' at main working tree is not the repository directory" -msgstr "" - -#: worktree.c:315 -#, c-format -msgid "'%s' file does not contain absolute path to the working tree location" -msgstr "" - -#: worktree.c:327 -#, c-format -msgid "'%s' does not exist" -msgstr "" - -#: worktree.c:333 -#, c-format -msgid "'%s' is not a .git file, error code %d" -msgstr "" - -#: worktree.c:342 -#, c-format -msgid "'%s' does not point back to '%s'" -msgstr "" - -#: worktree.c:600 -msgid "not a directory" -msgstr "" - -#: worktree.c:609 -msgid ".git is not a file" -msgstr "" - -#: worktree.c:611 -msgid ".git file broken" -msgstr "" - -#: worktree.c:613 -msgid ".git file incorrect" -msgstr "" - -#: worktree.c:719 -msgid "not a valid path" -msgstr "" - -#: worktree.c:725 -msgid "unable to locate repository; .git is not a file" -msgstr "" - -#: worktree.c:729 -msgid "unable to locate repository; .git file does not reference a repository" -msgstr "" - -#: worktree.c:733 -msgid "unable to locate repository; .git file broken" -msgstr "" - -#: worktree.c:739 -msgid "gitdir unreadable" -msgstr "" - -#: worktree.c:743 -msgid "gitdir incorrect" -msgstr "" - -#: worktree.c:768 -msgid "not a valid directory" -msgstr "" - -#: worktree.c:774 -msgid "gitdir file does not exist" -msgstr "" - -#: worktree.c:779 worktree.c:788 -#, c-format -msgid "unable to read gitdir file (%s)" -msgstr "" - -#: worktree.c:798 -#, c-format -msgid "short read (expected %<PRIuMAX> bytes, read %<PRIuMAX>)" -msgstr "" - -#: worktree.c:806 -msgid "invalid gitdir file" -msgstr "" - -#: worktree.c:814 -msgid "gitdir file points to non-existent location" -msgstr "" - -#: worktree.c:830 -#, c-format -msgid "unable to set %s in '%s'" -msgstr "" - -#: worktree.c:832 -#, c-format -msgid "unable to unset %s in '%s'" -msgstr "" - -#: worktree.c:852 -msgid "failed to set extensions.worktreeConfig setting" -msgstr "" - -#: wrapper.c:161 -#, c-format -msgid "could not setenv '%s'" -msgstr "" - -#: wrapper.c:213 -#, c-format -msgid "unable to create '%s'" -msgstr "" - -#: wrapper.c:215 wrapper.c:385 -#, c-format -msgid "could not open '%s' for reading and writing" -msgstr "" - -#: wrapper.c:416 wrapper.c:683 -#, c-format -msgid "unable to access '%s'" -msgstr "" - -#: wrapper.c:691 -msgid "unable to get current working directory" -msgstr "" - -#: wt-status.c:158 -msgid "Unmerged paths:" -msgstr "" - -#: wt-status.c:187 wt-status.c:219 -msgid " (use \"git restore --staged <file>...\" to unstage)" -msgstr "" - -#: wt-status.c:190 wt-status.c:222 -#, c-format -msgid " (use \"git restore --source=%s --staged <file>...\" to unstage)" -msgstr "" - -#: wt-status.c:193 wt-status.c:225 -msgid " (use \"git rm --cached <file>...\" to unstage)" -msgstr "" - -#: wt-status.c:197 -msgid " (use \"git add <file>...\" to mark resolution)" -msgstr "" - -#: wt-status.c:199 wt-status.c:203 -msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)" -msgstr "" - -#: wt-status.c:201 -msgid " (use \"git rm <file>...\" to mark resolution)" -msgstr "" - -#: wt-status.c:211 wt-status.c:1140 -msgid "Changes to be committed:" -msgstr "" - -#: wt-status.c:234 wt-status.c:1149 -msgid "Changes not staged for commit:" -msgstr "" - -#: wt-status.c:238 -msgid " (use \"git add <file>...\" to update what will be committed)" -msgstr "" - -#: wt-status.c:240 -msgid " (use \"git add/rm <file>...\" to update what will be committed)" -msgstr "" - -#: wt-status.c:241 -msgid "" -" (use \"git restore <file>...\" to discard changes in working directory)" -msgstr "" - -#: wt-status.c:243 -msgid " (commit or discard the untracked or modified content in submodules)" -msgstr "" - -#: wt-status.c:254 -#, c-format -msgid " (use \"git %s <file>...\" to include in what will be committed)" -msgstr "" - -#: wt-status.c:266 -msgid "both deleted:" -msgstr "" - -#: wt-status.c:268 -msgid "added by us:" -msgstr "" - -#: wt-status.c:270 -msgid "deleted by them:" -msgstr "" - -#: wt-status.c:272 -msgid "added by them:" -msgstr "" - -#: wt-status.c:274 -msgid "deleted by us:" -msgstr "" - -#: wt-status.c:276 -msgid "both added:" -msgstr "" - -#: wt-status.c:278 -msgid "both modified:" -msgstr "" - -#: wt-status.c:288 -msgid "new file:" -msgstr "" - -#: wt-status.c:290 -msgid "copied:" -msgstr "" - -#: wt-status.c:292 -msgid "deleted:" -msgstr "" - -#: wt-status.c:294 -msgid "modified:" -msgstr "" - -#: wt-status.c:296 -msgid "renamed:" -msgstr "" - -#: wt-status.c:298 -msgid "typechange:" -msgstr "" - -#: wt-status.c:300 -msgid "unknown:" -msgstr "" - -#: wt-status.c:302 -msgid "unmerged:" -msgstr "" - -#: wt-status.c:382 -msgid "new commits, " -msgstr "" - -#: wt-status.c:384 -msgid "modified content, " -msgstr "" - -#: wt-status.c:386 -msgid "untracked content, " -msgstr "" - -#: wt-status.c:973 -#, c-format -msgid "Your stash currently has %d entry" -msgid_plural "Your stash currently has %d entries" -msgstr[0] "" -msgstr[1] "" - -#: wt-status.c:1004 -msgid "Submodules changed but not updated:" -msgstr "" - -#: wt-status.c:1006 -msgid "Submodule changes to be committed:" -msgstr "" - -#: wt-status.c:1088 -msgid "" -"Do not modify or remove the line above.\n" -"Everything below it will be ignored." -msgstr "" - -#: wt-status.c:1180 -#, c-format -msgid "" -"\n" -"It took %.2f seconds to compute the branch ahead/behind values.\n" -"You can use '--no-ahead-behind' to avoid this.\n" -msgstr "" - -#: wt-status.c:1210 -msgid "You have unmerged paths." -msgstr "" - -#: wt-status.c:1213 -msgid " (fix conflicts and run \"git commit\")" -msgstr "" - -#: wt-status.c:1215 -msgid " (use \"git merge --abort\" to abort the merge)" -msgstr "" - -#: wt-status.c:1219 -msgid "All conflicts fixed but you are still merging." -msgstr "" - -#: wt-status.c:1222 -msgid " (use \"git commit\" to conclude merge)" -msgstr "" - -#: wt-status.c:1233 -msgid "You are in the middle of an am session." -msgstr "" - -#: wt-status.c:1236 -msgid "The current patch is empty." -msgstr "" - -#: wt-status.c:1241 -msgid " (fix conflicts and then run \"git am --continue\")" -msgstr "" - -#: wt-status.c:1243 -msgid " (use \"git am --skip\" to skip this patch)" -msgstr "" - -#: wt-status.c:1246 -msgid "" -" (use \"git am --allow-empty\" to record this patch as an empty commit)" -msgstr "" - -#: wt-status.c:1248 -msgid " (use \"git am --abort\" to restore the original branch)" -msgstr "" - -#: wt-status.c:1381 -msgid "git-rebase-todo is missing." -msgstr "" - -#: wt-status.c:1383 -msgid "No commands done." -msgstr "" - -#: wt-status.c:1386 -#, c-format -msgid "Last command done (%<PRIuMAX> command done):" -msgid_plural "Last commands done (%<PRIuMAX> commands done):" -msgstr[0] "" -msgstr[1] "" - -#: wt-status.c:1397 -#, c-format -msgid " (see more in file %s)" -msgstr "" - -#: wt-status.c:1402 -msgid "No commands remaining." -msgstr "" - -#: wt-status.c:1405 -#, c-format -msgid "Next command to do (%<PRIuMAX> remaining command):" -msgid_plural "Next commands to do (%<PRIuMAX> remaining commands):" -msgstr[0] "" -msgstr[1] "" - -#: wt-status.c:1413 -msgid " (use \"git rebase --edit-todo\" to view and edit)" -msgstr "" - -#: wt-status.c:1425 -#, c-format -msgid "You are currently rebasing branch '%s' on '%s'." -msgstr "" - -#: wt-status.c:1430 -msgid "You are currently rebasing." -msgstr "" - -#: wt-status.c:1443 -msgid " (fix conflicts and then run \"git rebase --continue\")" -msgstr "" - -#: wt-status.c:1445 -msgid " (use \"git rebase --skip\" to skip this patch)" -msgstr "" - -#: wt-status.c:1447 -msgid " (use \"git rebase --abort\" to check out the original branch)" -msgstr "" - -#: wt-status.c:1454 -msgid " (all conflicts fixed: run \"git rebase --continue\")" -msgstr "" - -#: wt-status.c:1458 -#, c-format -msgid "" -"You are currently splitting a commit while rebasing branch '%s' on '%s'." -msgstr "" - -#: wt-status.c:1463 -msgid "You are currently splitting a commit during a rebase." -msgstr "" - -#: wt-status.c:1466 -msgid " (Once your working directory is clean, run \"git rebase --continue\")" -msgstr "" - -#: wt-status.c:1470 -#, c-format -msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." -msgstr "" - -#: wt-status.c:1475 -msgid "You are currently editing a commit during a rebase." -msgstr "" - -#: wt-status.c:1478 -msgid " (use \"git commit --amend\" to amend the current commit)" -msgstr "" - -#: wt-status.c:1480 -msgid "" -" (use \"git rebase --continue\" once you are satisfied with your changes)" -msgstr "" - -#: wt-status.c:1491 -msgid "Cherry-pick currently in progress." -msgstr "" - -#: wt-status.c:1494 -#, c-format -msgid "You are currently cherry-picking commit %s." -msgstr "" - -#: wt-status.c:1501 -msgid " (fix conflicts and run \"git cherry-pick --continue\")" -msgstr "" - -#: wt-status.c:1504 -msgid " (run \"git cherry-pick --continue\" to continue)" -msgstr "" - -#: wt-status.c:1507 -msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" -msgstr "" - -#: wt-status.c:1509 -msgid " (use \"git cherry-pick --skip\" to skip this patch)" -msgstr "" - -#: wt-status.c:1511 -msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" -msgstr "" - -#: wt-status.c:1521 -msgid "Revert currently in progress." -msgstr "" - -#: wt-status.c:1524 -#, c-format -msgid "You are currently reverting commit %s." -msgstr "" - -#: wt-status.c:1530 -msgid " (fix conflicts and run \"git revert --continue\")" -msgstr "" - -#: wt-status.c:1533 -msgid " (run \"git revert --continue\" to continue)" -msgstr "" - -#: wt-status.c:1536 -msgid " (all conflicts fixed: run \"git revert --continue\")" -msgstr "" - -#: wt-status.c:1538 -msgid " (use \"git revert --skip\" to skip this patch)" -msgstr "" - -#: wt-status.c:1540 -msgid " (use \"git revert --abort\" to cancel the revert operation)" -msgstr "" - -#: wt-status.c:1550 -#, c-format -msgid "You are currently bisecting, started from branch '%s'." -msgstr "" - -#: wt-status.c:1554 -msgid "You are currently bisecting." -msgstr "" - -#: wt-status.c:1557 -msgid " (use \"git bisect reset\" to get back to the original branch)" -msgstr "" - -#: wt-status.c:1568 -msgid "You are in a sparse checkout." -msgstr "" - -#: wt-status.c:1571 -#, c-format -msgid "You are in a sparse checkout with %d%% of tracked files present." -msgstr "" - -#: wt-status.c:1815 -msgid "On branch " -msgstr "" - -#: wt-status.c:1822 -msgid "interactive rebase in progress; onto " -msgstr "" - -#: wt-status.c:1824 -msgid "rebase in progress; onto " -msgstr "" - -#: wt-status.c:1829 -msgid "HEAD detached at " -msgstr "" - -#: wt-status.c:1831 -msgid "HEAD detached from " -msgstr "" - -#: wt-status.c:1834 -msgid "Not currently on any branch." -msgstr "" - -#: wt-status.c:1851 -msgid "Initial commit" -msgstr "" - -#: wt-status.c:1852 -msgid "No commits yet" -msgstr "" - -#: wt-status.c:1866 -msgid "Untracked files" -msgstr "" - -#: wt-status.c:1868 -msgid "Ignored files" -msgstr "" - -#: wt-status.c:1872 -#, c-format -msgid "" -"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" -"may speed it up, but you have to be careful not to forget to add\n" -"new files yourself (see 'git help status')." -msgstr "" - -#: wt-status.c:1878 -#, c-format -msgid "Untracked files not listed%s" -msgstr "" - -#: wt-status.c:1880 -msgid " (use -u option to show untracked files)" -msgstr "" - -#: wt-status.c:1886 -msgid "No changes" -msgstr "" - -#: wt-status.c:1891 -#, c-format -msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" -msgstr "" - -#: wt-status.c:1895 -#, c-format -msgid "no changes added to commit\n" -msgstr "" - -#: wt-status.c:1899 -#, c-format -msgid "" -"nothing added to commit but untracked files present (use \"git add\" to " -"track)\n" -msgstr "" - -#: wt-status.c:1903 -#, c-format -msgid "nothing added to commit but untracked files present\n" -msgstr "" - -#: wt-status.c:1907 -#, c-format -msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" -msgstr "" - -#: wt-status.c:1911 wt-status.c:1917 -#, c-format -msgid "nothing to commit\n" -msgstr "" - -#: wt-status.c:1914 -#, c-format -msgid "nothing to commit (use -u to show untracked files)\n" -msgstr "" - -#: wt-status.c:1919 -#, c-format -msgid "nothing to commit, working tree clean\n" -msgstr "" - -#: wt-status.c:2024 -msgid "No commits yet on " -msgstr "" - -#: wt-status.c:2028 -msgid "HEAD (no branch)" -msgstr "" - -#: wt-status.c:2059 -msgid "different" -msgstr "" - -#: wt-status.c:2061 wt-status.c:2069 -msgid "behind " -msgstr "" - -#: wt-status.c:2064 wt-status.c:2067 -msgid "ahead " -msgstr "" - -#. TRANSLATORS: the action is e.g. "pull with rebase" -#: wt-status.c:2605 -#, c-format -msgid "cannot %s: You have unstaged changes." -msgstr "" - -#: wt-status.c:2611 -msgid "additionally, your index contains uncommitted changes." -msgstr "" - -#: wt-status.c:2613 -#, c-format -msgid "cannot %s: Your index contains uncommitted changes." -msgstr "" - -#: compat/simple-ipc/ipc-unix-socket.c:205 -msgid "could not send IPC command" -msgstr "" - -#: compat/simple-ipc/ipc-unix-socket.c:212 -msgid "could not read IPC response" -msgstr "" - -#: compat/simple-ipc/ipc-unix-socket.c:892 -#, c-format -msgid "could not start accept_thread '%s'" -msgstr "" - -#: compat/simple-ipc/ipc-unix-socket.c:904 -#, c-format -msgid "could not start worker[0] for '%s'" -msgstr "" - -#: compat/precompose_utf8.c:58 builtin/clone.c:353 -#, c-format -msgid "failed to unlink '%s'" -msgstr "" - -#: compat/fsmonitor/fsm-listen-darwin.c:355 -msgid "Unable to create FSEventStream." -msgstr "" - -#: compat/fsmonitor/fsm-listen-darwin.c:403 -msgid "Failed to start the FSEventStream" -msgstr "" - -#: builtin/add.c:26 -msgid "git add [<options>] [--] <pathspec>..." -msgstr "" - -#: builtin/add.c:63 -#, c-format -msgid "cannot chmod %cx '%s'" -msgstr "" - -#: builtin/add.c:105 -#, c-format -msgid "unexpected diff status %c" -msgstr "" - -#: builtin/add.c:110 builtin/commit.c:299 -msgid "updating files failed" -msgstr "" - -#: builtin/add.c:120 -#, c-format -msgid "remove '%s'\n" -msgstr "" - -#: builtin/add.c:204 -msgid "Unstaged changes after refreshing the index:" -msgstr "" - -#: builtin/add.c:312 builtin/rev-parse.c:993 -msgid "Could not read the index" -msgstr "" - -#: builtin/add.c:325 -msgid "Could not write patch" -msgstr "" - -#: builtin/add.c:328 -msgid "editing patch failed" -msgstr "" - -#: builtin/add.c:331 -#, c-format -msgid "Could not stat '%s'" -msgstr "" - -#: builtin/add.c:333 -msgid "Empty patch. Aborted." -msgstr "" - -#: builtin/add.c:339 -#, c-format -msgid "Could not apply '%s'" -msgstr "" - -#: builtin/add.c:347 -msgid "The following paths are ignored by one of your .gitignore files:\n" -msgstr "" - -#: builtin/add.c:367 builtin/clean.c:927 builtin/fetch.c:175 builtin/mv.c:124 -#: builtin/prune-packed.c:14 builtin/pull.c:208 builtin/push.c:550 -#: builtin/remote.c:1454 builtin/rm.c:244 builtin/send-pack.c:194 -msgid "dry run" -msgstr "" - -#: builtin/add.c:368 builtin/check-ignore.c:22 builtin/commit.c:1483 -#: builtin/count-objects.c:98 builtin/fsck.c:789 builtin/log.c:2338 -#: builtin/mv.c:123 builtin/read-tree.c:120 -msgid "be verbose" -msgstr "" - -#: builtin/add.c:370 -msgid "interactive picking" -msgstr "" - -#: builtin/add.c:371 builtin/checkout.c:1599 builtin/reset.c:417 -msgid "select hunks interactively" -msgstr "" - -#: builtin/add.c:372 -msgid "edit current diff and apply" -msgstr "" - -#: builtin/add.c:373 -msgid "allow adding otherwise ignored files" -msgstr "" - -#: builtin/add.c:374 -msgid "update tracked files" -msgstr "" - -#: builtin/add.c:375 -msgid "renormalize EOL of tracked files (implies -u)" -msgstr "" - -#: builtin/add.c:376 -msgid "record only the fact that the path will be added later" -msgstr "" - -#: builtin/add.c:377 -msgid "add changes from all tracked and untracked files" -msgstr "" - -#: builtin/add.c:380 -msgid "ignore paths removed in the working tree (same as --no-all)" -msgstr "" - -#: builtin/add.c:382 -msgid "don't add, only refresh the index" -msgstr "" - -#: builtin/add.c:383 -msgid "just skip files which cannot be added because of errors" -msgstr "" - -#: builtin/add.c:384 -msgid "check if - even missing - files are ignored in dry run" -msgstr "" - -#: builtin/add.c:385 builtin/mv.c:128 builtin/rm.c:251 -msgid "allow updating entries outside of the sparse-checkout cone" -msgstr "" - -#: builtin/add.c:387 builtin/update-index.c:1023 -msgid "override the executable bit of the listed files" -msgstr "" - -#: builtin/add.c:389 -msgid "warn when adding an embedded repository" -msgstr "" - -#: builtin/add.c:407 -#, c-format -msgid "" -"You've added another git repository inside your current repository.\n" -"Clones of the outer repository will not contain the contents of\n" -"the embedded repository and will not know how to obtain it.\n" -"If you meant to add a submodule, use:\n" -"\n" -"\tgit submodule add <url> %s\n" -"\n" -"If you added this path by mistake, you can remove it from the\n" -"index with:\n" -"\n" -"\tgit rm --cached %s\n" -"\n" -"See \"git help submodule\" for more information." -msgstr "" - -#: builtin/add.c:436 -#, c-format -msgid "adding embedded git repository: %s" -msgstr "" - -#: builtin/add.c:456 -msgid "" -"Use -f if you really want to add them.\n" -"Turn this message off by running\n" -"\"git config advice.addIgnoredFile false\"" -msgstr "" - -#: builtin/add.c:471 -msgid "adding files failed" -msgstr "" - -#: builtin/add.c:534 -#, c-format -msgid "--chmod param '%s' must be either -x or +x" -msgstr "" - -#: builtin/add.c:555 builtin/checkout.c:1770 builtin/commit.c:365 -#: builtin/reset.c:436 builtin/rm.c:275 builtin/stash.c:1702 -#, c-format -msgid "'%s' and pathspec arguments cannot be used together" -msgstr "" - -#: builtin/add.c:566 -#, c-format -msgid "Nothing specified, nothing added.\n" -msgstr "" - -#: builtin/add.c:568 -msgid "" -"Maybe you wanted to say 'git add .'?\n" -"Turn this message off by running\n" -"\"git config advice.addEmptyPathspec false\"" -msgstr "" - -#: builtin/am.c:393 -msgid "could not parse author script" -msgstr "" - -#: builtin/am.c:483 -#, c-format -msgid "'%s' was deleted by the applypatch-msg hook" -msgstr "" - -#: builtin/am.c:525 -#, c-format -msgid "Malformed input line: '%s'." -msgstr "" - -#: builtin/am.c:563 -#, c-format -msgid "Failed to copy notes from '%s' to '%s'" -msgstr "" - -#: builtin/am.c:589 -msgid "fseek failed" -msgstr "" - -#: builtin/am.c:777 -#, c-format -msgid "could not parse patch '%s'" -msgstr "" - -#: builtin/am.c:842 -msgid "Only one StGIT patch series can be applied at once" -msgstr "" - -#: builtin/am.c:890 -msgid "invalid timestamp" -msgstr "" - -#: builtin/am.c:895 builtin/am.c:907 -msgid "invalid Date line" -msgstr "" - -#: builtin/am.c:902 -msgid "invalid timezone offset" -msgstr "" - -#: builtin/am.c:995 -msgid "Patch format detection failed." -msgstr "" - -#: builtin/am.c:1000 builtin/clone.c:306 -#, c-format -msgid "failed to create directory '%s'" -msgstr "" - -#: builtin/am.c:1005 -msgid "Failed to split patches." -msgstr "" - -#: builtin/am.c:1154 -#, c-format -msgid "When you have resolved this problem, run \"%s --continue\"." -msgstr "" - -#: builtin/am.c:1155 -#, c-format -msgid "If you prefer to skip this patch, run \"%s --skip\" instead." -msgstr "" - -#: builtin/am.c:1160 -#, c-format -msgid "To record the empty patch as an empty commit, run \"%s --allow-empty\"." -msgstr "" - -#: builtin/am.c:1162 -#, c-format -msgid "To restore the original branch and stop patching, run \"%s --abort\"." -msgstr "" - -#: builtin/am.c:1257 -msgid "Patch sent with format=flowed; space at the end of lines might be lost." -msgstr "" - -#: builtin/am.c:1345 -#, c-format -msgid "missing author line in commit %s" -msgstr "" - -#: builtin/am.c:1348 -#, c-format -msgid "invalid ident line: %.*s" -msgstr "" - -#: builtin/am.c:1567 -msgid "Repository lacks necessary blobs to fall back on 3-way merge." -msgstr "" - -#: builtin/am.c:1569 -msgid "Using index info to reconstruct a base tree..." -msgstr "" - -#: builtin/am.c:1588 -msgid "" -"Did you hand edit your patch?\n" -"It does not apply to blobs recorded in its index." -msgstr "" - -#: builtin/am.c:1594 -msgid "Falling back to patching base and 3-way merge..." -msgstr "" - -#: builtin/am.c:1620 -msgid "Failed to merge in the changes." -msgstr "" - -#: builtin/am.c:1652 -msgid "applying to an empty history" -msgstr "" - -#: builtin/am.c:1704 builtin/am.c:1708 -#, c-format -msgid "cannot resume: %s does not exist." -msgstr "" - -#: builtin/am.c:1726 -msgid "Commit Body is:" -msgstr "" - -#. TRANSLATORS: Make sure to include [y], [n], [e], [v] and [a] -#. in your translation. The program will only accept English -#. input at this point. -#. -#: builtin/am.c:1736 -#, c-format -msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " -msgstr "" - -#: builtin/am.c:1782 builtin/commit.c:410 -msgid "unable to write index file" -msgstr "" - -#: builtin/am.c:1786 -#, c-format -msgid "Dirty index: cannot apply patches (dirty: %s)" -msgstr "" - -#: builtin/am.c:1828 -#, c-format -msgid "Skipping: %.*s" -msgstr "" - -#: builtin/am.c:1833 -#, c-format -msgid "Creating an empty commit: %.*s" -msgstr "" - -#: builtin/am.c:1837 -msgid "Patch is empty." -msgstr "" - -#: builtin/am.c:1848 builtin/am.c:1917 -#, c-format -msgid "Applying: %.*s" -msgstr "" - -#: builtin/am.c:1865 -msgid "No changes -- Patch already applied." -msgstr "" - -#: builtin/am.c:1871 -#, c-format -msgid "Patch failed at %s %.*s" -msgstr "" - -#: builtin/am.c:1875 -msgid "Use 'git am --show-current-patch=diff' to see the failed patch" -msgstr "" - -#: builtin/am.c:1921 -msgid "No changes - recorded it as an empty commit." -msgstr "" - -#: builtin/am.c:1923 -msgid "" -"No changes - did you forget to use 'git add'?\n" -"If there is nothing left to stage, chances are that something else\n" -"already introduced the same changes; you might want to skip this patch." -msgstr "" - -#: builtin/am.c:1931 -msgid "" -"You still have unmerged paths in your index.\n" -"You should 'git add' each file with resolved conflicts to mark them as " -"such.\n" -"You might run `git rm` on a file to accept \"deleted by them\" for it." -msgstr "" - -#: builtin/am.c:2039 builtin/am.c:2043 builtin/am.c:2055 builtin/reset.c:455 -#: builtin/reset.c:463 -#, c-format -msgid "Could not parse object '%s'." -msgstr "" - -#: builtin/am.c:2091 builtin/am.c:2167 -msgid "failed to clean index" -msgstr "" - -#: builtin/am.c:2135 -msgid "" -"You seem to have moved HEAD since the last 'am' failure.\n" -"Not rewinding to ORIG_HEAD" -msgstr "" - -#: builtin/am.c:2292 -#, c-format -msgid "options '%s=%s' and '%s=%s' cannot be used together" -msgstr "" - -#: builtin/am.c:2323 -msgid "git am [<options>] [(<mbox> | <Maildir>)...]" -msgstr "" - -#: builtin/am.c:2324 -msgid "git am [<options>] (--continue | --skip | --abort)" -msgstr "" - -#: builtin/am.c:2330 -msgid "run interactively" -msgstr "" - -#: builtin/am.c:2332 -msgid "historical option -- no-op" -msgstr "" - -#: builtin/am.c:2334 -msgid "allow fall back on 3way merging if needed" -msgstr "" - -#: builtin/am.c:2335 builtin/init-db.c:547 builtin/prune-packed.c:16 -#: builtin/repack.c:646 builtin/stash.c:946 -msgid "be quiet" -msgstr "" - -#: builtin/am.c:2337 -msgid "add a Signed-off-by trailer to the commit message" -msgstr "" - -#: builtin/am.c:2340 -msgid "recode into utf8 (default)" -msgstr "" - -#: builtin/am.c:2342 -msgid "pass -k flag to git-mailinfo" -msgstr "" - -#: builtin/am.c:2344 -msgid "pass -b flag to git-mailinfo" -msgstr "" - -#: builtin/am.c:2346 -msgid "pass -m flag to git-mailinfo" -msgstr "" - -#: builtin/am.c:2348 -msgid "pass --keep-cr flag to git-mailsplit for mbox format" -msgstr "" - -#: builtin/am.c:2351 -msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" -msgstr "" - -#: builtin/am.c:2354 -msgid "strip everything before a scissors line" -msgstr "" - -#: builtin/am.c:2356 -msgid "pass it through git-mailinfo" -msgstr "" - -#: builtin/am.c:2359 builtin/am.c:2362 builtin/am.c:2365 builtin/am.c:2368 -#: builtin/am.c:2371 builtin/am.c:2374 builtin/am.c:2377 builtin/am.c:2380 -#: builtin/am.c:2386 -msgid "pass it through git-apply" -msgstr "" - -#: builtin/am.c:2376 builtin/commit.c:1514 builtin/fmt-merge-msg.c:18 -#: builtin/fmt-merge-msg.c:21 builtin/grep.c:920 builtin/merge.c:263 -#: builtin/pull.c:142 builtin/pull.c:204 builtin/pull.c:221 -#: builtin/rebase.c:1074 builtin/repack.c:657 builtin/repack.c:661 -#: builtin/repack.c:663 builtin/show-branch.c:650 builtin/show-ref.c:172 -#: builtin/tag.c:446 parse-options.h:159 parse-options.h:180 -#: parse-options.h:348 -msgid "n" -msgstr "" - -#: builtin/am.c:2382 builtin/branch.c:695 builtin/bugreport.c:109 -#: builtin/cat-file.c:848 builtin/cat-file.c:852 builtin/cat-file.c:856 -#: builtin/for-each-ref.c:41 builtin/ls-tree.c:357 builtin/replace.c:555 -#: builtin/tag.c:480 builtin/verify-tag.c:38 -msgid "format" -msgstr "" - -#: builtin/am.c:2383 -msgid "format the patch(es) are in" -msgstr "" - -#: builtin/am.c:2389 -msgid "override error message when patch failure occurs" -msgstr "" - -#: builtin/am.c:2391 -msgid "continue applying patches after resolving a conflict" -msgstr "" - -#: builtin/am.c:2394 -msgid "synonyms for --continue" -msgstr "" - -#: builtin/am.c:2397 -msgid "skip the current patch" -msgstr "" - -#: builtin/am.c:2400 -msgid "restore the original branch and abort the patching operation" -msgstr "" - -#: builtin/am.c:2403 -msgid "abort the patching operation but keep HEAD where it is" -msgstr "" - -#: builtin/am.c:2407 -msgid "show the patch being applied" -msgstr "" - -#: builtin/am.c:2411 -msgid "record the empty patch as an empty commit" -msgstr "" - -#: builtin/am.c:2415 -msgid "lie about committer date" -msgstr "" - -#: builtin/am.c:2417 -msgid "use current timestamp for author date" -msgstr "" - -#: builtin/am.c:2419 builtin/commit-tree.c:118 builtin/commit.c:1642 -#: builtin/merge.c:302 builtin/pull.c:179 builtin/rebase.c:1127 -#: builtin/revert.c:117 builtin/tag.c:461 -msgid "key-id" -msgstr "" - -#: builtin/am.c:2420 builtin/rebase.c:1128 -msgid "GPG-sign commits" -msgstr "" - -#: builtin/am.c:2423 -msgid "how to handle empty patches" -msgstr "" - -#: builtin/am.c:2426 -msgid "(internal use for git-rebase)" -msgstr "" - -#: builtin/am.c:2444 -msgid "" -"The -b/--binary option has been a no-op for long time, and\n" -"it will be removed. Please do not use it anymore." -msgstr "" - -#: builtin/am.c:2451 -msgid "failed to read the index" -msgstr "" - -#: builtin/am.c:2466 -#, c-format -msgid "previous rebase directory %s still exists but mbox given." -msgstr "" - -#: builtin/am.c:2490 -#, c-format -msgid "" -"Stray %s directory found.\n" -"Use \"git am --abort\" to remove it." -msgstr "" - -#: builtin/am.c:2496 -msgid "Resolve operation not in progress, we are not resuming." -msgstr "" - -#: builtin/am.c:2506 -msgid "interactive mode requires patches on the command line" -msgstr "" - -#: builtin/apply.c:8 -msgid "git apply [<options>] [<patch>...]" -msgstr "" - -#: builtin/archive.c:18 -msgid "could not redirect output" -msgstr "" - -#: builtin/archive.c:35 -msgid "git archive: Remote with no URL" -msgstr "" - -#: builtin/archive.c:59 -msgid "git archive: expected ACK/NAK, got a flush packet" -msgstr "" - -#: builtin/archive.c:62 -#, c-format -msgid "git archive: NACK %s" -msgstr "" - -#: builtin/archive.c:63 -msgid "git archive: protocol error" -msgstr "" - -#: builtin/archive.c:67 -msgid "git archive: expected a flush" -msgstr "" - -#: builtin/bisect--helper.c:24 -msgid "git bisect--helper --bisect-reset [<commit>]" -msgstr "" - -#: builtin/bisect--helper.c:26 -msgid "" -"git bisect--helper --bisect-start [--term-{new,bad}=<term> --term-{old,good}" -"=<term>] [--no-checkout] [--first-parent] [<bad> [<good>...]] [--] " -"[<paths>...]" -msgstr "" - -#: builtin/bisect--helper.c:29 -msgid "git bisect--helper --bisect-state (bad|new) [<rev>]" -msgstr "" - -#: builtin/bisect--helper.c:30 -msgid "git bisect--helper --bisect-state (good|old) [<rev>...]" -msgstr "" - -#: builtin/bisect--helper.c:31 -msgid "git bisect--helper --bisect-replay <filename>" -msgstr "" - -#: builtin/bisect--helper.c:32 -msgid "git bisect--helper --bisect-skip [(<rev>|<range>)...]" -msgstr "" - -#: builtin/bisect--helper.c:34 -msgid "git bisect--helper --bisect-run <cmd>..." -msgstr "" - -#: builtin/bisect--helper.c:109 -#, c-format -msgid "cannot open file '%s' in mode '%s'" -msgstr "" - -#: builtin/bisect--helper.c:116 -#, c-format -msgid "could not write to file '%s'" -msgstr "" - -#: builtin/bisect--helper.c:154 -#, c-format -msgid "cannot open file '%s' for reading" -msgstr "" - -#: builtin/bisect--helper.c:170 -#, c-format -msgid "'%s' is not a valid term" -msgstr "" - -#: builtin/bisect--helper.c:174 -#, c-format -msgid "can't use the builtin command '%s' as a term" -msgstr "" - -#: builtin/bisect--helper.c:184 -#, c-format -msgid "can't change the meaning of the term '%s'" -msgstr "" - -#: builtin/bisect--helper.c:194 -msgid "please use two different terms" -msgstr "" - -#: builtin/bisect--helper.c:210 -#, c-format -msgid "We are not bisecting.\n" -msgstr "" - -#: builtin/bisect--helper.c:218 -#, c-format -msgid "'%s' is not a valid commit" -msgstr "" - -#: builtin/bisect--helper.c:227 -#, c-format -msgid "" -"could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." -msgstr "" - -#: builtin/bisect--helper.c:271 -#, c-format -msgid "Bad bisect_write argument: %s" -msgstr "" - -#: builtin/bisect--helper.c:276 -#, c-format -msgid "couldn't get the oid of the rev '%s'" -msgstr "" - -#: builtin/bisect--helper.c:288 -#, c-format -msgid "couldn't open the file '%s'" -msgstr "" - -#: builtin/bisect--helper.c:314 -#, c-format -msgid "Invalid command: you're currently in a %s/%s bisect" -msgstr "" - -#: builtin/bisect--helper.c:341 -#, c-format -msgid "" -"You need to give me at least one %s and %s revision.\n" -"You can use \"git bisect %s\" and \"git bisect %s\" for that." -msgstr "" - -#: builtin/bisect--helper.c:345 -#, c-format -msgid "" -"You need to start by \"git bisect start\".\n" -"You then need to give me at least one %s and %s revision.\n" -"You can use \"git bisect %s\" and \"git bisect %s\" for that." -msgstr "" - -#: builtin/bisect--helper.c:365 -#, c-format -msgid "bisecting only with a %s commit" -msgstr "" - -#. TRANSLATORS: Make sure to include [Y] and [n] in your -#. translation. The program will only accept English input -#. at this point. -#. -#: builtin/bisect--helper.c:373 -msgid "Are you sure [Y/n]? " -msgstr "" - -#: builtin/bisect--helper.c:434 -msgid "no terms defined" -msgstr "" - -#: builtin/bisect--helper.c:437 -#, c-format -msgid "" -"Your current terms are %s for the old state\n" -"and %s for the new state.\n" -msgstr "" - -#: builtin/bisect--helper.c:447 -#, c-format -msgid "" -"invalid argument %s for 'git bisect terms'.\n" -"Supported options are: --term-good|--term-old and --term-bad|--term-new." -msgstr "" - -#: builtin/bisect--helper.c:514 builtin/bisect--helper.c:1038 -msgid "revision walk setup failed\n" -msgstr "" - -#: builtin/bisect--helper.c:536 -#, c-format -msgid "could not open '%s' for appending" -msgstr "" - -#: builtin/bisect--helper.c:655 builtin/bisect--helper.c:668 -msgid "'' is not a valid term" -msgstr "" - -#: builtin/bisect--helper.c:678 -#, c-format -msgid "unrecognized option: '%s'" -msgstr "" - -#: builtin/bisect--helper.c:682 -#, c-format -msgid "'%s' does not appear to be a valid revision" -msgstr "" - -#: builtin/bisect--helper.c:713 -msgid "bad HEAD - I need a HEAD" -msgstr "" - -#: builtin/bisect--helper.c:728 -#, c-format -msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'." -msgstr "" - -#: builtin/bisect--helper.c:749 -msgid "won't bisect on cg-seek'ed tree" -msgstr "" - -#: builtin/bisect--helper.c:752 -msgid "bad HEAD - strange symbolic ref" -msgstr "" - -#: builtin/bisect--helper.c:772 -#, c-format -msgid "invalid ref: '%s'" -msgstr "" - -#: builtin/bisect--helper.c:830 -msgid "You need to start by \"git bisect start\"\n" -msgstr "" - -#. TRANSLATORS: Make sure to include [Y] and [n] in your -#. translation. The program will only accept English input -#. at this point. -#. -#: builtin/bisect--helper.c:841 -msgid "Do you want me to do it for you [Y/n]? " -msgstr "" - -#: builtin/bisect--helper.c:859 -msgid "Please call `--bisect-state` with at least one argument" -msgstr "" - -#: builtin/bisect--helper.c:872 -#, c-format -msgid "'git bisect %s' can take only one argument." -msgstr "" - -#: builtin/bisect--helper.c:884 builtin/bisect--helper.c:897 -#, c-format -msgid "Bad rev input: %s" -msgstr "" - -#: builtin/bisect--helper.c:904 -#, c-format -msgid "Bad rev input (not a commit): %s" -msgstr "" - -#: builtin/bisect--helper.c:936 -msgid "We are not bisecting." -msgstr "" - -#: builtin/bisect--helper.c:986 -#, c-format -msgid "'%s'?? what are you talking about?" -msgstr "" - -#: builtin/bisect--helper.c:998 -#, c-format -msgid "cannot read file '%s' for replaying" -msgstr "" - -#: builtin/bisect--helper.c:1120 builtin/bisect--helper.c:1152 -#, c-format -msgid "running %s\n" -msgstr "" - -#: builtin/bisect--helper.c:1145 builtin/bisect--helper.c:1335 -msgid "bisect run failed: no command provided." -msgstr "" - -#: builtin/bisect--helper.c:1166 -#, c-format -msgid "unable to verify '%s' on good revision" -msgstr "" - -#: builtin/bisect--helper.c:1172 -#, c-format -msgid "bogus exit code %d for good revision" -msgstr "" - -#: builtin/bisect--helper.c:1180 -#, c-format -msgid "bisect run failed: exit code %d from '%s' is < 0 or >= 128" -msgstr "" - -#: builtin/bisect--helper.c:1195 -#, c-format -msgid "cannot open file '%s' for writing" -msgstr "" - -#: builtin/bisect--helper.c:1213 -msgid "bisect run cannot continue any more" -msgstr "" - -#: builtin/bisect--helper.c:1215 -#, c-format -msgid "bisect run success" -msgstr "" - -#: builtin/bisect--helper.c:1218 -#, c-format -msgid "bisect found first bad commit" -msgstr "" - -#: builtin/bisect--helper.c:1221 -#, c-format -msgid "" -"bisect run failed: 'git bisect--helper --bisect-state %s' exited with error " -"code %d" -msgstr "" - -#: builtin/bisect--helper.c:1253 -msgid "reset the bisection state" -msgstr "" - -#: builtin/bisect--helper.c:1255 -msgid "check whether bad or good terms exist" -msgstr "" - -#: builtin/bisect--helper.c:1257 -msgid "print out the bisect terms" -msgstr "" - -#: builtin/bisect--helper.c:1259 -msgid "start the bisect session" -msgstr "" - -#: builtin/bisect--helper.c:1261 -msgid "find the next bisection commit" -msgstr "" - -#: builtin/bisect--helper.c:1263 -msgid "mark the state of ref (or refs)" -msgstr "" - -#: builtin/bisect--helper.c:1265 -msgid "list the bisection steps so far" -msgstr "" - -#: builtin/bisect--helper.c:1267 -msgid "replay the bisection process from the given file" -msgstr "" - -#: builtin/bisect--helper.c:1269 -msgid "skip some commits for checkout" -msgstr "" - -#: builtin/bisect--helper.c:1271 -msgid "visualize the bisection" -msgstr "" - -#: builtin/bisect--helper.c:1273 -msgid "use <cmd>... to automatically bisect" -msgstr "" - -#: builtin/bisect--helper.c:1275 -msgid "no log for BISECT_WRITE" -msgstr "" - -#: builtin/bisect--helper.c:1290 -msgid "--bisect-reset requires either no argument or a commit" -msgstr "" - -#: builtin/bisect--helper.c:1295 -msgid "--bisect-terms requires 0 or 1 argument" -msgstr "" - -#: builtin/bisect--helper.c:1304 -msgid "--bisect-next requires 0 arguments" -msgstr "" - -#: builtin/bisect--helper.c:1315 -msgid "--bisect-log requires 0 arguments" -msgstr "" - -#: builtin/bisect--helper.c:1320 -msgid "no logfile given" -msgstr "" - -#: builtin/blame.c:32 -msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>" -msgstr "" - -#: builtin/blame.c:37 -msgid "<rev-opts> are documented in git-rev-list(1)" -msgstr "" - -#: builtin/blame.c:406 -#, c-format -msgid "expecting a color: %s" -msgstr "" - -#: builtin/blame.c:413 -msgid "must end with a color" -msgstr "" - -#: builtin/blame.c:842 -#, c-format -msgid "cannot find revision %s to ignore" -msgstr "" - -#: builtin/blame.c:864 -msgid "show blame entries as we find them, incrementally" -msgstr "" - -#: builtin/blame.c:865 -msgid "do not show object names of boundary commits (Default: off)" -msgstr "" - -#: builtin/blame.c:866 -msgid "do not treat root commits as boundaries (Default: off)" -msgstr "" - -#: builtin/blame.c:867 -msgid "show work cost statistics" -msgstr "" - -#: builtin/blame.c:868 builtin/checkout.c:1554 builtin/clone.c:98 -#: builtin/commit-graph.c:75 builtin/commit-graph.c:228 builtin/fetch.c:181 -#: builtin/merge.c:301 builtin/multi-pack-index.c:103 -#: builtin/multi-pack-index.c:154 builtin/multi-pack-index.c:180 -#: builtin/multi-pack-index.c:208 builtin/pull.c:120 builtin/push.c:566 -#: builtin/remote.c:683 builtin/send-pack.c:202 -msgid "force progress reporting" -msgstr "" - -#: builtin/blame.c:869 -msgid "show output score for blame entries" -msgstr "" - -#: builtin/blame.c:870 -msgid "show original filename (Default: auto)" -msgstr "" - -#: builtin/blame.c:871 -msgid "show original linenumber (Default: off)" -msgstr "" - -#: builtin/blame.c:872 -msgid "show in a format designed for machine consumption" -msgstr "" - -#: builtin/blame.c:873 -msgid "show porcelain format with per-line commit information" -msgstr "" - -#: builtin/blame.c:874 -msgid "use the same output mode as git-annotate (Default: off)" -msgstr "" - -#: builtin/blame.c:875 -msgid "show raw timestamp (Default: off)" -msgstr "" - -#: builtin/blame.c:876 -msgid "show long commit SHA1 (Default: off)" -msgstr "" - -#: builtin/blame.c:877 -msgid "suppress author name and timestamp (Default: off)" -msgstr "" - -#: builtin/blame.c:878 -msgid "show author email instead of name (Default: off)" -msgstr "" - -#: builtin/blame.c:879 -msgid "ignore whitespace differences" -msgstr "" - -#: builtin/blame.c:880 builtin/log.c:1857 -msgid "rev" -msgstr "" - -#: builtin/blame.c:880 -msgid "ignore <rev> when blaming" -msgstr "" - -#: builtin/blame.c:881 -msgid "ignore revisions from <file>" -msgstr "" - -#: builtin/blame.c:882 -msgid "color redundant metadata from previous line differently" -msgstr "" - -#: builtin/blame.c:883 -msgid "color lines by age" -msgstr "" - -#: builtin/blame.c:884 -msgid "spend extra cycles to find better match" -msgstr "" - -#: builtin/blame.c:885 -msgid "use revisions from <file> instead of calling git-rev-list" -msgstr "" - -#: builtin/blame.c:886 -msgid "use <file>'s contents as the final image" -msgstr "" - -#: builtin/blame.c:887 builtin/blame.c:888 -msgid "score" -msgstr "" - -#: builtin/blame.c:887 -msgid "find line copies within and across files" -msgstr "" - -#: builtin/blame.c:888 -msgid "find line movements within and across files" -msgstr "" - -#: builtin/blame.c:889 -msgid "range" -msgstr "" - -#: builtin/blame.c:890 -msgid "process only line range <start>,<end> or function :<funcname>" -msgstr "" - -#: builtin/blame.c:949 -msgid "--progress can't be used with --incremental or porcelain formats" -msgstr "" - -#. TRANSLATORS: This string is used to tell us the -#. maximum display width for a relative timestamp in -#. "git blame" output. For C locale, "4 years, 11 -#. months ago", which takes 22 places, is the longest -#. among various forms of relative timestamps, but -#. your language may need more or fewer display -#. columns. -#. -#: builtin/blame.c:1000 -msgid "4 years, 11 months ago" -msgstr "" - -#: builtin/blame.c:1116 -#, c-format -msgid "file %s has only %lu line" -msgid_plural "file %s has only %lu lines" -msgstr[0] "" -msgstr[1] "" - -#: builtin/blame.c:1161 -msgid "Blaming lines" -msgstr "" - -#: builtin/branch.c:29 -msgid "git branch [<options>] [-r | -a] [--merged] [--no-merged]" -msgstr "" - -#: builtin/branch.c:30 -msgid "" -"git branch [<options>] [-f] [--recurse-submodules] <branch-name> [<start-" -"point>]" -msgstr "" - -#: builtin/branch.c:31 -msgid "git branch [<options>] [-l] [<pattern>...]" -msgstr "" - -#: builtin/branch.c:32 -msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..." -msgstr "" - -#: builtin/branch.c:33 -msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>" -msgstr "" - -#: builtin/branch.c:34 -msgid "git branch [<options>] (-c | -C) [<old-branch>] <new-branch>" -msgstr "" - -#: builtin/branch.c:35 -msgid "git branch [<options>] [-r | -a] [--points-at]" -msgstr "" - -#: builtin/branch.c:36 -msgid "git branch [<options>] [-r | -a] [--format]" -msgstr "" - -#: builtin/branch.c:165 -#, c-format -msgid "" -"deleting branch '%s' that has been merged to\n" -" '%s', but not yet merged to HEAD." -msgstr "" - -#: builtin/branch.c:169 -#, c-format -msgid "" -"not deleting branch '%s' that is not yet merged to\n" -" '%s', even though it is merged to HEAD." -msgstr "" - -#: builtin/branch.c:183 -#, c-format -msgid "Couldn't look up commit object for '%s'" -msgstr "" - -#: builtin/branch.c:187 -#, c-format -msgid "" -"The branch '%s' is not fully merged.\n" -"If you are sure you want to delete it, run 'git branch -D %s'." -msgstr "" - -#: builtin/branch.c:200 -msgid "Update of config-file failed" -msgstr "" - -#: builtin/branch.c:235 -msgid "cannot use -a with -d" -msgstr "" - -#: builtin/branch.c:242 -msgid "Couldn't look up commit object for HEAD" -msgstr "" - -#: builtin/branch.c:259 -#, c-format -msgid "Cannot delete branch '%s' checked out at '%s'" -msgstr "" - -#: builtin/branch.c:274 -#, c-format -msgid "remote-tracking branch '%s' not found." -msgstr "" - -#: builtin/branch.c:275 -#, c-format -msgid "branch '%s' not found." -msgstr "" - -#: builtin/branch.c:306 -#, c-format -msgid "Deleted remote-tracking branch %s (was %s).\n" -msgstr "" - -#: builtin/branch.c:307 -#, c-format -msgid "Deleted branch %s (was %s).\n" -msgstr "" - -#: builtin/branch.c:457 builtin/tag.c:64 -msgid "unable to parse format string" -msgstr "" - -#: builtin/branch.c:488 -msgid "could not resolve HEAD" -msgstr "" - -#: builtin/branch.c:494 -#, c-format -msgid "HEAD (%s) points outside of refs/heads/" -msgstr "" - -#: builtin/branch.c:509 -#, c-format -msgid "Branch %s is being rebased at %s" -msgstr "" - -#: builtin/branch.c:513 -#, c-format -msgid "Branch %s is being bisected at %s" -msgstr "" - -#: builtin/branch.c:530 -msgid "cannot copy the current branch while not on any." -msgstr "" - -#: builtin/branch.c:532 -msgid "cannot rename the current branch while not on any." -msgstr "" - -#: builtin/branch.c:543 -#, c-format -msgid "Invalid branch name: '%s'" -msgstr "" - -#: builtin/branch.c:572 -msgid "Branch rename failed" -msgstr "" - -#: builtin/branch.c:574 -msgid "Branch copy failed" -msgstr "" - -#: builtin/branch.c:578 -#, c-format -msgid "Created a copy of a misnamed branch '%s'" -msgstr "" - -#: builtin/branch.c:581 -#, c-format -msgid "Renamed a misnamed branch '%s' away" -msgstr "" - -#: builtin/branch.c:587 -#, c-format -msgid "Branch renamed to %s, but HEAD is not updated!" -msgstr "" - -#: builtin/branch.c:596 -msgid "Branch is renamed, but update of config-file failed" -msgstr "" - -#: builtin/branch.c:598 -msgid "Branch is copied, but update of config-file failed" -msgstr "" - -#: builtin/branch.c:614 -#, c-format -msgid "" -"Please edit the description for the branch\n" -" %s\n" -"Lines starting with '%c' will be stripped.\n" -msgstr "" - -#: builtin/branch.c:651 -msgid "Generic options" -msgstr "" - -#: builtin/branch.c:653 -msgid "show hash and subject, give twice for upstream branch" -msgstr "" - -#: builtin/branch.c:654 -msgid "suppress informational messages" -msgstr "" - -#: builtin/branch.c:656 builtin/checkout.c:1571 -#: builtin/submodule--helper.c:3077 -msgid "set branch tracking configuration" -msgstr "" - -#: builtin/branch.c:659 -msgid "do not use" -msgstr "" - -#: builtin/branch.c:661 -msgid "upstream" -msgstr "" - -#: builtin/branch.c:661 -msgid "change the upstream info" -msgstr "" - -#: builtin/branch.c:662 -msgid "unset the upstream info" -msgstr "" - -#: builtin/branch.c:663 -msgid "use colored output" -msgstr "" - -#: builtin/branch.c:664 -msgid "act on remote-tracking branches" -msgstr "" - -#: builtin/branch.c:666 builtin/branch.c:668 -msgid "print only branches that contain the commit" -msgstr "" - -#: builtin/branch.c:667 builtin/branch.c:669 -msgid "print only branches that don't contain the commit" -msgstr "" - -#: builtin/branch.c:672 -msgid "Specific git-branch actions:" -msgstr "" - -#: builtin/branch.c:673 -msgid "list both remote-tracking and local branches" -msgstr "" - -#: builtin/branch.c:675 -msgid "delete fully merged branch" -msgstr "" - -#: builtin/branch.c:676 -msgid "delete branch (even if not merged)" -msgstr "" - -#: builtin/branch.c:677 -msgid "move/rename a branch and its reflog" -msgstr "" - -#: builtin/branch.c:678 -msgid "move/rename a branch, even if target exists" -msgstr "" - -#: builtin/branch.c:679 -msgid "copy a branch and its reflog" -msgstr "" - -#: builtin/branch.c:680 -msgid "copy a branch, even if target exists" -msgstr "" - -#: builtin/branch.c:681 -msgid "list branch names" -msgstr "" - -#: builtin/branch.c:682 -msgid "show current branch name" -msgstr "" - -#: builtin/branch.c:683 builtin/submodule--helper.c:3075 -msgid "create the branch's reflog" -msgstr "" - -#: builtin/branch.c:685 -msgid "edit the description for the branch" -msgstr "" - -#: builtin/branch.c:686 -msgid "force creation, move/rename, deletion" -msgstr "" - -#: builtin/branch.c:687 -msgid "print only branches that are merged" -msgstr "" - -#: builtin/branch.c:688 -msgid "print only branches that are not merged" -msgstr "" - -#: builtin/branch.c:689 -msgid "list branches in columns" -msgstr "" - -#: builtin/branch.c:691 builtin/for-each-ref.c:45 builtin/notes.c:413 -#: builtin/notes.c:416 builtin/notes.c:579 builtin/notes.c:582 -#: builtin/tag.c:476 -msgid "object" -msgstr "" - -#: builtin/branch.c:692 -msgid "print only branches of the object" -msgstr "" - -#: builtin/branch.c:693 builtin/for-each-ref.c:51 builtin/tag.c:483 -msgid "sorting and filtering are case insensitive" -msgstr "" - -#: builtin/branch.c:694 builtin/ls-files.c:667 -msgid "recurse through submodules" -msgstr "" - -#: builtin/branch.c:695 builtin/for-each-ref.c:41 builtin/ls-tree.c:358 -#: builtin/tag.c:481 builtin/verify-tag.c:38 -msgid "format to use for the output" -msgstr "" - -#: builtin/branch.c:718 builtin/clone.c:684 -msgid "HEAD not found below refs/heads!" -msgstr "" - -#: builtin/branch.c:739 -msgid "" -"branch with --recurse-submodules can only be used if submodule." -"propagateBranches is enabled" -msgstr "" - -#: builtin/branch.c:741 -msgid "--recurse-submodules can only be used to create branches" -msgstr "" - -#: builtin/branch.c:770 builtin/branch.c:826 builtin/branch.c:835 -msgid "branch name required" -msgstr "" - -#: builtin/branch.c:802 -msgid "Cannot give description to detached HEAD" -msgstr "" - -#: builtin/branch.c:807 -msgid "cannot edit description of more than one branch" -msgstr "" - -#: builtin/branch.c:814 -#, c-format -msgid "No commit on branch '%s' yet." -msgstr "" - -#: builtin/branch.c:817 -#, c-format -msgid "No branch named '%s'." -msgstr "" - -#: builtin/branch.c:832 -msgid "too many branches for a copy operation" -msgstr "" - -#: builtin/branch.c:841 -msgid "too many arguments for a rename operation" -msgstr "" - -#: builtin/branch.c:846 -msgid "too many arguments to set new upstream" -msgstr "" - -#: builtin/branch.c:850 -#, c-format -msgid "" -"could not set upstream of HEAD to %s when it does not point to any branch." -msgstr "" - -#: builtin/branch.c:853 builtin/branch.c:873 -#, c-format -msgid "no such branch '%s'" -msgstr "" - -#: builtin/branch.c:857 -#, c-format -msgid "branch '%s' does not exist" -msgstr "" - -#: builtin/branch.c:867 -msgid "too many arguments to unset upstream" -msgstr "" - -#: builtin/branch.c:871 -msgid "could not unset upstream of HEAD when it does not point to any branch." -msgstr "" - -#: builtin/branch.c:877 -#, c-format -msgid "Branch '%s' has no upstream information" -msgstr "" - -#: builtin/branch.c:890 -msgid "" -"The -a, and -r, options to 'git branch' do not take a branch name.\n" -"Did you mean to use: -a|-r --list <pattern>?" -msgstr "" - -#: builtin/branch.c:894 -msgid "" -"the '--set-upstream' option is no longer supported. Please use '--track' or " -"'--set-upstream-to' instead." -msgstr "" - -#: builtin/bugreport.c:16 -msgid "git version:\n" -msgstr "" - -#: builtin/bugreport.c:22 -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "" - -#: builtin/bugreport.c:32 -msgid "compiler info: " -msgstr "" - -#: builtin/bugreport.c:35 -msgid "libc info: " -msgstr "" - -#: builtin/bugreport.c:49 -msgid "not run from a git repository - no hooks to show\n" -msgstr "" - -#: builtin/bugreport.c:62 -msgid "git bugreport [-o|--output-directory <file>] [-s|--suffix <format>]" -msgstr "" - -#: builtin/bugreport.c:69 -msgid "" -"Thank you for filling out a Git bug report!\n" -"Please answer the following questions to help us understand your issue.\n" -"\n" -"What did you do before the bug happened? (Steps to reproduce your issue)\n" -"\n" -"What did you expect to happen? (Expected behavior)\n" -"\n" -"What happened instead? (Actual behavior)\n" -"\n" -"What's different between what you expected and what actually happened?\n" -"\n" -"Anything else you want to add:\n" -"\n" -"Please review the rest of the bug report below.\n" -"You can delete any lines you don't wish to share.\n" -msgstr "" - -#: builtin/bugreport.c:108 -msgid "specify a destination for the bugreport file" -msgstr "" - -#: builtin/bugreport.c:110 -msgid "specify a strftime format suffix for the filename" -msgstr "" - -#: builtin/bugreport.c:132 -#, c-format -msgid "could not create leading directories for '%s'" -msgstr "" - -#: builtin/bugreport.c:139 -msgid "System Info" -msgstr "" - -#: builtin/bugreport.c:142 -msgid "Enabled Hooks" -msgstr "" - -#: builtin/bugreport.c:149 -#, c-format -msgid "unable to write to %s" -msgstr "" - -#: builtin/bugreport.c:159 -#, c-format -msgid "Created new report at '%s'.\n" -msgstr "" - -#: builtin/bundle.c:15 builtin/bundle.c:23 -msgid "git bundle create [<options>] <file> <git-rev-list args>" -msgstr "" - -#: builtin/bundle.c:16 builtin/bundle.c:28 -msgid "git bundle verify [<options>] <file>" -msgstr "" - -#: builtin/bundle.c:17 builtin/bundle.c:33 -msgid "git bundle list-heads <file> [<refname>...]" -msgstr "" - -#: builtin/bundle.c:18 builtin/bundle.c:38 -msgid "git bundle unbundle <file> [<refname>...]" -msgstr "" - -#: builtin/bundle.c:65 builtin/pack-objects.c:3899 -msgid "do not show progress meter" -msgstr "" - -#: builtin/bundle.c:67 builtin/bundle.c:168 builtin/pack-objects.c:3901 -msgid "show progress meter" -msgstr "" - -#: builtin/bundle.c:69 builtin/pack-objects.c:3903 -msgid "show progress meter during object writing phase" -msgstr "" - -#: builtin/bundle.c:72 builtin/pack-objects.c:3906 -msgid "similar to --all-progress when progress meter is shown" -msgstr "" - -#: builtin/bundle.c:74 -msgid "specify bundle format version" -msgstr "" - -#: builtin/bundle.c:94 -msgid "Need a repository to create a bundle." -msgstr "" - -#: builtin/bundle.c:108 -msgid "do not show bundle details" -msgstr "" - -#: builtin/bundle.c:127 -#, c-format -msgid "%s is okay\n" -msgstr "" - -#: builtin/bundle.c:183 -msgid "Need a repository to unbundle." -msgstr "" - -#: builtin/bundle.c:186 -msgid "Unbundling objects" -msgstr "" - -#: builtin/bundle.c:220 builtin/remote.c:1758 -#, c-format -msgid "Unknown subcommand: %s" -msgstr "" - -#: builtin/cat-file.c:568 -msgid "flush is only for --buffer mode" -msgstr "" - -#: builtin/cat-file.c:612 -msgid "empty command in input" -msgstr "" - -#: builtin/cat-file.c:614 -#, c-format -msgid "whitespace before command: '%s'" -msgstr "" - -#: builtin/cat-file.c:623 -#, c-format -msgid "%s requires arguments" -msgstr "" - -#: builtin/cat-file.c:628 -#, c-format -msgid "%s takes no arguments" -msgstr "" - -#: builtin/cat-file.c:636 -#, c-format -msgid "unknown command: '%s'" -msgstr "" - -#: builtin/cat-file.c:795 -msgid "only one batch option may be specified" -msgstr "" - -#: builtin/cat-file.c:824 -msgid "git cat-file <type> <object>" -msgstr "" - -#: builtin/cat-file.c:825 -msgid "git cat-file (-e | -p) <object>" -msgstr "" - -#: builtin/cat-file.c:826 -msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -msgstr "" - -#: builtin/cat-file.c:827 -msgid "" -"git cat-file (--batch | --batch-check | --batch-command) [--batch-all-" -"objects]\n" -" [--buffer] [--follow-symlinks] [--unordered]\n" -" [--textconv | --filters]" -msgstr "" - -#: builtin/cat-file.c:830 -msgid "" -"git cat-file (--textconv | --filters)\n" -" [<rev>:<path|tree-ish> | --path=<path|tree-ish> <rev>]" -msgstr "" - -#: builtin/cat-file.c:836 -msgid "Check object existence or emit object contents" -msgstr "" - -#: builtin/cat-file.c:838 -msgid "check if <object> exists" -msgstr "" - -#: builtin/cat-file.c:839 -msgid "pretty-print <object> content" -msgstr "" - -#: builtin/cat-file.c:841 -msgid "Emit [broken] object attributes" -msgstr "" - -#: builtin/cat-file.c:842 -msgid "show object type (one of 'blob', 'tree', 'commit', 'tag', ...)" -msgstr "" - -#: builtin/cat-file.c:843 -msgid "show object size" -msgstr "" - -#: builtin/cat-file.c:845 -msgid "allow -s and -t to work with broken/corrupt objects" -msgstr "" - -#: builtin/cat-file.c:847 -msgid "Batch objects requested on stdin (or --batch-all-objects)" -msgstr "" - -#: builtin/cat-file.c:849 -msgid "show full <object> or <rev> contents" -msgstr "" - -#: builtin/cat-file.c:853 -msgid "like --batch, but don't emit <contents>" -msgstr "" - -#: builtin/cat-file.c:857 -msgid "read commands from stdin" -msgstr "" - -#: builtin/cat-file.c:861 -msgid "with --batch[-check]: ignores stdin, batches all known objects" -msgstr "" - -#: builtin/cat-file.c:863 -msgid "Change or optimize batch output" -msgstr "" - -#: builtin/cat-file.c:864 -msgid "buffer --batch output" -msgstr "" - -#: builtin/cat-file.c:866 -msgid "follow in-tree symlinks" -msgstr "" - -#: builtin/cat-file.c:868 -msgid "do not order objects before emitting them" -msgstr "" - -#: builtin/cat-file.c:870 -msgid "" -"Emit object (blob or tree) with conversion or filter (stand-alone, or with " -"batch)" -msgstr "" - -#: builtin/cat-file.c:872 -msgid "run textconv on object's content" -msgstr "" - -#: builtin/cat-file.c:874 -msgid "run filters on object's content" -msgstr "" - -#: builtin/cat-file.c:875 -msgid "blob|tree" -msgstr "" - -#: builtin/cat-file.c:876 -msgid "use a <path> for (--textconv | --filters); Not with 'batch'" -msgstr "" - -#: builtin/cat-file.c:894 -#, c-format -msgid "'%s=<%s>' needs '%s' or '%s'" -msgstr "" - -#: builtin/cat-file.c:896 -msgid "path|tree-ish" -msgstr "" - -#: builtin/cat-file.c:903 builtin/cat-file.c:906 builtin/cat-file.c:909 -#, c-format -msgid "'%s' requires a batch mode" -msgstr "" - -#: builtin/cat-file.c:921 -#, c-format -msgid "'-%c' is incompatible with batch mode" -msgstr "" - -#: builtin/cat-file.c:924 -msgid "batch modes take no arguments" -msgstr "" - -#: builtin/cat-file.c:932 builtin/cat-file.c:935 -#, c-format -msgid "<rev> required with '%s'" -msgstr "" - -#: builtin/cat-file.c:938 -#, c-format -msgid "<object> required with '-%c'" -msgstr "" - -#: builtin/cat-file.c:943 builtin/notes.c:374 builtin/notes.c:429 -#: builtin/notes.c:507 builtin/notes.c:519 builtin/notes.c:596 -#: builtin/notes.c:663 builtin/notes.c:813 builtin/notes.c:965 -#: builtin/notes.c:987 builtin/prune-packed.c:25 builtin/receive-pack.c:2489 -#: builtin/tag.c:592 -msgid "too many arguments" -msgstr "" - -#: builtin/cat-file.c:947 -#, c-format -msgid "only two arguments allowed in <type> <object> mode, not %d" -msgstr "" - -#: builtin/check-attr.c:13 -msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..." -msgstr "" - -#: builtin/check-attr.c:14 -msgid "git check-attr --stdin [-z] [-a | --all | <attr>...]" -msgstr "" - -#: builtin/check-attr.c:21 -msgid "report all attributes set on file" -msgstr "" - -#: builtin/check-attr.c:22 -msgid "use .gitattributes only from the index" -msgstr "" - -#: builtin/check-attr.c:23 builtin/check-ignore.c:25 builtin/hash-object.c:101 -msgid "read file names from stdin" -msgstr "" - -#: builtin/check-attr.c:25 builtin/check-ignore.c:27 -msgid "terminate input and output records by a NUL character" -msgstr "" - -#: builtin/check-ignore.c:21 builtin/checkout.c:1550 builtin/gc.c:550 -#: builtin/worktree.c:565 -msgid "suppress progress reporting" -msgstr "" - -#: builtin/check-ignore.c:29 -msgid "show non-matching input paths" -msgstr "" - -#: builtin/check-ignore.c:31 -msgid "ignore index when checking" -msgstr "" - -#: builtin/check-ignore.c:165 -msgid "cannot specify pathnames with --stdin" -msgstr "" - -#: builtin/check-ignore.c:168 -msgid "-z only makes sense with --stdin" -msgstr "" - -#: builtin/check-ignore.c:170 -msgid "no path specified" -msgstr "" - -#: builtin/check-ignore.c:174 -msgid "--quiet is only valid with a single pathname" -msgstr "" - -#: builtin/check-ignore.c:176 -msgid "cannot have both --quiet and --verbose" -msgstr "" - -#: builtin/check-ignore.c:179 -msgid "--non-matching is only valid with --verbose" -msgstr "" - -#: builtin/check-mailmap.c:9 -msgid "git check-mailmap [<options>] <contact>..." -msgstr "" - -#: builtin/check-mailmap.c:14 -msgid "also read contacts from stdin" -msgstr "" - -#: builtin/check-mailmap.c:25 -#, c-format -msgid "unable to parse contact: %s" -msgstr "" - -#: builtin/check-mailmap.c:48 -msgid "no contacts specified" -msgstr "" - -#: builtin/checkout--worker.c:110 -msgid "git checkout--worker [<options>]" -msgstr "" - -#: builtin/checkout--worker.c:118 builtin/checkout-index.c:235 -#: builtin/column.c:31 builtin/column.c:32 builtin/submodule--helper.c:1878 -#: builtin/submodule--helper.c:1881 builtin/submodule--helper.c:1889 -#: builtin/submodule--helper.c:2716 builtin/worktree.c:563 -#: builtin/worktree.c:808 -msgid "string" -msgstr "" - -#: builtin/checkout--worker.c:119 builtin/checkout-index.c:236 -msgid "when creating files, prepend <string>" -msgstr "" - -#: builtin/checkout-index.c:184 -msgid "git checkout-index [<options>] [--] [<file>...]" -msgstr "" - -#: builtin/checkout-index.c:201 -msgid "stage should be between 1 and 3 or all" -msgstr "" - -#: builtin/checkout-index.c:219 -msgid "check out all files in the index" -msgstr "" - -#: builtin/checkout-index.c:221 -msgid "do not skip files with skip-worktree set" -msgstr "" - -#: builtin/checkout-index.c:222 -msgid "force overwrite of existing files" -msgstr "" - -#: builtin/checkout-index.c:224 -msgid "no warning for existing files and files not in index" -msgstr "" - -#: builtin/checkout-index.c:226 -msgid "don't checkout new files" -msgstr "" - -#: builtin/checkout-index.c:228 -msgid "update stat information in the index file" -msgstr "" - -#: builtin/checkout-index.c:232 -msgid "read list of paths from the standard input" -msgstr "" - -#: builtin/checkout-index.c:234 -msgid "write the content to temporary files" -msgstr "" - -#: builtin/checkout-index.c:238 -msgid "copy out the files from named stage" -msgstr "" - -#: builtin/checkout.c:34 -msgid "git checkout [<options>] <branch>" -msgstr "" - -#: builtin/checkout.c:35 -msgid "git checkout [<options>] [<branch>] -- <file>..." -msgstr "" - -#: builtin/checkout.c:40 -msgid "git switch [<options>] [<branch>]" -msgstr "" - -#: builtin/checkout.c:45 -msgid "git restore [<options>] [--source=<branch>] <file>..." -msgstr "" - -#: builtin/checkout.c:199 builtin/checkout.c:238 -#, c-format -msgid "path '%s' does not have our version" -msgstr "" - -#: builtin/checkout.c:201 builtin/checkout.c:240 -#, c-format -msgid "path '%s' does not have their version" -msgstr "" - -#: builtin/checkout.c:217 -#, c-format -msgid "path '%s' does not have all necessary versions" -msgstr "" - -#: builtin/checkout.c:271 -#, c-format -msgid "path '%s' does not have necessary versions" -msgstr "" - -#: builtin/checkout.c:291 -#, c-format -msgid "path '%s': cannot merge" -msgstr "" - -#: builtin/checkout.c:307 -#, c-format -msgid "Unable to add merge result for '%s'" -msgstr "" - -#: builtin/checkout.c:424 -#, c-format -msgid "Recreated %d merge conflict" -msgid_plural "Recreated %d merge conflicts" -msgstr[0] "" -msgstr[1] "" - -#: builtin/checkout.c:429 -#, c-format -msgid "Updated %d path from %s" -msgid_plural "Updated %d paths from %s" -msgstr[0] "" -msgstr[1] "" - -#: builtin/checkout.c:436 -#, c-format -msgid "Updated %d path from the index" -msgid_plural "Updated %d paths from the index" -msgstr[0] "" -msgstr[1] "" - -#: builtin/checkout.c:459 builtin/checkout.c:462 builtin/checkout.c:465 -#: builtin/checkout.c:469 -#, c-format -msgid "'%s' cannot be used with updating paths" -msgstr "" - -#: builtin/checkout.c:479 -#, c-format -msgid "Cannot update paths and switch to branch '%s' at the same time." -msgstr "" - -#: builtin/checkout.c:483 -#, c-format -msgid "neither '%s' or '%s' is specified" -msgstr "" - -#: builtin/checkout.c:487 -#, c-format -msgid "'%s' must be used when '%s' is not specified" -msgstr "" - -#: builtin/checkout.c:492 builtin/checkout.c:497 -#, c-format -msgid "'%s' or '%s' cannot be used with %s" -msgstr "" - -#: builtin/checkout.c:571 builtin/checkout.c:578 -#, c-format -msgid "path '%s' is unmerged" -msgstr "" - -#: builtin/checkout.c:753 -msgid "you need to resolve your current index first" -msgstr "" - -#: builtin/checkout.c:809 -#, c-format -msgid "" -"cannot continue with staged changes in the following files:\n" -"%s" -msgstr "" - -#: builtin/checkout.c:902 -#, c-format -msgid "Can not do reflog for '%s': %s\n" -msgstr "" - -#: builtin/checkout.c:947 -msgid "HEAD is now at" -msgstr "" - -#: builtin/checkout.c:951 builtin/clone.c:615 t/helper/test-fast-rebase.c:203 -msgid "unable to update HEAD" -msgstr "" - -#: builtin/checkout.c:955 -#, c-format -msgid "Reset branch '%s'\n" -msgstr "" - -#: builtin/checkout.c:958 -#, c-format -msgid "Already on '%s'\n" -msgstr "" - -#: builtin/checkout.c:962 -#, c-format -msgid "Switched to and reset branch '%s'\n" -msgstr "" - -#: builtin/checkout.c:964 builtin/checkout.c:1398 -#, c-format -msgid "Switched to a new branch '%s'\n" -msgstr "" - -#: builtin/checkout.c:966 -#, c-format -msgid "Switched to branch '%s'\n" -msgstr "" - -#: builtin/checkout.c:1017 -#, c-format -msgid " ... and %d more.\n" -msgstr "" - -#: builtin/checkout.c:1023 -#, c-format -msgid "" -"Warning: you are leaving %d commit behind, not connected to\n" -"any of your branches:\n" -"\n" -"%s\n" -msgid_plural "" -"Warning: you are leaving %d commits behind, not connected to\n" -"any of your branches:\n" -"\n" -"%s\n" -msgstr[0] "" -msgstr[1] "" - -#: builtin/checkout.c:1042 -#, c-format -msgid "" -"If you want to keep it by creating a new branch, this may be a good time\n" -"to do so with:\n" -"\n" -" git branch <new-branch-name> %s\n" -"\n" -msgid_plural "" -"If you want to keep them by creating a new branch, this may be a good time\n" -"to do so with:\n" -"\n" -" git branch <new-branch-name> %s\n" -"\n" -msgstr[0] "" -msgstr[1] "" - -#: builtin/checkout.c:1077 -msgid "internal error in revision walk" -msgstr "" - -#: builtin/checkout.c:1081 -msgid "Previous HEAD position was" -msgstr "" - -#: builtin/checkout.c:1124 builtin/checkout.c:1393 -msgid "You are on a branch yet to be born" -msgstr "" - -#: builtin/checkout.c:1206 -#, c-format -msgid "" -"'%s' could be both a local file and a tracking branch.\n" -"Please use -- (and optionally --no-guess) to disambiguate" -msgstr "" - -#: builtin/checkout.c:1213 -msgid "" -"If you meant to check out a remote tracking branch on, e.g. 'origin',\n" -"you can do so by fully qualifying the name with the --track option:\n" -"\n" -" git checkout --track origin/<name>\n" -"\n" -"If you'd like to always have checkouts of an ambiguous <name> prefer\n" -"one remote, e.g. the 'origin' remote, consider setting\n" -"checkout.defaultRemote=origin in your config." -msgstr "" - -#: builtin/checkout.c:1223 -#, c-format -msgid "'%s' matched multiple (%d) remote tracking branches" -msgstr "" - -#: builtin/checkout.c:1289 -msgid "only one reference expected" -msgstr "" - -#: builtin/checkout.c:1306 -#, c-format -msgid "only one reference expected, %d given." -msgstr "" - -#: builtin/checkout.c:1352 builtin/worktree.c:338 builtin/worktree.c:508 -#, c-format -msgid "invalid reference: %s" -msgstr "" - -#: builtin/checkout.c:1365 builtin/checkout.c:1744 -#, c-format -msgid "reference is not a tree: %s" -msgstr "" - -#: builtin/checkout.c:1413 -#, c-format -msgid "a branch is expected, got tag '%s'" -msgstr "" - -#: builtin/checkout.c:1415 -#, c-format -msgid "a branch is expected, got remote branch '%s'" -msgstr "" - -#: builtin/checkout.c:1417 builtin/checkout.c:1426 -#, c-format -msgid "a branch is expected, got '%s'" -msgstr "" - -#: builtin/checkout.c:1420 -#, c-format -msgid "a branch is expected, got commit '%s'" -msgstr "" - -#: builtin/checkout.c:1429 -msgid "" -"If you want to detach HEAD at the commit, try again with the --detach option." -msgstr "" - -#: builtin/checkout.c:1442 -msgid "" -"cannot switch branch while merging\n" -"Consider \"git merge --quit\" or \"git worktree add\"." -msgstr "" - -#: builtin/checkout.c:1446 -msgid "" -"cannot switch branch in the middle of an am session\n" -"Consider \"git am --quit\" or \"git worktree add\"." -msgstr "" - -#: builtin/checkout.c:1450 -msgid "" -"cannot switch branch while rebasing\n" -"Consider \"git rebase --quit\" or \"git worktree add\"." -msgstr "" - -#: builtin/checkout.c:1454 -msgid "" -"cannot switch branch while cherry-picking\n" -"Consider \"git cherry-pick --quit\" or \"git worktree add\"." -msgstr "" - -#: builtin/checkout.c:1458 -msgid "" -"cannot switch branch while reverting\n" -"Consider \"git revert --quit\" or \"git worktree add\"." -msgstr "" - -#: builtin/checkout.c:1462 -msgid "you are switching branch while bisecting" -msgstr "" - -#: builtin/checkout.c:1469 -msgid "paths cannot be used with switching branches" -msgstr "" - -#: builtin/checkout.c:1472 builtin/checkout.c:1476 builtin/checkout.c:1480 -#, c-format -msgid "'%s' cannot be used with switching branches" -msgstr "" - -#: builtin/checkout.c:1484 builtin/checkout.c:1487 builtin/checkout.c:1490 -#: builtin/checkout.c:1495 builtin/checkout.c:1500 -#, c-format -msgid "'%s' cannot be used with '%s'" -msgstr "" - -#: builtin/checkout.c:1497 -#, c-format -msgid "'%s' cannot take <start-point>" -msgstr "" - -#: builtin/checkout.c:1505 -#, c-format -msgid "Cannot switch branch to a non-commit '%s'" -msgstr "" - -#: builtin/checkout.c:1512 -msgid "missing branch or commit argument" -msgstr "" - -#: builtin/checkout.c:1555 -msgid "perform a 3-way merge with the new branch" -msgstr "" - -#: builtin/checkout.c:1556 builtin/log.c:1844 parse-options.h:354 -msgid "style" -msgstr "" - -#: builtin/checkout.c:1557 -msgid "conflict style (merge, diff3, or zdiff3)" -msgstr "" - -#: builtin/checkout.c:1569 builtin/worktree.c:560 -msgid "detach HEAD at named commit" -msgstr "" - -#: builtin/checkout.c:1574 -msgid "force checkout (throw away local modifications)" -msgstr "" - -#: builtin/checkout.c:1576 -msgid "new-branch" -msgstr "" - -#: builtin/checkout.c:1576 -msgid "new unparented branch" -msgstr "" - -#: builtin/checkout.c:1578 builtin/merge.c:305 -msgid "update ignored files (default)" -msgstr "" - -#: builtin/checkout.c:1581 -msgid "do not check if another worktree is holding the given ref" -msgstr "" - -#: builtin/checkout.c:1594 -msgid "checkout our version for unmerged files" -msgstr "" - -#: builtin/checkout.c:1597 -msgid "checkout their version for unmerged files" -msgstr "" - -#: builtin/checkout.c:1601 -msgid "do not limit pathspecs to sparse entries only" -msgstr "" - -#: builtin/checkout.c:1659 -#, c-format -msgid "options '-%c', '-%c', and '%s' cannot be used together" -msgstr "" - -#: builtin/checkout.c:1700 -msgid "--track needs a branch name" -msgstr "" - -#: builtin/checkout.c:1705 -#, c-format -msgid "missing branch name; try -%c" -msgstr "" - -#: builtin/checkout.c:1737 -#, c-format -msgid "could not resolve %s" -msgstr "" - -#: builtin/checkout.c:1753 -msgid "invalid path specification" -msgstr "" - -#: builtin/checkout.c:1760 -#, c-format -msgid "'%s' is not a commit and a branch '%s' cannot be created from it" -msgstr "" - -#: builtin/checkout.c:1764 -#, c-format -msgid "git checkout: --detach does not take a path argument '%s'" -msgstr "" - -#: builtin/checkout.c:1789 -msgid "" -"git checkout: --ours/--theirs, --force and --merge are incompatible when\n" -"checking out of the index." -msgstr "" - -#: builtin/checkout.c:1794 -msgid "you must specify path(s) to restore" -msgstr "" - -#: builtin/checkout.c:1819 builtin/checkout.c:1821 builtin/checkout.c:1873 -#: builtin/checkout.c:1875 builtin/clone.c:130 builtin/remote.c:171 -#: builtin/remote.c:173 builtin/submodule--helper.c:3038 -#: builtin/submodule--helper.c:3371 builtin/worktree.c:556 -#: builtin/worktree.c:558 -msgid "branch" -msgstr "" - -#: builtin/checkout.c:1820 -msgid "create and checkout a new branch" -msgstr "" - -#: builtin/checkout.c:1822 -msgid "create/reset and checkout a branch" -msgstr "" - -#: builtin/checkout.c:1823 -msgid "create reflog for new branch" -msgstr "" - -#: builtin/checkout.c:1825 -msgid "second guess 'git checkout <no-such-branch>' (default)" -msgstr "" - -#: builtin/checkout.c:1826 -msgid "use overlay mode (default)" -msgstr "" - -#: builtin/checkout.c:1874 -msgid "create and switch to a new branch" -msgstr "" - -#: builtin/checkout.c:1876 -msgid "create/reset and switch to a branch" -msgstr "" - -#: builtin/checkout.c:1878 -msgid "second guess 'git switch <no-such-branch>'" -msgstr "" - -#: builtin/checkout.c:1880 -msgid "throw away local modifications" -msgstr "" - -#: builtin/checkout.c:1916 -msgid "which tree-ish to checkout from" -msgstr "" - -#: builtin/checkout.c:1918 -msgid "restore the index" -msgstr "" - -#: builtin/checkout.c:1920 -msgid "restore the working tree (default)" -msgstr "" - -#: builtin/checkout.c:1922 -msgid "ignore unmerged entries" -msgstr "" - -#: builtin/checkout.c:1923 -msgid "use overlay mode" -msgstr "" - -#: builtin/clean.c:29 -msgid "" -"git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..." -msgstr "" - -#: builtin/clean.c:33 -#, c-format -msgid "Removing %s\n" -msgstr "" - -#: builtin/clean.c:34 -#, c-format -msgid "Would remove %s\n" -msgstr "" - -#: builtin/clean.c:35 -#, c-format -msgid "Skipping repository %s\n" -msgstr "" - -#: builtin/clean.c:36 -#, c-format -msgid "Would skip repository %s\n" -msgstr "" - -#: builtin/clean.c:38 -#, c-format -msgid "could not lstat %s\n" -msgstr "" - -#: builtin/clean.c:39 -msgid "Refusing to remove current working directory\n" -msgstr "" - -#: builtin/clean.c:40 -msgid "Would refuse to remove current working directory\n" -msgstr "" - -#: builtin/clean.c:326 git-add--interactive.perl:593 -#, c-format -msgid "" -"Prompt help:\n" -"1 - select a numbered item\n" -"foo - select item based on unique prefix\n" -" - (empty) select nothing\n" -msgstr "" - -#: builtin/clean.c:330 git-add--interactive.perl:602 -#, c-format -msgid "" -"Prompt help:\n" -"1 - select a single item\n" -"3-5 - select a range of items\n" -"2-3,6-9 - select multiple ranges\n" -"foo - select item based on unique prefix\n" -"-... - unselect specified items\n" -"* - choose all items\n" -" - (empty) finish selecting\n" -msgstr "" - -#: builtin/clean.c:545 git-add--interactive.perl:568 -#: git-add--interactive.perl:573 -#, c-format, perl-format -msgid "Huh (%s)?\n" -msgstr "" - -#: builtin/clean.c:685 -#, c-format -msgid "Input ignore patterns>> " -msgstr "" - -#: builtin/clean.c:719 -#, c-format -msgid "WARNING: Cannot find items matched by: %s" -msgstr "" - -#: builtin/clean.c:740 -msgid "Select items to delete" -msgstr "" - -#. TRANSLATORS: Make sure to keep [y/N] as is -#: builtin/clean.c:781 -#, c-format -msgid "Remove %s [y/N]? " -msgstr "" - -#: builtin/clean.c:812 -msgid "" -"clean - start cleaning\n" -"filter by pattern - exclude items from deletion\n" -"select by numbers - select items to be deleted by numbers\n" -"ask each - confirm each deletion (like \"rm -i\")\n" -"quit - stop cleaning\n" -"help - this screen\n" -"? - help for prompt selection" -msgstr "" - -#: builtin/clean.c:848 -msgid "Would remove the following item:" -msgid_plural "Would remove the following items:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/clean.c:864 -msgid "No more files to clean, exiting." -msgstr "" - -#: builtin/clean.c:926 -msgid "do not print names of files removed" -msgstr "" - -#: builtin/clean.c:928 -msgid "force" -msgstr "" - -#: builtin/clean.c:929 -msgid "interactive cleaning" -msgstr "" - -#: builtin/clean.c:931 -msgid "remove whole directories" -msgstr "" - -#: builtin/clean.c:932 builtin/describe.c:565 builtin/describe.c:567 -#: builtin/grep.c:938 builtin/log.c:185 builtin/log.c:187 -#: builtin/ls-files.c:651 builtin/name-rev.c:585 builtin/name-rev.c:587 -#: builtin/show-ref.c:179 -msgid "pattern" -msgstr "" - -#: builtin/clean.c:933 -msgid "add <pattern> to ignore rules" -msgstr "" - -#: builtin/clean.c:934 -msgid "remove ignored files, too" -msgstr "" - -#: builtin/clean.c:936 -msgid "remove only ignored files" -msgstr "" - -#: builtin/clean.c:951 -msgid "" -"clean.requireForce set to true and neither -i, -n, nor -f given; refusing to " -"clean" -msgstr "" - -#: builtin/clean.c:954 -msgid "" -"clean.requireForce defaults to true and neither -i, -n, nor -f given; " -"refusing to clean" -msgstr "" - -#: builtin/clean.c:966 -msgid "-x and -X cannot be used together" -msgstr "" - -#: builtin/clone.c:47 -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "" - -#: builtin/clone.c:100 -msgid "don't clone shallow repository" -msgstr "" - -#: builtin/clone.c:102 -msgid "don't create a checkout" -msgstr "" - -#: builtin/clone.c:103 builtin/clone.c:105 builtin/init-db.c:542 -msgid "create a bare repository" -msgstr "" - -#: builtin/clone.c:107 -msgid "create a mirror repository (implies bare)" -msgstr "" - -#: builtin/clone.c:109 -msgid "to clone from a local repository" -msgstr "" - -#: builtin/clone.c:111 -msgid "don't use local hardlinks, always copy" -msgstr "" - -#: builtin/clone.c:113 -msgid "setup as shared repository" -msgstr "" - -#: builtin/clone.c:115 -msgid "pathspec" -msgstr "" - -#: builtin/clone.c:115 -msgid "initialize submodules in the clone" -msgstr "" - -#: builtin/clone.c:119 -msgid "number of submodules cloned in parallel" -msgstr "" - -#: builtin/clone.c:120 builtin/init-db.c:539 -msgid "template-directory" -msgstr "" - -#: builtin/clone.c:121 builtin/init-db.c:540 -msgid "directory from which templates will be used" -msgstr "" - -#: builtin/clone.c:123 builtin/clone.c:125 builtin/submodule--helper.c:1885 -#: builtin/submodule--helper.c:2719 builtin/submodule--helper.c:3378 -msgid "reference repository" -msgstr "" - -#: builtin/clone.c:127 builtin/submodule--helper.c:1887 -#: builtin/submodule--helper.c:2721 -msgid "use --reference only while cloning" -msgstr "" - -#: builtin/clone.c:128 builtin/column.c:27 builtin/fmt-merge-msg.c:27 -#: builtin/init-db.c:550 builtin/merge-file.c:48 builtin/merge.c:290 -#: builtin/pack-objects.c:3967 builtin/repack.c:669 -#: builtin/submodule--helper.c:3380 t/helper/test-simple-ipc.c:595 -#: t/helper/test-simple-ipc.c:597 -msgid "name" -msgstr "" - -#: builtin/clone.c:129 -msgid "use <name> instead of 'origin' to track upstream" -msgstr "" - -#: builtin/clone.c:131 -msgid "checkout <branch> instead of the remote's HEAD" -msgstr "" - -#: builtin/clone.c:133 -msgid "path to git-upload-pack on the remote" -msgstr "" - -#: builtin/clone.c:134 builtin/fetch.c:182 builtin/grep.c:877 -#: builtin/pull.c:212 -msgid "depth" -msgstr "" - -#: builtin/clone.c:135 -msgid "create a shallow clone of that depth" -msgstr "" - -#: builtin/clone.c:136 builtin/fetch.c:184 builtin/pack-objects.c:3956 -#: builtin/pull.c:215 -msgid "time" -msgstr "" - -#: builtin/clone.c:137 -msgid "create a shallow clone since a specific time" -msgstr "" - -#: builtin/clone.c:138 builtin/fetch.c:186 builtin/fetch.c:212 -#: builtin/pull.c:218 builtin/pull.c:243 builtin/rebase.c:1050 -msgid "revision" -msgstr "" - -#: builtin/clone.c:139 builtin/fetch.c:187 builtin/pull.c:219 -msgid "deepen history of shallow clone, excluding rev" -msgstr "" - -#: builtin/clone.c:141 builtin/submodule--helper.c:1897 -#: builtin/submodule--helper.c:2735 -msgid "clone only one branch, HEAD or --branch" -msgstr "" - -#: builtin/clone.c:143 -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "" - -#: builtin/clone.c:145 -msgid "any cloned submodules will be shallow" -msgstr "" - -#: builtin/clone.c:146 builtin/init-db.c:548 -msgid "gitdir" -msgstr "" - -#: builtin/clone.c:147 builtin/init-db.c:549 -msgid "separate git dir from working tree" -msgstr "" - -#: builtin/clone.c:148 -msgid "key=value" -msgstr "" - -#: builtin/clone.c:149 -msgid "set config inside the new repository" -msgstr "" - -#: builtin/clone.c:151 builtin/fetch.c:207 builtin/ls-remote.c:77 -#: builtin/pull.c:234 builtin/push.c:575 builtin/send-pack.c:200 -msgid "server-specific" -msgstr "" - -#: builtin/clone.c:151 builtin/fetch.c:207 builtin/ls-remote.c:77 -#: builtin/pull.c:235 builtin/push.c:575 builtin/send-pack.c:201 -msgid "option to transmit" -msgstr "" - -#: builtin/clone.c:152 builtin/fetch.c:208 builtin/pull.c:238 -#: builtin/push.c:576 -msgid "use IPv4 addresses only" -msgstr "" - -#: builtin/clone.c:154 builtin/fetch.c:210 builtin/pull.c:241 -#: builtin/push.c:578 -msgid "use IPv6 addresses only" -msgstr "" - -#: builtin/clone.c:158 -msgid "apply partial clone filters to submodules" -msgstr "" - -#: builtin/clone.c:160 -msgid "any cloned submodules will use their remote-tracking branch" -msgstr "" - -#: builtin/clone.c:162 -msgid "initialize sparse-checkout file to include only files at root" -msgstr "" - -#: builtin/clone.c:237 -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "" - -#: builtin/clone.c:310 -#, c-format -msgid "%s exists and is not a directory" -msgstr "" - -#: builtin/clone.c:328 -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "" - -#: builtin/clone.c:359 -#, c-format -msgid "failed to create link '%s'" -msgstr "" - -#: builtin/clone.c:363 -#, c-format -msgid "failed to copy file to '%s'" -msgstr "" - -#: builtin/clone.c:368 -#, c-format -msgid "failed to iterate over '%s'" -msgstr "" - -#: builtin/clone.c:395 -#, c-format -msgid "done.\n" -msgstr "" - -#: builtin/clone.c:409 -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" - -#: builtin/clone.c:486 -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "" - -#: builtin/clone.c:603 -#, c-format -msgid "unable to update %s" -msgstr "" - -#: builtin/clone.c:651 -msgid "failed to initialize sparse-checkout" -msgstr "" - -#: builtin/clone.c:674 -msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" -msgstr "" - -#: builtin/clone.c:709 -msgid "unable to checkout working tree" -msgstr "" - -#: builtin/clone.c:793 -msgid "unable to write parameters to config file" -msgstr "" - -#: builtin/clone.c:856 -msgid "cannot repack to clean up" -msgstr "" - -#: builtin/clone.c:858 -msgid "cannot unlink temporary alternates file" -msgstr "" - -#: builtin/clone.c:901 -msgid "Too many arguments." -msgstr "" - -#: builtin/clone.c:905 contrib/scalar/scalar.c:413 -msgid "You must specify a repository to clone." -msgstr "" - -#: builtin/clone.c:918 -#, c-format -msgid "options '%s' and '%s %s' cannot be used together" -msgstr "" - -#: builtin/clone.c:935 -#, c-format -msgid "repository '%s' does not exist" -msgstr "" - -#: builtin/clone.c:939 builtin/fetch.c:2176 -#, c-format -msgid "depth %s is not a positive number" -msgstr "" - -#: builtin/clone.c:949 -#, c-format -msgid "destination path '%s' already exists and is not an empty directory." -msgstr "" - -#: builtin/clone.c:955 -#, c-format -msgid "repository path '%s' already exists and is not an empty directory." -msgstr "" - -#: builtin/clone.c:969 -#, c-format -msgid "working tree '%s' already exists." -msgstr "" - -#: builtin/clone.c:984 builtin/clone.c:1005 builtin/difftool.c:256 -#: builtin/log.c:2037 builtin/worktree.c:350 builtin/worktree.c:382 -#, c-format -msgid "could not create leading directories of '%s'" -msgstr "" - -#: builtin/clone.c:989 -#, c-format -msgid "could not create work tree dir '%s'" -msgstr "" - -#: builtin/clone.c:1009 -#, c-format -msgid "Cloning into bare repository '%s'...\n" -msgstr "" - -#: builtin/clone.c:1011 -#, c-format -msgid "Cloning into '%s'...\n" -msgstr "" - -#: builtin/clone.c:1040 -msgid "" -"clone --recursive is not compatible with both --reference and --reference-if-" -"able" -msgstr "" - -#: builtin/clone.c:1116 builtin/remote.c:201 builtin/remote.c:721 -#, c-format -msgid "'%s' is not a valid remote name" -msgstr "" - -#: builtin/clone.c:1157 -msgid "--depth is ignored in local clones; use file:// instead." -msgstr "" - -#: builtin/clone.c:1159 -msgid "--shallow-since is ignored in local clones; use file:// instead." -msgstr "" - -#: builtin/clone.c:1161 -msgid "--shallow-exclude is ignored in local clones; use file:// instead." -msgstr "" - -#: builtin/clone.c:1163 -msgid "--filter is ignored in local clones; use file:// instead." -msgstr "" - -#: builtin/clone.c:1168 -msgid "source repository is shallow, ignoring --local" -msgstr "" - -#: builtin/clone.c:1173 -msgid "--local is ignored" -msgstr "" - -#: builtin/clone.c:1185 -msgid "cannot clone from filtered bundle" -msgstr "" - -#: builtin/clone.c:1265 builtin/clone.c:1324 -msgid "remote transport reported error" -msgstr "" - -#: builtin/clone.c:1277 builtin/clone.c:1289 -#, c-format -msgid "Remote branch %s not found in upstream %s" -msgstr "" - -#: builtin/clone.c:1292 -msgid "You appear to have cloned an empty repository." -msgstr "" - -#: builtin/column.c:10 -msgid "git column [<options>]" -msgstr "" - -#: builtin/column.c:27 -msgid "lookup config vars" -msgstr "" - -#: builtin/column.c:28 builtin/column.c:29 -msgid "layout to use" -msgstr "" - -#: builtin/column.c:30 -msgid "maximum width" -msgstr "" - -#: builtin/column.c:31 -msgid "padding space on left border" -msgstr "" - -#: builtin/column.c:32 -msgid "padding space on right border" -msgstr "" - -#: builtin/column.c:33 -msgid "padding space between columns" -msgstr "" - -#: builtin/column.c:51 -msgid "--command must be the first argument" -msgstr "" - -#: builtin/commit-graph.c:13 -msgid "" -"git commit-graph verify [--object-dir <objdir>] [--shallow] [--[no-]progress]" -msgstr "" - -#: builtin/commit-graph.c:16 -msgid "" -"git commit-graph write [--object-dir <objdir>] [--append] [--" -"split[=<strategy>]] [--reachable|--stdin-packs|--stdin-commits] [--changed-" -"paths] [--[no-]max-new-filters <n>] [--[no-]progress] <split options>" -msgstr "" - -#: builtin/commit-graph.c:51 builtin/fetch.c:196 builtin/log.c:1813 -msgid "dir" -msgstr "" - -#: builtin/commit-graph.c:52 -msgid "the object directory to store the graph" -msgstr "" - -#: builtin/commit-graph.c:73 -msgid "if the commit-graph is split, only verify the tip file" -msgstr "" - -#: builtin/commit-graph.c:100 -#, c-format -msgid "Could not open commit-graph '%s'" -msgstr "" - -#: builtin/commit-graph.c:137 -#, c-format -msgid "unrecognized --split argument, %s" -msgstr "" - -#: builtin/commit-graph.c:150 -#, c-format -msgid "unexpected non-hex object ID: %s" -msgstr "" - -#: builtin/commit-graph.c:155 -#, c-format -msgid "invalid object: %s" -msgstr "" - -#: builtin/commit-graph.c:205 -msgid "start walk at all refs" -msgstr "" - -#: builtin/commit-graph.c:207 -msgid "scan pack-indexes listed by stdin for commits" -msgstr "" - -#: builtin/commit-graph.c:209 -msgid "start walk at commits listed by stdin" -msgstr "" - -#: builtin/commit-graph.c:211 -msgid "include all commits already in the commit-graph file" -msgstr "" - -#: builtin/commit-graph.c:213 -msgid "enable computation for changed paths" -msgstr "" - -#: builtin/commit-graph.c:215 -msgid "allow writing an incremental commit-graph file" -msgstr "" - -#: builtin/commit-graph.c:219 -msgid "maximum number of commits in a non-base split commit-graph" -msgstr "" - -#: builtin/commit-graph.c:221 -msgid "maximum ratio between two levels of a split commit-graph" -msgstr "" - -#: builtin/commit-graph.c:223 -msgid "only expire files older than a given date-time" -msgstr "" - -#: builtin/commit-graph.c:225 -msgid "maximum number of changed-path Bloom filters to compute" -msgstr "" - -#: builtin/commit-graph.c:251 -msgid "use at most one of --reachable, --stdin-commits, or --stdin-packs" -msgstr "" - -#: builtin/commit-graph.c:282 -msgid "Collecting commits from input" -msgstr "" - -#: builtin/commit-graph.c:328 builtin/multi-pack-index.c:259 -#, c-format -msgid "unrecognized subcommand: %s" -msgstr "" - -#: builtin/commit-tree.c:18 -msgid "" -"git commit-tree [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] [(-F " -"<file>)...] <tree>" -msgstr "" - -#: builtin/commit-tree.c:31 -#, c-format -msgid "duplicate parent %s ignored" -msgstr "" - -#: builtin/commit-tree.c:56 builtin/commit-tree.c:134 builtin/log.c:590 -#, c-format -msgid "not a valid object name %s" -msgstr "" - -#: builtin/commit-tree.c:94 -#, c-format -msgid "git commit-tree: failed to read '%s'" -msgstr "" - -#: builtin/commit-tree.c:96 -#, c-format -msgid "git commit-tree: failed to close '%s'" -msgstr "" - -#: builtin/commit-tree.c:109 -msgid "parent" -msgstr "" - -#: builtin/commit-tree.c:110 -msgid "id of a parent commit object" -msgstr "" - -#: builtin/commit-tree.c:112 builtin/commit.c:1626 builtin/merge.c:284 -#: builtin/notes.c:407 builtin/notes.c:573 builtin/stash.c:1666 -#: builtin/tag.c:455 -msgid "message" -msgstr "" - -#: builtin/commit-tree.c:113 builtin/commit.c:1626 -msgid "commit message" -msgstr "" - -#: builtin/commit-tree.c:116 -msgid "read commit log message from file" -msgstr "" - -#: builtin/commit-tree.c:119 builtin/commit.c:1643 builtin/merge.c:303 -#: builtin/pull.c:180 builtin/revert.c:118 -msgid "GPG sign commit" -msgstr "" - -#: builtin/commit-tree.c:131 -msgid "must give exactly one tree" -msgstr "" - -#: builtin/commit-tree.c:138 -msgid "git commit-tree: failed to read" -msgstr "" - -#: builtin/commit.c:43 -msgid "git commit [<options>] [--] <pathspec>..." -msgstr "" - -#: builtin/commit.c:48 -msgid "git status [<options>] [--] <pathspec>..." -msgstr "" - -#: builtin/commit.c:53 -msgid "" -"You asked to amend the most recent commit, but doing so would make\n" -"it empty. You can repeat your command with --allow-empty, or you can\n" -"remove the commit entirely with \"git reset HEAD^\".\n" -msgstr "" - -#: builtin/commit.c:58 -msgid "" -"The previous cherry-pick is now empty, possibly due to conflict resolution.\n" -"If you wish to commit it anyway, use:\n" -"\n" -" git commit --allow-empty\n" -"\n" -msgstr "" - -#: builtin/commit.c:65 -msgid "Otherwise, please use 'git rebase --skip'\n" -msgstr "" - -#: builtin/commit.c:68 -msgid "Otherwise, please use 'git cherry-pick --skip'\n" -msgstr "" - -#: builtin/commit.c:71 -msgid "" -"and then use:\n" -"\n" -" git cherry-pick --continue\n" -"\n" -"to resume cherry-picking the remaining commits.\n" -"If you wish to skip this commit, use:\n" -"\n" -" git cherry-pick --skip\n" -"\n" -msgstr "" - -#: builtin/commit.c:326 -msgid "failed to unpack HEAD tree object" -msgstr "" - -#: builtin/commit.c:376 -msgid "No paths with --include/--only does not make sense." -msgstr "" - -#: builtin/commit.c:388 -msgid "unable to create temporary index" -msgstr "" - -#: builtin/commit.c:397 -msgid "interactive add failed" -msgstr "" - -#: builtin/commit.c:412 -msgid "unable to update temporary index" -msgstr "" - -#: builtin/commit.c:414 -msgid "Failed to update main cache tree" -msgstr "" - -#: builtin/commit.c:439 builtin/commit.c:462 builtin/commit.c:510 -msgid "unable to write new_index file" -msgstr "" - -#: builtin/commit.c:491 -msgid "cannot do a partial commit during a merge." -msgstr "" - -#: builtin/commit.c:493 -msgid "cannot do a partial commit during a cherry-pick." -msgstr "" - -#: builtin/commit.c:495 -msgid "cannot do a partial commit during a rebase." -msgstr "" - -#: builtin/commit.c:503 -msgid "cannot read the index" -msgstr "" - -#: builtin/commit.c:522 -msgid "unable to write temporary index file" -msgstr "" - -#: builtin/commit.c:620 -#, c-format -msgid "commit '%s' lacks author header" -msgstr "" - -#: builtin/commit.c:622 -#, c-format -msgid "commit '%s' has malformed author line" -msgstr "" - -#: builtin/commit.c:641 -msgid "malformed --author parameter" -msgstr "" - -#: builtin/commit.c:694 -msgid "" -"unable to select a comment character that is not used\n" -"in the current commit message" -msgstr "" - -#: builtin/commit.c:750 builtin/commit.c:784 builtin/commit.c:1170 -#, c-format -msgid "could not lookup commit %s" -msgstr "" - -#: builtin/commit.c:762 builtin/shortlog.c:417 -#, c-format -msgid "(reading log message from standard input)\n" -msgstr "" - -#: builtin/commit.c:764 -msgid "could not read log from standard input" -msgstr "" - -#: builtin/commit.c:768 -#, c-format -msgid "could not read log file '%s'" -msgstr "" - -#: builtin/commit.c:805 -#, c-format -msgid "options '%s' and '%s:%s' cannot be used together" -msgstr "" - -#: builtin/commit.c:817 builtin/commit.c:833 -msgid "could not read SQUASH_MSG" -msgstr "" - -#: builtin/commit.c:824 -msgid "could not read MERGE_MSG" -msgstr "" - -#: builtin/commit.c:884 -msgid "could not write commit template" -msgstr "" - -#: builtin/commit.c:897 -#, c-format -msgid "" -"Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be ignored.\n" -msgstr "" - -#: builtin/commit.c:899 -#, c-format -msgid "" -"Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be ignored, and an empty message aborts the commit.\n" -msgstr "" - -#: builtin/commit.c:903 -#, c-format -msgid "" -"Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be kept; you may remove them yourself if you want to.\n" -msgstr "" - -#: builtin/commit.c:907 -#, c-format -msgid "" -"Please enter the commit message for your changes. Lines starting\n" -"with '%c' will be kept; you may remove them yourself if you want to.\n" -"An empty message aborts the commit.\n" -msgstr "" - -#: builtin/commit.c:919 -msgid "" -"\n" -"It looks like you may be committing a merge.\n" -"If this is not correct, please run\n" -"\tgit update-ref -d MERGE_HEAD\n" -"and try again.\n" -msgstr "" - -#: builtin/commit.c:924 -msgid "" -"\n" -"It looks like you may be committing a cherry-pick.\n" -"If this is not correct, please run\n" -"\tgit update-ref -d CHERRY_PICK_HEAD\n" -"and try again.\n" -msgstr "" - -#: builtin/commit.c:951 -#, c-format -msgid "%sAuthor: %.*s <%.*s>" -msgstr "" - -#: builtin/commit.c:959 -#, c-format -msgid "%sDate: %s" -msgstr "" - -#: builtin/commit.c:966 -#, c-format -msgid "%sCommitter: %.*s <%.*s>" -msgstr "" - -#: builtin/commit.c:984 -msgid "Cannot read index" -msgstr "" - -#: builtin/commit.c:1029 -msgid "unable to pass trailers to --trailers" -msgstr "" - -#: builtin/commit.c:1069 -msgid "Error building trees" -msgstr "" - -#: builtin/commit.c:1083 builtin/tag.c:317 -#, c-format -msgid "Please supply the message using either -m or -F option.\n" -msgstr "" - -#: builtin/commit.c:1128 -#, c-format -msgid "--author '%s' is not 'Name <email>' and matches no existing author" -msgstr "" - -#: builtin/commit.c:1142 -#, c-format -msgid "Invalid ignored mode '%s'" -msgstr "" - -#: builtin/commit.c:1160 builtin/commit.c:1450 -#, c-format -msgid "Invalid untracked files mode '%s'" -msgstr "" - -#: builtin/commit.c:1231 -msgid "You are in the middle of a merge -- cannot reword." -msgstr "" - -#: builtin/commit.c:1233 -msgid "You are in the middle of a cherry-pick -- cannot reword." -msgstr "" - -#: builtin/commit.c:1236 -#, c-format -msgid "reword option of '%s' and path '%s' cannot be used together" -msgstr "" - -#: builtin/commit.c:1238 -#, c-format -msgid "reword option of '%s' and '%s' cannot be used together" -msgstr "" - -#: builtin/commit.c:1263 -msgid "You have nothing to amend." -msgstr "" - -#: builtin/commit.c:1266 -msgid "You are in the middle of a merge -- cannot amend." -msgstr "" - -#: builtin/commit.c:1268 -msgid "You are in the middle of a cherry-pick -- cannot amend." -msgstr "" - -#: builtin/commit.c:1270 -msgid "You are in the middle of a rebase -- cannot amend." -msgstr "" - -#: builtin/commit.c:1290 -msgid "--reset-author can be used only with -C, -c or --amend." -msgstr "" - -#: builtin/commit.c:1337 -#, c-format -msgid "unknown option: --fixup=%s:%s" -msgstr "" - -#: builtin/commit.c:1354 -#, c-format -msgid "paths '%s ...' with -a does not make sense" -msgstr "" - -#: builtin/commit.c:1485 builtin/commit.c:1654 -msgid "show status concisely" -msgstr "" - -#: builtin/commit.c:1487 builtin/commit.c:1656 -msgid "show branch information" -msgstr "" - -#: builtin/commit.c:1489 -msgid "show stash information" -msgstr "" - -#: builtin/commit.c:1491 builtin/commit.c:1658 -msgid "compute full ahead/behind values" -msgstr "" - -#: builtin/commit.c:1493 -msgid "version" -msgstr "" - -#: builtin/commit.c:1493 builtin/commit.c:1660 builtin/push.c:551 -#: builtin/worktree.c:765 -msgid "machine-readable output" -msgstr "" - -#: builtin/commit.c:1496 builtin/commit.c:1662 -msgid "show status in long format (default)" -msgstr "" - -#: builtin/commit.c:1499 builtin/commit.c:1665 -msgid "terminate entries with NUL" -msgstr "" - -#: builtin/commit.c:1501 builtin/commit.c:1505 builtin/commit.c:1668 -#: builtin/fast-export.c:1172 builtin/fast-export.c:1175 -#: builtin/fast-export.c:1178 builtin/rebase.c:1139 parse-options.h:368 -msgid "mode" -msgstr "" - -#: builtin/commit.c:1502 builtin/commit.c:1668 -msgid "show untracked files, optional modes: all, normal, no. (Default: all)" -msgstr "" - -#: builtin/commit.c:1506 -msgid "" -"show ignored files, optional modes: traditional, matching, no. (Default: " -"traditional)" -msgstr "" - -#: builtin/commit.c:1508 parse-options.h:197 -msgid "when" -msgstr "" - -#: builtin/commit.c:1509 -msgid "" -"ignore changes to submodules, optional when: all, dirty, untracked. " -"(Default: all)" -msgstr "" - -#: builtin/commit.c:1511 -msgid "list untracked files in columns" -msgstr "" - -#: builtin/commit.c:1512 -msgid "do not detect renames" -msgstr "" - -#: builtin/commit.c:1514 -msgid "detect renames, optionally set similarity index" -msgstr "" - -#: builtin/commit.c:1537 -msgid "Unsupported combination of ignored and untracked-files arguments" -msgstr "" - -#: builtin/commit.c:1619 -msgid "suppress summary after successful commit" -msgstr "" - -#: builtin/commit.c:1620 -msgid "show diff in commit message template" -msgstr "" - -#: builtin/commit.c:1622 -msgid "Commit message options" -msgstr "" - -#: builtin/commit.c:1623 builtin/merge.c:288 builtin/tag.c:457 -msgid "read message from file" -msgstr "" - -#: builtin/commit.c:1624 -msgid "author" -msgstr "" - -#: builtin/commit.c:1624 -msgid "override author for commit" -msgstr "" - -#: builtin/commit.c:1625 builtin/gc.c:551 -msgid "date" -msgstr "" - -#: builtin/commit.c:1625 -msgid "override date for commit" -msgstr "" - -#: builtin/commit.c:1627 builtin/commit.c:1628 builtin/commit.c:1634 -#: parse-options.h:360 ref-filter.h:89 -msgid "commit" -msgstr "" - -#: builtin/commit.c:1627 -msgid "reuse and edit message from specified commit" -msgstr "" - -#: builtin/commit.c:1628 -msgid "reuse message from specified commit" -msgstr "" - -#. TRANSLATORS: Leave "[(amend|reword):]" as-is, -#. and only translate <commit>. -#. -#: builtin/commit.c:1633 -msgid "[(amend|reword):]commit" -msgstr "" - -#: builtin/commit.c:1633 -msgid "" -"use autosquash formatted message to fixup or amend/reword specified commit" -msgstr "" - -#: builtin/commit.c:1634 -msgid "use autosquash formatted message to squash specified commit" -msgstr "" - -#: builtin/commit.c:1635 -msgid "the commit is authored by me now (used with -C/-c/--amend)" -msgstr "" - -#: builtin/commit.c:1636 builtin/interpret-trailers.c:111 -msgid "trailer" -msgstr "" - -#: builtin/commit.c:1636 -msgid "add custom trailer(s)" -msgstr "" - -#: builtin/commit.c:1637 builtin/log.c:1788 builtin/merge.c:306 -#: builtin/pull.c:146 builtin/revert.c:110 -msgid "add a Signed-off-by trailer" -msgstr "" - -#: builtin/commit.c:1638 -msgid "use specified template file" -msgstr "" - -#: builtin/commit.c:1639 -msgid "force edit of commit" -msgstr "" - -#: builtin/commit.c:1641 -msgid "include status in commit message template" -msgstr "" - -#: builtin/commit.c:1646 -msgid "Commit contents options" -msgstr "" - -#: builtin/commit.c:1647 -msgid "commit all changed files" -msgstr "" - -#: builtin/commit.c:1648 -msgid "add specified files to index for commit" -msgstr "" - -#: builtin/commit.c:1649 -msgid "interactively add files" -msgstr "" - -#: builtin/commit.c:1650 -msgid "interactively add changes" -msgstr "" - -#: builtin/commit.c:1651 -msgid "commit only specified files" -msgstr "" - -#: builtin/commit.c:1652 -msgid "bypass pre-commit and commit-msg hooks" -msgstr "" - -#: builtin/commit.c:1653 -msgid "show what would be committed" -msgstr "" - -#: builtin/commit.c:1666 -msgid "amend previous commit" -msgstr "" - -#: builtin/commit.c:1667 -msgid "bypass post-rewrite hook" -msgstr "" - -#: builtin/commit.c:1674 -msgid "ok to record an empty change" -msgstr "" - -#: builtin/commit.c:1676 -msgid "ok to record a change with an empty message" -msgstr "" - -#: builtin/commit.c:1752 -#, c-format -msgid "Corrupt MERGE_HEAD file (%s)" -msgstr "" - -#: builtin/commit.c:1759 -msgid "could not read MERGE_MODE" -msgstr "" - -#: builtin/commit.c:1780 -#, c-format -msgid "could not read commit message: %s" -msgstr "" - -#: builtin/commit.c:1787 -#, c-format -msgid "Aborting commit due to empty commit message.\n" -msgstr "" - -#: builtin/commit.c:1792 -#, c-format -msgid "Aborting commit; you did not edit the message.\n" -msgstr "" - -#: builtin/commit.c:1803 -#, c-format -msgid "Aborting commit due to empty commit message body.\n" -msgstr "" - -#: builtin/commit.c:1839 -msgid "" -"repository has been updated, but unable to write\n" -"new_index file. Check that disk is not full and quota is\n" -"not exceeded, and then \"git restore --staged :/\" to recover." -msgstr "" - -#: builtin/config.c:11 -msgid "git config [<options>]" -msgstr "" - -#: builtin/config.c:109 builtin/env--helper.c:27 -#, c-format -msgid "unrecognized --type argument, %s" -msgstr "" - -#: builtin/config.c:121 -msgid "only one type at a time" -msgstr "" - -#: builtin/config.c:130 -msgid "Config file location" -msgstr "" - -#: builtin/config.c:131 -msgid "use global config file" -msgstr "" - -#: builtin/config.c:132 -msgid "use system config file" -msgstr "" - -#: builtin/config.c:133 -msgid "use repository config file" -msgstr "" - -#: builtin/config.c:134 -msgid "use per-worktree config file" -msgstr "" - -#: builtin/config.c:135 -msgid "use given config file" -msgstr "" - -#: builtin/config.c:136 -msgid "blob-id" -msgstr "" - -#: builtin/config.c:136 -msgid "read config from given blob object" -msgstr "" - -#: builtin/config.c:137 -msgid "Action" -msgstr "" - -#: builtin/config.c:138 -msgid "get value: name [value-pattern]" -msgstr "" - -#: builtin/config.c:139 -msgid "get all values: key [value-pattern]" -msgstr "" - -#: builtin/config.c:140 -msgid "get values for regexp: name-regex [value-pattern]" -msgstr "" - -#: builtin/config.c:141 -msgid "get value specific for the URL: section[.var] URL" -msgstr "" - -#: builtin/config.c:142 -msgid "replace all matching variables: name value [value-pattern]" -msgstr "" - -#: builtin/config.c:143 -msgid "add a new variable: name value" -msgstr "" - -#: builtin/config.c:144 -msgid "remove a variable: name [value-pattern]" -msgstr "" - -#: builtin/config.c:145 -msgid "remove all matches: name [value-pattern]" -msgstr "" - -#: builtin/config.c:146 -msgid "rename section: old-name new-name" -msgstr "" - -#: builtin/config.c:147 -msgid "remove a section: name" -msgstr "" - -#: builtin/config.c:148 -msgid "list all" -msgstr "" - -#: builtin/config.c:149 -msgid "use string equality when comparing values to 'value-pattern'" -msgstr "" - -#: builtin/config.c:150 -msgid "open an editor" -msgstr "" - -#: builtin/config.c:151 -msgid "find the color configured: slot [default]" -msgstr "" - -#: builtin/config.c:152 -msgid "find the color setting: slot [stdout-is-tty]" -msgstr "" - -#: builtin/config.c:153 -msgid "Type" -msgstr "" - -#: builtin/config.c:154 builtin/env--helper.c:42 builtin/hash-object.c:97 -msgid "type" -msgstr "" - -#: builtin/config.c:154 builtin/env--helper.c:43 -msgid "value is given this type" -msgstr "" - -#: builtin/config.c:155 -msgid "value is \"true\" or \"false\"" -msgstr "" - -#: builtin/config.c:156 -msgid "value is decimal number" -msgstr "" - -#: builtin/config.c:157 -msgid "value is --bool or --int" -msgstr "" - -#: builtin/config.c:158 -msgid "value is --bool or string" -msgstr "" - -#: builtin/config.c:159 -msgid "value is a path (file or directory name)" -msgstr "" - -#: builtin/config.c:160 -msgid "value is an expiry date" -msgstr "" - -#: builtin/config.c:161 -msgid "Other" -msgstr "" - -#: builtin/config.c:162 -msgid "terminate values with NUL byte" -msgstr "" - -#: builtin/config.c:163 -msgid "show variable names only" -msgstr "" - -#: builtin/config.c:164 -msgid "respect include directives on lookup" -msgstr "" - -#: builtin/config.c:165 -msgid "show origin of config (file, standard input, blob, command line)" -msgstr "" - -#: builtin/config.c:166 -msgid "show scope of config (worktree, local, global, system, command)" -msgstr "" - -#: builtin/config.c:167 builtin/env--helper.c:45 -msgid "value" -msgstr "" - -#: builtin/config.c:167 -msgid "with --get, use default value when missing entry" -msgstr "" - -#: builtin/config.c:181 -#, c-format -msgid "wrong number of arguments, should be %d" -msgstr "" - -#: builtin/config.c:183 -#, c-format -msgid "wrong number of arguments, should be from %d to %d" -msgstr "" - -#: builtin/config.c:339 -#, c-format -msgid "invalid key pattern: %s" -msgstr "" - -#: builtin/config.c:377 -#, c-format -msgid "failed to format default config value: %s" -msgstr "" - -#: builtin/config.c:441 -#, c-format -msgid "cannot parse color '%s'" -msgstr "" - -#: builtin/config.c:483 -msgid "unable to parse default color value" -msgstr "" - -#: builtin/config.c:536 builtin/config.c:833 -msgid "not in a git directory" -msgstr "" - -#: builtin/config.c:539 -msgid "writing to stdin is not supported" -msgstr "" - -#: builtin/config.c:542 -msgid "writing config blobs is not supported" -msgstr "" - -#: builtin/config.c:627 -#, c-format -msgid "" -"# This is Git's per-user configuration file.\n" -"[user]\n" -"# Please adapt and uncomment the following lines:\n" -"#\tname = %s\n" -"#\temail = %s\n" -msgstr "" - -#: builtin/config.c:652 -msgid "only one config file at a time" -msgstr "" - -#: builtin/config.c:658 -msgid "--local can only be used inside a git repository" -msgstr "" - -#: builtin/config.c:660 -msgid "--blob can only be used inside a git repository" -msgstr "" - -#: builtin/config.c:662 -msgid "--worktree can only be used inside a git repository" -msgstr "" - -#: builtin/config.c:684 -msgid "$HOME not set" -msgstr "" - -#: builtin/config.c:708 -msgid "" -"--worktree cannot be used with multiple working trees unless the config\n" -"extension worktreeConfig is enabled. Please read \"CONFIGURATION FILE\"\n" -"section in \"git help worktree\" for details" -msgstr "" - -#: builtin/config.c:743 -msgid "--get-color and variable type are incoherent" -msgstr "" - -#: builtin/config.c:748 -msgid "only one action at a time" -msgstr "" - -#: builtin/config.c:761 -msgid "--name-only is only applicable to --list or --get-regexp" -msgstr "" - -#: builtin/config.c:767 -msgid "" -"--show-origin is only applicable to --get, --get-all, --get-regexp, and --" -"list" -msgstr "" - -#: builtin/config.c:773 -msgid "--default is only applicable to --get" -msgstr "" - -#: builtin/config.c:806 -msgid "--fixed-value only applies with 'value-pattern'" -msgstr "" - -#: builtin/config.c:822 -#, c-format -msgid "unable to read config file '%s'" -msgstr "" - -#: builtin/config.c:825 -msgid "error processing config file(s)" -msgstr "" - -#: builtin/config.c:835 -msgid "editing stdin is not supported" -msgstr "" - -#: builtin/config.c:837 -msgid "editing blobs is not supported" -msgstr "" - -#: builtin/config.c:851 -#, c-format -msgid "cannot create configuration file %s" -msgstr "" - -#: builtin/config.c:864 -#, c-format -msgid "" -"cannot overwrite multiple values with a single value\n" -" Use a regexp, --add or --replace-all to change %s." -msgstr "" - -#: builtin/config.c:943 builtin/config.c:954 -#, c-format -msgid "no such section: %s" -msgstr "" - -#: builtin/count-objects.c:100 -msgid "print sizes in human readable format" -msgstr "" - -#: builtin/credential-cache--daemon.c:227 -#, c-format -msgid "" -"The permissions on your socket directory are too loose; other\n" -"users may be able to read your cached credentials. Consider running:\n" -"\n" -"\tchmod 0700 %s" -msgstr "" - -#: builtin/credential-cache--daemon.c:276 -msgid "print debugging messages to stderr" -msgstr "" - -#: builtin/credential-cache--daemon.c:316 -msgid "credential-cache--daemon unavailable; no unix socket support" -msgstr "" - -#: builtin/credential-cache.c:180 -msgid "credential-cache unavailable; no unix socket support" -msgstr "" - -#: builtin/credential-store.c:66 -#, c-format -msgid "unable to get credential storage lock in %d ms" -msgstr "" - -#: builtin/describe.c:26 -msgid "git describe [<options>] [<commit-ish>...]" -msgstr "" - -#: builtin/describe.c:27 -msgid "git describe [<options>] --dirty" -msgstr "" - -#: builtin/describe.c:63 -msgid "head" -msgstr "" - -#: builtin/describe.c:63 -msgid "lightweight" -msgstr "" - -#: builtin/describe.c:63 -msgid "annotated" -msgstr "" - -#: builtin/describe.c:277 -#, c-format -msgid "annotated tag %s not available" -msgstr "" - -#: builtin/describe.c:281 -#, c-format -msgid "tag '%s' is externally known as '%s'" -msgstr "" - -#: builtin/describe.c:328 -#, c-format -msgid "no tag exactly matches '%s'" -msgstr "" - -#: builtin/describe.c:330 -#, c-format -msgid "No exact match on refs or tags, searching to describe\n" -msgstr "" - -#: builtin/describe.c:397 -#, c-format -msgid "finished search at %s\n" -msgstr "" - -#: builtin/describe.c:424 -#, c-format -msgid "" -"No annotated tags can describe '%s'.\n" -"However, there were unannotated tags: try --tags." -msgstr "" - -#: builtin/describe.c:428 -#, c-format -msgid "" -"No tags can describe '%s'.\n" -"Try --always, or create some tags." -msgstr "" - -#: builtin/describe.c:458 -#, c-format -msgid "traversed %lu commits\n" -msgstr "" - -#: builtin/describe.c:461 -#, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" - -#: builtin/describe.c:529 -#, c-format -msgid "describe %s\n" -msgstr "" - -#: builtin/describe.c:532 -#, c-format -msgid "Not a valid object name %s" -msgstr "" - -#: builtin/describe.c:540 -#, c-format -msgid "%s is neither a commit nor blob" -msgstr "" - -#: builtin/describe.c:554 -msgid "find the tag that comes after the commit" -msgstr "" - -#: builtin/describe.c:555 -msgid "debug search strategy on stderr" -msgstr "" - -#: builtin/describe.c:556 -msgid "use any ref" -msgstr "" - -#: builtin/describe.c:557 -msgid "use any tag, even unannotated" -msgstr "" - -#: builtin/describe.c:558 -msgid "always use long format" -msgstr "" - -#: builtin/describe.c:559 -msgid "only follow first parent" -msgstr "" - -#: builtin/describe.c:562 -msgid "only output exact matches" -msgstr "" - -#: builtin/describe.c:564 -msgid "consider <n> most recent tags (default: 10)" -msgstr "" - -#: builtin/describe.c:566 -msgid "only consider tags matching <pattern>" -msgstr "" - -#: builtin/describe.c:568 -msgid "do not consider tags matching <pattern>" -msgstr "" - -#: builtin/describe.c:570 builtin/name-rev.c:595 -msgid "show abbreviated commit object as fallback" -msgstr "" - -#: builtin/describe.c:571 builtin/describe.c:574 -msgid "mark" -msgstr "" - -#: builtin/describe.c:572 -msgid "append <mark> on dirty working tree (default: \"-dirty\")" -msgstr "" - -#: builtin/describe.c:575 -msgid "append <mark> on broken working tree (default: \"-broken\")" -msgstr "" - -#: builtin/describe.c:622 -msgid "No names found, cannot describe anything." -msgstr "" - -#: builtin/describe.c:673 builtin/describe.c:675 -#, c-format -msgid "option '%s' and commit-ishes cannot be used together" -msgstr "" - -#: builtin/diff-tree.c:157 -msgid "--merge-base only works with two commits" -msgstr "" - -#: builtin/diff.c:92 -#, c-format -msgid "'%s': not a regular file or symlink" -msgstr "" - -#: builtin/diff.c:259 -#, c-format -msgid "invalid option: %s" -msgstr "" - -#: builtin/diff.c:376 -#, c-format -msgid "%s...%s: no merge base" -msgstr "" - -#: builtin/diff.c:491 -msgid "Not a git repository" -msgstr "" - -#: builtin/diff.c:537 builtin/grep.c:700 -#, c-format -msgid "invalid object '%s' given." -msgstr "" - -#: builtin/diff.c:548 -#, c-format -msgid "more than two blobs given: '%s'" -msgstr "" - -#: builtin/diff.c:553 -#, c-format -msgid "unhandled object '%s' given." -msgstr "" - -#: builtin/diff.c:587 -#, c-format -msgid "%s...%s: multiple merge bases, using %s" -msgstr "" - -#: builtin/difftool.c:31 -msgid "git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]" -msgstr "" - -#: builtin/difftool.c:287 -#, c-format -msgid "could not read symlink %s" -msgstr "" - -#: builtin/difftool.c:289 -#, c-format -msgid "could not read symlink file %s" -msgstr "" - -#: builtin/difftool.c:297 -#, c-format -msgid "could not read object %s for symlink %s" -msgstr "" - -#: builtin/difftool.c:421 -msgid "" -"combined diff formats ('-c' and '--cc') are not supported in\n" -"directory diff mode ('-d' and '--dir-diff')." -msgstr "" - -#: builtin/difftool.c:626 -#, c-format -msgid "both files modified: '%s' and '%s'." -msgstr "" - -#: builtin/difftool.c:628 -msgid "working tree file has been left." -msgstr "" - -#: builtin/difftool.c:639 -#, c-format -msgid "temporary files exist in '%s'." -msgstr "" - -#: builtin/difftool.c:640 -msgid "you may want to cleanup or recover these." -msgstr "" - -#: builtin/difftool.c:645 -#, c-format -msgid "failed: %d" -msgstr "" - -#: builtin/difftool.c:690 -msgid "use `diff.guitool` instead of `diff.tool`" -msgstr "" - -#: builtin/difftool.c:692 -msgid "perform a full-directory diff" -msgstr "" - -#: builtin/difftool.c:694 -msgid "do not prompt before launching a diff tool" -msgstr "" - -#: builtin/difftool.c:699 -msgid "use symlinks in dir-diff mode" -msgstr "" - -#: builtin/difftool.c:700 -msgid "tool" -msgstr "" - -#: builtin/difftool.c:701 -msgid "use the specified diff tool" -msgstr "" - -#: builtin/difftool.c:703 -msgid "print a list of diff tools that may be used with `--tool`" -msgstr "" - -#: builtin/difftool.c:706 -msgid "" -"make 'git-difftool' exit when an invoked diff tool returns a non-zero exit " -"code" -msgstr "" - -#: builtin/difftool.c:709 -msgid "specify a custom command for viewing diffs" -msgstr "" - -#: builtin/difftool.c:710 -msgid "passed to `diff`" -msgstr "" - -#: builtin/difftool.c:726 -msgid "difftool requires worktree or --no-index" -msgstr "" - -#: builtin/difftool.c:745 -msgid "no <tool> given for --tool=<tool>" -msgstr "" - -#: builtin/difftool.c:752 -msgid "no <cmd> given for --extcmd=<cmd>" -msgstr "" - -#: builtin/env--helper.c:6 -msgid "git env--helper --type=[bool|ulong] <options> <env-var>" -msgstr "" - -#: builtin/env--helper.c:46 -msgid "default for git_env_*(...) to fall back on" -msgstr "" - -#: builtin/env--helper.c:48 -msgid "be quiet only use git_env_*() value as exit code" -msgstr "" - -#: builtin/env--helper.c:67 -#, c-format -msgid "option `--default' expects a boolean value with `--type=bool`, not `%s`" -msgstr "" - -#: builtin/env--helper.c:82 -#, c-format -msgid "" -"option `--default' expects an unsigned long value with `--type=ulong`, not `" -"%s`" -msgstr "" - -#: builtin/fast-export.c:29 -msgid "git fast-export [<rev-list-opts>]" -msgstr "" - -#: builtin/fast-export.c:843 -msgid "Error: Cannot export nested tags unless --mark-tags is specified." -msgstr "" - -#: builtin/fast-export.c:1152 -msgid "--anonymize-map token cannot be empty" -msgstr "" - -#: builtin/fast-export.c:1171 -msgid "show progress after <n> objects" -msgstr "" - -#: builtin/fast-export.c:1173 -msgid "select handling of signed tags" -msgstr "" - -#: builtin/fast-export.c:1176 -msgid "select handling of tags that tag filtered objects" -msgstr "" - -#: builtin/fast-export.c:1179 -msgid "select handling of commit messages in an alternate encoding" -msgstr "" - -#: builtin/fast-export.c:1182 -msgid "dump marks to this file" -msgstr "" - -#: builtin/fast-export.c:1184 -msgid "import marks from this file" -msgstr "" - -#: builtin/fast-export.c:1188 -msgid "import marks from this file if it exists" -msgstr "" - -#: builtin/fast-export.c:1190 -msgid "fake a tagger when tags lack one" -msgstr "" - -#: builtin/fast-export.c:1192 -msgid "output full tree for each commit" -msgstr "" - -#: builtin/fast-export.c:1194 -msgid "use the done feature to terminate the stream" -msgstr "" - -#: builtin/fast-export.c:1195 -msgid "skip output of blob data" -msgstr "" - -#: builtin/fast-export.c:1196 builtin/log.c:1860 -msgid "refspec" -msgstr "" - -#: builtin/fast-export.c:1197 -msgid "apply refspec to exported refs" -msgstr "" - -#: builtin/fast-export.c:1198 -msgid "anonymize output" -msgstr "" - -#: builtin/fast-export.c:1199 -msgid "from:to" -msgstr "" - -#: builtin/fast-export.c:1200 -msgid "convert <from> to <to> in anonymized output" -msgstr "" - -#: builtin/fast-export.c:1203 -msgid "reference parents which are not in fast-export stream by object id" -msgstr "" - -#: builtin/fast-export.c:1205 -msgid "show original object ids of blobs/commits" -msgstr "" - -#: builtin/fast-export.c:1207 -msgid "label tags with mark ids" -msgstr "" - -#: builtin/fast-import.c:3097 -#, c-format -msgid "Missing from marks for submodule '%s'" -msgstr "" - -#: builtin/fast-import.c:3099 -#, c-format -msgid "Missing to marks for submodule '%s'" -msgstr "" - -#: builtin/fast-import.c:3234 -#, c-format -msgid "Expected 'mark' command, got %s" -msgstr "" - -#: builtin/fast-import.c:3239 -#, c-format -msgid "Expected 'to' command, got %s" -msgstr "" - -#: builtin/fast-import.c:3331 -msgid "Expected format name:filename for submodule rewrite option" -msgstr "" - -#: builtin/fast-import.c:3386 -#, c-format -msgid "feature '%s' forbidden in input without --allow-unsafe-features" -msgstr "" - -#: builtin/fetch-pack.c:246 -#, c-format -msgid "Lockfile created but not reported: %s" -msgstr "" - -#: builtin/fetch.c:36 -msgid "git fetch [<options>] [<repository> [<refspec>...]]" -msgstr "" - -#: builtin/fetch.c:37 -msgid "git fetch [<options>] <group>" -msgstr "" - -#: builtin/fetch.c:38 -msgid "git fetch --multiple [<options>] [(<repository> | <group>)...]" -msgstr "" - -#: builtin/fetch.c:39 -msgid "git fetch --all [<options>]" -msgstr "" - -#: builtin/fetch.c:124 -msgid "fetch.parallel cannot be negative" -msgstr "" - -#: builtin/fetch.c:147 builtin/pull.c:189 -msgid "fetch from all remotes" -msgstr "" - -#: builtin/fetch.c:149 builtin/pull.c:249 -msgid "set upstream for git pull/fetch" -msgstr "" - -#: builtin/fetch.c:151 builtin/pull.c:192 -msgid "append to .git/FETCH_HEAD instead of overwriting" -msgstr "" - -#: builtin/fetch.c:153 -msgid "use atomic transaction to update references" -msgstr "" - -#: builtin/fetch.c:155 builtin/pull.c:195 -msgid "path to upload pack on remote end" -msgstr "" - -#: builtin/fetch.c:156 -msgid "force overwrite of local reference" -msgstr "" - -#: builtin/fetch.c:158 -msgid "fetch from multiple remotes" -msgstr "" - -#: builtin/fetch.c:160 builtin/pull.c:199 -msgid "fetch all tags and associated objects" -msgstr "" - -#: builtin/fetch.c:162 -msgid "do not fetch all tags (--no-tags)" -msgstr "" - -#: builtin/fetch.c:164 -msgid "number of submodules fetched in parallel" -msgstr "" - -#: builtin/fetch.c:166 -msgid "modify the refspec to place all refs within refs/prefetch/" -msgstr "" - -#: builtin/fetch.c:168 builtin/pull.c:202 -msgid "prune remote-tracking branches no longer on remote" -msgstr "" - -#: builtin/fetch.c:170 -msgid "prune local tags no longer on remote and clobber changed tags" -msgstr "" - -#: builtin/fetch.c:171 builtin/fetch.c:199 builtin/pull.c:123 -msgid "on-demand" -msgstr "" - -#: builtin/fetch.c:172 -msgid "control recursive fetching of submodules" -msgstr "" - -#: builtin/fetch.c:177 -msgid "write fetched references to the FETCH_HEAD file" -msgstr "" - -#: builtin/fetch.c:178 builtin/pull.c:210 -msgid "keep downloaded pack" -msgstr "" - -#: builtin/fetch.c:180 -msgid "allow updating of HEAD ref" -msgstr "" - -#: builtin/fetch.c:183 builtin/fetch.c:189 builtin/pull.c:213 -#: builtin/pull.c:222 -msgid "deepen history of shallow clone" -msgstr "" - -#: builtin/fetch.c:185 builtin/pull.c:216 -msgid "deepen history of shallow repository based on time" -msgstr "" - -#: builtin/fetch.c:191 builtin/pull.c:225 -msgid "convert to a complete repository" -msgstr "" - -#: builtin/fetch.c:194 -msgid "re-fetch without negotiating common commits" -msgstr "" - -#: builtin/fetch.c:197 -msgid "prepend this to submodule path output" -msgstr "" - -#: builtin/fetch.c:200 -msgid "" -"default for recursive fetching of submodules (lower priority than config " -"files)" -msgstr "" - -#: builtin/fetch.c:204 builtin/pull.c:228 -msgid "accept refs that update .git/shallow" -msgstr "" - -#: builtin/fetch.c:205 builtin/pull.c:230 -msgid "refmap" -msgstr "" - -#: builtin/fetch.c:206 builtin/pull.c:231 -msgid "specify fetch refmap" -msgstr "" - -#: builtin/fetch.c:213 builtin/pull.c:244 -msgid "report that we have only objects reachable from this object" -msgstr "" - -#: builtin/fetch.c:215 -msgid "do not fetch a packfile; instead, print ancestors of negotiation tips" -msgstr "" - -#: builtin/fetch.c:218 builtin/fetch.c:220 -msgid "run 'maintenance --auto' after fetching" -msgstr "" - -#: builtin/fetch.c:222 builtin/pull.c:247 -msgid "check for forced-updates on all updated branches" -msgstr "" - -#: builtin/fetch.c:224 -msgid "write the commit-graph after fetching" -msgstr "" - -#: builtin/fetch.c:226 -msgid "accept refspecs from stdin" -msgstr "" - -#: builtin/fetch.c:618 -msgid "couldn't find remote ref HEAD" -msgstr "" - -#: builtin/fetch.c:893 -#, c-format -msgid "object %s not found" -msgstr "" - -#: builtin/fetch.c:897 -msgid "[up to date]" -msgstr "" - -#: builtin/fetch.c:909 builtin/fetch.c:927 builtin/fetch.c:999 -msgid "[rejected]" -msgstr "" - -#: builtin/fetch.c:911 -msgid "can't fetch in current branch" -msgstr "" - -#: builtin/fetch.c:912 -msgid "checked out in another worktree" -msgstr "" - -#: builtin/fetch.c:922 -msgid "[tag update]" -msgstr "" - -#: builtin/fetch.c:923 builtin/fetch.c:960 builtin/fetch.c:982 -#: builtin/fetch.c:994 -msgid "unable to update local ref" -msgstr "" - -#: builtin/fetch.c:927 -msgid "would clobber existing tag" -msgstr "" - -#: builtin/fetch.c:949 -msgid "[new tag]" -msgstr "" - -#: builtin/fetch.c:952 -msgid "[new branch]" -msgstr "" - -#: builtin/fetch.c:955 -msgid "[new ref]" -msgstr "" - -#: builtin/fetch.c:994 -msgid "forced update" -msgstr "" - -#: builtin/fetch.c:999 -msgid "non-fast-forward" -msgstr "" - -#: builtin/fetch.c:1102 -msgid "" -"fetch normally indicates which branches had a forced update,\n" -"but that check has been disabled; to re-enable, use '--show-forced-updates'\n" -"flag or run 'git config fetch.showForcedUpdates true'" -msgstr "" - -#: builtin/fetch.c:1106 -#, c-format -msgid "" -"it took %.2f seconds to check forced updates; you can use\n" -"'--no-show-forced-updates' or run 'git config fetch.showForcedUpdates " -"false'\n" -"to avoid this check\n" -msgstr "" - -#: builtin/fetch.c:1136 -#, c-format -msgid "%s did not send all necessary objects\n" -msgstr "" - -#: builtin/fetch.c:1156 -#, c-format -msgid "rejected %s because shallow roots are not allowed to be updated" -msgstr "" - -#: builtin/fetch.c:1259 builtin/fetch.c:1418 -#, c-format -msgid "From %.*s\n" -msgstr "" - -#: builtin/fetch.c:1269 -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" - -#: builtin/fetch.c:1377 -#, c-format -msgid " (%s will become dangling)" -msgstr "" - -#: builtin/fetch.c:1378 -#, c-format -msgid " (%s has become dangling)" -msgstr "" - -#: builtin/fetch.c:1421 -msgid "[deleted]" -msgstr "" - -#: builtin/fetch.c:1422 builtin/remote.c:1153 -msgid "(none)" -msgstr "" - -#: builtin/fetch.c:1446 -#, c-format -msgid "refusing to fetch into branch '%s' checked out at '%s'" -msgstr "" - -#: builtin/fetch.c:1466 -#, c-format -msgid "option \"%s\" value \"%s\" is not valid for %s" -msgstr "" - -#: builtin/fetch.c:1469 -#, c-format -msgid "option \"%s\" is ignored for %s\n" -msgstr "" - -#: builtin/fetch.c:1496 -#, c-format -msgid "the object %s does not exist" -msgstr "" - -#: builtin/fetch.c:1748 -msgid "multiple branches detected, incompatible with --set-upstream" -msgstr "" - -#: builtin/fetch.c:1760 -#, c-format -msgid "" -"could not set upstream of HEAD to '%s' from '%s' when it does not point to " -"any branch." -msgstr "" - -#: builtin/fetch.c:1773 -msgid "not setting upstream for a remote remote-tracking branch" -msgstr "" - -#: builtin/fetch.c:1775 -msgid "not setting upstream for a remote tag" -msgstr "" - -#: builtin/fetch.c:1777 -msgid "unknown branch type" -msgstr "" - -#: builtin/fetch.c:1779 -msgid "" -"no source branch found;\n" -"you need to specify exactly one branch with the --set-upstream option" -msgstr "" - -#: builtin/fetch.c:1904 builtin/fetch.c:1967 -#, c-format -msgid "Fetching %s\n" -msgstr "" - -#: builtin/fetch.c:1914 builtin/fetch.c:1969 -#, c-format -msgid "could not fetch %s" -msgstr "" - -#: builtin/fetch.c:1926 -#, c-format -msgid "could not fetch '%s' (exit code: %d)\n" -msgstr "" - -#: builtin/fetch.c:2030 -msgid "" -"no remote repository specified; please specify either a URL or a\n" -"remote name from which new revisions should be fetched" -msgstr "" - -#: builtin/fetch.c:2066 -msgid "you need to specify a tag name" -msgstr "" - -#: builtin/fetch.c:2156 -msgid "--negotiate-only needs one or more --negotiation-tip=*" -msgstr "" - -#: builtin/fetch.c:2160 -msgid "negative depth in --deepen is not supported" -msgstr "" - -#: builtin/fetch.c:2169 -msgid "--unshallow on a complete repository does not make sense" -msgstr "" - -#: builtin/fetch.c:2186 -msgid "fetch --all does not take a repository argument" -msgstr "" - -#: builtin/fetch.c:2188 -msgid "fetch --all does not make sense with refspecs" -msgstr "" - -#: builtin/fetch.c:2197 -#, c-format -msgid "no such remote or remote group: %s" -msgstr "" - -#: builtin/fetch.c:2205 -msgid "fetching a group and specifying refspecs does not make sense" -msgstr "" - -#: builtin/fetch.c:2221 -msgid "must supply remote when using --negotiate-only" -msgstr "" - -#: builtin/fetch.c:2226 -msgid "protocol does not support --negotiate-only, exiting" -msgstr "" - -#: builtin/fetch.c:2246 -msgid "" -"--filter can only be used with the remote configured in extensions." -"partialclone" -msgstr "" - -#: builtin/fetch.c:2250 -msgid "--atomic can only be used when fetching from one remote" -msgstr "" - -#: builtin/fetch.c:2254 -msgid "--stdin can only be used when fetching from one remote" -msgstr "" - -#: builtin/fmt-merge-msg.c:7 -msgid "" -"git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]" -msgstr "" - -#: builtin/fmt-merge-msg.c:19 -msgid "populate log with at most <n> entries from shortlog" -msgstr "" - -#: builtin/fmt-merge-msg.c:22 -msgid "alias for --log (deprecated)" -msgstr "" - -#: builtin/fmt-merge-msg.c:25 -msgid "text" -msgstr "" - -#: builtin/fmt-merge-msg.c:26 -msgid "use <text> as start of message" -msgstr "" - -#: builtin/fmt-merge-msg.c:28 -msgid "use <name> instead of the real target branch" -msgstr "" - -#: builtin/fmt-merge-msg.c:29 -msgid "file to read from" -msgstr "" - -#: builtin/for-each-ref.c:10 -msgid "git for-each-ref [<options>] [<pattern>]" -msgstr "" - -#: builtin/for-each-ref.c:11 -msgid "git for-each-ref [--points-at <object>]" -msgstr "" - -#: builtin/for-each-ref.c:12 -msgid "git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]" -msgstr "" - -#: builtin/for-each-ref.c:13 -msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" -msgstr "" - -#: builtin/for-each-ref.c:31 -msgid "quote placeholders suitably for shells" -msgstr "" - -#: builtin/for-each-ref.c:33 -msgid "quote placeholders suitably for perl" -msgstr "" - -#: builtin/for-each-ref.c:35 -msgid "quote placeholders suitably for python" -msgstr "" - -#: builtin/for-each-ref.c:37 -msgid "quote placeholders suitably for Tcl" -msgstr "" - -#: builtin/for-each-ref.c:40 -msgid "show only <n> matched refs" -msgstr "" - -#: builtin/for-each-ref.c:42 builtin/tag.c:482 -msgid "respect format colors" -msgstr "" - -#: builtin/for-each-ref.c:45 -msgid "print only refs which points at the given object" -msgstr "" - -#: builtin/for-each-ref.c:47 -msgid "print only refs that are merged" -msgstr "" - -#: builtin/for-each-ref.c:48 -msgid "print only refs that are not merged" -msgstr "" - -#: builtin/for-each-ref.c:49 -msgid "print only refs which contain the commit" -msgstr "" - -#: builtin/for-each-ref.c:50 -msgid "print only refs which don't contain the commit" -msgstr "" - -#: builtin/for-each-repo.c:9 -msgid "git for-each-repo --config=<config> <command-args>" -msgstr "" - -#: builtin/for-each-repo.c:34 -msgid "config" -msgstr "" - -#: builtin/for-each-repo.c:35 -msgid "config key storing a list of repository paths" -msgstr "" - -#: builtin/for-each-repo.c:43 -msgid "missing --config=<config>" -msgstr "" - -#: builtin/fsck.c:69 builtin/fsck.c:128 builtin/fsck.c:129 -msgid "unknown" -msgstr "" - -#. TRANSLATORS: e.g. error in tree 01bfda: <more explanation> -#: builtin/fsck.c:78 builtin/fsck.c:100 -#, c-format -msgid "error in %s %s: %s" -msgstr "" - -#. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> -#: builtin/fsck.c:94 -#, c-format -msgid "warning in %s %s: %s" -msgstr "" - -#: builtin/fsck.c:124 builtin/fsck.c:127 -#, c-format -msgid "broken link from %7s %s" -msgstr "" - -#: builtin/fsck.c:136 -msgid "wrong object type in link" -msgstr "" - -#: builtin/fsck.c:152 -#, c-format -msgid "" -"broken link from %7s %s\n" -" to %7s %s" -msgstr "" - -#: builtin/fsck.c:264 -#, c-format -msgid "missing %s %s" -msgstr "" - -#: builtin/fsck.c:291 -#, c-format -msgid "unreachable %s %s" -msgstr "" - -#: builtin/fsck.c:311 -#, c-format -msgid "dangling %s %s" -msgstr "" - -#: builtin/fsck.c:321 -msgid "could not create lost-found" -msgstr "" - -#: builtin/fsck.c:332 -#, c-format -msgid "could not finish '%s'" -msgstr "" - -#: builtin/fsck.c:349 -#, c-format -msgid "Checking %s" -msgstr "" - -#: builtin/fsck.c:387 -#, c-format -msgid "Checking connectivity (%d objects)" -msgstr "" - -#: builtin/fsck.c:406 -#, c-format -msgid "Checking %s %s" -msgstr "" - -#: builtin/fsck.c:411 -msgid "broken links" -msgstr "" - -#: builtin/fsck.c:420 -#, c-format -msgid "root %s" -msgstr "" - -#: builtin/fsck.c:428 -#, c-format -msgid "tagged %s %s (%s) in %s" -msgstr "" - -#: builtin/fsck.c:457 -#, c-format -msgid "%s: object corrupt or missing" -msgstr "" - -#: builtin/fsck.c:482 -#, c-format -msgid "%s: invalid reflog entry %s" -msgstr "" - -#: builtin/fsck.c:496 -#, c-format -msgid "Checking reflog %s->%s" -msgstr "" - -#: builtin/fsck.c:530 -#, c-format -msgid "%s: invalid sha1 pointer %s" -msgstr "" - -#: builtin/fsck.c:537 -#, c-format -msgid "%s: not a commit" -msgstr "" - -#: builtin/fsck.c:591 -msgid "notice: No default references" -msgstr "" - -#: builtin/fsck.c:621 -#, c-format -msgid "%s: hash-path mismatch, found at: %s" -msgstr "" - -#: builtin/fsck.c:624 -#, c-format -msgid "%s: object corrupt or missing: %s" -msgstr "" - -#: builtin/fsck.c:628 -#, c-format -msgid "%s: object is of unknown type '%s': %s" -msgstr "" - -#: builtin/fsck.c:645 -#, c-format -msgid "%s: object could not be parsed: %s" -msgstr "" - -#: builtin/fsck.c:665 -#, c-format -msgid "bad sha1 file: %s" -msgstr "" - -#: builtin/fsck.c:686 -msgid "Checking object directory" -msgstr "" - -#: builtin/fsck.c:689 -msgid "Checking object directories" -msgstr "" - -#: builtin/fsck.c:705 -#, c-format -msgid "Checking %s link" -msgstr "" - -#: builtin/fsck.c:710 builtin/index-pack.c:862 -#, c-format -msgid "invalid %s" -msgstr "" - -#: builtin/fsck.c:717 -#, c-format -msgid "%s points to something strange (%s)" -msgstr "" - -#: builtin/fsck.c:723 -#, c-format -msgid "%s: detached HEAD points at nothing" -msgstr "" - -#: builtin/fsck.c:727 -#, c-format -msgid "notice: %s points to an unborn branch (%s)" -msgstr "" - -#: builtin/fsck.c:739 -msgid "Checking cache tree" -msgstr "" - -#: builtin/fsck.c:744 -#, c-format -msgid "%s: invalid sha1 pointer in cache-tree" -msgstr "" - -#: builtin/fsck.c:753 -msgid "non-tree in cache-tree" -msgstr "" - -#: builtin/fsck.c:784 -msgid "git fsck [<options>] [<object>...]" -msgstr "" - -#: builtin/fsck.c:790 -msgid "show unreachable objects" -msgstr "" - -#: builtin/fsck.c:791 -msgid "show dangling objects" -msgstr "" - -#: builtin/fsck.c:792 -msgid "report tags" -msgstr "" - -#: builtin/fsck.c:793 -msgid "report root nodes" -msgstr "" - -#: builtin/fsck.c:794 -msgid "make index objects head nodes" -msgstr "" - -#: builtin/fsck.c:795 -msgid "make reflogs head nodes (default)" -msgstr "" - -#: builtin/fsck.c:796 -msgid "also consider packs and alternate objects" -msgstr "" - -#: builtin/fsck.c:797 -msgid "check only connectivity" -msgstr "" - -#: builtin/fsck.c:798 builtin/mktag.c:75 -msgid "enable more strict checking" -msgstr "" - -#: builtin/fsck.c:800 -msgid "write dangling objects in .git/lost-found" -msgstr "" - -#: builtin/fsck.c:801 builtin/prune.c:146 -msgid "show progress" -msgstr "" - -#: builtin/fsck.c:802 -msgid "show verbose names for reachable objects" -msgstr "" - -#: builtin/fsck.c:862 builtin/index-pack.c:261 -msgid "Checking objects" -msgstr "" - -#: builtin/fsck.c:890 -#, c-format -msgid "%s: object missing" -msgstr "" - -#: builtin/fsck.c:901 -#, c-format -msgid "invalid parameter: expected sha1, got '%s'" -msgstr "" - -#: builtin/fsmonitor--daemon.c:13 -msgid "git fsmonitor--daemon start [<options>]" -msgstr "" - -#: builtin/fsmonitor--daemon.c:14 -msgid "git fsmonitor--daemon run [<options>]" -msgstr "" - -#: builtin/fsmonitor--daemon.c:15 -msgid "git fsmonitor--daemon stop" -msgstr "" - -#: builtin/fsmonitor--daemon.c:16 -msgid "git fsmonitor--daemon status" -msgstr "" - -#: builtin/fsmonitor--daemon.c:38 builtin/fsmonitor--daemon.c:47 -#, c-format -msgid "value of '%s' out of range: %d" -msgstr "" - -#: builtin/fsmonitor--daemon.c:57 -#, c-format -msgid "value of '%s' not bool or int: %d" -msgstr "" - -#: builtin/fsmonitor--daemon.c:99 -#, c-format -msgid "fsmonitor-daemon is watching '%s'\n" -msgstr "" - -#: builtin/fsmonitor--daemon.c:104 -#, c-format -msgid "fsmonitor-daemon is not watching '%s'\n" -msgstr "" - -#: builtin/fsmonitor--daemon.c:170 -#, c-format -msgid "could not create fsmonitor cookie '%s'" -msgstr "" - -#: builtin/fsmonitor--daemon.c:753 -#, c-format -msgid "fsmonitor: cookie_result '%d' != SEEN" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1187 -#, c-format -msgid "could not start IPC thread pool on '%s'" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1199 -msgid "could not start fsmonitor listener thread" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1297 -msgid "could not initialize listener thread" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1328 builtin/fsmonitor--daemon.c:1383 -#, c-format -msgid "fsmonitor--daemon is already running '%s'" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1332 -#, c-format -msgid "running fsmonitor-daemon in '%s'\n" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1387 -#, c-format -msgid "starting fsmonitor-daemon in '%s'\n" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1413 -msgid "daemon failed to start" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1416 -msgid "daemon not online yet" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1419 -msgid "daemon terminated" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1429 -msgid "detach from console" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1432 -msgid "use <n> ipc worker threads" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1435 -msgid "max seconds to wait for background daemon startup" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1449 -#, c-format -msgid "invalid 'ipc-threads' value (%d)" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1464 -#, c-format -msgid "Unhandled subcommand '%s'" -msgstr "" - -#: builtin/fsmonitor--daemon.c:1477 -msgid "fsmonitor--daemon not supported on this platform" -msgstr "" - -#: builtin/gc.c:39 -msgid "git gc [<options>]" -msgstr "" - -#: builtin/gc.c:93 -#, c-format -msgid "Failed to fstat %s: %s" -msgstr "" - -#: builtin/gc.c:129 -#, c-format -msgid "failed to parse '%s' value '%s'" -msgstr "" - -#: builtin/gc.c:488 builtin/init-db.c:57 -#, c-format -msgid "cannot stat '%s'" -msgstr "" - -#: builtin/gc.c:504 -#, c-format -msgid "" -"The last gc run reported the following. Please correct the root cause\n" -"and remove %s\n" -"Automatic cleanup will not be performed until the file is removed.\n" -"\n" -"%s" -msgstr "" - -#: builtin/gc.c:552 -msgid "prune unreferenced objects" -msgstr "" - -#: builtin/gc.c:554 -msgid "be more thorough (increased runtime)" -msgstr "" - -#: builtin/gc.c:555 -msgid "enable auto-gc mode" -msgstr "" - -#: builtin/gc.c:558 -msgid "force running gc even if there may be another gc running" -msgstr "" - -#: builtin/gc.c:561 -msgid "repack all other packs except the largest pack" -msgstr "" - -#: builtin/gc.c:577 -#, c-format -msgid "failed to parse gc.logexpiry value %s" -msgstr "" - -#: builtin/gc.c:588 -#, c-format -msgid "failed to parse prune expiry value %s" -msgstr "" - -#: builtin/gc.c:608 -#, c-format -msgid "Auto packing the repository in background for optimum performance.\n" -msgstr "" - -#: builtin/gc.c:610 -#, c-format -msgid "Auto packing the repository for optimum performance.\n" -msgstr "" - -#: builtin/gc.c:611 -#, c-format -msgid "See \"git help gc\" for manual housekeeping.\n" -msgstr "" - -#: builtin/gc.c:652 -#, c-format -msgid "" -"gc is already running on machine '%s' pid %<PRIuMAX> (use --force if not)" -msgstr "" - -#: builtin/gc.c:707 -msgid "" -"There are too many unreachable loose objects; run 'git prune' to remove them." -msgstr "" - -#: builtin/gc.c:717 -msgid "" -"git maintenance run [--auto] [--[no-]quiet] [--task=<task>] [--schedule]" -msgstr "" - -#: builtin/gc.c:747 -msgid "--no-schedule is not allowed" -msgstr "" - -#: builtin/gc.c:752 -#, c-format -msgid "unrecognized --schedule argument '%s'" -msgstr "" - -#: builtin/gc.c:870 -msgid "failed to write commit-graph" -msgstr "" - -#: builtin/gc.c:906 -msgid "failed to prefetch remotes" -msgstr "" - -#: builtin/gc.c:1022 -msgid "failed to start 'git pack-objects' process" -msgstr "" - -#: builtin/gc.c:1039 -msgid "failed to finish 'git pack-objects' process" -msgstr "" - -#: builtin/gc.c:1090 -msgid "failed to write multi-pack-index" -msgstr "" - -#: builtin/gc.c:1106 -msgid "'git multi-pack-index expire' failed" -msgstr "" - -#: builtin/gc.c:1165 -msgid "'git multi-pack-index repack' failed" -msgstr "" - -#: builtin/gc.c:1174 -msgid "" -"skipping incremental-repack task because core.multiPackIndex is disabled" -msgstr "" - -#: builtin/gc.c:1278 -#, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "" - -#: builtin/gc.c:1308 -#, c-format -msgid "task '%s' failed" -msgstr "" - -#: builtin/gc.c:1390 -#, c-format -msgid "'%s' is not a valid task" -msgstr "" - -#: builtin/gc.c:1395 -#, c-format -msgid "task '%s' cannot be selected multiple times" -msgstr "" - -#: builtin/gc.c:1410 -msgid "run tasks based on the state of the repository" -msgstr "" - -#: builtin/gc.c:1411 -msgid "frequency" -msgstr "" - -#: builtin/gc.c:1412 -msgid "run tasks based on frequency" -msgstr "" - -#: builtin/gc.c:1415 -msgid "do not report progress or other information over stderr" -msgstr "" - -#: builtin/gc.c:1416 -msgid "task" -msgstr "" - -#: builtin/gc.c:1417 -msgid "run a specific task" -msgstr "" - -#: builtin/gc.c:1434 -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "" - -#: builtin/gc.c:1477 -msgid "failed to run 'git config'" -msgstr "" - -#: builtin/gc.c:1629 -#, c-format -msgid "failed to expand path '%s'" -msgstr "" - -#: builtin/gc.c:1656 builtin/gc.c:1694 -msgid "failed to start launchctl" -msgstr "" - -#: builtin/gc.c:1769 builtin/gc.c:2237 -#, c-format -msgid "failed to create directories for '%s'" -msgstr "" - -#: builtin/gc.c:1796 -#, c-format -msgid "failed to bootstrap service %s" -msgstr "" - -#: builtin/gc.c:1889 -msgid "failed to create temp xml file" -msgstr "" - -#: builtin/gc.c:1979 -msgid "failed to start schtasks" -msgstr "" - -#: builtin/gc.c:2063 -msgid "failed to run 'crontab -l'; your system might not support 'cron'" -msgstr "" - -#: builtin/gc.c:2080 -msgid "failed to run 'crontab'; your system might not support 'cron'" -msgstr "" - -#: builtin/gc.c:2084 -msgid "failed to open stdin of 'crontab'" -msgstr "" - -#: builtin/gc.c:2126 -msgid "'crontab' died" -msgstr "" - -#: builtin/gc.c:2191 -msgid "failed to start systemctl" -msgstr "" - -#: builtin/gc.c:2201 -msgid "failed to run systemctl" -msgstr "" - -#: builtin/gc.c:2210 builtin/gc.c:2215 builtin/worktree.c:63 -#: builtin/worktree.c:1024 -#, c-format -msgid "failed to delete '%s'" -msgstr "" - -#: builtin/gc.c:2395 -#, c-format -msgid "unrecognized --scheduler argument '%s'" -msgstr "" - -#: builtin/gc.c:2420 -msgid "neither systemd timers nor crontab are available" -msgstr "" - -#: builtin/gc.c:2435 -#, c-format -msgid "%s scheduler is not available" -msgstr "" - -#: builtin/gc.c:2449 -msgid "another process is scheduling background maintenance" -msgstr "" - -#: builtin/gc.c:2471 -msgid "git maintenance start [--scheduler=<scheduler>]" -msgstr "" - -#: builtin/gc.c:2480 -msgid "scheduler" -msgstr "" - -#: builtin/gc.c:2481 -msgid "scheduler to trigger git maintenance run" -msgstr "" - -#: builtin/gc.c:2495 -msgid "failed to add repo to global config" -msgstr "" - -#: builtin/gc.c:2504 -msgid "git maintenance <subcommand> [<options>]" -msgstr "" - -#: builtin/gc.c:2523 -#, c-format -msgid "invalid subcommand: %s" -msgstr "" - -#: builtin/grep.c:32 -msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]" -msgstr "" - -#: builtin/grep.c:241 -#, c-format -msgid "grep: failed to create thread: %s" -msgstr "" - -#: builtin/grep.c:295 -#, c-format -msgid "invalid number of threads specified (%d) for %s" -msgstr "" - -#. TRANSLATORS: %s is the configuration -#. variable for tweaking threads, currently -#. grep.threads -#. -#: builtin/grep.c:303 builtin/index-pack.c:1587 builtin/index-pack.c:1791 -#: builtin/pack-objects.c:3150 -#, c-format -msgid "no threads support, ignoring %s" -msgstr "" - -#: builtin/grep.c:490 builtin/grep.c:619 builtin/grep.c:659 -#, c-format -msgid "unable to read tree (%s)" -msgstr "" - -#: builtin/grep.c:674 -#, c-format -msgid "unable to grep from object of type %s" -msgstr "" - -#: builtin/grep.c:754 -#, c-format -msgid "switch `%c' expects a numerical value" -msgstr "" - -#: builtin/grep.c:852 -msgid "search in index instead of in the work tree" -msgstr "" - -#: builtin/grep.c:854 -msgid "find in contents not managed by git" -msgstr "" - -#: builtin/grep.c:856 -msgid "search in both tracked and untracked files" -msgstr "" - -#: builtin/grep.c:858 -msgid "ignore files specified via '.gitignore'" -msgstr "" - -#: builtin/grep.c:860 -msgid "recursively search in each submodule" -msgstr "" - -#: builtin/grep.c:863 -msgid "show non-matching lines" -msgstr "" - -#: builtin/grep.c:865 -msgid "case insensitive matching" -msgstr "" - -#: builtin/grep.c:867 -msgid "match patterns only at word boundaries" -msgstr "" - -#: builtin/grep.c:869 -msgid "process binary files as text" -msgstr "" - -#: builtin/grep.c:871 -msgid "don't match patterns in binary files" -msgstr "" - -#: builtin/grep.c:874 -msgid "process binary files with textconv filters" -msgstr "" - -#: builtin/grep.c:876 -msgid "search in subdirectories (default)" -msgstr "" - -#: builtin/grep.c:878 -msgid "descend at most <depth> levels" -msgstr "" - -#: builtin/grep.c:882 -msgid "use extended POSIX regular expressions" -msgstr "" - -#: builtin/grep.c:885 -msgid "use basic POSIX regular expressions (default)" -msgstr "" - -#: builtin/grep.c:888 -msgid "interpret patterns as fixed strings" -msgstr "" - -#: builtin/grep.c:891 -msgid "use Perl-compatible regular expressions" -msgstr "" - -#: builtin/grep.c:894 -msgid "show line numbers" -msgstr "" - -#: builtin/grep.c:895 -msgid "show column number of first match" -msgstr "" - -#: builtin/grep.c:896 -msgid "don't show filenames" -msgstr "" - -#: builtin/grep.c:897 -msgid "show filenames" -msgstr "" - -#: builtin/grep.c:899 -msgid "show filenames relative to top directory" -msgstr "" - -#: builtin/grep.c:901 -msgid "show only filenames instead of matching lines" -msgstr "" - -#: builtin/grep.c:903 -msgid "synonym for --files-with-matches" -msgstr "" - -#: builtin/grep.c:906 -msgid "show only the names of files without match" -msgstr "" - -#: builtin/grep.c:908 -msgid "print NUL after filenames" -msgstr "" - -#: builtin/grep.c:911 -msgid "show only matching parts of a line" -msgstr "" - -#: builtin/grep.c:913 -msgid "show the number of matches instead of matching lines" -msgstr "" - -#: builtin/grep.c:914 -msgid "highlight matches" -msgstr "" - -#: builtin/grep.c:916 -msgid "print empty line between matches from different files" -msgstr "" - -#: builtin/grep.c:918 -msgid "show filename only once above matches from same file" -msgstr "" - -#: builtin/grep.c:921 -msgid "show <n> context lines before and after matches" -msgstr "" - -#: builtin/grep.c:924 -msgid "show <n> context lines before matches" -msgstr "" - -#: builtin/grep.c:926 -msgid "show <n> context lines after matches" -msgstr "" - -#: builtin/grep.c:928 -msgid "use <n> worker threads" -msgstr "" - -#: builtin/grep.c:929 -msgid "shortcut for -C NUM" -msgstr "" - -#: builtin/grep.c:932 -msgid "show a line with the function name before matches" -msgstr "" - -#: builtin/grep.c:934 -msgid "show the surrounding function" -msgstr "" - -#: builtin/grep.c:937 -msgid "read patterns from file" -msgstr "" - -#: builtin/grep.c:939 -msgid "match <pattern>" -msgstr "" - -#: builtin/grep.c:941 -msgid "combine patterns specified with -e" -msgstr "" - -#: builtin/grep.c:953 -msgid "indicate hit with exit status without output" -msgstr "" - -#: builtin/grep.c:955 -msgid "show only matches from files that match all patterns" -msgstr "" - -#: builtin/grep.c:958 -msgid "pager" -msgstr "" - -#: builtin/grep.c:958 -msgid "show matching files in the pager" -msgstr "" - -#: builtin/grep.c:962 -msgid "allow calling of grep(1) (ignored by this build)" -msgstr "" - -#: builtin/grep.c:1028 -msgid "no pattern given" -msgstr "" - -#: builtin/grep.c:1064 -msgid "--no-index or --untracked cannot be used with revs" -msgstr "" - -#: builtin/grep.c:1072 -#, c-format -msgid "unable to resolve revision: %s" -msgstr "" - -#: builtin/grep.c:1102 -msgid "--untracked not supported with --recurse-submodules" -msgstr "" - -#: builtin/grep.c:1106 -msgid "invalid option combination, ignoring --threads" -msgstr "" - -#: builtin/grep.c:1109 builtin/pack-objects.c:4084 -msgid "no threads support, ignoring --threads" -msgstr "" - -#: builtin/grep.c:1112 builtin/index-pack.c:1584 builtin/pack-objects.c:3147 -#, c-format -msgid "invalid number of threads specified (%d)" -msgstr "" - -#: builtin/grep.c:1146 -msgid "--open-files-in-pager only works on the worktree" -msgstr "" - -#: builtin/grep.c:1179 -msgid "--[no-]exclude-standard cannot be used for tracked contents" -msgstr "" - -#: builtin/grep.c:1187 -msgid "both --cached and trees are given" -msgstr "" - -#: builtin/hash-object.c:83 -msgid "" -"git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] " -"[--] <file>..." -msgstr "" - -#: builtin/hash-object.c:97 -msgid "object type" -msgstr "" - -#: builtin/hash-object.c:98 -msgid "write the object into the object database" -msgstr "" - -#: builtin/hash-object.c:100 -msgid "read the object from stdin" -msgstr "" - -#: builtin/hash-object.c:102 -msgid "store file as is without filters" -msgstr "" - -#: builtin/hash-object.c:103 -msgid "" -"just hash any random garbage to create corrupt objects for debugging Git" -msgstr "" - -#: builtin/hash-object.c:104 -msgid "process file as it were from this path" -msgstr "" - -#: builtin/help.c:57 -msgid "print all available commands" -msgstr "" - -#: builtin/help.c:60 -msgid "show external commands in --all" -msgstr "" - -#: builtin/help.c:61 -msgid "show aliases in --all" -msgstr "" - -#: builtin/help.c:62 -msgid "exclude guides" -msgstr "" - -#: builtin/help.c:63 -msgid "show man page" -msgstr "" - -#: builtin/help.c:64 -msgid "show manual in web browser" -msgstr "" - -#: builtin/help.c:66 -msgid "show info page" -msgstr "" - -#: builtin/help.c:68 -msgid "print command description" -msgstr "" - -#: builtin/help.c:70 -msgid "print list of useful guides" -msgstr "" - -#: builtin/help.c:72 -msgid "print all configuration variable names" -msgstr "" - -#: builtin/help.c:84 -msgid "git help [[-i|--info] [-m|--man] [-w|--web]] [<command>]" -msgstr "" - -#: builtin/help.c:201 -#, c-format -msgid "unrecognized help format '%s'" -msgstr "" - -#: builtin/help.c:227 -msgid "Failed to start emacsclient." -msgstr "" - -#: builtin/help.c:240 -msgid "Failed to parse emacsclient version." -msgstr "" - -#: builtin/help.c:248 -#, c-format -msgid "emacsclient version '%d' too old (< 22)." -msgstr "" - -#: builtin/help.c:266 builtin/help.c:288 builtin/help.c:298 builtin/help.c:306 -#, c-format -msgid "failed to exec '%s'" -msgstr "" - -#: builtin/help.c:344 -#, c-format -msgid "" -"'%s': path for unsupported man viewer.\n" -"Please consider using 'man.<tool>.cmd' instead." -msgstr "" - -#: builtin/help.c:356 -#, c-format -msgid "" -"'%s': cmd for supported man viewer.\n" -"Please consider using 'man.<tool>.path' instead." -msgstr "" - -#: builtin/help.c:471 -#, c-format -msgid "'%s': unknown man viewer." -msgstr "" - -#: builtin/help.c:487 -msgid "no man viewer handled the request" -msgstr "" - -#: builtin/help.c:494 -msgid "no info viewer handled the request" -msgstr "" - -#: builtin/help.c:555 builtin/help.c:566 git.c:348 -#, c-format -msgid "'%s' is aliased to '%s'" -msgstr "" - -#: builtin/help.c:569 git.c:380 -#, c-format -msgid "bad alias.%s string: %s" -msgstr "" - -#: builtin/help.c:611 -#, c-format -msgid "the '%s' option doesn't take any non-option arguments" -msgstr "" - -#: builtin/help.c:631 -msgid "" -"the '--no-[external-commands|aliases]' options can only be used with '--all'" -msgstr "" - -#: builtin/help.c:643 builtin/help.c:671 -#, c-format -msgid "usage: %s%s" -msgstr "" - -#: builtin/help.c:666 -msgid "'git help config' for more information" -msgstr "" - -#: builtin/hook.c:10 -msgid "git hook run [--ignore-missing] <hook-name> [-- <hook-args>]" -msgstr "" - -#: builtin/hook.c:30 -msgid "silently ignore missing requested <hook-name>" -msgstr "" - -#: builtin/index-pack.c:221 -#, c-format -msgid "object type mismatch at %s" -msgstr "" - -#: builtin/index-pack.c:241 -#, c-format -msgid "did not receive expected object %s" -msgstr "" - -#: builtin/index-pack.c:244 -#, c-format -msgid "object %s: expected type %s, found %s" -msgstr "" - -#: builtin/index-pack.c:294 -#, c-format -msgid "cannot fill %d byte" -msgid_plural "cannot fill %d bytes" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:304 -msgid "early EOF" -msgstr "" - -#: builtin/index-pack.c:305 -msgid "read error on input" -msgstr "" - -#: builtin/index-pack.c:317 -msgid "used more bytes than were available" -msgstr "" - -#: builtin/index-pack.c:324 builtin/pack-objects.c:754 -msgid "pack too large for current definition of off_t" -msgstr "" - -#: builtin/index-pack.c:329 -#, c-format -msgid "pack exceeds maximum allowed size (%s)" -msgstr "" - -#: builtin/index-pack.c:362 -msgid "pack signature mismatch" -msgstr "" - -#: builtin/index-pack.c:364 -#, c-format -msgid "pack version %<PRIu32> unsupported" -msgstr "" - -#: builtin/index-pack.c:380 -#, c-format -msgid "pack has bad object at offset %<PRIuMAX>: %s" -msgstr "" - -#: builtin/index-pack.c:485 -#, c-format -msgid "inflate returned %d" -msgstr "" - -#: builtin/index-pack.c:534 -msgid "offset value overflow for delta base object" -msgstr "" - -#: builtin/index-pack.c:542 -msgid "delta base offset is out of bound" -msgstr "" - -#: builtin/index-pack.c:550 -#, c-format -msgid "unknown object type %d" -msgstr "" - -#: builtin/index-pack.c:581 -msgid "cannot pread pack file" -msgstr "" - -#: builtin/index-pack.c:583 -#, c-format -msgid "premature end of pack file, %<PRIuMAX> byte missing" -msgid_plural "premature end of pack file, %<PRIuMAX> bytes missing" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:609 -msgid "serious inflate inconsistency" -msgstr "" - -#: builtin/index-pack.c:754 builtin/index-pack.c:760 builtin/index-pack.c:784 -#: builtin/index-pack.c:823 builtin/index-pack.c:832 -#, c-format -msgid "SHA1 COLLISION FOUND WITH %s !" -msgstr "" - -#: builtin/index-pack.c:757 builtin/pack-objects.c:290 -#: builtin/pack-objects.c:350 builtin/pack-objects.c:456 -#, c-format -msgid "unable to read %s" -msgstr "" - -#: builtin/index-pack.c:821 -#, c-format -msgid "cannot read existing object info %s" -msgstr "" - -#: builtin/index-pack.c:829 -#, c-format -msgid "cannot read existing object %s" -msgstr "" - -#: builtin/index-pack.c:843 -#, c-format -msgid "invalid blob object %s" -msgstr "" - -#: builtin/index-pack.c:846 builtin/index-pack.c:865 -msgid "fsck error in packed object" -msgstr "" - -#: builtin/index-pack.c:867 -#, c-format -msgid "Not all child objects of %s are reachable" -msgstr "" - -#: builtin/index-pack.c:928 builtin/index-pack.c:975 -msgid "failed to apply delta" -msgstr "" - -#: builtin/index-pack.c:1161 -msgid "Receiving objects" -msgstr "" - -#: builtin/index-pack.c:1161 -msgid "Indexing objects" -msgstr "" - -#: builtin/index-pack.c:1195 -msgid "pack is corrupted (SHA1 mismatch)" -msgstr "" - -#: builtin/index-pack.c:1200 -msgid "cannot fstat packfile" -msgstr "" - -#: builtin/index-pack.c:1203 -msgid "pack has junk at the end" -msgstr "" - -#: builtin/index-pack.c:1215 -msgid "confusion beyond insanity in parse_pack_objects()" -msgstr "" - -#: builtin/index-pack.c:1238 -msgid "Resolving deltas" -msgstr "" - -#: builtin/index-pack.c:1249 builtin/pack-objects.c:2913 -#, c-format -msgid "unable to create thread: %s" -msgstr "" - -#: builtin/index-pack.c:1282 -msgid "confusion beyond insanity" -msgstr "" - -#: builtin/index-pack.c:1288 -#, c-format -msgid "completed with %d local object" -msgid_plural "completed with %d local objects" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:1300 -#, c-format -msgid "Unexpected tail checksum for %s (disk corruption?)" -msgstr "" - -#: builtin/index-pack.c:1304 -#, c-format -msgid "pack has %d unresolved delta" -msgid_plural "pack has %d unresolved deltas" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:1328 -#, c-format -msgid "unable to deflate appended object (%d)" -msgstr "" - -#: builtin/index-pack.c:1423 -#, c-format -msgid "local object %s is corrupt" -msgstr "" - -#: builtin/index-pack.c:1445 -#, c-format -msgid "packfile name '%s' does not end with '.%s'" -msgstr "" - -#: builtin/index-pack.c:1469 -#, c-format -msgid "cannot write %s file '%s'" -msgstr "" - -#: builtin/index-pack.c:1477 -#, c-format -msgid "cannot close written %s file '%s'" -msgstr "" - -#: builtin/index-pack.c:1494 -#, c-format -msgid "unable to rename temporary '*.%s' file to '%s'" -msgstr "" - -#: builtin/index-pack.c:1519 -msgid "error while closing pack file" -msgstr "" - -#: builtin/index-pack.c:1578 builtin/pack-objects.c:3158 -#, c-format -msgid "bad pack.indexversion=%<PRIu32>" -msgstr "" - -#: builtin/index-pack.c:1648 -#, c-format -msgid "Cannot open existing pack file '%s'" -msgstr "" - -#: builtin/index-pack.c:1650 -#, c-format -msgid "Cannot open existing pack idx file for '%s'" -msgstr "" - -#: builtin/index-pack.c:1698 -#, c-format -msgid "non delta: %d object" -msgid_plural "non delta: %d objects" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:1705 -#, c-format -msgid "chain length = %d: %lu object" -msgid_plural "chain length = %d: %lu objects" -msgstr[0] "" -msgstr[1] "" - -#: builtin/index-pack.c:1748 -msgid "Cannot come back to cwd" -msgstr "" - -#: builtin/index-pack.c:1802 builtin/index-pack.c:1805 -#: builtin/index-pack.c:1825 builtin/index-pack.c:1829 -#, c-format -msgid "bad %s" -msgstr "" - -#: builtin/index-pack.c:1835 builtin/init-db.c:379 builtin/init-db.c:614 -#, c-format -msgid "unknown hash algorithm '%s'" -msgstr "" - -#: builtin/index-pack.c:1856 -msgid "--stdin requires a git repository" -msgstr "" - -#: builtin/index-pack.c:1873 -msgid "--verify with no packfile name given" -msgstr "" - -#: builtin/index-pack.c:1939 builtin/unpack-objects.c:584 -msgid "fsck error in pack objects" -msgstr "" - -#: builtin/init-db.c:63 -#, c-format -msgid "cannot stat template '%s'" -msgstr "" - -#: builtin/init-db.c:68 -#, c-format -msgid "cannot opendir '%s'" -msgstr "" - -#: builtin/init-db.c:80 -#, c-format -msgid "cannot readlink '%s'" -msgstr "" - -#: builtin/init-db.c:82 -#, c-format -msgid "cannot symlink '%s' '%s'" -msgstr "" - -#: builtin/init-db.c:88 -#, c-format -msgid "cannot copy '%s' to '%s'" -msgstr "" - -#: builtin/init-db.c:92 -#, c-format -msgid "ignoring template %s" -msgstr "" - -#: builtin/init-db.c:123 -#, c-format -msgid "templates not found in %s" -msgstr "" - -#: builtin/init-db.c:138 -#, c-format -msgid "not copying templates from '%s': %s" -msgstr "" - -#: builtin/init-db.c:263 -#, c-format -msgid "invalid initial branch name: '%s'" -msgstr "" - -#: builtin/init-db.c:354 -#, c-format -msgid "unable to handle file type %d" -msgstr "" - -#: builtin/init-db.c:357 -#, c-format -msgid "unable to move %s to %s" -msgstr "" - -#: builtin/init-db.c:373 -msgid "attempt to reinitialize repository with different hash" -msgstr "" - -#: builtin/init-db.c:397 builtin/init-db.c:400 -#, c-format -msgid "%s already exists" -msgstr "" - -#: builtin/init-db.c:432 -#, c-format -msgid "re-init: ignored --initial-branch=%s" -msgstr "" - -#: builtin/init-db.c:463 -#, c-format -msgid "Reinitialized existing shared Git repository in %s%s\n" -msgstr "" - -#: builtin/init-db.c:464 -#, c-format -msgid "Reinitialized existing Git repository in %s%s\n" -msgstr "" - -#: builtin/init-db.c:468 -#, c-format -msgid "Initialized empty shared Git repository in %s%s\n" -msgstr "" - -#: builtin/init-db.c:469 -#, c-format -msgid "Initialized empty Git repository in %s%s\n" -msgstr "" - -#: builtin/init-db.c:518 -msgid "" -"git init [-q | --quiet] [--bare] [--template=<template-directory>] [--" -"shared[=<permissions>]] [<directory>]" -msgstr "" - -#: builtin/init-db.c:544 -msgid "permissions" -msgstr "" - -#: builtin/init-db.c:545 -msgid "specify that the git repository is to be shared amongst several users" -msgstr "" - -#: builtin/init-db.c:551 -msgid "override the name of the initial branch" -msgstr "" - -#: builtin/init-db.c:552 builtin/verify-pack.c:74 -msgid "hash" -msgstr "" - -#: builtin/init-db.c:553 builtin/show-index.c:22 builtin/verify-pack.c:75 -msgid "specify the hash algorithm to use" -msgstr "" - -#: builtin/init-db.c:591 builtin/init-db.c:596 -#, c-format -msgid "cannot mkdir %s" -msgstr "" - -#: builtin/init-db.c:600 builtin/init-db.c:655 -#, c-format -msgid "cannot chdir to %s" -msgstr "" - -#: builtin/init-db.c:627 -#, c-format -msgid "" -"%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-" -"dir=<directory>)" -msgstr "" - -#: builtin/init-db.c:679 -#, c-format -msgid "Cannot access work tree '%s'" -msgstr "" - -#: builtin/init-db.c:684 -msgid "--separate-git-dir incompatible with bare repository" -msgstr "" - -#: builtin/interpret-trailers.c:16 -msgid "" -"git interpret-trailers [--in-place] [--trim-empty] [(--trailer " -"<token>[(=|:)<value>])...] [<file>...]" -msgstr "" - -#: builtin/interpret-trailers.c:95 -msgid "edit files in place" -msgstr "" - -#: builtin/interpret-trailers.c:96 -msgid "trim empty trailers" -msgstr "" - -#: builtin/interpret-trailers.c:99 -msgid "where to place the new trailer" -msgstr "" - -#: builtin/interpret-trailers.c:101 -msgid "action if trailer already exists" -msgstr "" - -#: builtin/interpret-trailers.c:103 -msgid "action if trailer is missing" -msgstr "" - -#: builtin/interpret-trailers.c:105 -msgid "output only the trailers" -msgstr "" - -#: builtin/interpret-trailers.c:106 -msgid "do not apply config rules" -msgstr "" - -#: builtin/interpret-trailers.c:107 -msgid "join whitespace-continued values" -msgstr "" - -#: builtin/interpret-trailers.c:108 -msgid "set parsing options" -msgstr "" - -#: builtin/interpret-trailers.c:110 -msgid "do not treat --- specially" -msgstr "" - -#: builtin/interpret-trailers.c:112 -msgid "trailer(s) to add" -msgstr "" - -#: builtin/interpret-trailers.c:123 -msgid "--trailer with --only-input does not make sense" -msgstr "" - -#: builtin/interpret-trailers.c:133 -msgid "no input file given for in-place editing" -msgstr "" - -#: builtin/log.c:60 -msgid "git log [<options>] [<revision-range>] [[--] <path>...]" -msgstr "" - -#: builtin/log.c:61 -msgid "git show [<options>] <object>..." -msgstr "" - -#: builtin/log.c:114 -#, c-format -msgid "invalid --decorate option: %s" -msgstr "" - -#: builtin/log.c:181 -msgid "show source" -msgstr "" - -#: builtin/log.c:182 -msgid "use mail map file" -msgstr "" - -#: builtin/log.c:185 -msgid "only decorate refs that match <pattern>" -msgstr "" - -#: builtin/log.c:187 -msgid "do not decorate refs that match <pattern>" -msgstr "" - -#: builtin/log.c:188 -msgid "decorate options" -msgstr "" - -#: builtin/log.c:191 -msgid "" -"trace the evolution of line range <start>,<end> or function :<funcname> in " -"<file>" -msgstr "" - -#: builtin/log.c:214 -msgid "-L<range>:<file> cannot be used with pathspec" -msgstr "" - -#: builtin/log.c:322 -#, c-format -msgid "Final output: %d %s\n" -msgstr "" - -#: builtin/log.c:429 -msgid "unable to create temporary object directory" -msgstr "" - -#: builtin/log.c:599 -#, c-format -msgid "git show %s: bad file" -msgstr "" - -#: builtin/log.c:614 builtin/log.c:706 -#, c-format -msgid "could not read object %s" -msgstr "" - -#: builtin/log.c:731 -#, c-format -msgid "unknown type: %d" -msgstr "" - -#: builtin/log.c:880 -#, c-format -msgid "%s: invalid cover from description mode" -msgstr "" - -#: builtin/log.c:887 -msgid "format.headers without value" -msgstr "" - -#: builtin/log.c:1016 -#, c-format -msgid "cannot open patch file %s" -msgstr "" - -#: builtin/log.c:1033 -msgid "need exactly one range" -msgstr "" - -#: builtin/log.c:1043 -msgid "not a range" -msgstr "" - -#: builtin/log.c:1207 -msgid "cover letter needs email format" -msgstr "" - -#: builtin/log.c:1213 -msgid "failed to create cover-letter file" -msgstr "" - -#: builtin/log.c:1300 -#, c-format -msgid "insane in-reply-to: %s" -msgstr "" - -#: builtin/log.c:1327 -msgid "git format-patch [<options>] [<since> | <revision-range>]" -msgstr "" - -#: builtin/log.c:1385 -msgid "two output directories?" -msgstr "" - -#: builtin/log.c:1536 builtin/log.c:2369 builtin/log.c:2371 builtin/log.c:2383 -#, c-format -msgid "unknown commit %s" -msgstr "" - -#: builtin/log.c:1547 builtin/replace.c:58 builtin/replace.c:207 -#: builtin/replace.c:210 -#, c-format -msgid "failed to resolve '%s' as a valid ref" -msgstr "" - -#: builtin/log.c:1556 -msgid "could not find exact merge base" -msgstr "" - -#: builtin/log.c:1566 -msgid "" -"failed to get upstream, if you want to record base commit automatically,\n" -"please use git branch --set-upstream-to to track a remote branch.\n" -"Or you could specify base commit by --base=<base-commit-id> manually" -msgstr "" - -#: builtin/log.c:1589 -msgid "failed to find exact merge base" -msgstr "" - -#: builtin/log.c:1606 -msgid "base commit should be the ancestor of revision list" -msgstr "" - -#: builtin/log.c:1616 -msgid "base commit shouldn't be in revision list" -msgstr "" - -#: builtin/log.c:1674 -msgid "cannot get patch id" -msgstr "" - -#: builtin/log.c:1737 -msgid "failed to infer range-diff origin of current series" -msgstr "" - -#: builtin/log.c:1739 -#, c-format -msgid "using '%s' as range-diff origin of current series" -msgstr "" - -#: builtin/log.c:1783 -msgid "use [PATCH n/m] even with a single patch" -msgstr "" - -#: builtin/log.c:1786 -msgid "use [PATCH] even with multiple patches" -msgstr "" - -#: builtin/log.c:1790 -msgid "print patches to standard out" -msgstr "" - -#: builtin/log.c:1792 -msgid "generate a cover letter" -msgstr "" - -#: builtin/log.c:1794 -msgid "use simple number sequence for output file names" -msgstr "" - -#: builtin/log.c:1795 -msgid "sfx" -msgstr "" - -#: builtin/log.c:1796 -msgid "use <sfx> instead of '.patch'" -msgstr "" - -#: builtin/log.c:1798 -msgid "start numbering patches at <n> instead of 1" -msgstr "" - -#: builtin/log.c:1799 -msgid "reroll-count" -msgstr "" - -#: builtin/log.c:1800 -msgid "mark the series as Nth re-roll" -msgstr "" - -#: builtin/log.c:1802 -msgid "max length of output filename" -msgstr "" - -#: builtin/log.c:1804 -msgid "use [RFC PATCH] instead of [PATCH]" -msgstr "" - -#: builtin/log.c:1807 -msgid "cover-from-description-mode" -msgstr "" - -#: builtin/log.c:1808 -msgid "generate parts of a cover letter based on a branch's description" -msgstr "" - -#: builtin/log.c:1810 -msgid "use [<prefix>] instead of [PATCH]" -msgstr "" - -#: builtin/log.c:1813 -msgid "store resulting files in <dir>" -msgstr "" - -#: builtin/log.c:1816 -msgid "don't strip/add [PATCH]" -msgstr "" - -#: builtin/log.c:1819 -msgid "don't output binary diffs" -msgstr "" - -#: builtin/log.c:1821 -msgid "output all-zero hash in From header" -msgstr "" - -#: builtin/log.c:1823 -msgid "don't include a patch matching a commit upstream" -msgstr "" - -#: builtin/log.c:1825 -msgid "show patch format instead of default (patch + stat)" -msgstr "" - -#: builtin/log.c:1827 -msgid "Messaging" -msgstr "" - -#: builtin/log.c:1828 -msgid "header" -msgstr "" - -#: builtin/log.c:1829 -msgid "add email header" -msgstr "" - -#: builtin/log.c:1830 builtin/log.c:1831 -msgid "email" -msgstr "" - -#: builtin/log.c:1830 -msgid "add To: header" -msgstr "" - -#: builtin/log.c:1831 -msgid "add Cc: header" -msgstr "" - -#: builtin/log.c:1832 -msgid "ident" -msgstr "" - -#: builtin/log.c:1833 -msgid "set From address to <ident> (or committer ident if absent)" -msgstr "" - -#: builtin/log.c:1835 -msgid "message-id" -msgstr "" - -#: builtin/log.c:1836 -msgid "make first mail a reply to <message-id>" -msgstr "" - -#: builtin/log.c:1837 builtin/log.c:1840 -msgid "boundary" -msgstr "" - -#: builtin/log.c:1838 -msgid "attach the patch" -msgstr "" - -#: builtin/log.c:1841 -msgid "inline the patch" -msgstr "" - -#: builtin/log.c:1845 -msgid "enable message threading, styles: shallow, deep" -msgstr "" - -#: builtin/log.c:1847 -msgid "signature" -msgstr "" - -#: builtin/log.c:1848 -msgid "add a signature" -msgstr "" - -#: builtin/log.c:1849 -msgid "base-commit" -msgstr "" - -#: builtin/log.c:1850 -msgid "add prerequisite tree info to the patch series" -msgstr "" - -#: builtin/log.c:1853 -msgid "add a signature from a file" -msgstr "" - -#: builtin/log.c:1854 -msgid "don't print the patch filenames" -msgstr "" - -#: builtin/log.c:1856 -msgid "show progress while generating patches" -msgstr "" - -#: builtin/log.c:1858 -msgid "show changes against <rev> in cover letter or single patch" -msgstr "" - -#: builtin/log.c:1861 -msgid "show changes against <refspec> in cover letter or single patch" -msgstr "" - -#: builtin/log.c:1863 builtin/range-diff.c:28 -msgid "percentage by which creation is weighted" -msgstr "" - -#: builtin/log.c:1953 -#, c-format -msgid "invalid ident line: %s" -msgstr "" - -#: builtin/log.c:1978 -msgid "--name-only does not make sense" -msgstr "" - -#: builtin/log.c:1980 -msgid "--name-status does not make sense" -msgstr "" - -#: builtin/log.c:1982 -msgid "--check does not make sense" -msgstr "" - -#: builtin/log.c:1984 -msgid "--remerge-diff does not make sense" -msgstr "" - -#: builtin/log.c:2129 -msgid "--interdiff requires --cover-letter or single patch" -msgstr "" - -#: builtin/log.c:2133 -msgid "Interdiff:" -msgstr "" - -#: builtin/log.c:2134 -#, c-format -msgid "Interdiff against v%d:" -msgstr "" - -#: builtin/log.c:2144 -msgid "--range-diff requires --cover-letter or single patch" -msgstr "" - -#: builtin/log.c:2152 -msgid "Range-diff:" -msgstr "" - -#: builtin/log.c:2153 -#, c-format -msgid "Range-diff against v%d:" -msgstr "" - -#: builtin/log.c:2164 -#, c-format -msgid "unable to read signature file '%s'" -msgstr "" - -#: builtin/log.c:2200 -msgid "Generating patches" -msgstr "" - -#: builtin/log.c:2244 -msgid "failed to create output files" -msgstr "" - -#: builtin/log.c:2304 -msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" -msgstr "" - -#: builtin/log.c:2358 -#, c-format -msgid "" -"Could not find a tracked remote branch, please specify <upstream> manually.\n" -msgstr "" - -#: builtin/ls-files.c:564 -msgid "git ls-files [<options>] [<file>...]" -msgstr "" - -#: builtin/ls-files.c:618 -msgid "separate paths with the NUL character" -msgstr "" - -#: builtin/ls-files.c:620 -msgid "identify the file status with tags" -msgstr "" - -#: builtin/ls-files.c:622 -msgid "use lowercase letters for 'assume unchanged' files" -msgstr "" - -#: builtin/ls-files.c:624 -msgid "use lowercase letters for 'fsmonitor clean' files" -msgstr "" - -#: builtin/ls-files.c:626 -msgid "show cached files in the output (default)" -msgstr "" - -#: builtin/ls-files.c:628 -msgid "show deleted files in the output" -msgstr "" - -#: builtin/ls-files.c:630 -msgid "show modified files in the output" -msgstr "" - -#: builtin/ls-files.c:632 -msgid "show other files in the output" -msgstr "" - -#: builtin/ls-files.c:634 -msgid "show ignored files in the output" -msgstr "" - -#: builtin/ls-files.c:637 -msgid "show staged contents' object name in the output" -msgstr "" - -#: builtin/ls-files.c:639 -msgid "show files on the filesystem that need to be removed" -msgstr "" - -#: builtin/ls-files.c:641 -msgid "show 'other' directories' names only" -msgstr "" - -#: builtin/ls-files.c:643 -msgid "show line endings of files" -msgstr "" - -#: builtin/ls-files.c:645 -msgid "don't show empty directories" -msgstr "" - -#: builtin/ls-files.c:648 -msgid "show unmerged files in the output" -msgstr "" - -#: builtin/ls-files.c:650 -msgid "show resolve-undo information" -msgstr "" - -#: builtin/ls-files.c:652 -msgid "skip files matching pattern" -msgstr "" - -#: builtin/ls-files.c:655 -msgid "read exclude patterns from <file>" -msgstr "" - -#: builtin/ls-files.c:658 -msgid "read additional per-directory exclude patterns in <file>" -msgstr "" - -#: builtin/ls-files.c:660 -msgid "add the standard git exclusions" -msgstr "" - -#: builtin/ls-files.c:664 -msgid "make the output relative to the project top directory" -msgstr "" - -#: builtin/ls-files.c:669 -msgid "if any <file> is not in the index, treat this as an error" -msgstr "" - -#: builtin/ls-files.c:670 -msgid "tree-ish" -msgstr "" - -#: builtin/ls-files.c:671 -msgid "pretend that paths removed since <tree-ish> are still present" -msgstr "" - -#: builtin/ls-files.c:673 -msgid "show debugging data" -msgstr "" - -#: builtin/ls-files.c:675 -msgid "suppress duplicate entries" -msgstr "" - -#: builtin/ls-files.c:677 -msgid "show sparse directories in the presence of a sparse index" -msgstr "" - -#: builtin/ls-remote.c:9 -msgid "" -"git ls-remote [--heads] [--tags] [--refs] [--upload-pack=<exec>]\n" -" [-q | --quiet] [--exit-code] [--get-url]\n" -" [--symref] [<repository> [<refs>...]]" -msgstr "" - -#: builtin/ls-remote.c:60 -msgid "do not print remote URL" -msgstr "" - -#: builtin/ls-remote.c:61 builtin/ls-remote.c:63 builtin/rebase.c:1131 -msgid "exec" -msgstr "" - -#: builtin/ls-remote.c:62 builtin/ls-remote.c:64 -msgid "path of git-upload-pack on the remote host" -msgstr "" - -#: builtin/ls-remote.c:66 -msgid "limit to tags" -msgstr "" - -#: builtin/ls-remote.c:67 -msgid "limit to heads" -msgstr "" - -#: builtin/ls-remote.c:68 -msgid "do not show peeled tags" -msgstr "" - -#: builtin/ls-remote.c:70 -msgid "take url.<base>.insteadOf into account" -msgstr "" - -#: builtin/ls-remote.c:73 -msgid "exit with exit code 2 if no matching refs are found" -msgstr "" - -#: builtin/ls-remote.c:76 -msgid "show underlying ref in addition to the object pointed by it" -msgstr "" - -#: builtin/ls-tree.c:36 -msgid "git ls-tree [<options>] <tree-ish> [<path>...]" -msgstr "" - -#: builtin/ls-tree.c:54 -#, c-format -msgid "could not get object info about '%s'" -msgstr "" - -#: builtin/ls-tree.c:79 -#, c-format -msgid "bad ls-tree format: element '%s' does not start with '('" -msgstr "" - -#: builtin/ls-tree.c:83 -#, c-format -msgid "bad ls-tree format: element '%s' does not end in ')'" -msgstr "" - -#: builtin/ls-tree.c:109 -#, c-format -msgid "bad ls-tree format: %%%.*s" -msgstr "" - -#: builtin/ls-tree.c:336 -msgid "only show trees" -msgstr "" - -#: builtin/ls-tree.c:338 -msgid "recurse into subtrees" -msgstr "" - -#: builtin/ls-tree.c:340 -msgid "show trees when recursing" -msgstr "" - -#: builtin/ls-tree.c:343 -msgid "terminate entries with NUL byte" -msgstr "" - -#: builtin/ls-tree.c:344 -msgid "include object size" -msgstr "" - -#: builtin/ls-tree.c:346 builtin/ls-tree.c:348 -msgid "list only filenames" -msgstr "" - -#: builtin/ls-tree.c:350 -msgid "list only objects" -msgstr "" - -#: builtin/ls-tree.c:353 -msgid "use full path names" -msgstr "" - -#: builtin/ls-tree.c:355 -msgid "list entire tree; not just current directory (implies --full-name)" -msgstr "" - -#: builtin/ls-tree.c:391 -msgid "--format can't be combined with other format-altering options" -msgstr "" - -#. TRANSLATORS: keep <> in "<" mail ">" info. -#: builtin/mailinfo.c:14 -msgid "git mailinfo [<options>] <msg> <patch> < mail >info" -msgstr "" - -#: builtin/mailinfo.c:58 -msgid "keep subject" -msgstr "" - -#: builtin/mailinfo.c:60 -msgid "keep non patch brackets in subject" -msgstr "" - -#: builtin/mailinfo.c:62 -msgid "copy Message-ID to the end of commit message" -msgstr "" - -#: builtin/mailinfo.c:64 -msgid "re-code metadata to i18n.commitEncoding" -msgstr "" - -#: builtin/mailinfo.c:67 -msgid "disable charset re-coding of metadata" -msgstr "" - -#: builtin/mailinfo.c:69 -msgid "encoding" -msgstr "" - -#: builtin/mailinfo.c:70 -msgid "re-code metadata to this encoding" -msgstr "" - -#: builtin/mailinfo.c:72 -msgid "use scissors" -msgstr "" - -#: builtin/mailinfo.c:73 -msgid "<action>" -msgstr "" - -#: builtin/mailinfo.c:74 -msgid "action when quoted CR is found" -msgstr "" - -#: builtin/mailinfo.c:77 -msgid "use headers in message's body" -msgstr "" - -#: builtin/mailsplit.c:227 -msgid "reading patches from stdin/tty..." -msgstr "" - -#: builtin/mailsplit.c:242 -#, c-format -msgid "empty mbox: '%s'" -msgstr "" - -#: builtin/merge-base.c:32 -msgid "git merge-base [-a | --all] <commit> <commit>..." -msgstr "" - -#: builtin/merge-base.c:33 -msgid "git merge-base [-a | --all] --octopus <commit>..." -msgstr "" - -#: builtin/merge-base.c:34 -msgid "git merge-base --independent <commit>..." -msgstr "" - -#: builtin/merge-base.c:35 -msgid "git merge-base --is-ancestor <commit> <commit>" -msgstr "" - -#: builtin/merge-base.c:36 -msgid "git merge-base --fork-point <ref> [<commit>]" -msgstr "" - -#: builtin/merge-base.c:144 -msgid "output all common ancestors" -msgstr "" - -#: builtin/merge-base.c:146 -msgid "find ancestors for a single n-way merge" -msgstr "" - -#: builtin/merge-base.c:148 -msgid "list revs not reachable from others" -msgstr "" - -#: builtin/merge-base.c:150 -msgid "is the first one ancestor of the other?" -msgstr "" - -#: builtin/merge-base.c:152 -msgid "find where <commit> forked from reflog of <ref>" -msgstr "" - -#: builtin/merge-file.c:9 -msgid "" -"git merge-file [<options>] [-L <name1> [-L <orig> [-L <name2>]]] <file1> " -"<orig-file> <file2>" -msgstr "" - -#: builtin/merge-file.c:35 -msgid "send results to standard output" -msgstr "" - -#: builtin/merge-file.c:36 -msgid "use a diff3 based merge" -msgstr "" - -#: builtin/merge-file.c:37 -msgid "use a zealous diff3 based merge" -msgstr "" - -#: builtin/merge-file.c:39 -msgid "for conflicts, use our version" -msgstr "" - -#: builtin/merge-file.c:41 -msgid "for conflicts, use their version" -msgstr "" - -#: builtin/merge-file.c:43 -msgid "for conflicts, use a union version" -msgstr "" - -#: builtin/merge-file.c:46 -msgid "for conflicts, use this marker size" -msgstr "" - -#: builtin/merge-file.c:47 -msgid "do not warn about conflicts" -msgstr "" - -#: builtin/merge-file.c:49 -msgid "set labels for file1/orig-file/file2" -msgstr "" - -#: builtin/merge-recursive.c:47 -#, c-format -msgid "unknown option %s" -msgstr "" - -#: builtin/merge-recursive.c:53 -#, c-format -msgid "could not parse object '%s'" -msgstr "" - -#: builtin/merge-recursive.c:57 -#, c-format -msgid "cannot handle more than %d base. Ignoring %s." -msgid_plural "cannot handle more than %d bases. Ignoring %s." -msgstr[0] "" -msgstr[1] "" - -#: builtin/merge-recursive.c:65 -msgid "not handling anything other than two heads merge." -msgstr "" - -#: builtin/merge-recursive.c:74 builtin/merge-recursive.c:76 -#, c-format -msgid "could not resolve ref '%s'" -msgstr "" - -#: builtin/merge-recursive.c:82 -#, c-format -msgid "Merging %s with %s\n" -msgstr "" - -#: builtin/merge.c:59 -msgid "git merge [<options>] [<commit>...]" -msgstr "" - -#: builtin/merge.c:125 -msgid "switch `m' requires a value" -msgstr "" - -#: builtin/merge.c:148 -#, c-format -msgid "option `%s' requires a value" -msgstr "" - -#: builtin/merge.c:201 -#, c-format -msgid "Could not find merge strategy '%s'.\n" -msgstr "" - -#: builtin/merge.c:202 -#, c-format -msgid "Available strategies are:" -msgstr "" - -#: builtin/merge.c:207 -#, c-format -msgid "Available custom strategies are:" -msgstr "" - -#: builtin/merge.c:258 builtin/pull.c:134 -msgid "do not show a diffstat at the end of the merge" -msgstr "" - -#: builtin/merge.c:261 builtin/pull.c:137 -msgid "show a diffstat at the end of the merge" -msgstr "" - -#: builtin/merge.c:262 builtin/pull.c:140 -msgid "(synonym to --stat)" -msgstr "" - -#: builtin/merge.c:264 builtin/pull.c:143 -msgid "add (at most <n>) entries from shortlog to merge commit message" -msgstr "" - -#: builtin/merge.c:267 builtin/pull.c:149 -msgid "create a single commit instead of doing a merge" -msgstr "" - -#: builtin/merge.c:269 builtin/pull.c:152 -msgid "perform a commit if the merge succeeds (default)" -msgstr "" - -#: builtin/merge.c:271 builtin/pull.c:155 -msgid "edit message before committing" -msgstr "" - -#: builtin/merge.c:273 -msgid "allow fast-forward (default)" -msgstr "" - -#: builtin/merge.c:275 builtin/pull.c:162 -msgid "abort if fast-forward is not possible" -msgstr "" - -#: builtin/merge.c:279 builtin/pull.c:168 -msgid "verify that the named commit has a valid GPG signature" -msgstr "" - -#: builtin/merge.c:280 builtin/notes.c:785 builtin/pull.c:172 -#: builtin/rebase.c:1145 builtin/revert.c:114 -msgid "strategy" -msgstr "" - -#: builtin/merge.c:281 builtin/pull.c:173 -msgid "merge strategy to use" -msgstr "" - -#: builtin/merge.c:282 builtin/pull.c:176 -msgid "option=value" -msgstr "" - -#: builtin/merge.c:283 builtin/pull.c:177 -msgid "option for selected merge strategy" -msgstr "" - -#: builtin/merge.c:285 -msgid "merge commit message (for a non-fast-forward merge)" -msgstr "" - -#: builtin/merge.c:291 -msgid "use <name> instead of the real target" -msgstr "" - -#: builtin/merge.c:294 -msgid "abort the current in-progress merge" -msgstr "" - -#: builtin/merge.c:296 -msgid "--abort but leave index and working tree alone" -msgstr "" - -#: builtin/merge.c:298 -msgid "continue the current in-progress merge" -msgstr "" - -#: builtin/merge.c:300 builtin/pull.c:184 -msgid "allow merging unrelated histories" -msgstr "" - -#: builtin/merge.c:307 -msgid "bypass pre-merge-commit and commit-msg hooks" -msgstr "" - -#: builtin/merge.c:323 -msgid "could not run stash." -msgstr "" - -#: builtin/merge.c:328 -msgid "stash failed" -msgstr "" - -#: builtin/merge.c:333 -#, c-format -msgid "not a valid object: %s" -msgstr "" - -#: builtin/merge.c:355 builtin/merge.c:372 -msgid "read-tree failed" -msgstr "" - -#: builtin/merge.c:403 -msgid "Already up to date. (nothing to squash)" -msgstr "" - -#: builtin/merge.c:417 -#, c-format -msgid "Squash commit -- not updating HEAD\n" -msgstr "" - -#: builtin/merge.c:467 -#, c-format -msgid "No merge message -- not updating HEAD\n" -msgstr "" - -#: builtin/merge.c:517 -#, c-format -msgid "'%s' does not point to a commit" -msgstr "" - -#: builtin/merge.c:605 -#, c-format -msgid "Bad branch.%s.mergeoptions string: %s" -msgstr "" - -#: builtin/merge.c:732 -msgid "Not handling anything other than two heads merge." -msgstr "" - -#: builtin/merge.c:745 -#, c-format -msgid "unknown strategy option: -X%s" -msgstr "" - -#: builtin/merge.c:764 t/helper/test-fast-rebase.c:223 -#, c-format -msgid "unable to write %s" -msgstr "" - -#: builtin/merge.c:816 -#, c-format -msgid "Could not read from '%s'" -msgstr "" - -#: builtin/merge.c:825 -#, c-format -msgid "Not committing merge; use 'git commit' to complete the merge.\n" -msgstr "" - -#: builtin/merge.c:831 -msgid "" -"Please enter a commit message to explain why this merge is necessary,\n" -"especially if it merges an updated upstream into a topic branch.\n" -"\n" -msgstr "" - -#: builtin/merge.c:836 -msgid "An empty message aborts the commit.\n" -msgstr "" - -#: builtin/merge.c:839 -#, c-format -msgid "" -"Lines starting with '%c' will be ignored, and an empty message aborts\n" -"the commit.\n" -msgstr "" - -#: builtin/merge.c:900 -msgid "Empty commit message." -msgstr "" - -#: builtin/merge.c:915 -#, c-format -msgid "Wonderful.\n" -msgstr "" - -#: builtin/merge.c:976 -#, c-format -msgid "Automatic merge failed; fix conflicts and then commit the result.\n" -msgstr "" - -#: builtin/merge.c:1015 -msgid "No current branch." -msgstr "" - -#: builtin/merge.c:1017 -msgid "No remote for the current branch." -msgstr "" - -#: builtin/merge.c:1019 -msgid "No default upstream defined for the current branch." -msgstr "" - -#: builtin/merge.c:1024 -#, c-format -msgid "No remote-tracking branch for %s from %s" -msgstr "" - -#: builtin/merge.c:1081 -#, c-format -msgid "Bad value '%s' in environment '%s'" -msgstr "" - -#: builtin/merge.c:1183 -#, c-format -msgid "not something we can merge in %s: %s" -msgstr "" - -#: builtin/merge.c:1217 -msgid "not something we can merge" -msgstr "" - -#: builtin/merge.c:1330 -msgid "--abort expects no arguments" -msgstr "" - -#: builtin/merge.c:1334 -msgid "There is no merge to abort (MERGE_HEAD missing)." -msgstr "" - -#: builtin/merge.c:1352 -msgid "--quit expects no arguments" -msgstr "" - -#: builtin/merge.c:1365 -msgid "--continue expects no arguments" -msgstr "" - -#: builtin/merge.c:1369 -msgid "There is no merge in progress (MERGE_HEAD missing)." -msgstr "" - -#: builtin/merge.c:1385 -msgid "" -"You have not concluded your merge (MERGE_HEAD exists).\n" -"Please, commit your changes before you merge." -msgstr "" - -#: builtin/merge.c:1392 -msgid "" -"You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" -"Please, commit your changes before you merge." -msgstr "" - -#: builtin/merge.c:1395 -msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." -msgstr "" - -#: builtin/merge.c:1427 -msgid "No commit specified and merge.defaultToUpstream not set." -msgstr "" - -#: builtin/merge.c:1444 -msgid "Squash commit into empty head not supported yet" -msgstr "" - -#: builtin/merge.c:1446 -msgid "Non-fast-forward commit does not make sense into an empty head" -msgstr "" - -#: builtin/merge.c:1451 -#, c-format -msgid "%s - not something we can merge" -msgstr "" - -#: builtin/merge.c:1453 -msgid "Can merge only exactly one commit into empty head" -msgstr "" - -#: builtin/merge.c:1540 -msgid "refusing to merge unrelated histories" -msgstr "" - -#: builtin/merge.c:1559 -#, c-format -msgid "Updating %s..%s\n" -msgstr "" - -#: builtin/merge.c:1606 -#, c-format -msgid "Trying really trivial in-index merge...\n" -msgstr "" - -#: builtin/merge.c:1613 -#, c-format -msgid "Nope.\n" -msgstr "" - -#: builtin/merge.c:1671 builtin/merge.c:1737 -#, c-format -msgid "Rewinding the tree to pristine...\n" -msgstr "" - -#: builtin/merge.c:1675 -#, c-format -msgid "Trying merge strategy %s...\n" -msgstr "" - -#: builtin/merge.c:1727 -#, c-format -msgid "No merge strategy handled the merge.\n" -msgstr "" - -#: builtin/merge.c:1729 -#, c-format -msgid "Merge with strategy %s failed.\n" -msgstr "" - -#: builtin/merge.c:1739 -#, c-format -msgid "Using the %s strategy to prepare resolving by hand.\n" -msgstr "" - -#: builtin/merge.c:1753 -#, c-format -msgid "Automatic merge went well; stopped before committing as requested\n" -msgstr "" - -#: builtin/mktag.c:27 -#, c-format -msgid "warning: tag input does not pass fsck: %s" -msgstr "" - -#: builtin/mktag.c:38 -#, c-format -msgid "error: tag input does not pass fsck: %s" -msgstr "" - -#: builtin/mktag.c:41 -#, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "" - -#: builtin/mktag.c:56 -#, c-format -msgid "could not read tagged object '%s'" -msgstr "" - -#: builtin/mktag.c:59 -#, c-format -msgid "object '%s' tagged as '%s', but is a '%s' type" -msgstr "" - -#: builtin/mktag.c:97 -msgid "tag on stdin did not pass our strict fsck check" -msgstr "" - -#: builtin/mktag.c:100 -msgid "tag on stdin did not refer to a valid object" -msgstr "" - -#: builtin/mktag.c:103 builtin/tag.c:243 -msgid "unable to write tag file" -msgstr "" - -#: builtin/mktree.c:154 -msgid "input is NUL terminated" -msgstr "" - -#: builtin/mktree.c:155 builtin/write-tree.c:26 -msgid "allow missing objects" -msgstr "" - -#: builtin/mktree.c:156 -msgid "allow creation of more than one tree" -msgstr "" - -#: builtin/multi-pack-index.c:10 -msgid "" -"git multi-pack-index [<options>] write [--preferred-pack=<pack>][--refs-" -"snapshot=<path>]" -msgstr "" - -#: builtin/multi-pack-index.c:14 -msgid "git multi-pack-index [<options>] verify" -msgstr "" - -#: builtin/multi-pack-index.c:17 -msgid "git multi-pack-index [<options>] expire" -msgstr "" - -#: builtin/multi-pack-index.c:20 -msgid "git multi-pack-index [<options>] repack [--batch-size=<size>]" -msgstr "" - -#: builtin/multi-pack-index.c:57 -msgid "object directory containing set of packfile and pack-index pairs" -msgstr "" - -#: builtin/multi-pack-index.c:98 -msgid "preferred-pack" -msgstr "" - -#: builtin/multi-pack-index.c:99 -msgid "pack for reuse when computing a multi-pack bitmap" -msgstr "" - -#: builtin/multi-pack-index.c:100 -msgid "write multi-pack bitmap" -msgstr "" - -#: builtin/multi-pack-index.c:105 -msgid "write multi-pack index containing only given indexes" -msgstr "" - -#: builtin/multi-pack-index.c:107 -msgid "refs snapshot for selecting bitmap commits" -msgstr "" - -#: builtin/multi-pack-index.c:206 -msgid "" -"during repack, collect pack-files of smaller size into a batch that is " -"larger than this size" -msgstr "" - -#: builtin/mv.c:18 -msgid "git mv [<options>] <source>... <destination>" -msgstr "" - -#: builtin/mv.c:83 -#, c-format -msgid "Directory %s is in index and no submodule?" -msgstr "" - -#: builtin/mv.c:85 -msgid "Please stage your changes to .gitmodules or stash them to proceed" -msgstr "" - -#: builtin/mv.c:103 -#, c-format -msgid "%.*s is in index" -msgstr "" - -#: builtin/mv.c:125 -msgid "force move/rename even if target exists" -msgstr "" - -#: builtin/mv.c:127 -msgid "skip move/rename errors" -msgstr "" - -#: builtin/mv.c:172 -#, c-format -msgid "destination '%s' is not a directory" -msgstr "" - -#: builtin/mv.c:184 -#, c-format -msgid "Checking rename of '%s' to '%s'\n" -msgstr "" - -#: builtin/mv.c:190 -msgid "bad source" -msgstr "" - -#: builtin/mv.c:193 -msgid "can not move directory into itself" -msgstr "" - -#: builtin/mv.c:196 -msgid "cannot move directory over file" -msgstr "" - -#: builtin/mv.c:205 -msgid "source directory is empty" -msgstr "" - -#: builtin/mv.c:231 -msgid "not under version control" -msgstr "" - -#: builtin/mv.c:233 -msgid "conflicted" -msgstr "" - -#: builtin/mv.c:236 -msgid "destination exists" -msgstr "" - -#: builtin/mv.c:244 -#, c-format -msgid "overwriting '%s'" -msgstr "" - -#: builtin/mv.c:247 -msgid "Cannot overwrite" -msgstr "" - -#: builtin/mv.c:250 -msgid "multiple sources for the same target" -msgstr "" - -#: builtin/mv.c:252 -msgid "destination directory does not exist" -msgstr "" - -#: builtin/mv.c:280 -#, c-format -msgid "%s, source=%s, destination=%s" -msgstr "" - -#: builtin/mv.c:308 -#, c-format -msgid "Renaming %s to %s\n" -msgstr "" - -#: builtin/mv.c:314 builtin/remote.c:812 builtin/repack.c:861 -#, c-format -msgid "renaming '%s' failed" -msgstr "" - -#: builtin/name-rev.c:524 -msgid "git name-rev [<options>] <commit>..." -msgstr "" - -#: builtin/name-rev.c:525 -msgid "git name-rev [<options>] --all" -msgstr "" - -#: builtin/name-rev.c:526 -msgid "git name-rev [<options>] --annotate-stdin" -msgstr "" - -#: builtin/name-rev.c:583 -msgid "print only ref-based names (no object names)" -msgstr "" - -#: builtin/name-rev.c:584 -msgid "only use tags to name the commits" -msgstr "" - -#: builtin/name-rev.c:586 -msgid "only use refs matching <pattern>" -msgstr "" - -#: builtin/name-rev.c:588 -msgid "ignore refs matching <pattern>" -msgstr "" - -#: builtin/name-rev.c:590 -msgid "list all commits reachable from all refs" -msgstr "" - -#: builtin/name-rev.c:591 -msgid "deprecated: use annotate-stdin instead" -msgstr "" - -#: builtin/name-rev.c:592 -msgid "annotate text from stdin" -msgstr "" - -#: builtin/name-rev.c:593 -msgid "allow to print `undefined` names (default)" -msgstr "" - -#: builtin/name-rev.c:599 -msgid "dereference tags in the input (internal use)" -msgstr "" - -#: builtin/notes.c:28 -msgid "git notes [--ref <notes-ref>] [list [<object>]]" -msgstr "" - -#: builtin/notes.c:29 -msgid "" -"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [-m <msg> | -F <file> " -"| (-c | -C) <object>] [<object>]" -msgstr "" - -#: builtin/notes.c:30 -msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" -msgstr "" - -#: builtin/notes.c:31 -msgid "" -"git notes [--ref <notes-ref>] append [--allow-empty] [-m <msg> | -F <file> | " -"(-c | -C) <object>] [<object>]" -msgstr "" - -#: builtin/notes.c:32 -msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" -msgstr "" - -#: builtin/notes.c:33 -msgid "git notes [--ref <notes-ref>] show [<object>]" -msgstr "" - -#: builtin/notes.c:34 -msgid "" -"git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>" -msgstr "" - -#: builtin/notes.c:37 -msgid "git notes [--ref <notes-ref>] remove [<object>...]" -msgstr "" - -#: builtin/notes.c:38 -msgid "git notes [--ref <notes-ref>] prune [-n] [-v]" -msgstr "" - -#: builtin/notes.c:39 -msgid "git notes [--ref <notes-ref>] get-ref" -msgstr "" - -#: builtin/notes.c:44 -msgid "git notes [list [<object>]]" -msgstr "" - -#: builtin/notes.c:49 -msgid "git notes add [<options>] [<object>]" -msgstr "" - -#: builtin/notes.c:54 -msgid "git notes copy [<options>] <from-object> <to-object>" -msgstr "" - -#: builtin/notes.c:55 -msgid "git notes copy --stdin [<from-object> <to-object>]..." -msgstr "" - -#: builtin/notes.c:60 -msgid "git notes append [<options>] [<object>]" -msgstr "" - -#: builtin/notes.c:65 -msgid "git notes edit [<object>]" -msgstr "" - -#: builtin/notes.c:70 -msgid "git notes show [<object>]" -msgstr "" - -#: builtin/notes.c:75 -msgid "git notes merge [<options>] <notes-ref>" -msgstr "" - -#: builtin/notes.c:76 -msgid "git notes merge --commit [<options>]" -msgstr "" - -#: builtin/notes.c:77 -msgid "git notes merge --abort [<options>]" -msgstr "" - -#: builtin/notes.c:82 -msgid "git notes remove [<object>]" -msgstr "" - -#: builtin/notes.c:87 -msgid "git notes prune [<options>]" -msgstr "" - -#: builtin/notes.c:97 -msgid "Write/edit the notes for the following object:" -msgstr "" - -#: builtin/notes.c:149 -#, c-format -msgid "unable to start 'show' for object '%s'" -msgstr "" - -#: builtin/notes.c:153 -msgid "could not read 'show' output" -msgstr "" - -#: builtin/notes.c:161 -#, c-format -msgid "failed to finish 'show' for object '%s'" -msgstr "" - -#: builtin/notes.c:194 -msgid "please supply the note contents using either -m or -F option" -msgstr "" - -#: builtin/notes.c:203 -msgid "unable to write note object" -msgstr "" - -#: builtin/notes.c:206 -#, c-format -msgid "the note contents have been left in %s" -msgstr "" - -#: builtin/notes.c:240 builtin/tag.c:582 -#, c-format -msgid "could not open or read '%s'" -msgstr "" - -#: builtin/notes.c:261 builtin/notes.c:311 builtin/notes.c:313 -#: builtin/notes.c:381 builtin/notes.c:436 builtin/notes.c:524 -#: builtin/notes.c:529 builtin/notes.c:608 builtin/notes.c:670 -#, c-format -msgid "failed to resolve '%s' as a valid ref." -msgstr "" - -#: builtin/notes.c:263 -#, c-format -msgid "failed to read object '%s'." -msgstr "" - -#: builtin/notes.c:266 -#, c-format -msgid "cannot read note data from non-blob object '%s'." -msgstr "" - -#: builtin/notes.c:307 -#, c-format -msgid "malformed input line: '%s'." -msgstr "" - -#: builtin/notes.c:322 -#, c-format -msgid "failed to copy notes from '%s' to '%s'" -msgstr "" - -#. TRANSLATORS: the first %s will be replaced by a git -#. notes command: 'add', 'merge', 'remove', etc. -#. -#: builtin/notes.c:354 -#, c-format -msgid "refusing to %s notes in %s (outside of refs/notes/)" -msgstr "" - -#: builtin/notes.c:387 builtin/notes.c:676 -#, c-format -msgid "no note found for object %s." -msgstr "" - -#: builtin/notes.c:408 builtin/notes.c:574 -msgid "note contents as a string" -msgstr "" - -#: builtin/notes.c:411 builtin/notes.c:577 -msgid "note contents in a file" -msgstr "" - -#: builtin/notes.c:414 builtin/notes.c:580 -msgid "reuse and edit specified note object" -msgstr "" - -#: builtin/notes.c:417 builtin/notes.c:583 -msgid "reuse specified note object" -msgstr "" - -#: builtin/notes.c:420 builtin/notes.c:586 -msgid "allow storing empty note" -msgstr "" - -#: builtin/notes.c:421 builtin/notes.c:494 -msgid "replace existing notes" -msgstr "" - -#: builtin/notes.c:446 -#, c-format -msgid "" -"Cannot add notes. Found existing notes for object %s. Use '-f' to overwrite " -"existing notes" -msgstr "" - -#: builtin/notes.c:461 builtin/notes.c:542 -#, c-format -msgid "Overwriting existing notes for object %s\n" -msgstr "" - -#: builtin/notes.c:473 builtin/notes.c:635 builtin/notes.c:904 -#, c-format -msgid "Removing note for object %s\n" -msgstr "" - -#: builtin/notes.c:495 -msgid "read objects from stdin" -msgstr "" - -#: builtin/notes.c:497 -msgid "load rewriting config for <command> (implies --stdin)" -msgstr "" - -#: builtin/notes.c:515 -msgid "too few arguments" -msgstr "" - -#: builtin/notes.c:536 -#, c-format -msgid "" -"Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " -"existing notes" -msgstr "" - -#: builtin/notes.c:548 -#, c-format -msgid "missing notes on source object %s. Cannot copy." -msgstr "" - -#: builtin/notes.c:601 -#, c-format -msgid "" -"The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" -"Please use 'git notes add -f -m/-F/-c/-C' instead.\n" -msgstr "" - -#: builtin/notes.c:696 -msgid "failed to delete ref NOTES_MERGE_PARTIAL" -msgstr "" - -#: builtin/notes.c:698 -msgid "failed to delete ref NOTES_MERGE_REF" -msgstr "" - -#: builtin/notes.c:700 -msgid "failed to remove 'git notes merge' worktree" -msgstr "" - -#: builtin/notes.c:720 -msgid "failed to read ref NOTES_MERGE_PARTIAL" -msgstr "" - -#: builtin/notes.c:722 -msgid "could not find commit from NOTES_MERGE_PARTIAL." -msgstr "" - -#: builtin/notes.c:724 -msgid "could not parse commit from NOTES_MERGE_PARTIAL." -msgstr "" - -#: builtin/notes.c:737 -msgid "failed to resolve NOTES_MERGE_REF" -msgstr "" - -#: builtin/notes.c:740 -msgid "failed to finalize notes merge" -msgstr "" - -#: builtin/notes.c:766 -#, c-format -msgid "unknown notes merge strategy %s" -msgstr "" - -#: builtin/notes.c:782 -msgid "General options" -msgstr "" - -#: builtin/notes.c:784 -msgid "Merge options" -msgstr "" - -#: builtin/notes.c:786 -msgid "" -"resolve notes conflicts using the given strategy (manual/ours/theirs/union/" -"cat_sort_uniq)" -msgstr "" - -#: builtin/notes.c:788 -msgid "Committing unmerged notes" -msgstr "" - -#: builtin/notes.c:790 -msgid "finalize notes merge by committing unmerged notes" -msgstr "" - -#: builtin/notes.c:792 -msgid "Aborting notes merge resolution" -msgstr "" - -#: builtin/notes.c:794 -msgid "abort notes merge" -msgstr "" - -#: builtin/notes.c:805 -msgid "cannot mix --commit, --abort or -s/--strategy" -msgstr "" - -#: builtin/notes.c:810 -msgid "must specify a notes ref to merge" -msgstr "" - -#: builtin/notes.c:834 -#, c-format -msgid "unknown -s/--strategy: %s" -msgstr "" - -#: builtin/notes.c:874 -#, c-format -msgid "a notes merge into %s is already in-progress at %s" -msgstr "" - -#: builtin/notes.c:878 -#, c-format -msgid "failed to store link to current notes ref (%s)" -msgstr "" - -#: builtin/notes.c:880 -#, c-format -msgid "" -"Automatic notes merge failed. Fix conflicts in %s and commit the result with " -"'git notes merge --commit', or abort the merge with 'git notes merge --" -"abort'.\n" -msgstr "" - -#: builtin/notes.c:899 builtin/tag.c:595 -#, c-format -msgid "Failed to resolve '%s' as a valid ref." -msgstr "" - -#: builtin/notes.c:902 -#, c-format -msgid "Object %s has no note\n" -msgstr "" - -#: builtin/notes.c:914 -msgid "attempt to remove non-existent note is not an error" -msgstr "" - -#: builtin/notes.c:917 -msgid "read object names from the standard input" -msgstr "" - -#: builtin/notes.c:956 builtin/prune.c:144 builtin/worktree.c:148 -msgid "do not remove, show only" -msgstr "" - -#: builtin/notes.c:957 -msgid "report pruned notes" -msgstr "" - -#: builtin/notes.c:1000 -msgid "notes-ref" -msgstr "" - -#: builtin/notes.c:1001 -msgid "use notes from <notes-ref>" -msgstr "" - -#: builtin/notes.c:1036 builtin/stash.c:1802 -#, c-format -msgid "unknown subcommand: %s" -msgstr "" - -#: builtin/pack-objects.c:182 -msgid "" -"git pack-objects --stdout [<options>...] [< <ref-list> | < <object-list>]" -msgstr "" - -#: builtin/pack-objects.c:183 -msgid "" -"git pack-objects [<options>...] <base-name> [< <ref-list> | < <object-list>]" -msgstr "" - -#: builtin/pack-objects.c:570 -#, c-format -msgid "" -"write_reuse_object: could not locate %s, expected at offset %<PRIuMAX> in " -"pack %s" -msgstr "" - -#: builtin/pack-objects.c:578 -#, c-format -msgid "bad packed object CRC for %s" -msgstr "" - -#: builtin/pack-objects.c:589 -#, c-format -msgid "corrupt packed object for %s" -msgstr "" - -#: builtin/pack-objects.c:720 -#, c-format -msgid "recursive delta detected for object %s" -msgstr "" - -#: builtin/pack-objects.c:939 -#, c-format -msgid "ordered %u objects, expected %<PRIu32>" -msgstr "" - -#: builtin/pack-objects.c:1034 -#, c-format -msgid "expected object at offset %<PRIuMAX> in pack %s" -msgstr "" - -#: builtin/pack-objects.c:1158 -msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" -msgstr "" - -#: builtin/pack-objects.c:1171 -msgid "Writing objects" -msgstr "" - -#: builtin/pack-objects.c:1243 builtin/update-index.c:90 -#, c-format -msgid "failed to stat %s" -msgstr "" - -#: builtin/pack-objects.c:1276 -msgid "failed to write bitmap index" -msgstr "" - -#: builtin/pack-objects.c:1302 -#, c-format -msgid "wrote %<PRIu32> objects while expecting %<PRIu32>" -msgstr "" - -#: builtin/pack-objects.c:1544 -msgid "disabling bitmap writing, as some objects are not being packed" -msgstr "" - -#: builtin/pack-objects.c:1992 -#, c-format -msgid "delta base offset overflow in pack for %s" -msgstr "" - -#: builtin/pack-objects.c:2001 -#, c-format -msgid "delta base offset out of bound for %s" -msgstr "" - -#: builtin/pack-objects.c:2282 -msgid "Counting objects" -msgstr "" - -#: builtin/pack-objects.c:2447 -#, c-format -msgid "unable to parse object header of %s" -msgstr "" - -#: builtin/pack-objects.c:2517 builtin/pack-objects.c:2533 -#: builtin/pack-objects.c:2543 -#, c-format -msgid "object %s cannot be read" -msgstr "" - -#: builtin/pack-objects.c:2520 builtin/pack-objects.c:2547 -#, c-format -msgid "object %s inconsistent object length (%<PRIuMAX> vs %<PRIuMAX>)" -msgstr "" - -#: builtin/pack-objects.c:2557 -msgid "suboptimal pack - out of memory" -msgstr "" - -#: builtin/pack-objects.c:2872 -#, c-format -msgid "Delta compression using up to %d threads" -msgstr "" - -#: builtin/pack-objects.c:3011 -#, c-format -msgid "unable to pack objects reachable from tag %s" -msgstr "" - -#: builtin/pack-objects.c:3097 -msgid "Compressing objects" -msgstr "" - -#: builtin/pack-objects.c:3103 -msgid "inconsistency with delta count" -msgstr "" - -#: builtin/pack-objects.c:3182 -#, c-format -msgid "" -"value of uploadpack.blobpackfileuri must be of the form '<object-hash> <pack-" -"hash> <uri>' (got '%s')" -msgstr "" - -#: builtin/pack-objects.c:3185 -#, c-format -msgid "" -"object already configured in another uploadpack.blobpackfileuri (got '%s')" -msgstr "" - -#: builtin/pack-objects.c:3220 -#, c-format -msgid "could not get type of object %s in pack %s" -msgstr "" - -#: builtin/pack-objects.c:3348 builtin/pack-objects.c:3359 -#: builtin/pack-objects.c:3373 -#, c-format -msgid "could not find pack '%s'" -msgstr "" - -#: builtin/pack-objects.c:3416 -#, c-format -msgid "" -"expected edge object ID, got garbage:\n" -" %s" -msgstr "" - -#: builtin/pack-objects.c:3422 -#, c-format -msgid "" -"expected object ID, got garbage:\n" -" %s" -msgstr "" - -#: builtin/pack-objects.c:3540 builtin/pack-objects.c:3627 -msgid "cannot open pack index" -msgstr "" - -#: builtin/pack-objects.c:3549 -#, c-format -msgid "loose object at %s could not be examined" -msgstr "" - -#: builtin/pack-objects.c:3635 -msgid "unable to force loose object" -msgstr "" - -#: builtin/pack-objects.c:3763 -#, c-format -msgid "not a rev '%s'" -msgstr "" - -#: builtin/pack-objects.c:3766 builtin/rev-parse.c:1061 -#, c-format -msgid "bad revision '%s'" -msgstr "" - -#: builtin/pack-objects.c:3794 -msgid "unable to add recent objects" -msgstr "" - -#: builtin/pack-objects.c:3847 -#, c-format -msgid "unsupported index version %s" -msgstr "" - -#: builtin/pack-objects.c:3851 -#, c-format -msgid "bad index version '%s'" -msgstr "" - -#: builtin/pack-objects.c:3907 -msgid "<version>[,<offset>]" -msgstr "" - -#: builtin/pack-objects.c:3908 -msgid "write the pack index file in the specified idx format version" -msgstr "" - -#: builtin/pack-objects.c:3911 -msgid "maximum size of each output pack file" -msgstr "" - -#: builtin/pack-objects.c:3913 -msgid "ignore borrowed objects from alternate object store" -msgstr "" - -#: builtin/pack-objects.c:3915 -msgid "ignore packed objects" -msgstr "" - -#: builtin/pack-objects.c:3917 -msgid "limit pack window by objects" -msgstr "" - -#: builtin/pack-objects.c:3919 -msgid "limit pack window by memory in addition to object limit" -msgstr "" - -#: builtin/pack-objects.c:3921 -msgid "maximum length of delta chain allowed in the resulting pack" -msgstr "" - -#: builtin/pack-objects.c:3923 -msgid "reuse existing deltas" -msgstr "" - -#: builtin/pack-objects.c:3925 -msgid "reuse existing objects" -msgstr "" - -#: builtin/pack-objects.c:3927 -msgid "use OFS_DELTA objects" -msgstr "" - -#: builtin/pack-objects.c:3929 -msgid "use threads when searching for best delta matches" -msgstr "" - -#: builtin/pack-objects.c:3931 -msgid "do not create an empty pack output" -msgstr "" - -#: builtin/pack-objects.c:3933 -msgid "read revision arguments from standard input" -msgstr "" - -#: builtin/pack-objects.c:3935 -msgid "limit the objects to those that are not yet packed" -msgstr "" - -#: builtin/pack-objects.c:3938 -msgid "include objects reachable from any reference" -msgstr "" - -#: builtin/pack-objects.c:3941 -msgid "include objects referred by reflog entries" -msgstr "" - -#: builtin/pack-objects.c:3944 -msgid "include objects referred to by the index" -msgstr "" - -#: builtin/pack-objects.c:3947 -msgid "read packs from stdin" -msgstr "" - -#: builtin/pack-objects.c:3949 -msgid "output pack to stdout" -msgstr "" - -#: builtin/pack-objects.c:3951 -msgid "include tag objects that refer to objects to be packed" -msgstr "" - -#: builtin/pack-objects.c:3953 -msgid "keep unreachable objects" -msgstr "" - -#: builtin/pack-objects.c:3955 -msgid "pack loose unreachable objects" -msgstr "" - -#: builtin/pack-objects.c:3957 -msgid "unpack unreachable objects newer than <time>" -msgstr "" - -#: builtin/pack-objects.c:3960 -msgid "use the sparse reachability algorithm" -msgstr "" - -#: builtin/pack-objects.c:3962 -msgid "create thin packs" -msgstr "" - -#: builtin/pack-objects.c:3964 -msgid "create packs suitable for shallow fetches" -msgstr "" - -#: builtin/pack-objects.c:3966 -msgid "ignore packs that have companion .keep file" -msgstr "" - -#: builtin/pack-objects.c:3968 -msgid "ignore this pack" -msgstr "" - -#: builtin/pack-objects.c:3970 -msgid "pack compression level" -msgstr "" - -#: builtin/pack-objects.c:3972 -msgid "do not hide commits by grafts" -msgstr "" - -#: builtin/pack-objects.c:3974 -msgid "use a bitmap index if available to speed up counting objects" -msgstr "" - -#: builtin/pack-objects.c:3976 -msgid "write a bitmap index together with the pack index" -msgstr "" - -#: builtin/pack-objects.c:3980 -msgid "write a bitmap index if possible" -msgstr "" - -#: builtin/pack-objects.c:3984 -msgid "handling for missing objects" -msgstr "" - -#: builtin/pack-objects.c:3987 -msgid "do not pack objects in promisor packfiles" -msgstr "" - -#: builtin/pack-objects.c:3989 -msgid "respect islands during delta compression" -msgstr "" - -#: builtin/pack-objects.c:3991 -msgid "protocol" -msgstr "" - -#: builtin/pack-objects.c:3992 -msgid "exclude any configured uploadpack.blobpackfileuri with this protocol" -msgstr "" - -#: builtin/pack-objects.c:4027 -#, c-format -msgid "delta chain depth %d is too deep, forcing %d" -msgstr "" - -#: builtin/pack-objects.c:4032 -#, c-format -msgid "pack.deltaCacheLimit is too high, forcing %d" -msgstr "" - -#: builtin/pack-objects.c:4088 -msgid "--max-pack-size cannot be used to build a pack for transfer" -msgstr "" - -#: builtin/pack-objects.c:4090 -msgid "minimum pack size limit is 1 MiB" -msgstr "" - -#: builtin/pack-objects.c:4095 -msgid "--thin cannot be used to build an indexable pack" -msgstr "" - -#: builtin/pack-objects.c:4104 -msgid "cannot use --filter without --stdout" -msgstr "" - -#: builtin/pack-objects.c:4106 -msgid "cannot use --filter with --stdin-packs" -msgstr "" - -#: builtin/pack-objects.c:4110 -msgid "cannot use internal rev list with --stdin-packs" -msgstr "" - -#: builtin/pack-objects.c:4169 -msgid "Enumerating objects" -msgstr "" - -#: builtin/pack-objects.c:4210 -#, c-format -msgid "" -"Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>), pack-" -"reused %<PRIu32>" -msgstr "" - -#: builtin/pack-redundant.c:601 -msgid "" -"'git pack-redundant' is nominated for removal.\n" -"If you still use this command, please add an extra\n" -"option, '--i-still-use-this', on the command line\n" -"and let us know you still use it by sending an e-mail\n" -"to <git@vger.kernel.org>. Thanks.\n" -msgstr "" - -#: builtin/pack-refs.c:8 -msgid "git pack-refs [<options>]" -msgstr "" - -#: builtin/pack-refs.c:16 -msgid "pack everything" -msgstr "" - -#: builtin/pack-refs.c:17 -msgid "prune loose refs (default)" -msgstr "" - -#: builtin/prune.c:14 -msgid "git prune [-n] [-v] [--progress] [--expire <time>] [--] [<head>...]" -msgstr "" - -#: builtin/prune.c:145 -msgid "report pruned objects" -msgstr "" - -#: builtin/prune.c:148 -msgid "expire objects older than <time>" -msgstr "" - -#: builtin/prune.c:150 -msgid "limit traversal to objects outside promisor packfiles" -msgstr "" - -#: builtin/prune.c:163 -msgid "cannot prune in a precious-objects repo" -msgstr "" - -#: builtin/pull.c:67 -msgid "git pull [<options>] [<repository> [<refspec>...]]" -msgstr "" - -#: builtin/pull.c:124 -msgid "control for recursive fetching of submodules" -msgstr "" - -#: builtin/pull.c:128 -msgid "Options related to merging" -msgstr "" - -#: builtin/pull.c:131 -msgid "incorporate changes by rebasing rather than merging" -msgstr "" - -#: builtin/pull.c:159 builtin/revert.c:126 -msgid "allow fast-forward" -msgstr "" - -#: builtin/pull.c:165 -msgid "control use of pre-merge-commit and commit-msg hooks" -msgstr "" - -#: builtin/pull.c:171 parse-options.h:371 -msgid "automatically stash/stash pop before and after" -msgstr "" - -#: builtin/pull.c:187 -msgid "Options related to fetching" -msgstr "" - -#: builtin/pull.c:197 -msgid "force overwrite of local branch" -msgstr "" - -#: builtin/pull.c:205 -msgid "number of submodules pulled in parallel" -msgstr "" - -#: builtin/pull.c:449 -msgid "" -"There is no candidate for rebasing against among the refs that you just " -"fetched." -msgstr "" - -#: builtin/pull.c:451 -msgid "" -"There are no candidates for merging among the refs that you just fetched." -msgstr "" - -#: builtin/pull.c:452 -msgid "" -"Generally this means that you provided a wildcard refspec which had no\n" -"matches on the remote end." -msgstr "" - -#: builtin/pull.c:455 -#, c-format -msgid "" -"You asked to pull from the remote '%s', but did not specify\n" -"a branch. Because this is not the default configured remote\n" -"for your current branch, you must specify a branch on the command line." -msgstr "" - -#: builtin/pull.c:460 builtin/rebase.c:978 -msgid "You are not currently on a branch." -msgstr "" - -#: builtin/pull.c:462 builtin/pull.c:477 -msgid "Please specify which branch you want to rebase against." -msgstr "" - -#: builtin/pull.c:464 builtin/pull.c:479 -msgid "Please specify which branch you want to merge with." -msgstr "" - -#: builtin/pull.c:465 builtin/pull.c:480 -msgid "See git-pull(1) for details." -msgstr "" - -#: builtin/pull.c:467 builtin/pull.c:473 builtin/pull.c:482 -#: builtin/rebase.c:984 -msgid "<remote>" -msgstr "" - -#: builtin/pull.c:467 builtin/pull.c:482 builtin/pull.c:487 -#: contrib/scalar/scalar.c:374 -msgid "<branch>" -msgstr "" - -#: builtin/pull.c:475 builtin/rebase.c:976 -msgid "There is no tracking information for the current branch." -msgstr "" - -#: builtin/pull.c:484 -msgid "" -"If you wish to set tracking information for this branch you can do so with:" -msgstr "" - -#: builtin/pull.c:489 -#, c-format -msgid "" -"Your configuration specifies to merge with the ref '%s'\n" -"from the remote, but no such ref was fetched." -msgstr "" - -#: builtin/pull.c:600 -#, c-format -msgid "unable to access commit %s" -msgstr "" - -#: builtin/pull.c:908 -msgid "ignoring --verify-signatures for rebase" -msgstr "" - -#: builtin/pull.c:969 -msgid "" -"You have divergent branches and need to specify how to reconcile them.\n" -"You can do so by running one of the following commands sometime before\n" -"your next pull:\n" -"\n" -" git config pull.rebase false # merge\n" -" git config pull.rebase true # rebase\n" -" git config pull.ff only # fast-forward only\n" -"\n" -"You can replace \"git config\" with \"git config --global\" to set a " -"default\n" -"preference for all repositories. You can also pass --rebase, --no-rebase,\n" -"or --ff-only on the command line to override the configured default per\n" -"invocation.\n" -msgstr "" - -#: builtin/pull.c:1047 -msgid "Updating an unborn branch with changes added to the index." -msgstr "" - -#: builtin/pull.c:1051 -msgid "pull with rebase" -msgstr "" - -#: builtin/pull.c:1052 -msgid "please commit or stash them." -msgstr "" - -#: builtin/pull.c:1077 -#, c-format -msgid "" -"fetch updated the current branch head.\n" -"fast-forwarding your working tree from\n" -"commit %s." -msgstr "" - -#: builtin/pull.c:1083 -#, c-format -msgid "" -"Cannot fast-forward your working tree.\n" -"After making sure that you saved anything precious from\n" -"$ git diff %s\n" -"output, run\n" -"$ git reset --hard\n" -"to recover." -msgstr "" - -#: builtin/pull.c:1098 -msgid "Cannot merge multiple branches into empty head." -msgstr "" - -#: builtin/pull.c:1103 -msgid "Cannot rebase onto multiple branches." -msgstr "" - -#: builtin/pull.c:1105 -msgid "Cannot fast-forward to multiple branches." -msgstr "" - -#: builtin/pull.c:1120 -msgid "Need to specify how to reconcile divergent branches." -msgstr "" - -#: builtin/pull.c:1134 -msgid "cannot rebase with locally recorded submodule modifications" -msgstr "" - -#: builtin/push.c:19 -msgid "git push [<options>] [<repository> [<refspec>...]]" -msgstr "" - -#: builtin/push.c:111 -msgid "tag shorthand without <tag>" -msgstr "" - -#: builtin/push.c:119 -msgid "--delete only accepts plain target ref names" -msgstr "" - -#: builtin/push.c:164 -msgid "" -"\n" -"To choose either option permanently, see push.default in 'git help config'." -msgstr "" - -#: builtin/push.c:167 -#, c-format -msgid "" -"The upstream branch of your current branch does not match\n" -"the name of your current branch. To push to the upstream branch\n" -"on the remote, use\n" -"\n" -" git push %s HEAD:%s\n" -"\n" -"To push to the branch of the same name on the remote, use\n" -"\n" -" git push %s HEAD\n" -"%s" -msgstr "" - -#: builtin/push.c:182 -#, c-format -msgid "" -"You are not currently on a branch.\n" -"To push the history leading to the current (detached HEAD)\n" -"state now, use\n" -"\n" -" git push %s HEAD:<name-of-remote-branch>\n" -msgstr "" - -#: builtin/push.c:191 -#, c-format -msgid "" -"The current branch %s has no upstream branch.\n" -"To push the current branch and set the remote as upstream, use\n" -"\n" -" git push --set-upstream %s %s\n" -msgstr "" - -#: builtin/push.c:199 -#, c-format -msgid "The current branch %s has multiple upstream branches, refusing to push." -msgstr "" - -#: builtin/push.c:217 -msgid "" -"You didn't specify any refspecs to push, and push.default is \"nothing\"." -msgstr "" - -#: builtin/push.c:243 -#, c-format -msgid "" -"You are pushing to remote '%s', which is not the upstream of\n" -"your current branch '%s', without telling me what to push\n" -"to update which remote branch." -msgstr "" - -#: builtin/push.c:258 -msgid "" -"Updates were rejected because the tip of your current branch is behind\n" -"its remote counterpart. Integrate the remote changes (e.g.\n" -"'git pull ...') before pushing again.\n" -"See the 'Note about fast-forwards' in 'git push --help' for details." -msgstr "" - -#: builtin/push.c:264 -msgid "" -"Updates were rejected because a pushed branch tip is behind its remote\n" -"counterpart. Check out this branch and integrate the remote changes\n" -"(e.g. 'git pull ...') before pushing again.\n" -"See the 'Note about fast-forwards' in 'git push --help' for details." -msgstr "" - -#: builtin/push.c:270 -msgid "" -"Updates were rejected because the remote contains work that you do\n" -"not have locally. This is usually caused by another repository pushing\n" -"to the same ref. You may want to first integrate the remote changes\n" -"(e.g., 'git pull ...') before pushing again.\n" -"See the 'Note about fast-forwards' in 'git push --help' for details." -msgstr "" - -#: builtin/push.c:277 -msgid "Updates were rejected because the tag already exists in the remote." -msgstr "" - -#: builtin/push.c:280 -msgid "" -"You cannot update a remote ref that points at a non-commit object,\n" -"or update a remote ref to make it point at a non-commit object,\n" -"without using the '--force' option.\n" -msgstr "" - -#: builtin/push.c:285 -msgid "" -"Updates were rejected because the tip of the remote-tracking\n" -"branch has been updated since the last checkout. You may want\n" -"to integrate those changes locally (e.g., 'git pull ...')\n" -"before forcing an update.\n" -msgstr "" - -#: builtin/push.c:355 -#, c-format -msgid "Pushing to %s\n" -msgstr "" - -#: builtin/push.c:362 -#, c-format -msgid "failed to push some refs to '%s'" -msgstr "" - -#: builtin/push.c:544 builtin/submodule--helper.c:3377 -msgid "repository" -msgstr "" - -#: builtin/push.c:545 builtin/send-pack.c:193 -msgid "push all refs" -msgstr "" - -#: builtin/push.c:546 builtin/send-pack.c:195 -msgid "mirror all refs" -msgstr "" - -#: builtin/push.c:548 -msgid "delete refs" -msgstr "" - -#: builtin/push.c:549 -msgid "push tags (can't be used with --all or --mirror)" -msgstr "" - -#: builtin/push.c:552 builtin/send-pack.c:196 -msgid "force updates" -msgstr "" - -#: builtin/push.c:553 builtin/send-pack.c:208 -msgid "<refname>:<expect>" -msgstr "" - -#: builtin/push.c:554 builtin/send-pack.c:209 -msgid "require old value of ref to be at this value" -msgstr "" - -#: builtin/push.c:557 builtin/send-pack.c:212 -msgid "require remote updates to be integrated locally" -msgstr "" - -#: builtin/push.c:560 -msgid "control recursive pushing of submodules" -msgstr "" - -#: builtin/push.c:561 builtin/send-pack.c:203 -msgid "use thin pack" -msgstr "" - -#: builtin/push.c:562 builtin/push.c:563 builtin/send-pack.c:190 -#: builtin/send-pack.c:191 -msgid "receive pack program" -msgstr "" - -#: builtin/push.c:564 -msgid "set upstream for git pull/status" -msgstr "" - -#: builtin/push.c:567 -msgid "prune locally removed refs" -msgstr "" - -#: builtin/push.c:569 -msgid "bypass pre-push hook" -msgstr "" - -#: builtin/push.c:570 -msgid "push missing but relevant tags" -msgstr "" - -#: builtin/push.c:572 builtin/send-pack.c:197 -msgid "GPG sign the push" -msgstr "" - -#: builtin/push.c:574 builtin/send-pack.c:204 -msgid "request atomic transaction on remote side" -msgstr "" - -#: builtin/push.c:594 -msgid "--delete doesn't make sense without any refs" -msgstr "" - -#: builtin/push.c:614 -#, c-format -msgid "bad repository '%s'" -msgstr "" - -#: builtin/push.c:615 -msgid "" -"No configured push destination.\n" -"Either specify the URL from the command-line or configure a remote " -"repository using\n" -"\n" -" git remote add <name> <url>\n" -"\n" -"and then push using the remote name\n" -"\n" -" git push <name>\n" -msgstr "" - -#: builtin/push.c:632 -msgid "--all can't be combined with refspecs" -msgstr "" - -#: builtin/push.c:638 -msgid "--mirror can't be combined with refspecs" -msgstr "" - -#: builtin/push.c:648 -msgid "push options must not have new line characters" -msgstr "" - -#: builtin/range-diff.c:9 -msgid "git range-diff [<options>] <old-base>..<old-tip> <new-base>..<new-tip>" -msgstr "" - -#: builtin/range-diff.c:10 -msgid "git range-diff [<options>] <old-tip>...<new-tip>" -msgstr "" - -#: builtin/range-diff.c:11 -msgid "git range-diff [<options>] <base> <old-tip> <new-tip>" -msgstr "" - -#: builtin/range-diff.c:30 -msgid "use simple diff colors" -msgstr "" - -#: builtin/range-diff.c:32 -msgid "notes" -msgstr "" - -#: builtin/range-diff.c:32 -msgid "passed to 'git log'" -msgstr "" - -#: builtin/range-diff.c:35 -msgid "only emit output related to the first range" -msgstr "" - -#: builtin/range-diff.c:37 -msgid "only emit output related to the second range" -msgstr "" - -#: builtin/range-diff.c:60 builtin/range-diff.c:64 -#, c-format -msgid "not a commit range: '%s'" -msgstr "" - -#: builtin/range-diff.c:74 -msgid "single arg format must be symmetric range" -msgstr "" - -#: builtin/range-diff.c:89 -msgid "need two commit ranges" -msgstr "" - -#: builtin/read-tree.c:41 -msgid "" -"git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) " -"[-u | -i]] [--no-sparse-checkout] [--index-output=<file>] (--empty | <tree-" -"ish1> [<tree-ish2> [<tree-ish3>]])" -msgstr "" - -#: builtin/read-tree.c:116 -msgid "write resulting index to <file>" -msgstr "" - -#: builtin/read-tree.c:119 -msgid "only empty the index" -msgstr "" - -#: builtin/read-tree.c:121 -msgid "Merging" -msgstr "" - -#: builtin/read-tree.c:123 -msgid "perform a merge in addition to a read" -msgstr "" - -#: builtin/read-tree.c:125 -msgid "3-way merge if no file level merging required" -msgstr "" - -#: builtin/read-tree.c:127 -msgid "3-way merge in presence of adds and removes" -msgstr "" - -#: builtin/read-tree.c:129 -msgid "same as -m, but discard unmerged entries" -msgstr "" - -#: builtin/read-tree.c:130 -msgid "<subdirectory>/" -msgstr "" - -#: builtin/read-tree.c:131 -msgid "read the tree into the index under <subdirectory>/" -msgstr "" - -#: builtin/read-tree.c:134 -msgid "update working tree with merge result" -msgstr "" - -#: builtin/read-tree.c:136 -msgid "gitignore" -msgstr "" - -#: builtin/read-tree.c:137 -msgid "allow explicitly ignored files to be overwritten" -msgstr "" - -#: builtin/read-tree.c:140 -msgid "don't check the working tree after merging" -msgstr "" - -#: builtin/read-tree.c:141 -msgid "don't update the index or the work tree" -msgstr "" - -#: builtin/read-tree.c:143 -msgid "skip applying sparse checkout filter" -msgstr "" - -#: builtin/read-tree.c:145 -msgid "debug unpack-trees" -msgstr "" - -#: builtin/read-tree.c:149 -msgid "suppress feedback messages" -msgstr "" - -#: builtin/read-tree.c:190 -msgid "You need to resolve your current index first" -msgstr "" - -#: builtin/rebase.c:36 -msgid "" -"git rebase [-i] [options] [--exec <cmd>] [--onto <newbase> | --keep-base] " -"[<upstream> [<branch>]]" -msgstr "" - -#: builtin/rebase.c:38 -msgid "" -"git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]" -msgstr "" - -#: builtin/rebase.c:231 -#, c-format -msgid "could not create temporary %s" -msgstr "" - -#: builtin/rebase.c:237 -msgid "could not mark as interactive" -msgstr "" - -#: builtin/rebase.c:290 -msgid "could not generate todo list" -msgstr "" - -#: builtin/rebase.c:332 -msgid "a base commit must be provided with --upstream or --onto" -msgstr "" - -#: builtin/rebase.c:391 -#, c-format -msgid "%s requires the merge backend" -msgstr "" - -#: builtin/rebase.c:433 -#, c-format -msgid "could not get 'onto': '%s'" -msgstr "" - -#: builtin/rebase.c:450 -#, c-format -msgid "invalid orig-head: '%s'" -msgstr "" - -#: builtin/rebase.c:475 -#, c-format -msgid "ignoring invalid allow_rerere_autoupdate: '%s'" -msgstr "" - -#: builtin/rebase.c:600 -msgid "" -"Resolve all conflicts manually, mark them as resolved with\n" -"\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n" -"You can instead skip this commit: run \"git rebase --skip\".\n" -"To abort and get back to the state before \"git rebase\", run \"git rebase --" -"abort\"." -msgstr "" - -#: builtin/rebase.c:685 -#, c-format -msgid "" -"\n" -"git encountered an error while preparing the patches to replay\n" -"these revisions:\n" -"\n" -" %s\n" -"\n" -"As a result, git cannot rebase them." -msgstr "" - -#: builtin/rebase.c:836 -#, c-format -msgid "could not switch to %s" -msgstr "" - -#: builtin/rebase.c:952 -#, c-format -msgid "" -"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"ask" -"\"." -msgstr "" - -#: builtin/rebase.c:970 -#, c-format -msgid "" -"%s\n" -"Please specify which branch you want to rebase against.\n" -"See git-rebase(1) for details.\n" -"\n" -" git rebase '<branch>'\n" -"\n" -msgstr "" - -#: builtin/rebase.c:986 -#, c-format -msgid "" -"If you wish to set tracking information for this branch you can do so with:\n" -"\n" -" git branch --set-upstream-to=%s/<branch> %s\n" -"\n" -msgstr "" - -#: builtin/rebase.c:1016 -msgid "exec commands cannot contain newlines" -msgstr "" - -#: builtin/rebase.c:1020 -msgid "empty exec command" -msgstr "" - -#: builtin/rebase.c:1051 -msgid "rebase onto given branch instead of upstream" -msgstr "" - -#: builtin/rebase.c:1053 -msgid "use the merge-base of upstream and branch as the current base" -msgstr "" - -#: builtin/rebase.c:1055 -msgid "allow pre-rebase hook to run" -msgstr "" - -#: builtin/rebase.c:1057 -msgid "be quiet. implies --no-stat" -msgstr "" - -#: builtin/rebase.c:1060 -msgid "display a diffstat of what changed upstream" -msgstr "" - -#: builtin/rebase.c:1063 -msgid "do not show diffstat of what changed upstream" -msgstr "" - -#: builtin/rebase.c:1066 -msgid "add a Signed-off-by trailer to each commit" -msgstr "" - -#: builtin/rebase.c:1069 -msgid "make committer date match author date" -msgstr "" - -#: builtin/rebase.c:1071 -msgid "ignore author date and use current date" -msgstr "" - -#: builtin/rebase.c:1073 -msgid "synonym of --reset-author-date" -msgstr "" - -#: builtin/rebase.c:1075 builtin/rebase.c:1079 -msgid "passed to 'git apply'" -msgstr "" - -#: builtin/rebase.c:1077 -msgid "ignore changes in whitespace" -msgstr "" - -#: builtin/rebase.c:1081 builtin/rebase.c:1084 -msgid "cherry-pick all commits, even if unchanged" -msgstr "" - -#: builtin/rebase.c:1086 -msgid "continue" -msgstr "" - -#: builtin/rebase.c:1089 -msgid "skip current patch and continue" -msgstr "" - -#: builtin/rebase.c:1091 -msgid "abort and check out the original branch" -msgstr "" - -#: builtin/rebase.c:1094 -msgid "abort but keep HEAD where it is" -msgstr "" - -#: builtin/rebase.c:1095 -msgid "edit the todo list during an interactive rebase" -msgstr "" - -#: builtin/rebase.c:1098 -msgid "show the patch file being applied or merged" -msgstr "" - -#: builtin/rebase.c:1101 -msgid "use apply strategies to rebase" -msgstr "" - -#: builtin/rebase.c:1105 -msgid "use merging strategies to rebase" -msgstr "" - -#: builtin/rebase.c:1109 -msgid "let the user edit the list of commits to rebase" -msgstr "" - -#: builtin/rebase.c:1113 -msgid "(DEPRECATED) try to recreate merges instead of ignoring them" -msgstr "" - -#: builtin/rebase.c:1118 -msgid "how to handle commits that become empty" -msgstr "" - -#: builtin/rebase.c:1121 -msgid "keep commits which start empty" -msgstr "" - -#: builtin/rebase.c:1125 -msgid "move commits that begin with squash!/fixup! under -i" -msgstr "" - -#: builtin/rebase.c:1132 -msgid "add exec lines after each commit of the editable list" -msgstr "" - -#: builtin/rebase.c:1136 -msgid "allow rebasing commits with empty messages" -msgstr "" - -#: builtin/rebase.c:1140 -msgid "try to rebase merges instead of skipping them" -msgstr "" - -#: builtin/rebase.c:1143 -msgid "use 'merge-base --fork-point' to refine upstream" -msgstr "" - -#: builtin/rebase.c:1145 -msgid "use the given merge strategy" -msgstr "" - -#: builtin/rebase.c:1147 builtin/revert.c:115 -msgid "option" -msgstr "" - -#: builtin/rebase.c:1148 -msgid "pass the argument through to the merge strategy" -msgstr "" - -#: builtin/rebase.c:1151 -msgid "rebase all reachable commits up to the root(s)" -msgstr "" - -#: builtin/rebase.c:1154 -msgid "automatically re-schedule any `exec` that fails" -msgstr "" - -#: builtin/rebase.c:1156 -msgid "apply all changes, even those already present upstream" -msgstr "" - -#: builtin/rebase.c:1177 -msgid "It looks like 'git am' is in progress. Cannot rebase." -msgstr "" - -#: builtin/rebase.c:1208 -msgid "--preserve-merges was replaced by --rebase-merges" -msgstr "" - -#: builtin/rebase.c:1230 -msgid "No rebase in progress?" -msgstr "" - -#: builtin/rebase.c:1234 -msgid "The --edit-todo action can only be used during interactive rebase." -msgstr "" - -#: builtin/rebase.c:1257 t/helper/test-fast-rebase.c:122 -msgid "Cannot read HEAD" -msgstr "" - -#: builtin/rebase.c:1269 -msgid "" -"You must edit all merge conflicts and then\n" -"mark them as resolved using git add" -msgstr "" - -#: builtin/rebase.c:1287 -msgid "could not discard worktree changes" -msgstr "" - -#: builtin/rebase.c:1308 -#, c-format -msgid "could not move back to %s" -msgstr "" - -#: builtin/rebase.c:1354 -#, c-format -msgid "" -"It seems that there is already a %s directory, and\n" -"I wonder if you are in the middle of another rebase. If that is the\n" -"case, please try\n" -"\t%s\n" -"If that is not the case, please\n" -"\t%s\n" -"and run me again. I am stopping in case you still have something\n" -"valuable there.\n" -msgstr "" - -#: builtin/rebase.c:1382 -msgid "switch `C' expects a numerical value" -msgstr "" - -#: builtin/rebase.c:1424 -#, c-format -msgid "Unknown mode: %s" -msgstr "" - -#: builtin/rebase.c:1463 -msgid "--strategy requires --merge or --interactive" -msgstr "" - -#: builtin/rebase.c:1492 -msgid "apply options and merge options cannot be used together" -msgstr "" - -#: builtin/rebase.c:1505 -#, c-format -msgid "Unknown rebase backend: %s" -msgstr "" - -#: builtin/rebase.c:1534 -msgid "--reschedule-failed-exec requires --exec or --interactive" -msgstr "" - -#: builtin/rebase.c:1565 -#, c-format -msgid "invalid upstream '%s'" -msgstr "" - -#: builtin/rebase.c:1571 -msgid "Could not create new root commit" -msgstr "" - -#: builtin/rebase.c:1597 -#, c-format -msgid "'%s': need exactly one merge base with branch" -msgstr "" - -#: builtin/rebase.c:1600 -#, c-format -msgid "'%s': need exactly one merge base" -msgstr "" - -#: builtin/rebase.c:1609 -#, c-format -msgid "Does not point to a valid commit '%s'" -msgstr "" - -#: builtin/rebase.c:1636 -#, c-format -msgid "no such branch/commit '%s'" -msgstr "" - -#: builtin/rebase.c:1647 builtin/submodule--helper.c:43 -#: builtin/submodule--helper.c:2477 -#, c-format -msgid "No such ref: %s" -msgstr "" - -#: builtin/rebase.c:1658 -msgid "Could not resolve HEAD to a revision" -msgstr "" - -#: builtin/rebase.c:1679 -msgid "Please commit or stash them." -msgstr "" - -#: builtin/rebase.c:1714 -msgid "HEAD is up to date." -msgstr "" - -#: builtin/rebase.c:1716 -#, c-format -msgid "Current branch %s is up to date.\n" -msgstr "" - -#: builtin/rebase.c:1724 -msgid "HEAD is up to date, rebase forced." -msgstr "" - -#: builtin/rebase.c:1726 -#, c-format -msgid "Current branch %s is up to date, rebase forced.\n" -msgstr "" - -#: builtin/rebase.c:1734 -msgid "The pre-rebase hook refused to rebase." -msgstr "" - -#: builtin/rebase.c:1741 -#, c-format -msgid "Changes to %s:\n" -msgstr "" - -#: builtin/rebase.c:1744 -#, c-format -msgid "Changes from %s to %s:\n" -msgstr "" - -#: builtin/rebase.c:1769 -#, c-format -msgid "First, rewinding head to replay your work on top of it...\n" -msgstr "" - -#: builtin/rebase.c:1781 -msgid "Could not detach HEAD" -msgstr "" - -#: builtin/rebase.c:1790 -#, c-format -msgid "Fast-forwarded %s to %s.\n" -msgstr "" - -#: builtin/receive-pack.c:35 -msgid "git receive-pack <git-dir>" -msgstr "" - -#: builtin/receive-pack.c:1263 -msgid "" -"By default, updating the current branch in a non-bare repository\n" -"is denied, because it will make the index and work tree inconsistent\n" -"with what you pushed, and will require 'git reset --hard' to match\n" -"the work tree to HEAD.\n" -"\n" -"You can set the 'receive.denyCurrentBranch' configuration variable\n" -"to 'ignore' or 'warn' in the remote repository to allow pushing into\n" -"its current branch; however, this is not recommended unless you\n" -"arranged to update its work tree to match what you pushed in some\n" -"other way.\n" -"\n" -"To squelch this message and still keep the default behaviour, set\n" -"'receive.denyCurrentBranch' configuration variable to 'refuse'." -msgstr "" - -#: builtin/receive-pack.c:1283 -msgid "" -"By default, deleting the current branch is denied, because the next\n" -"'git clone' won't result in any file checked out, causing confusion.\n" -"\n" -"You can set 'receive.denyDeleteCurrent' configuration variable to\n" -"'warn' or 'ignore' in the remote repository to allow deleting the\n" -"current branch, with or without a warning message.\n" -"\n" -"To squelch this message, you can set it to 'refuse'." -msgstr "" - -#: builtin/receive-pack.c:2476 -msgid "quiet" -msgstr "" - -#: builtin/receive-pack.c:2491 -msgid "you must specify a directory" -msgstr "" - -#: builtin/reflog.c:9 -msgid "git reflog [show] [<log-options>] [<ref>]" -msgstr "" - -#: builtin/reflog.c:12 -msgid "" -"git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" -" [--rewrite] [--updateref] [--stale-fix]\n" -" [--dry-run | -n] [--verbose] [--all [--single-worktree] | " -"<refs>...]" -msgstr "" - -#: builtin/reflog.c:17 -msgid "" -"git reflog delete [--rewrite] [--updateref]\n" -" [--dry-run | -n] [--verbose] <ref>@{<specifier>}..." -msgstr "" - -#: builtin/reflog.c:21 -msgid "git reflog exists <ref>" -msgstr "" - -#: builtin/reflog.c:197 builtin/reflog.c:211 -#, c-format -msgid "invalid timestamp '%s' given to '--%s'" -msgstr "" - -#: builtin/reflog.c:240 builtin/reflog.c:359 -msgid "do not actually prune any entries" -msgstr "" - -#: builtin/reflog.c:243 builtin/reflog.c:362 -msgid "" -"rewrite the old SHA1 with the new SHA1 of the entry that now precedes it" -msgstr "" - -#: builtin/reflog.c:246 builtin/reflog.c:365 -msgid "update the reference to the value of the top reflog entry" -msgstr "" - -#: builtin/reflog.c:248 builtin/reflog.c:367 -msgid "print extra information on screen" -msgstr "" - -#: builtin/reflog.c:249 builtin/reflog.c:253 -msgid "timestamp" -msgstr "" - -#: builtin/reflog.c:250 -msgid "prune entries older than the specified time" -msgstr "" - -#: builtin/reflog.c:254 -msgid "" -"prune entries older than <time> that are not reachable from the current tip " -"of the branch" -msgstr "" - -#: builtin/reflog.c:258 -msgid "prune any reflog entries that point to broken commits" -msgstr "" - -#: builtin/reflog.c:259 -msgid "process the reflogs of all references" -msgstr "" - -#: builtin/reflog.c:261 -msgid "limits processing to reflogs from the current worktree only" -msgstr "" - -#: builtin/reflog.c:294 -#, c-format -msgid "Marking reachable objects..." -msgstr "" - -#: builtin/reflog.c:338 -#, c-format -msgid "%s points nowhere!" -msgstr "" - -#: builtin/reflog.c:374 -msgid "no reflog specified to delete" -msgstr "" - -#: builtin/reflog.c:396 -#, c-format -msgid "invalid ref format: %s" -msgstr "" - -#: builtin/remote.c:19 -msgid "" -"git remote add [-t <branch>] [-m <master>] [-f] [--tags | --no-tags] [--" -"mirror=<fetch|push>] <name> <url>" -msgstr "" - -#: builtin/remote.c:20 builtin/remote.c:40 -msgid "git remote rename [--[no-]progress] <old> <new>" -msgstr "" - -#: builtin/remote.c:21 builtin/remote.c:45 -msgid "git remote remove <name>" -msgstr "" - -#: builtin/remote.c:22 builtin/remote.c:50 -msgid "git remote set-head <name> (-a | --auto | -d | --delete | <branch>)" -msgstr "" - -#: builtin/remote.c:23 -msgid "git remote [-v | --verbose] show [-n] <name>" -msgstr "" - -#: builtin/remote.c:24 -msgid "git remote prune [-n | --dry-run] <name>" -msgstr "" - -#: builtin/remote.c:25 -msgid "" -"git remote [-v | --verbose] update [-p | --prune] [(<group> | <remote>)...]" -msgstr "" - -#: builtin/remote.c:26 -msgid "git remote set-branches [--add] <name> <branch>..." -msgstr "" - -#: builtin/remote.c:27 builtin/remote.c:76 -msgid "git remote get-url [--push] [--all] <name>" -msgstr "" - -#: builtin/remote.c:28 builtin/remote.c:81 -msgid "git remote set-url [--push] <name> <newurl> [<oldurl>]" -msgstr "" - -#: builtin/remote.c:29 builtin/remote.c:82 -msgid "git remote set-url --add <name> <newurl>" -msgstr "" - -#: builtin/remote.c:30 builtin/remote.c:83 -msgid "git remote set-url --delete <name> <url>" -msgstr "" - -#: builtin/remote.c:35 -msgid "git remote add [<options>] <name> <url>" -msgstr "" - -#: builtin/remote.c:55 -msgid "git remote set-branches <name> <branch>..." -msgstr "" - -#: builtin/remote.c:56 -msgid "git remote set-branches --add <name> <branch>..." -msgstr "" - -#: builtin/remote.c:61 -msgid "git remote show [<options>] <name>" -msgstr "" - -#: builtin/remote.c:66 -msgid "git remote prune [<options>] <name>" -msgstr "" - -#: builtin/remote.c:71 -msgid "git remote update [<options>] [<group> | <remote>]..." -msgstr "" - -#: builtin/remote.c:100 -#, c-format -msgid "Updating %s" -msgstr "" - -#: builtin/remote.c:102 -#, c-format -msgid "Could not fetch %s" -msgstr "" - -#: builtin/remote.c:132 -msgid "" -"--mirror is dangerous and deprecated; please\n" -"\t use --mirror=fetch or --mirror=push instead" -msgstr "" - -#: builtin/remote.c:149 -#, c-format -msgid "unknown mirror argument: %s" -msgstr "" - -#: builtin/remote.c:165 -msgid "fetch the remote branches" -msgstr "" - -#: builtin/remote.c:167 -msgid "import all tags and associated objects when fetching" -msgstr "" - -#: builtin/remote.c:170 -msgid "or do not fetch any tag at all (--no-tags)" -msgstr "" - -#: builtin/remote.c:172 -msgid "branch(es) to track" -msgstr "" - -#: builtin/remote.c:173 -msgid "master branch" -msgstr "" - -#: builtin/remote.c:175 -msgid "set up remote as a mirror to push to or fetch from" -msgstr "" - -#: builtin/remote.c:187 -msgid "specifying a master branch makes no sense with --mirror" -msgstr "" - -#: builtin/remote.c:189 -msgid "specifying branches to track makes sense only with fetch mirrors" -msgstr "" - -#: builtin/remote.c:196 builtin/remote.c:716 -#, c-format -msgid "remote %s already exists." -msgstr "" - -#: builtin/remote.c:241 -#, c-format -msgid "Could not setup master '%s'" -msgstr "" - -#: builtin/remote.c:323 -#, c-format -msgid "unhandled branch.%s.rebase=%s; assuming 'true'" -msgstr "" - -#: builtin/remote.c:367 -#, c-format -msgid "Could not get fetch map for refspec %s" -msgstr "" - -#: builtin/remote.c:461 builtin/remote.c:469 -msgid "(matching)" -msgstr "" - -#: builtin/remote.c:473 -msgid "(delete)" -msgstr "" - -#: builtin/remote.c:664 -#, c-format -msgid "could not set '%s'" -msgstr "" - -#: builtin/remote.c:669 -#, c-format -msgid "" -"The %s configuration remote.pushDefault in:\n" -"\t%s:%d\n" -"now names the non-existent remote '%s'" -msgstr "" - -#: builtin/remote.c:707 builtin/remote.c:866 builtin/remote.c:973 -#, c-format -msgid "No such remote: '%s'" -msgstr "" - -#: builtin/remote.c:726 -#, c-format -msgid "Could not rename config section '%s' to '%s'" -msgstr "" - -#: builtin/remote.c:746 -#, c-format -msgid "" -"Not updating non-default fetch refspec\n" -"\t%s\n" -"\tPlease update the configuration manually if necessary." -msgstr "" - -#: builtin/remote.c:783 -msgid "Renaming remote references" -msgstr "" - -#: builtin/remote.c:794 -#, c-format -msgid "deleting '%s' failed" -msgstr "" - -#: builtin/remote.c:832 -#, c-format -msgid "creating '%s' failed" -msgstr "" - -#: builtin/remote.c:912 -msgid "" -"Note: A branch outside the refs/remotes/ hierarchy was not removed;\n" -"to delete it, use:" -msgid_plural "" -"Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" -"to delete them, use:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/remote.c:926 -#, c-format -msgid "Could not remove config section '%s'" -msgstr "" - -#: builtin/remote.c:1034 -#, c-format -msgid " new (next fetch will store in remotes/%s)" -msgstr "" - -#: builtin/remote.c:1037 -msgid " tracked" -msgstr "" - -#: builtin/remote.c:1039 -msgid " stale (use 'git remote prune' to remove)" -msgstr "" - -#: builtin/remote.c:1041 -msgid " ???" -msgstr "" - -#: builtin/remote.c:1082 -#, c-format -msgid "invalid branch.%s.merge; cannot rebase onto > 1 branch" -msgstr "" - -#: builtin/remote.c:1091 -#, c-format -msgid "rebases interactively onto remote %s" -msgstr "" - -#: builtin/remote.c:1093 -#, c-format -msgid "rebases interactively (with merges) onto remote %s" -msgstr "" - -#: builtin/remote.c:1096 -#, c-format -msgid "rebases onto remote %s" -msgstr "" - -#: builtin/remote.c:1100 -#, c-format -msgid " merges with remote %s" -msgstr "" - -#: builtin/remote.c:1103 -#, c-format -msgid "merges with remote %s" -msgstr "" - -#: builtin/remote.c:1106 -#, c-format -msgid "%-*s and with remote %s\n" -msgstr "" - -#: builtin/remote.c:1149 -msgid "create" -msgstr "" - -#: builtin/remote.c:1152 -msgid "delete" -msgstr "" - -#: builtin/remote.c:1156 -msgid "up to date" -msgstr "" - -#: builtin/remote.c:1159 -msgid "fast-forwardable" -msgstr "" - -#: builtin/remote.c:1162 -msgid "local out of date" -msgstr "" - -#: builtin/remote.c:1169 -#, c-format -msgid " %-*s forces to %-*s (%s)" -msgstr "" - -#: builtin/remote.c:1172 -#, c-format -msgid " %-*s pushes to %-*s (%s)" -msgstr "" - -#: builtin/remote.c:1176 -#, c-format -msgid " %-*s forces to %s" -msgstr "" - -#: builtin/remote.c:1179 -#, c-format -msgid " %-*s pushes to %s" -msgstr "" - -#: builtin/remote.c:1247 -msgid "do not query remotes" -msgstr "" - -#: builtin/remote.c:1268 -#, c-format -msgid "* remote %s" -msgstr "" - -#: builtin/remote.c:1269 -#, c-format -msgid " Fetch URL: %s" -msgstr "" - -#: builtin/remote.c:1270 builtin/remote.c:1286 builtin/remote.c:1423 -msgid "(no URL)" -msgstr "" - -#. TRANSLATORS: the colon ':' should align -#. with the one in " Fetch URL: %s" -#. translation. -#. -#: builtin/remote.c:1284 builtin/remote.c:1286 -#, c-format -msgid " Push URL: %s" -msgstr "" - -#: builtin/remote.c:1288 builtin/remote.c:1290 builtin/remote.c:1292 -#, c-format -msgid " HEAD branch: %s" -msgstr "" - -#: builtin/remote.c:1288 -msgid "(not queried)" -msgstr "" - -#: builtin/remote.c:1290 -msgid "(unknown)" -msgstr "" - -#: builtin/remote.c:1294 -#, c-format -msgid "" -" HEAD branch (remote HEAD is ambiguous, may be one of the following):\n" -msgstr "" - -#: builtin/remote.c:1306 -#, c-format -msgid " Remote branch:%s" -msgid_plural " Remote branches:%s" -msgstr[0] "" -msgstr[1] "" - -#: builtin/remote.c:1309 builtin/remote.c:1335 -msgid " (status not queried)" -msgstr "" - -#: builtin/remote.c:1318 -msgid " Local branch configured for 'git pull':" -msgid_plural " Local branches configured for 'git pull':" -msgstr[0] "" -msgstr[1] "" - -#: builtin/remote.c:1326 -msgid " Local refs will be mirrored by 'git push'" -msgstr "" - -#: builtin/remote.c:1332 -#, c-format -msgid " Local ref configured for 'git push'%s:" -msgid_plural " Local refs configured for 'git push'%s:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/remote.c:1353 -msgid "set refs/remotes/<name>/HEAD according to remote" -msgstr "" - -#: builtin/remote.c:1355 -msgid "delete refs/remotes/<name>/HEAD" -msgstr "" - -#: builtin/remote.c:1369 -msgid "Cannot determine remote HEAD" -msgstr "" - -#: builtin/remote.c:1371 -msgid "Multiple remote HEAD branches. Please choose one explicitly with:" -msgstr "" - -#: builtin/remote.c:1381 -#, c-format -msgid "Could not delete %s" -msgstr "" - -#: builtin/remote.c:1389 -#, c-format -msgid "Not a valid ref: %s" -msgstr "" - -#: builtin/remote.c:1391 -#, c-format -msgid "Could not setup %s" -msgstr "" - -#: builtin/remote.c:1409 -#, c-format -msgid " %s will become dangling!" -msgstr "" - -#: builtin/remote.c:1410 -#, c-format -msgid " %s has become dangling!" -msgstr "" - -#: builtin/remote.c:1419 -#, c-format -msgid "Pruning %s" -msgstr "" - -#: builtin/remote.c:1420 -#, c-format -msgid "URL: %s" -msgstr "" - -#: builtin/remote.c:1436 -#, c-format -msgid " * [would prune] %s" -msgstr "" - -#: builtin/remote.c:1439 -#, c-format -msgid " * [pruned] %s" -msgstr "" - -#: builtin/remote.c:1484 -msgid "prune remotes after fetching" -msgstr "" - -#: builtin/remote.c:1548 builtin/remote.c:1604 builtin/remote.c:1674 -#, c-format -msgid "No such remote '%s'" -msgstr "" - -#: builtin/remote.c:1566 -msgid "add branch" -msgstr "" - -#: builtin/remote.c:1573 -msgid "no remote specified" -msgstr "" - -#: builtin/remote.c:1590 -msgid "query push URLs rather than fetch URLs" -msgstr "" - -#: builtin/remote.c:1592 -msgid "return all URLs" -msgstr "" - -#: builtin/remote.c:1622 -#, c-format -msgid "no URLs configured for remote '%s'" -msgstr "" - -#: builtin/remote.c:1648 -msgid "manipulate push URLs" -msgstr "" - -#: builtin/remote.c:1650 -msgid "add URL" -msgstr "" - -#: builtin/remote.c:1652 -msgid "delete URLs" -msgstr "" - -#: builtin/remote.c:1659 -msgid "--add --delete doesn't make sense" -msgstr "" - -#: builtin/remote.c:1700 -#, c-format -msgid "Invalid old URL pattern: %s" -msgstr "" - -#: builtin/remote.c:1708 -#, c-format -msgid "No such URL found: %s" -msgstr "" - -#: builtin/remote.c:1710 -msgid "Will not delete all non-push URLs" -msgstr "" - -#: builtin/remote.c:1727 -msgid "be verbose; must be placed before a subcommand" -msgstr "" - -#: builtin/repack.c:29 -msgid "git repack [<options>]" -msgstr "" - -#: builtin/repack.c:34 -msgid "" -"Incremental repacks are incompatible with bitmap indexes. Use\n" -"--no-write-bitmap-index or disable the pack.writebitmaps configuration." -msgstr "" - -#: builtin/repack.c:206 -msgid "could not start pack-objects to repack promisor objects" -msgstr "" - -#: builtin/repack.c:280 builtin/repack.c:824 -msgid "repack: Expecting full hex object ID lines only from pack-objects." -msgstr "" - -#: builtin/repack.c:304 -msgid "could not finish pack-objects to repack promisor objects" -msgstr "" - -#: builtin/repack.c:319 -#, c-format -msgid "cannot open index for %s" -msgstr "" - -#: builtin/repack.c:378 -#, c-format -msgid "pack %s too large to consider in geometric progression" -msgstr "" - -#: builtin/repack.c:411 builtin/repack.c:418 builtin/repack.c:423 -#, c-format -msgid "pack %s too large to roll up" -msgstr "" - -#: builtin/repack.c:503 -#, c-format -msgid "could not open tempfile %s for writing" -msgstr "" - -#: builtin/repack.c:521 -msgid "could not close refs snapshot tempfile" -msgstr "" - -#: builtin/repack.c:634 -msgid "pack everything in a single pack" -msgstr "" - -#: builtin/repack.c:636 -msgid "same as -a, and turn unreachable objects loose" -msgstr "" - -#: builtin/repack.c:639 -msgid "remove redundant packs, and run git-prune-packed" -msgstr "" - -#: builtin/repack.c:641 -msgid "pass --no-reuse-delta to git-pack-objects" -msgstr "" - -#: builtin/repack.c:643 -msgid "pass --no-reuse-object to git-pack-objects" -msgstr "" - -#: builtin/repack.c:645 -msgid "do not run git-update-server-info" -msgstr "" - -#: builtin/repack.c:648 -msgid "pass --local to git-pack-objects" -msgstr "" - -#: builtin/repack.c:650 -msgid "write bitmap index" -msgstr "" - -#: builtin/repack.c:652 -msgid "pass --delta-islands to git-pack-objects" -msgstr "" - -#: builtin/repack.c:653 -msgid "approxidate" -msgstr "" - -#: builtin/repack.c:654 -msgid "with -A, do not loosen objects older than this" -msgstr "" - -#: builtin/repack.c:656 -msgid "with -a, repack unreachable objects" -msgstr "" - -#: builtin/repack.c:658 -msgid "size of the window used for delta compression" -msgstr "" - -#: builtin/repack.c:659 builtin/repack.c:665 -msgid "bytes" -msgstr "" - -#: builtin/repack.c:660 -msgid "same as the above, but limit memory size instead of entries count" -msgstr "" - -#: builtin/repack.c:662 -msgid "limits the maximum delta depth" -msgstr "" - -#: builtin/repack.c:664 -msgid "limits the maximum number of threads" -msgstr "" - -#: builtin/repack.c:666 -msgid "maximum size of each packfile" -msgstr "" - -#: builtin/repack.c:668 -msgid "repack objects in packs marked with .keep" -msgstr "" - -#: builtin/repack.c:670 -msgid "do not repack this pack" -msgstr "" - -#: builtin/repack.c:672 -msgid "find a geometric progression with factor <N>" -msgstr "" - -#: builtin/repack.c:674 -msgid "write a multi-pack index of the resulting packs" -msgstr "" - -#: builtin/repack.c:684 -msgid "cannot delete packs in a precious-objects repo" -msgstr "" - -#: builtin/repack.c:833 -msgid "Nothing new to pack." -msgstr "" - -#: builtin/repack.c:863 -#, c-format -msgid "missing required file: %s" -msgstr "" - -#: builtin/repack.c:865 -#, c-format -msgid "could not unlink: %s" -msgstr "" - -#: builtin/replace.c:22 -msgid "git replace [-f] <object> <replacement>" -msgstr "" - -#: builtin/replace.c:23 -msgid "git replace [-f] --edit <object>" -msgstr "" - -#: builtin/replace.c:24 -msgid "git replace [-f] --graft <commit> [<parent>...]" -msgstr "" - -#: builtin/replace.c:26 -msgid "git replace -d <object>..." -msgstr "" - -#: builtin/replace.c:27 -msgid "git replace [--format=<format>] [-l [<pattern>]]" -msgstr "" - -#: builtin/replace.c:90 -#, c-format -msgid "" -"invalid replace format '%s'\n" -"valid formats are 'short', 'medium' and 'long'" -msgstr "" - -#: builtin/replace.c:125 -#, c-format -msgid "replace ref '%s' not found" -msgstr "" - -#: builtin/replace.c:141 -#, c-format -msgid "Deleted replace ref '%s'" -msgstr "" - -#: builtin/replace.c:153 -#, c-format -msgid "'%s' is not a valid ref name" -msgstr "" - -#: builtin/replace.c:158 -#, c-format -msgid "replace ref '%s' already exists" -msgstr "" - -#: builtin/replace.c:178 -#, c-format -msgid "" -"Objects must be of the same type.\n" -"'%s' points to a replaced object of type '%s'\n" -"while '%s' points to a replacement object of type '%s'." -msgstr "" - -#: builtin/replace.c:229 -#, c-format -msgid "unable to open %s for writing" -msgstr "" - -#: builtin/replace.c:242 -msgid "cat-file reported failure" -msgstr "" - -#: builtin/replace.c:258 -#, c-format -msgid "unable to open %s for reading" -msgstr "" - -#: builtin/replace.c:271 -msgid "unable to spawn mktree" -msgstr "" - -#: builtin/replace.c:275 -msgid "unable to read from mktree" -msgstr "" - -#: builtin/replace.c:284 -msgid "mktree reported failure" -msgstr "" - -#: builtin/replace.c:288 -msgid "mktree did not return an object name" -msgstr "" - -#: builtin/replace.c:297 -#, c-format -msgid "unable to fstat %s" -msgstr "" - -#: builtin/replace.c:302 -msgid "unable to write object to database" -msgstr "" - -#: builtin/replace.c:325 -#, c-format -msgid "unable to get object type for %s" -msgstr "" - -#: builtin/replace.c:341 -msgid "editing object file failed" -msgstr "" - -#: builtin/replace.c:350 -#, c-format -msgid "new object is the same as the old one: '%s'" -msgstr "" - -#: builtin/replace.c:383 -#, c-format -msgid "could not parse %s as a commit" -msgstr "" - -#: builtin/replace.c:415 -#, c-format -msgid "bad mergetag in commit '%s'" -msgstr "" - -#: builtin/replace.c:417 -#, c-format -msgid "malformed mergetag in commit '%s'" -msgstr "" - -#: builtin/replace.c:429 -#, c-format -msgid "" -"original commit '%s' contains mergetag '%s' that is discarded; use --edit " -"instead of --graft" -msgstr "" - -#: builtin/replace.c:468 -#, c-format -msgid "the original commit '%s' has a gpg signature" -msgstr "" - -#: builtin/replace.c:469 -msgid "the signature will be removed in the replacement commit!" -msgstr "" - -#: builtin/replace.c:479 -#, c-format -msgid "could not write replacement commit for: '%s'" -msgstr "" - -#: builtin/replace.c:487 -#, c-format -msgid "graft for '%s' unnecessary" -msgstr "" - -#: builtin/replace.c:491 -#, c-format -msgid "new commit is the same as the old one: '%s'" -msgstr "" - -#: builtin/replace.c:526 -#, c-format -msgid "" -"could not convert the following graft(s):\n" -"%s" -msgstr "" - -#: builtin/replace.c:547 -msgid "list replace refs" -msgstr "" - -#: builtin/replace.c:548 -msgid "delete replace refs" -msgstr "" - -#: builtin/replace.c:549 -msgid "edit existing object" -msgstr "" - -#: builtin/replace.c:550 -msgid "change a commit's parents" -msgstr "" - -#: builtin/replace.c:551 -msgid "convert existing graft file" -msgstr "" - -#: builtin/replace.c:552 -msgid "replace the ref if it exists" -msgstr "" - -#: builtin/replace.c:554 -msgid "do not pretty-print contents for --edit" -msgstr "" - -#: builtin/replace.c:555 -msgid "use this format" -msgstr "" - -#: builtin/replace.c:568 -msgid "--format cannot be used when not listing" -msgstr "" - -#: builtin/replace.c:576 -msgid "-f only makes sense when writing a replacement" -msgstr "" - -#: builtin/replace.c:580 -msgid "--raw only makes sense with --edit" -msgstr "" - -#: builtin/replace.c:586 -msgid "-d needs at least one argument" -msgstr "" - -#: builtin/replace.c:592 -msgid "bad number of arguments" -msgstr "" - -#: builtin/replace.c:598 -msgid "-e needs exactly one argument" -msgstr "" - -#: builtin/replace.c:604 -msgid "-g needs at least one argument" -msgstr "" - -#: builtin/replace.c:610 -msgid "--convert-graft-file takes no argument" -msgstr "" - -#: builtin/replace.c:616 -msgid "only one pattern can be given with -l" -msgstr "" - -#: builtin/rerere.c:13 -msgid "git rerere [clear | forget <path>... | status | remaining | diff | gc]" -msgstr "" - -#: builtin/rerere.c:58 -msgid "register clean resolutions in index" -msgstr "" - -#: builtin/rerere.c:77 -msgid "'git rerere forget' without paths is deprecated" -msgstr "" - -#: builtin/rerere.c:111 -#, c-format -msgid "unable to generate diff for '%s'" -msgstr "" - -#: builtin/reset.c:33 -msgid "" -"git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" -msgstr "" - -#: builtin/reset.c:34 -msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..." -msgstr "" - -#: builtin/reset.c:35 -msgid "" -"git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]" -msgstr "" - -#: builtin/reset.c:36 -msgid "git reset --patch [<tree-ish>] [--] [<pathspec>...]" -msgstr "" - -#: builtin/reset.c:42 -msgid "mixed" -msgstr "" - -#: builtin/reset.c:42 -msgid "soft" -msgstr "" - -#: builtin/reset.c:42 -msgid "hard" -msgstr "" - -#: builtin/reset.c:42 -msgid "merge" -msgstr "" - -#: builtin/reset.c:42 -msgid "keep" -msgstr "" - -#: builtin/reset.c:90 -msgid "You do not have a valid HEAD." -msgstr "" - -#: builtin/reset.c:92 -msgid "Failed to find tree of HEAD." -msgstr "" - -#: builtin/reset.c:98 -#, c-format -msgid "Failed to find tree of %s." -msgstr "" - -#: builtin/reset.c:123 -#, c-format -msgid "HEAD is now at %s" -msgstr "" - -#: builtin/reset.c:304 -#, c-format -msgid "Cannot do a %s reset in the middle of a merge." -msgstr "" - -#: builtin/reset.c:402 builtin/stash.c:606 builtin/stash.c:669 -#: builtin/stash.c:693 -msgid "be quiet, only report errors" -msgstr "" - -#: builtin/reset.c:404 -msgid "skip refreshing the index after reset" -msgstr "" - -#: builtin/reset.c:406 -msgid "reset HEAD and index" -msgstr "" - -#: builtin/reset.c:407 -msgid "reset only HEAD" -msgstr "" - -#: builtin/reset.c:409 builtin/reset.c:411 -msgid "reset HEAD, index and working tree" -msgstr "" - -#: builtin/reset.c:413 -msgid "reset HEAD but keep local changes" -msgstr "" - -#: builtin/reset.c:419 -msgid "record only the fact that removed paths will be added later" -msgstr "" - -#: builtin/reset.c:452 -#, c-format -msgid "Failed to resolve '%s' as a valid revision." -msgstr "" - -#: builtin/reset.c:460 -#, c-format -msgid "Failed to resolve '%s' as a valid tree." -msgstr "" - -#: builtin/reset.c:479 -msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." -msgstr "" - -#: builtin/reset.c:481 -#, c-format -msgid "Cannot do %s reset with paths." -msgstr "" - -#: builtin/reset.c:496 -#, c-format -msgid "%s reset is not allowed in a bare repository" -msgstr "" - -#: builtin/reset.c:527 -msgid "Unstaged changes after reset:" -msgstr "" - -#: builtin/reset.c:530 -#, c-format -msgid "" -"It took %.2f seconds to refresh the index after reset. You can use\n" -"'--no-refresh' to avoid this." -msgstr "" - -#: builtin/reset.c:547 -#, c-format -msgid "Could not reset index file to revision '%s'." -msgstr "" - -#: builtin/reset.c:552 -msgid "Could not write new index file." -msgstr "" - -#: builtin/rev-list.c:659 -msgid "rev-list does not support display of notes" -msgstr "" - -#: builtin/rev-list.c:664 -#, c-format -msgid "marked counting and '%s' cannot be used together" -msgstr "" - -#: builtin/rev-parse.c:409 -msgid "git rev-parse --parseopt [<options>] -- [<args>...]" -msgstr "" - -#: builtin/rev-parse.c:414 -msgid "keep the `--` passed as an arg" -msgstr "" - -#: builtin/rev-parse.c:416 -msgid "stop parsing after the first non-option argument" -msgstr "" - -#: builtin/rev-parse.c:419 -msgid "output in stuck long form" -msgstr "" - -#: builtin/rev-parse.c:438 -msgid "premature end of input" -msgstr "" - -#: builtin/rev-parse.c:442 -msgid "no usage string given before the `--' separator" -msgstr "" - -#: builtin/rev-parse.c:548 -msgid "Needed a single revision" -msgstr "" - -#: builtin/rev-parse.c:552 -msgid "" -"git rev-parse --parseopt [<options>] -- [<args>...]\n" -" or: git rev-parse --sq-quote [<arg>...]\n" -" or: git rev-parse [<options>] [<arg>...]\n" -"\n" -"Run \"git rev-parse --parseopt -h\" for more information on the first usage." -msgstr "" - -#: builtin/rev-parse.c:712 -msgid "--resolve-git-dir requires an argument" -msgstr "" - -#: builtin/rev-parse.c:715 -#, c-format -msgid "not a gitdir '%s'" -msgstr "" - -#: builtin/rev-parse.c:739 -msgid "--git-path requires an argument" -msgstr "" - -#: builtin/rev-parse.c:749 -msgid "-n requires an argument" -msgstr "" - -#: builtin/rev-parse.c:763 -msgid "--path-format requires an argument" -msgstr "" - -#: builtin/rev-parse.c:769 -#, c-format -msgid "unknown argument to --path-format: %s" -msgstr "" - -#: builtin/rev-parse.c:776 -msgid "--default requires an argument" -msgstr "" - -#: builtin/rev-parse.c:782 -msgid "--prefix requires an argument" -msgstr "" - -#: builtin/rev-parse.c:851 -#, c-format -msgid "unknown mode for --abbrev-ref: %s" -msgstr "" - -#: builtin/rev-parse.c:1023 -#, c-format -msgid "unknown mode for --show-object-format: %s" -msgstr "" - -#: builtin/revert.c:24 -msgid "git revert [<options>] <commit-ish>..." -msgstr "" - -#: builtin/revert.c:25 -msgid "git revert <subcommand>" -msgstr "" - -#: builtin/revert.c:30 -msgid "git cherry-pick [<options>] <commit-ish>..." -msgstr "" - -#: builtin/revert.c:31 -msgid "git cherry-pick <subcommand>" -msgstr "" - -#: builtin/revert.c:72 -#, c-format -msgid "option `%s' expects a number greater than zero" -msgstr "" - -#: builtin/revert.c:92 -#, c-format -msgid "%s: %s cannot be used with %s" -msgstr "" - -#: builtin/revert.c:102 -msgid "end revert or cherry-pick sequence" -msgstr "" - -#: builtin/revert.c:103 -msgid "resume revert or cherry-pick sequence" -msgstr "" - -#: builtin/revert.c:104 -msgid "cancel revert or cherry-pick sequence" -msgstr "" - -#: builtin/revert.c:105 -msgid "skip current commit and continue" -msgstr "" - -#: builtin/revert.c:107 -msgid "don't automatically commit" -msgstr "" - -#: builtin/revert.c:108 -msgid "edit the commit message" -msgstr "" - -#: builtin/revert.c:111 -msgid "parent-number" -msgstr "" - -#: builtin/revert.c:112 -msgid "select mainline parent" -msgstr "" - -#: builtin/revert.c:114 -msgid "merge strategy" -msgstr "" - -#: builtin/revert.c:116 -msgid "option for merge strategy" -msgstr "" - -#: builtin/revert.c:125 -msgid "append commit name" -msgstr "" - -#: builtin/revert.c:127 -msgid "preserve initially empty commits" -msgstr "" - -#: builtin/revert.c:128 -msgid "allow commits with empty messages" -msgstr "" - -#: builtin/revert.c:129 -msgid "keep redundant, empty commits" -msgstr "" - -#: builtin/revert.c:241 -msgid "revert failed" -msgstr "" - -#: builtin/revert.c:254 -msgid "cherry-pick failed" -msgstr "" - -#: builtin/rm.c:20 -msgid "git rm [<options>] [--] <file>..." -msgstr "" - -#: builtin/rm.c:208 -msgid "" -"the following file has staged content different from both the\n" -"file and the HEAD:" -msgid_plural "" -"the following files have staged content different from both the\n" -"file and the HEAD:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/rm.c:213 -msgid "" -"\n" -"(use -f to force removal)" -msgstr "" - -#: builtin/rm.c:217 -msgid "the following file has changes staged in the index:" -msgid_plural "the following files have changes staged in the index:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/rm.c:221 builtin/rm.c:230 -msgid "" -"\n" -"(use --cached to keep the file, or -f to force removal)" -msgstr "" - -#: builtin/rm.c:227 -msgid "the following file has local modifications:" -msgid_plural "the following files have local modifications:" -msgstr[0] "" -msgstr[1] "" - -#: builtin/rm.c:245 -msgid "do not list removed files" -msgstr "" - -#: builtin/rm.c:246 -msgid "only remove from the index" -msgstr "" - -#: builtin/rm.c:247 -msgid "override the up-to-date check" -msgstr "" - -#: builtin/rm.c:248 -msgid "allow recursive removal" -msgstr "" - -#: builtin/rm.c:250 -msgid "exit with a zero status even if nothing matched" -msgstr "" - -#: builtin/rm.c:285 -msgid "No pathspec was given. Which files should I remove?" -msgstr "" - -#: builtin/rm.c:315 -msgid "please stage your changes to .gitmodules or stash them to proceed" -msgstr "" - -#: builtin/rm.c:337 -#, c-format -msgid "not removing '%s' recursively without -r" -msgstr "" - -#: builtin/rm.c:385 -#, c-format -msgid "git rm: unable to remove %s" -msgstr "" - -#: builtin/send-pack.c:20 -msgid "" -"git send-pack [--mirror] [--dry-run] [--force]\n" -" [--receive-pack=<git-receive-pack>]\n" -" [--verbose] [--thin] [--atomic]\n" -" [<host>:]<directory> (--all | <ref>...)" -msgstr "" - -#: builtin/send-pack.c:192 -msgid "remote name" -msgstr "" - -#: builtin/send-pack.c:205 -msgid "use stateless RPC protocol" -msgstr "" - -#: builtin/send-pack.c:206 -msgid "read refs from stdin" -msgstr "" - -#: builtin/send-pack.c:207 -msgid "print status from remote helper" -msgstr "" - -#: builtin/shortlog.c:16 -msgid "git shortlog [<options>] [<revision-range>] [[--] <path>...]" -msgstr "" - -#: builtin/shortlog.c:17 -msgid "git log --pretty=short | git shortlog [<options>]" -msgstr "" - -#: builtin/shortlog.c:123 -msgid "using multiple --group options with stdin is not supported" -msgstr "" - -#: builtin/shortlog.c:133 -msgid "using --group=trailer with stdin is not supported" -msgstr "" - -#: builtin/shortlog.c:323 -#, c-format -msgid "unknown group type: %s" -msgstr "" - -#: builtin/shortlog.c:351 -msgid "group by committer rather than author" -msgstr "" - -#: builtin/shortlog.c:354 -msgid "sort output according to the number of commits per author" -msgstr "" - -#: builtin/shortlog.c:356 -msgid "suppress commit descriptions, only provides commit count" -msgstr "" - -#: builtin/shortlog.c:358 -msgid "show the email address of each author" -msgstr "" - -#: builtin/shortlog.c:359 -msgid "<w>[,<i1>[,<i2>]]" -msgstr "" - -#: builtin/shortlog.c:360 -msgid "linewrap output" -msgstr "" - -#: builtin/shortlog.c:362 -msgid "field" -msgstr "" - -#: builtin/shortlog.c:363 -msgid "group by field" -msgstr "" - -#: builtin/shortlog.c:395 -msgid "too many arguments given outside repository" -msgstr "" - -#: builtin/show-branch.c:14 -msgid "" -"git show-branch [-a | --all] [-r | --remotes] [--topo-order | --date-order]\n" -" [--current] [--color[=<when>] | --no-color] [--sparse]\n" -" [--more=<n> | --list | --independent | --merge-base]\n" -" [--no-name | --sha1-name] [--topics] [(<rev> | <glob>)...]" -msgstr "" - -#: builtin/show-branch.c:18 -msgid "git show-branch (-g | --reflog)[=<n>[,<base>]] [--list] [<ref>]" -msgstr "" - -#: builtin/show-branch.c:396 -#, c-format -msgid "ignoring %s; cannot handle more than %d ref" -msgid_plural "ignoring %s; cannot handle more than %d refs" -msgstr[0] "" -msgstr[1] "" - -#: builtin/show-branch.c:548 -#, c-format -msgid "no matching refs with %s" -msgstr "" - -#: builtin/show-branch.c:645 -msgid "show remote-tracking and local branches" -msgstr "" - -#: builtin/show-branch.c:647 -msgid "show remote-tracking branches" -msgstr "" - -#: builtin/show-branch.c:649 -msgid "color '*!+-' corresponding to the branch" -msgstr "" - -#: builtin/show-branch.c:651 -msgid "show <n> more commits after the common ancestor" -msgstr "" - -#: builtin/show-branch.c:653 -msgid "synonym to more=-1" -msgstr "" - -#: builtin/show-branch.c:654 -msgid "suppress naming strings" -msgstr "" - -#: builtin/show-branch.c:656 -msgid "include the current branch" -msgstr "" - -#: builtin/show-branch.c:658 -msgid "name commits with their object names" -msgstr "" - -#: builtin/show-branch.c:660 -msgid "show possible merge bases" -msgstr "" - -#: builtin/show-branch.c:662 -msgid "show refs unreachable from any other ref" -msgstr "" - -#: builtin/show-branch.c:664 -msgid "show commits in topological order" -msgstr "" - -#: builtin/show-branch.c:667 -msgid "show only commits not on the first branch" -msgstr "" - -#: builtin/show-branch.c:669 -msgid "show merges reachable from only one tip" -msgstr "" - -#: builtin/show-branch.c:671 -msgid "topologically sort, maintaining date order where possible" -msgstr "" - -#: builtin/show-branch.c:674 -msgid "<n>[,<base>]" -msgstr "" - -#: builtin/show-branch.c:675 -msgid "show <n> most recent ref-log entries starting at base" -msgstr "" - -#: builtin/show-branch.c:735 -msgid "no branches given, and HEAD is not valid" -msgstr "" - -#: builtin/show-branch.c:738 -msgid "--reflog option needs one branch name" -msgstr "" - -#: builtin/show-branch.c:741 -#, c-format -msgid "only %d entry can be shown at one time." -msgid_plural "only %d entries can be shown at one time." -msgstr[0] "" -msgstr[1] "" - -#: builtin/show-branch.c:745 -#, c-format -msgid "no such ref %s" -msgstr "" - -#: builtin/show-branch.c:831 -#, c-format -msgid "cannot handle more than %d rev." -msgid_plural "cannot handle more than %d revs." -msgstr[0] "" -msgstr[1] "" - -#: builtin/show-branch.c:835 -#, c-format -msgid "'%s' is not a valid ref." -msgstr "" - -#: builtin/show-branch.c:838 -#, c-format -msgid "cannot find commit %s (%s)" -msgstr "" - -#: builtin/show-index.c:21 -msgid "hash-algorithm" -msgstr "" - -#: builtin/show-index.c:31 -msgid "Unknown hash algorithm" -msgstr "" - -#: builtin/show-ref.c:12 -msgid "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --" -"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]" -msgstr "" - -#: builtin/show-ref.c:13 -msgid "git show-ref --exclude-existing[=<pattern>]" -msgstr "" - -#: builtin/show-ref.c:162 -msgid "only show tags (can be combined with heads)" -msgstr "" - -#: builtin/show-ref.c:163 -msgid "only show heads (can be combined with tags)" -msgstr "" - -#: builtin/show-ref.c:164 -msgid "stricter reference checking, requires exact ref path" -msgstr "" - -#: builtin/show-ref.c:167 builtin/show-ref.c:169 -msgid "show the HEAD reference, even if it would be filtered out" -msgstr "" - -#: builtin/show-ref.c:171 -msgid "dereference tags into object IDs" -msgstr "" - -#: builtin/show-ref.c:173 -msgid "only show SHA1 hash using <n> digits" -msgstr "" - -#: builtin/show-ref.c:177 -msgid "do not print results to stdout (useful with --verify)" -msgstr "" - -#: builtin/show-ref.c:179 -msgid "show refs from stdin that aren't in local repository" -msgstr "" - -#: builtin/sparse-checkout.c:23 -msgid "git sparse-checkout (init|list|set|add|reapply|disable) <options>" -msgstr "" - -#: builtin/sparse-checkout.c:61 -msgid "this worktree is not sparse" -msgstr "" - -#: builtin/sparse-checkout.c:76 -msgid "this worktree is not sparse (sparse-checkout file may not exist)" -msgstr "" - -#: builtin/sparse-checkout.c:177 -#, c-format -msgid "" -"directory '%s' contains untracked files, but is not in the sparse-checkout " -"cone" -msgstr "" - -#: builtin/sparse-checkout.c:185 -#, c-format -msgid "failed to remove directory '%s'" -msgstr "" - -#: builtin/sparse-checkout.c:327 -msgid "failed to create directory for sparse-checkout file" -msgstr "" - -#: builtin/sparse-checkout.c:366 -msgid "failed to initialize worktree config" -msgstr "" - -#: builtin/sparse-checkout.c:411 -msgid "failed to modify sparse-index config" -msgstr "" - -#: builtin/sparse-checkout.c:441 builtin/sparse-checkout.c:793 -#: builtin/sparse-checkout.c:847 -msgid "initialize the sparse-checkout in cone mode" -msgstr "" - -#: builtin/sparse-checkout.c:443 builtin/sparse-checkout.c:795 -#: builtin/sparse-checkout.c:849 -msgid "toggle the use of a sparse index" -msgstr "" - -#: builtin/sparse-checkout.c:479 -#, c-format -msgid "failed to open '%s'" -msgstr "" - -#: builtin/sparse-checkout.c:531 -#, c-format -msgid "could not normalize path %s" -msgstr "" - -#: builtin/sparse-checkout.c:560 -#, c-format -msgid "unable to unquote C-style string '%s'" -msgstr "" - -#: builtin/sparse-checkout.c:615 builtin/sparse-checkout.c:643 -msgid "unable to load existing sparse-checkout patterns" -msgstr "" - -#: builtin/sparse-checkout.c:619 -msgid "existing sparse-checkout patterns do not use cone mode" -msgstr "" - -#: builtin/sparse-checkout.c:707 -msgid "please run from the toplevel directory in non-cone mode" -msgstr "" - -#: builtin/sparse-checkout.c:712 -msgid "specify directories rather than patterns (no leading slash)" -msgstr "" - -#: builtin/sparse-checkout.c:714 -msgid "" -"specify directories rather than patterns. If your directory starts with a " -"'!', pass --skip-checks" -msgstr "" - -#: builtin/sparse-checkout.c:716 -msgid "" -"specify directories rather than patterns. If your directory really has any " -"of '*?[]\\' in it, pass --skip-checks" -msgstr "" - -#: builtin/sparse-checkout.c:732 -#, c-format -msgid "" -"'%s' is not a directory; to treat it as a directory anyway, rerun with --" -"skip-checks" -msgstr "" - -#: builtin/sparse-checkout.c:734 -#, c-format -msgid "" -"pass a leading slash before paths such as '%s' if you want a single file " -"(see NON-CONE PROBLEMS in the git-sparse-checkout manual)." -msgstr "" - -#: builtin/sparse-checkout.c:739 -msgid "git sparse-checkout add [--skip-checks] (--stdin | <patterns>)" -msgstr "" - -#: builtin/sparse-checkout.c:752 builtin/sparse-checkout.c:797 -msgid "" -"skip some sanity checks on the given paths that might give false positives" -msgstr "" - -#: builtin/sparse-checkout.c:755 builtin/sparse-checkout.c:800 -msgid "read patterns from standard in" -msgstr "" - -#: builtin/sparse-checkout.c:760 -msgid "no sparse-checkout to add to" -msgstr "" - -#: builtin/sparse-checkout.c:775 -msgid "" -"git sparse-checkout set [--[no-]cone] [--[no-]sparse-index] [--skip-checks] " -"(--stdin | <patterns>)" -msgstr "" - -#: builtin/sparse-checkout.c:854 -msgid "must be in a sparse-checkout to reapply sparsity patterns" -msgstr "" - -#: builtin/sparse-checkout.c:914 -msgid "error while refreshing working directory" -msgstr "" - -#: builtin/stash.c:24 builtin/stash.c:40 -msgid "git stash list [<options>]" -msgstr "" - -#: builtin/stash.c:25 builtin/stash.c:45 -msgid "git stash show [<options>] [<stash>]" -msgstr "" - -#: builtin/stash.c:26 builtin/stash.c:50 -msgid "git stash drop [-q|--quiet] [<stash>]" -msgstr "" - -#: builtin/stash.c:27 -msgid "git stash ( pop | apply ) [--index] [-q|--quiet] [<stash>]" -msgstr "" - -#: builtin/stash.c:28 builtin/stash.c:65 -msgid "git stash branch <branchname> [<stash>]" -msgstr "" - -#: builtin/stash.c:30 -msgid "" -"git stash [push [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--" -"quiet]\n" -" [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n" -" [--pathspec-from-file=<file> [--pathspec-file-nul]]\n" -" [--] [<pathspec>...]]" -msgstr "" - -#: builtin/stash.c:34 -msgid "" -"git stash save [-p|--patch] [-S|--staged] [-k|--[no-]keep-index] [-q|--" -"quiet]\n" -" [-u|--include-untracked] [-a|--all] [<message>]" -msgstr "" - -#: builtin/stash.c:55 -msgid "git stash pop [--index] [-q|--quiet] [<stash>]" -msgstr "" - -#: builtin/stash.c:60 -msgid "git stash apply [--index] [-q|--quiet] [<stash>]" -msgstr "" - -#: builtin/stash.c:75 -msgid "git stash store [-m|--message <message>] [-q|--quiet] <commit>" -msgstr "" - -#: builtin/stash.c:80 -msgid "" -"git stash [push [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -" [-u|--include-untracked] [-a|--all] [-m|--message <message>]\n" -" [--] [<pathspec>...]]" -msgstr "" - -#: builtin/stash.c:87 -msgid "" -"git stash save [-p|--patch] [-k|--[no-]keep-index] [-q|--quiet]\n" -" [-u|--include-untracked] [-a|--all] [<message>]" -msgstr "" - -#: builtin/stash.c:130 -#, c-format -msgid "'%s' is not a stash-like commit" -msgstr "" - -#: builtin/stash.c:150 -#, c-format -msgid "Too many revisions specified:%s" -msgstr "" - -#: builtin/stash.c:164 -msgid "No stash entries found." -msgstr "" - -#: builtin/stash.c:178 -#, c-format -msgid "%s is not a valid reference" -msgstr "" - -#: builtin/stash.c:227 -msgid "git stash clear with arguments is unimplemented" -msgstr "" - -#: builtin/stash.c:447 -#, c-format -msgid "" -"WARNING: Untracked file in way of tracked file! Renaming\n" -" %s -> %s\n" -" to make room.\n" -msgstr "" - -#: builtin/stash.c:508 -msgid "cannot apply a stash in the middle of a merge" -msgstr "" - -#: builtin/stash.c:519 -#, c-format -msgid "could not generate diff %s^!." -msgstr "" - -#: builtin/stash.c:526 -msgid "conflicts in index. Try without --index." -msgstr "" - -#: builtin/stash.c:532 -msgid "could not save index tree" -msgstr "" - -#: builtin/stash.c:552 -#, c-format -msgid "Merging %s with %s" -msgstr "" - -#: builtin/stash.c:562 -msgid "Index was not unstashed." -msgstr "" - -#: builtin/stash.c:576 -msgid "could not restore untracked files from stash" -msgstr "" - -#: builtin/stash.c:608 builtin/stash.c:695 -msgid "attempt to recreate the index" -msgstr "" - -#: builtin/stash.c:641 -#, c-format -msgid "Dropped %s (%s)" -msgstr "" - -#: builtin/stash.c:644 -#, c-format -msgid "%s: Could not drop stash entry" -msgstr "" - -#: builtin/stash.c:657 -#, c-format -msgid "'%s' is not a stash reference" -msgstr "" - -#: builtin/stash.c:707 -msgid "The stash entry is kept in case you need it again." -msgstr "" - -#: builtin/stash.c:730 -msgid "No branch name specified" -msgstr "" - -#: builtin/stash.c:809 -msgid "failed to parse tree" -msgstr "" - -#: builtin/stash.c:820 -msgid "failed to unpack trees" -msgstr "" - -#: builtin/stash.c:840 -msgid "include untracked files in the stash" -msgstr "" - -#: builtin/stash.c:843 -msgid "only show untracked files in the stash" -msgstr "" - -#: builtin/stash.c:930 builtin/stash.c:967 -#, c-format -msgid "Cannot update %s with %s" -msgstr "" - -#: builtin/stash.c:948 builtin/stash.c:1667 builtin/stash.c:1739 -msgid "stash message" -msgstr "" - -#: builtin/stash.c:958 -msgid "\"git stash store\" requires one <commit> argument" -msgstr "" - -#: builtin/stash.c:1143 -msgid "No staged changes" -msgstr "" - -#: builtin/stash.c:1204 -msgid "No changes selected" -msgstr "" - -#: builtin/stash.c:1304 -msgid "You do not have the initial commit yet" -msgstr "" - -#: builtin/stash.c:1331 -msgid "Cannot save the current index state" -msgstr "" - -#: builtin/stash.c:1340 -msgid "Cannot save the untracked files" -msgstr "" - -#: builtin/stash.c:1351 builtin/stash.c:1370 -msgid "Cannot save the current worktree state" -msgstr "" - -#: builtin/stash.c:1361 -msgid "Cannot save the current staged state" -msgstr "" - -#: builtin/stash.c:1398 -msgid "Cannot record working tree state" -msgstr "" - -#: builtin/stash.c:1447 -msgid "Can't use --patch and --include-untracked or --all at the same time" -msgstr "" - -#: builtin/stash.c:1458 -msgid "Can't use --staged and --include-untracked or --all at the same time" -msgstr "" - -#: builtin/stash.c:1476 -msgid "Did you forget to 'git add'?" -msgstr "" - -#: builtin/stash.c:1491 -msgid "No local changes to save" -msgstr "" - -#: builtin/stash.c:1498 -msgid "Cannot initialize stash" -msgstr "" - -#: builtin/stash.c:1513 -msgid "Cannot save the current status" -msgstr "" - -#: builtin/stash.c:1518 -#, c-format -msgid "Saved working directory and index state %s" -msgstr "" - -#: builtin/stash.c:1615 -msgid "Cannot remove worktree changes" -msgstr "" - -#: builtin/stash.c:1656 builtin/stash.c:1728 -msgid "keep index" -msgstr "" - -#: builtin/stash.c:1658 builtin/stash.c:1730 -msgid "stash staged changes only" -msgstr "" - -#: builtin/stash.c:1660 builtin/stash.c:1732 -msgid "stash in patch mode" -msgstr "" - -#: builtin/stash.c:1661 builtin/stash.c:1733 -msgid "quiet mode" -msgstr "" - -#: builtin/stash.c:1663 builtin/stash.c:1735 -msgid "include untracked files in stash" -msgstr "" - -#: builtin/stash.c:1665 builtin/stash.c:1737 -msgid "include ignore files" -msgstr "" - -#: builtin/stripspace.c:37 -msgid "skip and remove all lines starting with comment character" -msgstr "" - -#: builtin/stripspace.c:40 -msgid "prepend comment character and space to each line" -msgstr "" - -#: builtin/submodule--helper.c:50 builtin/submodule--helper.c:2486 -#, c-format -msgid "Expecting a full ref name, got %s" -msgstr "" - -#: builtin/submodule--helper.c:103 -#, c-format -msgid "cannot strip one component off url '%s'" -msgstr "" - -#: builtin/submodule--helper.c:213 -#, c-format -msgid "" -"could not look up configuration '%s'. Assuming this repository is its own " -"authoritative upstream." -msgstr "" - -#: builtin/submodule--helper.c:413 builtin/submodule--helper.c:1873 -msgid "alternative anchor for relative paths" -msgstr "" - -#: builtin/submodule--helper.c:418 -msgid "git submodule--helper list [--prefix=<path>] [<path>...]" -msgstr "" - -#: builtin/submodule--helper.c:476 builtin/submodule--helper.c:617 -#: builtin/submodule--helper.c:640 -#, c-format -msgid "No url found for submodule path '%s' in .gitmodules" -msgstr "" - -#: builtin/submodule--helper.c:528 -#, c-format -msgid "Entering '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:531 -#, c-format -msgid "" -"run_command returned non-zero status for %s\n" -"." -msgstr "" - -#: builtin/submodule--helper.c:553 -#, c-format -msgid "" -"run_command returned non-zero status while recursing in the nested " -"submodules of %s\n" -"." -msgstr "" - -#: builtin/submodule--helper.c:569 -msgid "suppress output of entering each submodule command" -msgstr "" - -#: builtin/submodule--helper.c:571 builtin/submodule--helper.c:876 -#: builtin/submodule--helper.c:1458 -msgid "recurse into nested submodules" -msgstr "" - -#: builtin/submodule--helper.c:576 -msgid "git submodule--helper foreach [--quiet] [--recursive] [--] <command>" -msgstr "" - -#: builtin/submodule--helper.c:654 -#, c-format -msgid "Failed to register url for submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:658 -#, c-format -msgid "Submodule '%s' (%s) registered for path '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:668 -#, c-format -msgid "warning: command update mode suggested for submodule '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:675 -#, c-format -msgid "Failed to register update mode for submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:697 -msgid "suppress output for initializing a submodule" -msgstr "" - -#: builtin/submodule--helper.c:702 -msgid "git submodule--helper init [<options>] [<path>]" -msgstr "" - -#: builtin/submodule--helper.c:775 builtin/submodule--helper.c:910 -#, c-format -msgid "no submodule mapping found in .gitmodules for path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:823 -#, c-format -msgid "could not resolve HEAD ref inside the submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:850 builtin/submodule--helper.c:1428 -#, c-format -msgid "failed to recurse into submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:874 builtin/submodule--helper.c:1595 -msgid "suppress submodule status output" -msgstr "" - -#: builtin/submodule--helper.c:875 -msgid "" -"use commit stored in the index instead of the one stored in the submodule " -"HEAD" -msgstr "" - -#: builtin/submodule--helper.c:881 -msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]" -msgstr "" - -#: builtin/submodule--helper.c:905 -msgid "git submodule--helper name <path>" -msgstr "" - -#: builtin/submodule--helper.c:977 -#, c-format -msgid "* %s %s(blob)->%s(submodule)" -msgstr "" - -#: builtin/submodule--helper.c:980 -#, c-format -msgid "* %s %s(submodule)->%s(blob)" -msgstr "" - -#: builtin/submodule--helper.c:993 -#, c-format -msgid "%s" -msgstr "" - -#: builtin/submodule--helper.c:1043 -#, c-format -msgid "couldn't hash object from '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1047 -#, c-format -msgid "unexpected mode %o\n" -msgstr "" - -#: builtin/submodule--helper.c:1288 -msgid "use the commit stored in the index instead of the submodule HEAD" -msgstr "" - -#: builtin/submodule--helper.c:1290 -msgid "compare the commit in the index with that in the submodule HEAD" -msgstr "" - -#: builtin/submodule--helper.c:1292 -msgid "skip submodules with 'ignore_config' value set to 'all'" -msgstr "" - -#: builtin/submodule--helper.c:1294 -msgid "limit the summary size" -msgstr "" - -#: builtin/submodule--helper.c:1299 -msgid "git submodule--helper summary [<options>] [<commit>] [--] [<path>]" -msgstr "" - -#: builtin/submodule--helper.c:1323 -msgid "could not fetch a revision for HEAD" -msgstr "" - -#: builtin/submodule--helper.c:1384 -#, c-format -msgid "Synchronizing submodule url for '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:1390 -#, c-format -msgid "failed to register url for submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1399 -#, c-format -msgid "failed to get the default remote for submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1409 -#, c-format -msgid "failed to update remote for submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1456 -msgid "suppress output of synchronizing submodule url" -msgstr "" - -#: builtin/submodule--helper.c:1463 -msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]" -msgstr "" - -#: builtin/submodule--helper.c:1513 -#, c-format -msgid "" -"Submodule work tree '%s' contains a .git directory. This will be replaced " -"with a .git file by using absorbgitdirs." -msgstr "" - -#: builtin/submodule--helper.c:1530 -#, c-format -msgid "" -"Submodule work tree '%s' contains local modifications; use '-f' to discard " -"them" -msgstr "" - -#: builtin/submodule--helper.c:1538 -#, c-format -msgid "Cleared directory '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:1540 -#, c-format -msgid "Could not remove submodule work tree '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:1551 -#, c-format -msgid "could not create empty submodule directory %s" -msgstr "" - -#: builtin/submodule--helper.c:1567 -#, c-format -msgid "Submodule '%s' (%s) unregistered for path '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:1596 -msgid "remove submodule working trees even if they contain local changes" -msgstr "" - -#: builtin/submodule--helper.c:1597 -msgid "unregister all submodules" -msgstr "" - -#: builtin/submodule--helper.c:1602 -msgid "" -"git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]" -msgstr "" - -#: builtin/submodule--helper.c:1616 -msgid "Use '--all' if you really want to deinitialize all submodules" -msgstr "" - -#: builtin/submodule--helper.c:1665 -msgid "" -"An alternate computed from a superproject's alternate is invalid.\n" -"To allow Git to clone without an alternate in such a case, set\n" -"submodule.alternateErrorStrategy to 'info' or, equivalently, clone with\n" -"'--reference-if-able' instead of '--reference'." -msgstr "" - -#: builtin/submodule--helper.c:1710 builtin/submodule--helper.c:1713 -#, c-format -msgid "submodule '%s' cannot add alternate: %s" -msgstr "" - -#: builtin/submodule--helper.c:1749 -#, c-format -msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized" -msgstr "" - -#: builtin/submodule--helper.c:1756 -#, c-format -msgid "Value '%s' for submodule.alternateLocation is not recognized" -msgstr "" - -#: builtin/submodule--helper.c:1781 -#, c-format -msgid "refusing to create/use '%s' in another submodule's git dir" -msgstr "" - -#: builtin/submodule--helper.c:1826 -#, c-format -msgid "clone of '%s' into submodule path '%s' failed" -msgstr "" - -#: builtin/submodule--helper.c:1831 -#, c-format -msgid "directory not empty: '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1843 -#, c-format -msgid "could not get submodule directory for '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1876 -msgid "where the new submodule will be cloned to" -msgstr "" - -#: builtin/submodule--helper.c:1879 -msgid "name of the new submodule" -msgstr "" - -#: builtin/submodule--helper.c:1882 -msgid "url where to clone the submodule from" -msgstr "" - -#: builtin/submodule--helper.c:1890 builtin/submodule--helper.c:3383 -msgid "depth for shallow clones" -msgstr "" - -#: builtin/submodule--helper.c:1893 builtin/submodule--helper.c:2731 -#: builtin/submodule--helper.c:3376 -msgid "force cloning progress" -msgstr "" - -#: builtin/submodule--helper.c:1895 builtin/submodule--helper.c:2733 -msgid "disallow cloning into non-empty directory" -msgstr "" - -#: builtin/submodule--helper.c:1903 -msgid "" -"git submodule--helper clone [--prefix=<path>] [--quiet] [--reference " -"<repository>] [--name <name>] [--depth <depth>] [--single-branch] [--filter " -"<filter-spec>] --url <url> --path <path>" -msgstr "" - -#: builtin/submodule--helper.c:1943 -#, c-format -msgid "Invalid update mode '%s' for submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:1947 -#, c-format -msgid "Invalid update mode '%s' configured for submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2041 -#, c-format -msgid "Submodule path '%s' not initialized" -msgstr "" - -#: builtin/submodule--helper.c:2045 -msgid "Maybe you want to use 'update --init'?" -msgstr "" - -#: builtin/submodule--helper.c:2075 -#, c-format -msgid "Skipping unmerged submodule %s" -msgstr "" - -#: builtin/submodule--helper.c:2104 -#, c-format -msgid "Skipping submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2257 -#, c-format -msgid "Failed to clone '%s'. Retry scheduled" -msgstr "" - -#: builtin/submodule--helper.c:2268 -#, c-format -msgid "Failed to clone '%s' a second time, aborting" -msgstr "" - -#: builtin/submodule--helper.c:2371 -#, c-format -msgid "Unable to checkout '%s' in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2375 -#, c-format -msgid "Unable to rebase '%s' in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2379 -#, c-format -msgid "Unable to merge '%s' in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2383 -#, c-format -msgid "Execution of '%s %s' failed in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2402 -#, c-format -msgid "Submodule path '%s': checked out '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:2406 -#, c-format -msgid "Submodule path '%s': rebased into '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:2410 -#, c-format -msgid "Submodule path '%s': merged in '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:2414 -#, c-format -msgid "Submodule path '%s': '%s %s'\n" -msgstr "" - -#: builtin/submodule--helper.c:2438 -#, c-format -msgid "Unable to fetch in submodule path '%s'; trying to directly fetch %s:" -msgstr "" - -#: builtin/submodule--helper.c:2447 -#, c-format -msgid "" -"Fetched in submodule path '%s', but it did not contain %s. Direct fetching " -"of that commit failed." -msgstr "" - -#: builtin/submodule--helper.c:2481 -#, c-format -msgid "" -"Submodule (%s) branch configured to inherit branch from superproject, but " -"the superproject is not on any branch" -msgstr "" - -#: builtin/submodule--helper.c:2499 -#, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2588 -#, c-format -msgid "Unable to find current revision in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2599 -#, c-format -msgid "Unable to fetch in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2604 -#, c-format -msgid "Unable to find %s revision in submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2640 -#, c-format -msgid "Failed to recurse into submodule path '%s'" -msgstr "" - -#: builtin/submodule--helper.c:2699 -msgid "force checkout updates" -msgstr "" - -#: builtin/submodule--helper.c:2701 -msgid "initialize uninitialized submodules before update" -msgstr "" - -#: builtin/submodule--helper.c:2703 -msgid "use SHA-1 of submodule's remote tracking branch" -msgstr "" - -#: builtin/submodule--helper.c:2705 -msgid "traverse submodules recursively" -msgstr "" - -#: builtin/submodule--helper.c:2707 -msgid "don't fetch new objects from the remote site" -msgstr "" - -#: builtin/submodule--helper.c:2710 builtin/submodule--helper.c:2892 -msgid "path into the working tree" -msgstr "" - -#: builtin/submodule--helper.c:2713 -msgid "path into the working tree, across nested submodule boundaries" -msgstr "" - -#: builtin/submodule--helper.c:2717 -msgid "rebase, merge, checkout or none" -msgstr "" - -#: builtin/submodule--helper.c:2723 -msgid "create a shallow clone truncated to the specified number of revisions" -msgstr "" - -#: builtin/submodule--helper.c:2726 -msgid "parallel jobs" -msgstr "" - -#: builtin/submodule--helper.c:2728 -msgid "whether the initial clone should follow the shallow recommendation" -msgstr "" - -#: builtin/submodule--helper.c:2729 -msgid "don't print cloning progress" -msgstr "" - -#: builtin/submodule--helper.c:2741 -msgid "" -"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " -"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-" -"shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " -"[--] [<path>...]" -msgstr "" - -#: builtin/submodule--helper.c:2767 -msgid "bad value for update parameter" -msgstr "" - -#: builtin/submodule--helper.c:2893 -msgid "recurse into submodules" -msgstr "" - -#: builtin/submodule--helper.c:2899 -msgid "git submodule--helper absorb-git-dirs [<options>] [<path>...]" -msgstr "" - -#: builtin/submodule--helper.c:2955 -msgid "check if it is safe to write to the .gitmodules file" -msgstr "" - -#: builtin/submodule--helper.c:2958 -msgid "unset the config in the .gitmodules file" -msgstr "" - -#: builtin/submodule--helper.c:2963 -msgid "git submodule--helper config <name> [<value>]" -msgstr "" - -#: builtin/submodule--helper.c:2964 -msgid "git submodule--helper config --unset <name>" -msgstr "" - -#: builtin/submodule--helper.c:2984 builtin/submodule--helper.c:3238 -#: builtin/submodule--helper.c:3395 -msgid "please make sure that the .gitmodules file is in the working tree" -msgstr "" - -#: builtin/submodule--helper.c:3000 -msgid "suppress output for setting url of a submodule" -msgstr "" - -#: builtin/submodule--helper.c:3004 -msgid "git submodule--helper set-url [--quiet] <path> <newurl>" -msgstr "" - -#: builtin/submodule--helper.c:3037 -msgid "set the default tracking branch to master" -msgstr "" - -#: builtin/submodule--helper.c:3039 -msgid "set the default tracking branch" -msgstr "" - -#: builtin/submodule--helper.c:3043 -msgid "git submodule--helper set-branch [-q|--quiet] (-d|--default) <path>" -msgstr "" - -#: builtin/submodule--helper.c:3044 -msgid "" -"git submodule--helper set-branch [-q|--quiet] (-b|--branch) <branch> <path>" -msgstr "" - -#: builtin/submodule--helper.c:3051 -msgid "--branch or --default required" -msgstr "" - -#: builtin/submodule--helper.c:3072 builtin/submodule--helper.c:3375 -msgid "print only error messages" -msgstr "" - -#: builtin/submodule--helper.c:3073 -msgid "force creation" -msgstr "" - -#: builtin/submodule--helper.c:3081 -msgid "show whether the branch would be created" -msgstr "" - -#: builtin/submodule--helper.c:3085 -msgid "" -"git submodule--helper create-branch [-f|--force] [--create-reflog] [-q|--" -"quiet] [-t|--track] [-n|--dry-run] <name> <start-oid> <start-name>" -msgstr "" - -#: builtin/submodule--helper.c:3097 -#, c-format -msgid "creating branch '%s'" -msgstr "" - -#: builtin/submodule--helper.c:3155 -#, c-format -msgid "Adding existing repo at '%s' to the index\n" -msgstr "" - -#: builtin/submodule--helper.c:3158 -#, c-format -msgid "'%s' already exists and is not a valid git repo" -msgstr "" - -#: builtin/submodule--helper.c:3171 -#, c-format -msgid "A git directory for '%s' is found locally with remote(s):\n" -msgstr "" - -#: builtin/submodule--helper.c:3178 -#, c-format -msgid "" -"If you want to reuse this local git directory instead of cloning again from\n" -" %s\n" -"use the '--force' option. If the local git directory is not the correct " -"repo\n" -"or you are unsure what this means choose another name with the '--name' " -"option." -msgstr "" - -#: builtin/submodule--helper.c:3190 -#, c-format -msgid "Reactivating local git directory for submodule '%s'\n" -msgstr "" - -#: builtin/submodule--helper.c:3227 -#, c-format -msgid "unable to checkout submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:3266 -#, c-format -msgid "Failed to add submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:3270 builtin/submodule--helper.c:3275 -#: builtin/submodule--helper.c:3283 -#, c-format -msgid "Failed to register submodule '%s'" -msgstr "" - -#: builtin/submodule--helper.c:3339 -#, c-format -msgid "'%s' already exists in the index" -msgstr "" - -#: builtin/submodule--helper.c:3342 -#, c-format -msgid "'%s' already exists in the index and is not a submodule" -msgstr "" - -#: builtin/submodule--helper.c:3372 -msgid "branch of repository to add as submodule" -msgstr "" - -#: builtin/submodule--helper.c:3373 -msgid "allow adding an otherwise ignored submodule path" -msgstr "" - -#: builtin/submodule--helper.c:3379 -msgid "borrow the objects from reference repositories" -msgstr "" - -#: builtin/submodule--helper.c:3381 -msgid "" -"sets the submodule’s name to the given string instead of defaulting to its " -"path" -msgstr "" - -#: builtin/submodule--helper.c:3388 -msgid "git submodule--helper add [<options>] [--] <repository> [<path>]" -msgstr "" - -#: builtin/submodule--helper.c:3416 -msgid "Relative path can only be used from the toplevel of the working tree" -msgstr "" - -#: builtin/submodule--helper.c:3425 -#, c-format -msgid "repo URL: '%s' must be absolute or begin with ./|../" -msgstr "" - -#: builtin/submodule--helper.c:3460 -#, c-format -msgid "'%s' is not a valid submodule name" -msgstr "" - -#: builtin/submodule--helper.c:3520 git.c:453 git.c:729 -#, c-format -msgid "%s doesn't support --super-prefix" -msgstr "" - -#: builtin/submodule--helper.c:3526 -#, c-format -msgid "'%s' is not a valid submodule--helper subcommand" -msgstr "" - -#: builtin/symbolic-ref.c:8 -msgid "git symbolic-ref [<options>] <name> [<ref>]" -msgstr "" - -#: builtin/symbolic-ref.c:9 -msgid "git symbolic-ref -d [-q] <name>" -msgstr "" - -#: builtin/symbolic-ref.c:42 -msgid "suppress error message for non-symbolic (detached) refs" -msgstr "" - -#: builtin/symbolic-ref.c:43 -msgid "delete symbolic ref" -msgstr "" - -#: builtin/symbolic-ref.c:44 -msgid "shorten ref output" -msgstr "" - -#: builtin/symbolic-ref.c:45 builtin/update-ref.c:505 -msgid "reason" -msgstr "" - -#: builtin/symbolic-ref.c:45 builtin/update-ref.c:505 -msgid "reason of the update" -msgstr "" - -#: builtin/tag.c:26 -msgid "" -"git tag [-a | -s | -u <key-id>] [-f] [-m <msg> | -F <file>]\n" -" <tagname> [<head>]" -msgstr "" - -#: builtin/tag.c:28 -msgid "git tag -d <tagname>..." -msgstr "" - -#: builtin/tag.c:29 -msgid "" -"git tag -l [-n[<num>]] [--contains <commit>] [--no-contains <commit>] [--" -"points-at <object>]\n" -" [--format=<format>] [--merged <commit>] [--no-merged <commit>] " -"[<pattern>...]" -msgstr "" - -#: builtin/tag.c:31 -msgid "git tag -v [--format=<format>] <tagname>..." -msgstr "" - -#: builtin/tag.c:101 -#, c-format -msgid "tag '%s' not found." -msgstr "" - -#: builtin/tag.c:136 -#, c-format -msgid "Deleted tag '%s' (was %s)\n" -msgstr "" - -#: builtin/tag.c:171 -#, c-format -msgid "" -"\n" -"Write a message for tag:\n" -" %s\n" -"Lines starting with '%c' will be ignored.\n" -msgstr "" - -#: builtin/tag.c:175 -#, c-format -msgid "" -"\n" -"Write a message for tag:\n" -" %s\n" -"Lines starting with '%c' will be kept; you may remove them yourself if you " -"want to.\n" -msgstr "" - -#: builtin/tag.c:241 -msgid "unable to sign the tag" -msgstr "" - -#: builtin/tag.c:259 -#, c-format -msgid "" -"You have created a nested tag. The object referred to by your new tag is\n" -"already a tag. If you meant to tag the object that it points to, use:\n" -"\n" -"\tgit tag -f %s %s^{}" -msgstr "" - -#: builtin/tag.c:275 -msgid "bad object type." -msgstr "" - -#: builtin/tag.c:326 -msgid "no tag message?" -msgstr "" - -#: builtin/tag.c:333 -#, c-format -msgid "The tag message has been left in %s\n" -msgstr "" - -#: builtin/tag.c:445 -msgid "list tag names" -msgstr "" - -#: builtin/tag.c:447 -msgid "print <n> lines of each tag message" -msgstr "" - -#: builtin/tag.c:449 -msgid "delete tags" -msgstr "" - -#: builtin/tag.c:450 -msgid "verify tags" -msgstr "" - -#: builtin/tag.c:452 -msgid "Tag creation options" -msgstr "" - -#: builtin/tag.c:454 -msgid "annotated tag, needs a message" -msgstr "" - -#: builtin/tag.c:456 -msgid "tag message" -msgstr "" - -#: builtin/tag.c:458 -msgid "force edit of tag message" -msgstr "" - -#: builtin/tag.c:459 -msgid "annotated and GPG-signed tag" -msgstr "" - -#: builtin/tag.c:462 -msgid "use another key to sign the tag" -msgstr "" - -#: builtin/tag.c:463 -msgid "replace the tag if exists" -msgstr "" - -#: builtin/tag.c:464 builtin/update-ref.c:511 -msgid "create a reflog" -msgstr "" - -#: builtin/tag.c:466 -msgid "Tag listing options" -msgstr "" - -#: builtin/tag.c:467 -msgid "show tag list in columns" -msgstr "" - -#: builtin/tag.c:468 builtin/tag.c:470 -msgid "print only tags that contain the commit" -msgstr "" - -#: builtin/tag.c:469 builtin/tag.c:471 -msgid "print only tags that don't contain the commit" -msgstr "" - -#: builtin/tag.c:472 -msgid "print only tags that are merged" -msgstr "" - -#: builtin/tag.c:473 -msgid "print only tags that are not merged" -msgstr "" - -#: builtin/tag.c:477 -msgid "print only tags of the object" -msgstr "" - -#: builtin/tag.c:559 -#, c-format -msgid "the '%s' option is only allowed in list mode" -msgstr "" - -#: builtin/tag.c:598 -#, c-format -msgid "'%s' is not a valid tag name." -msgstr "" - -#: builtin/tag.c:603 -#, c-format -msgid "tag '%s' already exists" -msgstr "" - -#: builtin/tag.c:634 -#, c-format -msgid "Updated tag '%s' (was %s)\n" -msgstr "" - -#: builtin/unpack-objects.c:95 -msgid "pack exceeds maximum allowed size" -msgstr "" - -#: builtin/unpack-objects.c:504 -msgid "Unpacking objects" -msgstr "" - -#: builtin/update-index.c:84 -#, c-format -msgid "failed to create directory %s" -msgstr "" - -#: builtin/update-index.c:106 -#, c-format -msgid "failed to delete file %s" -msgstr "" - -#: builtin/update-index.c:113 builtin/update-index.c:219 -#, c-format -msgid "failed to delete directory %s" -msgstr "" - -#: builtin/update-index.c:138 -#, c-format -msgid "Testing mtime in '%s' " -msgstr "" - -#: builtin/update-index.c:152 -msgid "directory stat info does not change after adding a new file" -msgstr "" - -#: builtin/update-index.c:165 -msgid "directory stat info does not change after adding a new directory" -msgstr "" - -#: builtin/update-index.c:178 -msgid "directory stat info changes after updating a file" -msgstr "" - -#: builtin/update-index.c:189 -msgid "directory stat info changes after adding a file inside subdirectory" -msgstr "" - -#: builtin/update-index.c:200 -msgid "directory stat info does not change after deleting a file" -msgstr "" - -#: builtin/update-index.c:213 -msgid "directory stat info does not change after deleting a directory" -msgstr "" - -#: builtin/update-index.c:220 -msgid " OK" -msgstr "" - -#: builtin/update-index.c:589 -msgid "git update-index [<options>] [--] [<file>...]" -msgstr "" - -#: builtin/update-index.c:993 -msgid "continue refresh even when index needs update" -msgstr "" - -#: builtin/update-index.c:996 -msgid "refresh: ignore submodules" -msgstr "" - -#: builtin/update-index.c:999 -msgid "do not ignore new files" -msgstr "" - -#: builtin/update-index.c:1001 -msgid "let files replace directories and vice-versa" -msgstr "" - -#: builtin/update-index.c:1003 -msgid "notice files missing from worktree" -msgstr "" - -#: builtin/update-index.c:1005 -msgid "refresh even if index contains unmerged entries" -msgstr "" - -#: builtin/update-index.c:1008 -msgid "refresh stat information" -msgstr "" - -#: builtin/update-index.c:1012 -msgid "like --refresh, but ignore assume-unchanged setting" -msgstr "" - -#: builtin/update-index.c:1016 -msgid "<mode>,<object>,<path>" -msgstr "" - -#: builtin/update-index.c:1017 -msgid "add the specified entry to the index" -msgstr "" - -#: builtin/update-index.c:1027 -msgid "mark files as \"not changing\"" -msgstr "" - -#: builtin/update-index.c:1030 -msgid "clear assumed-unchanged bit" -msgstr "" - -#: builtin/update-index.c:1033 -msgid "mark files as \"index-only\"" -msgstr "" - -#: builtin/update-index.c:1036 -msgid "clear skip-worktree bit" -msgstr "" - -#: builtin/update-index.c:1039 -msgid "do not touch index-only entries" -msgstr "" - -#: builtin/update-index.c:1041 -msgid "add to index only; do not add content to object database" -msgstr "" - -#: builtin/update-index.c:1043 -msgid "remove named paths even if present in worktree" -msgstr "" - -#: builtin/update-index.c:1045 -msgid "with --stdin: input lines are terminated by null bytes" -msgstr "" - -#: builtin/update-index.c:1047 -msgid "read list of paths to be updated from standard input" -msgstr "" - -#: builtin/update-index.c:1051 -msgid "add entries from standard input to the index" -msgstr "" - -#: builtin/update-index.c:1055 -msgid "repopulate stages #2 and #3 for the listed paths" -msgstr "" - -#: builtin/update-index.c:1059 -msgid "only update entries that differ from HEAD" -msgstr "" - -#: builtin/update-index.c:1063 -msgid "ignore files missing from worktree" -msgstr "" - -#: builtin/update-index.c:1066 -msgid "report actions to standard output" -msgstr "" - -#: builtin/update-index.c:1068 -msgid "(for porcelains) forget saved unresolved conflicts" -msgstr "" - -#: builtin/update-index.c:1072 -msgid "write index in this format" -msgstr "" - -#: builtin/update-index.c:1074 -msgid "enable or disable split index" -msgstr "" - -#: builtin/update-index.c:1076 -msgid "enable/disable untracked cache" -msgstr "" - -#: builtin/update-index.c:1078 -msgid "test if the filesystem supports untracked cache" -msgstr "" - -#: builtin/update-index.c:1080 -msgid "enable untracked cache without testing the filesystem" -msgstr "" - -#: builtin/update-index.c:1082 -msgid "write out the index even if is not flagged as changed" -msgstr "" - -#: builtin/update-index.c:1084 -msgid "enable or disable file system monitor" -msgstr "" - -#: builtin/update-index.c:1086 -msgid "mark files as fsmonitor valid" -msgstr "" - -#: builtin/update-index.c:1089 -msgid "clear fsmonitor valid bit" -msgstr "" - -#: builtin/update-index.c:1195 -msgid "" -"core.splitIndex is set to false; remove or change it, if you really want to " -"enable split index" -msgstr "" - -#: builtin/update-index.c:1204 -msgid "" -"core.splitIndex is set to true; remove or change it, if you really want to " -"disable split index" -msgstr "" - -#: builtin/update-index.c:1216 -msgid "" -"core.untrackedCache is set to true; remove or change it, if you really want " -"to disable the untracked cache" -msgstr "" - -#: builtin/update-index.c:1220 -msgid "Untracked cache disabled" -msgstr "" - -#: builtin/update-index.c:1228 -msgid "" -"core.untrackedCache is set to false; remove or change it, if you really want " -"to enable the untracked cache" -msgstr "" - -#: builtin/update-index.c:1232 -#, c-format -msgid "Untracked cache enabled for '%s'" -msgstr "" - -#: builtin/update-index.c:1241 -msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor" -msgstr "" - -#: builtin/update-index.c:1246 -msgid "fsmonitor enabled" -msgstr "" - -#: builtin/update-index.c:1250 -msgid "" -"core.fsmonitor is set; remove it if you really want to disable fsmonitor" -msgstr "" - -#: builtin/update-index.c:1254 -msgid "fsmonitor disabled" -msgstr "" - -#: builtin/update-ref.c:10 -msgid "git update-ref [<options>] -d <refname> [<old-val>]" -msgstr "" - -#: builtin/update-ref.c:11 -msgid "git update-ref [<options>] <refname> <new-val> [<old-val>]" -msgstr "" - -#: builtin/update-ref.c:12 -msgid "git update-ref [<options>] --stdin [-z]" -msgstr "" - -#: builtin/update-ref.c:506 -msgid "delete the reference" -msgstr "" - -#: builtin/update-ref.c:508 -msgid "update <refname> not the one it points to" -msgstr "" - -#: builtin/update-ref.c:509 -msgid "stdin has NUL-terminated arguments" -msgstr "" - -#: builtin/update-ref.c:510 -msgid "read updates from stdin" -msgstr "" - -#: builtin/update-server-info.c:15 -msgid "update the info files from scratch" -msgstr "" - -#: builtin/upload-pack.c:11 -msgid "git upload-pack [<options>] <dir>" -msgstr "" - -#: builtin/upload-pack.c:24 t/helper/test-serve-v2.c:17 -msgid "quit after a single request/response exchange" -msgstr "" - -#: builtin/upload-pack.c:26 -msgid "serve up the info/refs for git-http-backend" -msgstr "" - -#: builtin/upload-pack.c:29 -msgid "do not try <directory>/.git/ if <directory> is no Git directory" -msgstr "" - -#: builtin/upload-pack.c:31 -msgid "interrupt transfer after <n> seconds of inactivity" -msgstr "" - -#: builtin/verify-commit.c:19 -msgid "git verify-commit [-v | --verbose] <commit>..." -msgstr "" - -#: builtin/verify-commit.c:68 -msgid "print commit contents" -msgstr "" - -#: builtin/verify-commit.c:69 builtin/verify-tag.c:37 -msgid "print raw gpg status output" -msgstr "" - -#: builtin/verify-pack.c:59 -msgid "git verify-pack [-v | --verbose] [-s | --stat-only] <pack>..." -msgstr "" - -#: builtin/verify-pack.c:70 -msgid "verbose" -msgstr "" - -#: builtin/verify-pack.c:72 -msgid "show statistics only" -msgstr "" - -#: builtin/verify-tag.c:18 -msgid "git verify-tag [-v | --verbose] [--format=<format>] <tag>..." -msgstr "" - -#: builtin/verify-tag.c:36 -msgid "print tag contents" -msgstr "" - -#: builtin/worktree.c:19 -msgid "git worktree add [<options>] <path> [<commit-ish>]" -msgstr "" - -#: builtin/worktree.c:20 -msgid "git worktree list [<options>]" -msgstr "" - -#: builtin/worktree.c:21 -msgid "git worktree lock [<options>] <path>" -msgstr "" - -#: builtin/worktree.c:22 -msgid "git worktree move <worktree> <new-path>" -msgstr "" - -#: builtin/worktree.c:23 -msgid "git worktree prune [<options>]" -msgstr "" - -#: builtin/worktree.c:24 -msgid "git worktree remove [<options>] <worktree>" -msgstr "" - -#: builtin/worktree.c:25 -msgid "git worktree repair [<path>...]" -msgstr "" - -#: builtin/worktree.c:26 -msgid "git worktree unlock <path>" -msgstr "" - -#: builtin/worktree.c:76 -#, c-format -msgid "Removing %s/%s: %s" -msgstr "" - -#: builtin/worktree.c:149 -msgid "report pruned working trees" -msgstr "" - -#: builtin/worktree.c:151 -msgid "expire working trees older than <time>" -msgstr "" - -#: builtin/worktree.c:221 -#, c-format -msgid "'%s' already exists" -msgstr "" - -#: builtin/worktree.c:230 -#, c-format -msgid "unusable worktree destination '%s'" -msgstr "" - -#: builtin/worktree.c:235 -#, c-format -msgid "" -"'%s' is a missing but locked worktree;\n" -"use '%s -f -f' to override, or 'unlock' and 'prune' or 'remove' to clear" -msgstr "" - -#: builtin/worktree.c:237 -#, c-format -msgid "" -"'%s' is a missing but already registered worktree;\n" -"use '%s -f' to override, or 'prune' or 'remove' to clear" -msgstr "" - -#: builtin/worktree.c:248 -#, c-format -msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly" -msgstr "" - -#: builtin/worktree.c:268 -#, c-format -msgid "failed to copy worktree config from '%s' to '%s'" -msgstr "" - -#: builtin/worktree.c:280 builtin/worktree.c:285 -#, c-format -msgid "failed to unset '%s' in '%s'" -msgstr "" - -#: builtin/worktree.c:356 -#, c-format -msgid "could not create directory of '%s'" -msgstr "" - -#: builtin/worktree.c:378 -msgid "initializing" -msgstr "" - -#: builtin/worktree.c:492 builtin/worktree.c:498 -#, c-format -msgid "Preparing worktree (new branch '%s')" -msgstr "" - -#: builtin/worktree.c:494 -#, c-format -msgid "Preparing worktree (resetting branch '%s'; was at %s)" -msgstr "" - -#: builtin/worktree.c:503 -#, c-format -msgid "Preparing worktree (checking out '%s')" -msgstr "" - -#: builtin/worktree.c:509 -#, c-format -msgid "Preparing worktree (detached HEAD %s)" -msgstr "" - -#: builtin/worktree.c:554 -msgid "checkout <branch> even if already checked out in other worktree" -msgstr "" - -#: builtin/worktree.c:557 -msgid "create a new branch" -msgstr "" - -#: builtin/worktree.c:559 -msgid "create or reset a branch" -msgstr "" - -#: builtin/worktree.c:561 -msgid "populate the new working tree" -msgstr "" - -#: builtin/worktree.c:562 -msgid "keep the new working tree locked" -msgstr "" - -#: builtin/worktree.c:564 builtin/worktree.c:809 -msgid "reason for locking" -msgstr "" - -#: builtin/worktree.c:567 -msgid "set up tracking mode (see git-branch(1))" -msgstr "" - -#: builtin/worktree.c:570 -msgid "try to match the new branch name with a remote-tracking branch" -msgstr "" - -#: builtin/worktree.c:584 -msgid "added with --lock" -msgstr "" - -#: builtin/worktree.c:646 -msgid "--[no-]track can only be used if a new branch is created" -msgstr "" - -#: builtin/worktree.c:766 -msgid "show extended annotations and reasons, if available" -msgstr "" - -#: builtin/worktree.c:768 -msgid "add 'prunable' annotation to worktrees older than <time>" -msgstr "" - -#: builtin/worktree.c:770 -msgid "terminate records with a NUL character" -msgstr "" - -#: builtin/worktree.c:821 builtin/worktree.c:854 builtin/worktree.c:928 -#: builtin/worktree.c:1052 -#, c-format -msgid "'%s' is not a working tree" -msgstr "" - -#: builtin/worktree.c:823 builtin/worktree.c:856 -msgid "The main working tree cannot be locked or unlocked" -msgstr "" - -#: builtin/worktree.c:828 -#, c-format -msgid "'%s' is already locked, reason: %s" -msgstr "" - -#: builtin/worktree.c:830 -#, c-format -msgid "'%s' is already locked" -msgstr "" - -#: builtin/worktree.c:858 -#, c-format -msgid "'%s' is not locked" -msgstr "" - -#: builtin/worktree.c:899 -msgid "working trees containing submodules cannot be moved or removed" -msgstr "" - -#: builtin/worktree.c:907 -msgid "force move even if worktree is dirty or locked" -msgstr "" - -#: builtin/worktree.c:930 builtin/worktree.c:1054 -#, c-format -msgid "'%s' is a main working tree" -msgstr "" - -#: builtin/worktree.c:935 -#, c-format -msgid "could not figure out destination name from '%s'" -msgstr "" - -#: builtin/worktree.c:948 -#, c-format -msgid "" -"cannot move a locked working tree, lock reason: %s\n" -"use 'move -f -f' to override or unlock first" -msgstr "" - -#: builtin/worktree.c:950 -msgid "" -"cannot move a locked working tree;\n" -"use 'move -f -f' to override or unlock first" -msgstr "" - -#: builtin/worktree.c:953 -#, c-format -msgid "validation failed, cannot move working tree: %s" -msgstr "" - -#: builtin/worktree.c:958 -#, c-format -msgid "failed to move '%s' to '%s'" -msgstr "" - -#: builtin/worktree.c:1004 -#, c-format -msgid "failed to run 'git status' on '%s'" -msgstr "" - -#: builtin/worktree.c:1008 -#, c-format -msgid "'%s' contains modified or untracked files, use --force to delete it" -msgstr "" - -#: builtin/worktree.c:1013 -#, c-format -msgid "failed to run 'git status' on '%s', code %d" -msgstr "" - -#: builtin/worktree.c:1036 -msgid "force removal even if worktree is dirty or locked" -msgstr "" - -#: builtin/worktree.c:1059 -#, c-format -msgid "" -"cannot remove a locked working tree, lock reason: %s\n" -"use 'remove -f -f' to override or unlock first" -msgstr "" - -#: builtin/worktree.c:1061 -msgid "" -"cannot remove a locked working tree;\n" -"use 'remove -f -f' to override or unlock first" -msgstr "" - -#: builtin/worktree.c:1064 -#, c-format -msgid "validation failed, cannot remove working tree: %s" -msgstr "" - -#: builtin/worktree.c:1088 -#, c-format -msgid "repair: %s: %s" -msgstr "" - -#: builtin/worktree.c:1091 -#, c-format -msgid "error: %s: %s" -msgstr "" - -#: builtin/write-tree.c:15 -msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]" -msgstr "" - -#: builtin/write-tree.c:28 -msgid "<prefix>/" -msgstr "" - -#: builtin/write-tree.c:29 -msgid "write tree object for a subdirectory <prefix>" -msgstr "" - -#: builtin/write-tree.c:31 -msgid "only useful for debugging" -msgstr "" - -#: git.c:28 -msgid "" -"git [--version] [--help] [-C <path>] [-c <name>=<value>]\n" -" [--exec-path[=<path>]] [--html-path] [--man-path] [--info-path]\n" -" [-p | --paginate | -P | --no-pager] [--no-replace-objects] [--" -"bare]\n" -" [--git-dir=<path>] [--work-tree=<path>] [--namespace=<name>]\n" -" [--super-prefix=<path>] [--config-env=<name>=<envvar>]\n" -" <command> [<args>]" -msgstr "" - -#: git.c:36 -msgid "" -"'git help -a' and 'git help -g' list available subcommands and some\n" -"concept guides. See 'git help <command>' or 'git help <concept>'\n" -"to read about a specific subcommand or concept.\n" -"See 'git help git' for an overview of the system." -msgstr "" - -#: git.c:188 git.c:216 git.c:300 -#, c-format -msgid "no directory given for '%s' option\n" -msgstr "" - -#: git.c:202 -#, c-format -msgid "no namespace given for --namespace\n" -msgstr "" - -#: git.c:230 -#, c-format -msgid "no prefix given for --super-prefix\n" -msgstr "" - -#: git.c:252 -#, c-format -msgid "-c expects a configuration string\n" -msgstr "" - -#: git.c:260 -#, c-format -msgid "no config key given for --config-env\n" -msgstr "" - -#: git.c:326 -#, c-format -msgid "unknown option: %s\n" -msgstr "" - -#: git.c:375 -#, c-format -msgid "while expanding alias '%s': '%s'" -msgstr "" - -#: git.c:384 -#, c-format -msgid "" -"alias '%s' changes environment variables.\n" -"You can use '!git' in the alias to do this" -msgstr "" - -#: git.c:391 -#, c-format -msgid "empty alias for %s" -msgstr "" - -#: git.c:394 -#, c-format -msgid "recursive alias: %s" -msgstr "" - -#: git.c:480 -msgid "write failure on standard output" -msgstr "" - -#: git.c:482 -msgid "unknown write failure on standard output" -msgstr "" - -#: git.c:484 -msgid "close failed on standard output" -msgstr "" - -#: git.c:838 -#, c-format -msgid "alias loop detected: expansion of '%s' does not terminate:%s" -msgstr "" - -#: git.c:888 -#, c-format -msgid "cannot handle %s as a builtin" -msgstr "" - -#: git.c:901 -#, c-format -msgid "" -"usage: %s\n" -"\n" -msgstr "" - -#: git.c:921 -#, c-format -msgid "expansion of alias '%s' failed; '%s' is not a git command\n" -msgstr "" - -#: git.c:933 -#, c-format -msgid "failed to run command '%s': %s\n" -msgstr "" - -#: http-fetch.c:128 -#, c-format -msgid "argument to --packfile must be a valid hash (got '%s')" -msgstr "" - -#: http-fetch.c:138 -msgid "not a git repository" -msgstr "" - -#: t/helper/test-fast-rebase.c:141 -msgid "unhandled options" -msgstr "" - -#: t/helper/test-fast-rebase.c:146 -msgid "error preparing revisions" -msgstr "" - -#: t/helper/test-reach.c:154 -#, c-format -msgid "commit %s is not marked reachable" -msgstr "" - -#: t/helper/test-reach.c:164 -msgid "too many commits marked reachable" -msgstr "" - -#: t/helper/test-serve-v2.c:7 -msgid "test-tool serve-v2 [<options>]" -msgstr "" - -#: t/helper/test-serve-v2.c:19 -msgid "exit immediately after advertising capabilities" -msgstr "" - -#: t/helper/test-simple-ipc.c:581 -msgid "test-helper simple-ipc is-active [<name>] [<options>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:582 -msgid "test-helper simple-ipc run-daemon [<name>] [<threads>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:583 -msgid "test-helper simple-ipc start-daemon [<name>] [<threads>] [<max-wait>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:584 -msgid "test-helper simple-ipc stop-daemon [<name>] [<max-wait>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:585 -msgid "test-helper simple-ipc send [<name>] [<token>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:586 -msgid "test-helper simple-ipc sendbytes [<name>] [<bytecount>] [<byte>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:587 -msgid "" -"test-helper simple-ipc multiple [<name>] [<threads>] [<bytecount>] " -"[<batchsize>]" -msgstr "" - -#: t/helper/test-simple-ipc.c:595 -msgid "name or pathname of unix domain socket" -msgstr "" - -#: t/helper/test-simple-ipc.c:597 -msgid "named-pipe name" -msgstr "" - -#: t/helper/test-simple-ipc.c:599 -msgid "number of threads in server thread pool" -msgstr "" - -#: t/helper/test-simple-ipc.c:600 -msgid "seconds to wait for daemon to start or stop" -msgstr "" - -#: t/helper/test-simple-ipc.c:602 -msgid "number of bytes" -msgstr "" - -#: t/helper/test-simple-ipc.c:603 -msgid "number of requests per thread" -msgstr "" - -#: t/helper/test-simple-ipc.c:605 -msgid "byte" -msgstr "" - -#: t/helper/test-simple-ipc.c:605 -msgid "ballast character" -msgstr "" - -#: t/helper/test-simple-ipc.c:606 -msgid "token" -msgstr "" - -#: t/helper/test-simple-ipc.c:606 -msgid "command token to send to the server" -msgstr "" - -#: http.c:350 -#, c-format -msgid "negative value for http.postbuffer; defaulting to %d" -msgstr "" - -#: http.c:371 -msgid "Delegation control is not supported with cURL < 7.22.0" -msgstr "" - -#: http.c:380 -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "" - -#: http.c:812 -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "" - -#: http.c:1016 -#, c-format -msgid "Unsupported SSL backend '%s'. Supported SSL backends:" -msgstr "" - -#: http.c:1023 -#, c-format -msgid "Could not set SSL backend to '%s': cURL was built without SSL backends" -msgstr "" - -#: http.c:1027 -#, c-format -msgid "Could not set SSL backend to '%s': already set" -msgstr "" - -#: http.c:1876 -#, c-format -msgid "" -"unable to update url base from redirection:\n" -" asked for: %s\n" -" redirect: %s" -msgstr "" - -#: remote-curl.c:184 -#, c-format -msgid "invalid quoting in push-option value: '%s'" -msgstr "" - -#: remote-curl.c:308 -#, c-format -msgid "%sinfo/refs not valid: is this a git repository?" -msgstr "" - -#: remote-curl.c:409 -msgid "invalid server response; expected service, got flush packet" -msgstr "" - -#: remote-curl.c:440 -#, c-format -msgid "invalid server response; got '%s'" -msgstr "" - -#: remote-curl.c:500 -#, c-format -msgid "repository '%s' not found" -msgstr "" - -#: remote-curl.c:504 -#, c-format -msgid "Authentication failed for '%s'" -msgstr "" - -#: remote-curl.c:508 -#, c-format -msgid "unable to access '%s' with http.pinnedPubkey configuration: %s" -msgstr "" - -#: remote-curl.c:512 -#, c-format -msgid "unable to access '%s': %s" -msgstr "" - -#: remote-curl.c:518 -#, c-format -msgid "redirecting to %s" -msgstr "" - -#: remote-curl.c:649 -msgid "shouldn't have EOF when not gentle on EOF" -msgstr "" - -#: remote-curl.c:661 -msgid "remote server sent unexpected response end packet" -msgstr "" - -#: remote-curl.c:730 -msgid "unable to rewind rpc post data - try increasing http.postBuffer" -msgstr "" - -#: remote-curl.c:759 -#, c-format -msgid "remote-curl: bad line length character: %.4s" -msgstr "" - -#: remote-curl.c:761 -msgid "remote-curl: unexpected response end packet" -msgstr "" - -#: remote-curl.c:837 -#, c-format -msgid "RPC failed; %s" -msgstr "" - -#: remote-curl.c:877 -msgid "cannot handle pushes this big" -msgstr "" - -#: remote-curl.c:990 -#, c-format -msgid "cannot deflate request; zlib deflate error %d" -msgstr "" - -#: remote-curl.c:994 -#, c-format -msgid "cannot deflate request; zlib end error %d" -msgstr "" - -#: remote-curl.c:1044 -#, c-format -msgid "%d bytes of length header were received" -msgstr "" - -#: remote-curl.c:1046 -#, c-format -msgid "%d bytes of body are still expected" -msgstr "" - -#: remote-curl.c:1135 -msgid "dumb http transport does not support shallow capabilities" -msgstr "" - -#: remote-curl.c:1150 -msgid "fetch failed." -msgstr "" - -#: remote-curl.c:1198 -msgid "cannot fetch by sha1 over smart http" -msgstr "" - -#: remote-curl.c:1242 remote-curl.c:1248 -#, c-format -msgid "protocol error: expected sha/ref, got '%s'" -msgstr "" - -#: remote-curl.c:1260 remote-curl.c:1378 -#, c-format -msgid "http transport does not support %s" -msgstr "" - -#: remote-curl.c:1296 -msgid "git-http-push failed" -msgstr "" - -#: remote-curl.c:1485 -msgid "remote-curl: usage: git remote-curl <remote> [<url>]" -msgstr "" - -#: remote-curl.c:1517 -msgid "remote-curl: error reading command stream from git" -msgstr "" - -#: remote-curl.c:1524 -msgid "remote-curl: fetch attempted without a local repo" -msgstr "" - -#: remote-curl.c:1565 -#, c-format -msgid "remote-curl: unknown command '%s' from git" -msgstr "" - -#: contrib/scalar/scalar.c:49 -msgid "need a working directory" -msgstr "" - -#: contrib/scalar/scalar.c:86 -msgid "could not find enlistment root" -msgstr "" - -#: contrib/scalar/scalar.c:89 contrib/scalar/scalar.c:350 -#: contrib/scalar/scalar.c:435 contrib/scalar/scalar.c:578 -#, c-format -msgid "could not switch to '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:179 -#, c-format -msgid "could not configure %s=%s" -msgstr "" - -#: contrib/scalar/scalar.c:197 -msgid "could not configure log.excludeDecoration" -msgstr "" - -#: contrib/scalar/scalar.c:218 -msgid "Scalar enlistments require a worktree" -msgstr "" - -#: contrib/scalar/scalar.c:310 -#, c-format -msgid "remote HEAD is not a branch: '%.*s'" -msgstr "" - -#: contrib/scalar/scalar.c:316 -msgid "failed to get default branch name from remote; using local default" -msgstr "" - -#: contrib/scalar/scalar.c:329 -msgid "failed to get default branch name" -msgstr "" - -#: contrib/scalar/scalar.c:340 -msgid "failed to unregister repository" -msgstr "" - -#: contrib/scalar/scalar.c:355 -msgid "failed to delete enlistment directory" -msgstr "" - -#: contrib/scalar/scalar.c:375 -msgid "branch to checkout after clone" -msgstr "" - -#: contrib/scalar/scalar.c:377 -msgid "when cloning, create full working directory" -msgstr "" - -#: contrib/scalar/scalar.c:379 -msgid "only download metadata for the branch that will be checked out" -msgstr "" - -#: contrib/scalar/scalar.c:384 -msgid "scalar clone [<options>] [--] <repo> [<dir>]" -msgstr "" - -#: contrib/scalar/scalar.c:409 -#, c-format -msgid "cannot deduce worktree name from '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:418 -#, c-format -msgid "directory '%s' exists already" -msgstr "" - -#: contrib/scalar/scalar.c:445 -#, c-format -msgid "failed to get default branch for '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:456 -#, c-format -msgid "could not configure remote in '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:465 -#, c-format -msgid "could not configure '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:468 -msgid "partial clone failed; attempting full clone" -msgstr "" - -#: contrib/scalar/scalar.c:472 -msgid "could not configure for full clone" -msgstr "" - -#: contrib/scalar/scalar.c:504 -msgid "`scalar list` does not take arguments" -msgstr "" - -#: contrib/scalar/scalar.c:517 -msgid "scalar register [<enlistment>]" -msgstr "" - -#: contrib/scalar/scalar.c:544 -msgid "reconfigure all registered enlistments" -msgstr "" - -#: contrib/scalar/scalar.c:548 -msgid "scalar reconfigure [--all | <enlistment>]" -msgstr "" - -#: contrib/scalar/scalar.c:566 -msgid "--all or <enlistment>, but not both" -msgstr "" - -#: contrib/scalar/scalar.c:581 -#, c-format -msgid "git repository gone in '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:621 -msgid "" -"scalar run <task> [<enlistment>]\n" -"Tasks:\n" -msgstr "" - -#: contrib/scalar/scalar.c:639 -#, c-format -msgid "no such task: '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:689 -msgid "scalar unregister [<enlistment>]" -msgstr "" - -#: contrib/scalar/scalar.c:736 -msgid "scalar delete <enlistment>" -msgstr "" - -#: contrib/scalar/scalar.c:751 -msgid "refusing to delete current working directory" -msgstr "" - -#: contrib/scalar/scalar.c:766 -msgid "include Git version" -msgstr "" - -#: contrib/scalar/scalar.c:768 -msgid "include Git's build options" -msgstr "" - -#: contrib/scalar/scalar.c:772 -msgid "scalar verbose [-v | --verbose] [--build-options]" -msgstr "" - -#: contrib/scalar/scalar.c:813 -msgid "-C requires a <directory>" -msgstr "" - -#: contrib/scalar/scalar.c:815 -#, c-format -msgid "could not change to '%s'" -msgstr "" - -#: contrib/scalar/scalar.c:821 -msgid "-c requires a <key>=<value> argument" -msgstr "" - -#: contrib/scalar/scalar.c:839 -msgid "" -"scalar [-C <directory>] [-c <key>=<value>] <command> [<options>]\n" -"\n" -"Commands:\n" -msgstr "" - -#: compat/compiler.h:26 -msgid "no compiler information available\n" -msgstr "" - -#: compat/compiler.h:38 -msgid "no libc information available\n" -msgstr "" - -#: list-objects-filter-options.h:126 -msgid "args" -msgstr "" - -#: list-objects-filter-options.h:127 -msgid "object filtering" -msgstr "" - -#: parse-options.h:188 -msgid "expiry-date" -msgstr "" - -#: parse-options.h:202 -msgid "no-op (backward compatibility)" -msgstr "" - -#: parse-options.h:341 -msgid "be more verbose" -msgstr "" - -#: parse-options.h:343 -msgid "be more quiet" -msgstr "" - -#: parse-options.h:349 -msgid "use <n> digits to display object names" -msgstr "" - -#: parse-options.h:368 -msgid "how to strip spaces and #comments from message" -msgstr "" - -#: parse-options.h:369 -msgid "read pathspec from file" -msgstr "" - -#: parse-options.h:370 -msgid "" -"with --pathspec-from-file, pathspec elements are separated with NUL character" -msgstr "" - -#: ref-filter.h:98 -msgid "key" -msgstr "" - -#: ref-filter.h:98 -msgid "field name to sort on" -msgstr "" - -#: rerere.h:44 -msgid "update the index with reused conflict resolution if possible" -msgstr "" - -#: command-list.h:50 -msgid "Add file contents to the index" -msgstr "" - -#: command-list.h:51 -msgid "Apply a series of patches from a mailbox" -msgstr "" - -#: command-list.h:52 -msgid "Annotate file lines with commit information" -msgstr "" - -#: command-list.h:53 -msgid "Apply a patch to files and/or to the index" -msgstr "" - -#: command-list.h:54 -msgid "Import a GNU Arch repository into Git" -msgstr "" - -#: command-list.h:55 -msgid "Create an archive of files from a named tree" -msgstr "" - -#: command-list.h:56 -msgid "Use binary search to find the commit that introduced a bug" -msgstr "" - -#: command-list.h:57 -msgid "Show what revision and author last modified each line of a file" -msgstr "" - -#: command-list.h:58 -msgid "List, create, or delete branches" -msgstr "" - -#: command-list.h:59 -msgid "Collect information for user to file a bug report" -msgstr "" - -#: command-list.h:60 -msgid "Move objects and refs by archive" -msgstr "" - -#: command-list.h:61 -msgid "Provide content or type and size information for repository objects" -msgstr "" - -#: command-list.h:62 -msgid "Display gitattributes information" -msgstr "" - -#: command-list.h:63 -msgid "Debug gitignore / exclude files" -msgstr "" - -#: command-list.h:64 -msgid "Show canonical names and email addresses of contacts" -msgstr "" - -#: command-list.h:65 -msgid "Ensures that a reference name is well formed" -msgstr "" - -#: command-list.h:66 -msgid "Switch branches or restore working tree files" -msgstr "" - -#: command-list.h:67 -msgid "Copy files from the index to the working tree" -msgstr "" - -#: command-list.h:68 -msgid "Find commits yet to be applied to upstream" -msgstr "" - -#: command-list.h:69 -msgid "Apply the changes introduced by some existing commits" -msgstr "" - -#: command-list.h:70 -msgid "Graphical alternative to git-commit" -msgstr "" - -#: command-list.h:71 -msgid "Remove untracked files from the working tree" -msgstr "" - -#: command-list.h:72 -msgid "Clone a repository into a new directory" -msgstr "" - -#: command-list.h:73 -msgid "Display data in columns" -msgstr "" - -#: command-list.h:74 -msgid "Record changes to the repository" -msgstr "" - -#: command-list.h:75 -msgid "Write and verify Git commit-graph files" -msgstr "" - -#: command-list.h:76 -msgid "Create a new commit object" -msgstr "" - -#: command-list.h:77 -msgid "Get and set repository or global options" -msgstr "" - -#: command-list.h:78 -msgid "Count unpacked number of objects and their disk consumption" -msgstr "" - -#: command-list.h:79 -msgid "Retrieve and store user credentials" -msgstr "" - -#: command-list.h:80 -msgid "Helper to temporarily store passwords in memory" -msgstr "" - -#: command-list.h:81 -msgid "Helper to store credentials on disk" -msgstr "" - -#: command-list.h:82 -msgid "Export a single commit to a CVS checkout" -msgstr "" - -#: command-list.h:83 -msgid "Salvage your data out of another SCM people love to hate" -msgstr "" - -#: command-list.h:84 -msgid "A CVS server emulator for Git" -msgstr "" - -#: command-list.h:85 -msgid "A really simple server for Git repositories" -msgstr "" - -#: command-list.h:86 -msgid "Give an object a human readable name based on an available ref" -msgstr "" - -#: command-list.h:87 -msgid "Show changes between commits, commit and working tree, etc" -msgstr "" - -#: command-list.h:88 -msgid "Compares files in the working tree and the index" -msgstr "" - -#: command-list.h:89 -msgid "Compare a tree to the working tree or index" -msgstr "" - -#: command-list.h:90 -msgid "Compares the content and mode of blobs found via two tree objects" -msgstr "" - -#: command-list.h:91 -msgid "Show changes using common diff tools" -msgstr "" - -#: command-list.h:92 -msgid "Git data exporter" -msgstr "" - -#: command-list.h:93 -msgid "Backend for fast Git data importers" -msgstr "" - -#: command-list.h:94 -msgid "Download objects and refs from another repository" -msgstr "" - -#: command-list.h:95 -msgid "Receive missing objects from another repository" -msgstr "" - -#: command-list.h:96 -msgid "Rewrite branches" -msgstr "" - -#: command-list.h:97 -msgid "Produce a merge commit message" -msgstr "" - -#: command-list.h:98 -msgid "Output information on each ref" -msgstr "" - -#: command-list.h:99 -msgid "Run a Git command on a list of repositories" -msgstr "" - -#: command-list.h:100 -msgid "Prepare patches for e-mail submission" -msgstr "" - -#: command-list.h:101 -msgid "Verifies the connectivity and validity of the objects in the database" -msgstr "" - -#: command-list.h:102 -msgid "Cleanup unnecessary files and optimize the local repository" -msgstr "" - -#: command-list.h:103 -msgid "Extract commit ID from an archive created using git-archive" -msgstr "" - -#: command-list.h:104 -msgid "Print lines matching a pattern" -msgstr "" - -#: command-list.h:105 -msgid "A portable graphical interface to Git" -msgstr "" - -#: command-list.h:106 -msgid "Compute object ID and optionally creates a blob from a file" -msgstr "" - -#: command-list.h:107 -msgid "Display help information about Git" -msgstr "" - -#: command-list.h:108 -msgid "Run git hooks" -msgstr "" - -#: command-list.h:109 -msgid "Server side implementation of Git over HTTP" -msgstr "" - -#: command-list.h:110 -msgid "Download from a remote Git repository via HTTP" -msgstr "" - -#: command-list.h:111 -msgid "Push objects over HTTP/DAV to another repository" -msgstr "" - -#: command-list.h:112 -msgid "Send a collection of patches from stdin to an IMAP folder" -msgstr "" - -#: command-list.h:113 -msgid "Build pack index file for an existing packed archive" -msgstr "" - -#: command-list.h:114 -msgid "Create an empty Git repository or reinitialize an existing one" -msgstr "" - -#: command-list.h:115 -msgid "Instantly browse your working repository in gitweb" -msgstr "" - -#: command-list.h:116 -msgid "Add or parse structured information in commit messages" -msgstr "" - -#: command-list.h:117 -msgid "Show commit logs" -msgstr "" - -#: command-list.h:118 -msgid "Show information about files in the index and the working tree" -msgstr "" - -#: command-list.h:119 -msgid "List references in a remote repository" -msgstr "" - -#: command-list.h:120 -msgid "List the contents of a tree object" -msgstr "" - -#: command-list.h:121 -msgid "Extracts patch and authorship from a single e-mail message" -msgstr "" - -#: command-list.h:122 -msgid "Simple UNIX mbox splitter program" -msgstr "" - -#: command-list.h:123 -msgid "Run tasks to optimize Git repository data" -msgstr "" - -#: command-list.h:124 -msgid "Join two or more development histories together" -msgstr "" - -#: command-list.h:125 -msgid "Find as good common ancestors as possible for a merge" -msgstr "" - -#: command-list.h:126 -msgid "Run a three-way file merge" -msgstr "" - -#: command-list.h:127 -msgid "Run a merge for files needing merging" -msgstr "" - -#: command-list.h:128 -msgid "The standard helper program to use with git-merge-index" -msgstr "" - -#: command-list.h:129 -msgid "Show three-way merge without touching index" -msgstr "" - -#: command-list.h:130 -msgid "Run merge conflict resolution tools to resolve merge conflicts" -msgstr "" - -#: command-list.h:131 -msgid "Creates a tag object with extra validation" -msgstr "" - -#: command-list.h:132 -msgid "Build a tree-object from ls-tree formatted text" -msgstr "" - -#: command-list.h:133 -msgid "Write and verify multi-pack-indexes" -msgstr "" - -#: command-list.h:134 -msgid "Move or rename a file, a directory, or a symlink" -msgstr "" - -#: command-list.h:135 -msgid "Find symbolic names for given revs" -msgstr "" - -#: command-list.h:136 -msgid "Add or inspect object notes" -msgstr "" - -#: command-list.h:137 -msgid "Import from and submit to Perforce repositories" -msgstr "" - -#: command-list.h:138 -msgid "Create a packed archive of objects" -msgstr "" - -#: command-list.h:139 -msgid "Find redundant pack files" -msgstr "" - -#: command-list.h:140 -msgid "Pack heads and tags for efficient repository access" -msgstr "" - -#: command-list.h:141 -msgid "Compute unique ID for a patch" -msgstr "" - -#: command-list.h:142 -msgid "Prune all unreachable objects from the object database" -msgstr "" - -#: command-list.h:143 -msgid "Remove extra objects that are already in pack files" -msgstr "" - -#: command-list.h:144 -msgid "Fetch from and integrate with another repository or a local branch" -msgstr "" - -#: command-list.h:145 -msgid "Update remote refs along with associated objects" -msgstr "" - -#: command-list.h:146 -msgid "Applies a quilt patchset onto the current branch" -msgstr "" - -#: command-list.h:147 -msgid "Compare two commit ranges (e.g. two versions of a branch)" -msgstr "" - -#: command-list.h:148 -msgid "Reads tree information into the index" -msgstr "" - -#: command-list.h:149 -msgid "Reapply commits on top of another base tip" -msgstr "" - -#: command-list.h:150 -msgid "Receive what is pushed into the repository" -msgstr "" - -#: command-list.h:151 -msgid "Manage reflog information" -msgstr "" - -#: command-list.h:152 -msgid "Manage set of tracked repositories" -msgstr "" - -#: command-list.h:153 -msgid "Pack unpacked objects in a repository" -msgstr "" - -#: command-list.h:154 -msgid "Create, list, delete refs to replace objects" -msgstr "" - -#: command-list.h:155 -msgid "Generates a summary of pending changes" -msgstr "" - -#: command-list.h:156 -msgid "Reuse recorded resolution of conflicted merges" -msgstr "" - -#: command-list.h:157 -msgid "Reset current HEAD to the specified state" -msgstr "" - -#: command-list.h:158 -msgid "Restore working tree files" -msgstr "" - -#: command-list.h:159 -msgid "Lists commit objects in reverse chronological order" -msgstr "" - -#: command-list.h:160 -msgid "Pick out and massage parameters" -msgstr "" - -#: command-list.h:161 -msgid "Revert some existing commits" -msgstr "" - -#: command-list.h:162 -msgid "Remove files from the working tree and from the index" -msgstr "" - -#: command-list.h:163 -msgid "Send a collection of patches as emails" -msgstr "" - -#: command-list.h:164 -msgid "Push objects over Git protocol to another repository" -msgstr "" - -#: command-list.h:165 -msgid "Git's i18n setup code for shell scripts" -msgstr "" - -#: command-list.h:166 -msgid "Common Git shell script setup code" -msgstr "" - -#: command-list.h:167 -msgid "Restricted login shell for Git-only SSH access" -msgstr "" - -#: command-list.h:168 -msgid "Summarize 'git log' output" -msgstr "" - -#: command-list.h:169 -msgid "Show various types of objects" -msgstr "" - -#: command-list.h:170 -msgid "Show branches and their commits" -msgstr "" - -#: command-list.h:171 -msgid "Show packed archive index" -msgstr "" - -#: command-list.h:172 -msgid "List references in a local repository" -msgstr "" - -#: command-list.h:173 -msgid "Reduce your working tree to a subset of tracked files" -msgstr "" - -#: command-list.h:174 -msgid "Add file contents to the staging area" -msgstr "" - -#: command-list.h:175 -msgid "Stash the changes in a dirty working directory away" -msgstr "" - -#: command-list.h:176 -msgid "Show the working tree status" -msgstr "" - -#: command-list.h:177 -msgid "Remove unnecessary whitespace" -msgstr "" - -#: command-list.h:178 -msgid "Initialize, update or inspect submodules" -msgstr "" - -#: command-list.h:179 -msgid "Bidirectional operation between a Subversion repository and Git" -msgstr "" - -#: command-list.h:180 -msgid "Switch branches" -msgstr "" - -#: command-list.h:181 -msgid "Read, modify and delete symbolic refs" -msgstr "" - -#: command-list.h:182 -msgid "Create, list, delete or verify a tag object signed with GPG" -msgstr "" - -#: command-list.h:183 -msgid "Creates a temporary file with a blob's contents" -msgstr "" - -#: command-list.h:184 -msgid "Unpack objects from a packed archive" -msgstr "" - -#: command-list.h:185 -msgid "Register file contents in the working tree to the index" -msgstr "" - -#: command-list.h:186 -msgid "Update the object name stored in a ref safely" -msgstr "" - -#: command-list.h:187 -msgid "Update auxiliary info file to help dumb servers" -msgstr "" - -#: command-list.h:188 -msgid "Send archive back to git-archive" -msgstr "" - -#: command-list.h:189 -msgid "Send objects packed back to git-fetch-pack" -msgstr "" - -#: command-list.h:190 -msgid "Show a Git logical variable" -msgstr "" - -#: command-list.h:191 -msgid "Check the GPG signature of commits" -msgstr "" - -#: command-list.h:192 -msgid "Validate packed Git archive files" -msgstr "" - -#: command-list.h:193 -msgid "Check the GPG signature of tags" -msgstr "" - -#: command-list.h:194 -msgid "Show logs with difference each commit introduces" -msgstr "" - -#: command-list.h:195 -msgid "Manage multiple working trees" -msgstr "" - -#: command-list.h:196 -msgid "Create a tree object from the current index" -msgstr "" - -#: command-list.h:197 -msgid "Defining attributes per path" -msgstr "" - -#: command-list.h:198 -msgid "Git command-line interface and conventions" -msgstr "" - -#: command-list.h:199 -msgid "A Git core tutorial for developers" -msgstr "" - -#: command-list.h:200 -msgid "Providing usernames and passwords to Git" -msgstr "" - -#: command-list.h:201 -msgid "Git for CVS users" -msgstr "" - -#: command-list.h:202 -msgid "Tweaking diff output" -msgstr "" - -#: command-list.h:203 -msgid "A useful minimum set of commands for Everyday Git" -msgstr "" - -#: command-list.h:204 -msgid "Frequently asked questions about using Git" -msgstr "" - -#: command-list.h:205 -msgid "A Git Glossary" -msgstr "" - -#: command-list.h:206 -msgid "Hooks used by Git" -msgstr "" - -#: command-list.h:207 -msgid "Specifies intentionally untracked files to ignore" -msgstr "" - -#: command-list.h:208 -msgid "The Git repository browser" -msgstr "" - -#: command-list.h:209 -msgid "Map author/committer names and/or E-Mail addresses" -msgstr "" - -#: command-list.h:210 -msgid "Defining submodule properties" -msgstr "" - -#: command-list.h:211 -msgid "Git namespaces" -msgstr "" - -#: command-list.h:212 -msgid "Helper programs to interact with remote repositories" -msgstr "" - -#: command-list.h:213 -msgid "Git Repository Layout" -msgstr "" - -#: command-list.h:214 -msgid "Specifying revisions and ranges for Git" -msgstr "" - -#: command-list.h:215 -msgid "Mounting one repository inside another" -msgstr "" - -#: command-list.h:216 -msgid "A tutorial introduction to Git" -msgstr "" - -#: command-list.h:217 -msgid "A tutorial introduction to Git: part two" -msgstr "" - -#: command-list.h:218 -msgid "Git web interface (web frontend to Git repositories)" -msgstr "" - -#: command-list.h:219 -msgid "An overview of recommended workflows with Git" -msgstr "" - -#: git-merge-octopus.sh:46 -msgid "" -"Error: Your local changes to the following files would be overwritten by " -"merge" -msgstr "" - -#: git-merge-octopus.sh:61 -msgid "Automated merge did not work." -msgstr "" - -#: git-merge-octopus.sh:62 -msgid "Should not be doing an octopus." -msgstr "" - -#: git-merge-octopus.sh:73 -#, sh-format -msgid "Unable to find common commit with $pretty_name" -msgstr "" - -#: git-merge-octopus.sh:77 -#, sh-format -msgid "Already up to date with $pretty_name" -msgstr "" - -#: git-merge-octopus.sh:89 -#, sh-format -msgid "Fast-forwarding to: $pretty_name" -msgstr "" - -#: git-merge-octopus.sh:97 -#, sh-format -msgid "Trying simple merge with $pretty_name" -msgstr "" - -#: git-merge-octopus.sh:102 -msgid "Simple merge did not work, trying automatic merge." -msgstr "" - -#: git-sh-setup.sh:89 git-sh-setup.sh:94 -#, sh-format -msgid "usage: $dashless $USAGE" -msgstr "" - -#: git-sh-setup.sh:182 -#, sh-format -msgid "Cannot chdir to $cdup, the toplevel of the working tree" -msgstr "" - -#: git-sh-setup.sh:191 git-sh-setup.sh:198 -#, sh-format -msgid "fatal: $program_name cannot be used without a working tree." -msgstr "" - -#: git-sh-setup.sh:212 -msgid "Cannot rewrite branches: You have unstaged changes." -msgstr "" - -#: git-sh-setup.sh:215 -#, sh-format -msgid "Cannot $action: You have unstaged changes." -msgstr "" - -#: git-sh-setup.sh:226 -#, sh-format -msgid "Cannot $action: Your index contains uncommitted changes." -msgstr "" - -#: git-sh-setup.sh:228 -msgid "Additionally, your index contains uncommitted changes." -msgstr "" - -#: git-sh-setup.sh:348 -msgid "You need to run this command from the toplevel of the working tree." -msgstr "" - -#: git-sh-setup.sh:353 -msgid "Unable to determine absolute path of git directory" -msgstr "" - -#. TRANSLATORS: you can adjust this to align "git add -i" status menu -#: git-add--interactive.perl:212 -#, perl-format -msgid "%12s %12s %s" -msgstr "" - -#: git-add--interactive.perl:632 -#, perl-format -msgid "touched %d path\n" -msgid_plural "touched %d paths\n" -msgstr[0] "" -msgstr[1] "" - -#: git-add--interactive.perl:1056 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be\n" -"marked for staging." -msgstr "" - -#: git-add--interactive.perl:1059 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be\n" -"marked for stashing." -msgstr "" - -#: git-add--interactive.perl:1062 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be\n" -"marked for unstaging." -msgstr "" - -#: git-add--interactive.perl:1065 git-add--interactive.perl:1074 -#: git-add--interactive.perl:1080 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be\n" -"marked for applying." -msgstr "" - -#: git-add--interactive.perl:1068 git-add--interactive.perl:1071 -#: git-add--interactive.perl:1077 -msgid "" -"If the patch applies cleanly, the edited hunk will immediately be\n" -"marked for discarding." -msgstr "" - -#: git-add--interactive.perl:1114 -#, perl-format -msgid "failed to open hunk edit file for writing: %s" -msgstr "" - -#: git-add--interactive.perl:1121 -#, perl-format -msgid "" -"---\n" -"To remove '%s' lines, make them ' ' lines (context).\n" -"To remove '%s' lines, delete them.\n" -"Lines starting with %s will be removed.\n" -msgstr "" - -#: git-add--interactive.perl:1143 -#, perl-format -msgid "failed to open hunk edit file for reading: %s" -msgstr "" - -#: git-add--interactive.perl:1253 -msgid "" -"y - stage this hunk\n" -"n - do not stage this hunk\n" -"q - quit; do not stage this hunk or any of the remaining ones\n" -"a - stage this hunk and all later hunks in the file\n" -"d - do not stage this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1259 -msgid "" -"y - stash this hunk\n" -"n - do not stash this hunk\n" -"q - quit; do not stash this hunk or any of the remaining ones\n" -"a - stash this hunk and all later hunks in the file\n" -"d - do not stash this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1265 -msgid "" -"y - unstage this hunk\n" -"n - do not unstage this hunk\n" -"q - quit; do not unstage this hunk or any of the remaining ones\n" -"a - unstage this hunk and all later hunks in the file\n" -"d - do not unstage this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1271 -msgid "" -"y - apply this hunk to index\n" -"n - do not apply this hunk to index\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1277 git-add--interactive.perl:1295 -msgid "" -"y - discard this hunk from worktree\n" -"n - do not discard this hunk from worktree\n" -"q - quit; do not discard this hunk or any of the remaining ones\n" -"a - discard this hunk and all later hunks in the file\n" -"d - do not discard this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1283 -msgid "" -"y - discard this hunk from index and worktree\n" -"n - do not discard this hunk from index and worktree\n" -"q - quit; do not discard this hunk or any of the remaining ones\n" -"a - discard this hunk and all later hunks in the file\n" -"d - do not discard this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1289 -msgid "" -"y - apply this hunk to index and worktree\n" -"n - do not apply this hunk to index and worktree\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1301 -msgid "" -"y - apply this hunk to worktree\n" -"n - do not apply this hunk to worktree\n" -"q - quit; do not apply this hunk or any of the remaining ones\n" -"a - apply this hunk and all later hunks in the file\n" -"d - do not apply this hunk or any of the later hunks in the file" -msgstr "" - -#: git-add--interactive.perl:1316 -msgid "" -"g - select a hunk to go to\n" -"/ - search for a hunk matching the given regex\n" -"j - leave this hunk undecided, see next undecided hunk\n" -"J - leave this hunk undecided, see next hunk\n" -"k - leave this hunk undecided, see previous undecided hunk\n" -"K - leave this hunk undecided, see previous hunk\n" -"s - split the current hunk into smaller hunks\n" -"e - manually edit the current hunk\n" -"? - print help\n" -msgstr "" - -#: git-add--interactive.perl:1347 -msgid "The selected hunks do not apply to the index!\n" -msgstr "" - -#: git-add--interactive.perl:1362 -#, perl-format -msgid "ignoring unmerged: %s\n" -msgstr "" - -#: git-add--interactive.perl:1481 -#, perl-format -msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: git-add--interactive.perl:1482 -#, perl-format -msgid "Apply deletion to worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: git-add--interactive.perl:1483 -#, perl-format -msgid "Apply addition to worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: git-add--interactive.perl:1484 -#, perl-format -msgid "Apply this hunk to worktree [y,n,q,a,d%s,?]? " -msgstr "" - -#: git-add--interactive.perl:1601 -msgid "No other hunks to goto\n" -msgstr "" - -#: git-add--interactive.perl:1619 -#, perl-format -msgid "Invalid number: '%s'\n" -msgstr "" - -#: git-add--interactive.perl:1624 -#, perl-format -msgid "Sorry, only %d hunk available.\n" -msgid_plural "Sorry, only %d hunks available.\n" -msgstr[0] "" -msgstr[1] "" - -#: git-add--interactive.perl:1659 -msgid "No other hunks to search\n" -msgstr "" - -#: git-add--interactive.perl:1676 -#, perl-format -msgid "Malformed search regexp %s: %s\n" -msgstr "" - -#: git-add--interactive.perl:1686 -msgid "No hunk matches the given pattern\n" -msgstr "" - -#: git-add--interactive.perl:1698 git-add--interactive.perl:1720 -msgid "No previous hunk\n" -msgstr "" - -#: git-add--interactive.perl:1707 git-add--interactive.perl:1726 -msgid "No next hunk\n" -msgstr "" - -#: git-add--interactive.perl:1732 -msgid "Sorry, cannot split this hunk\n" -msgstr "" - -#: git-add--interactive.perl:1738 -#, perl-format -msgid "Split into %d hunk.\n" -msgid_plural "Split into %d hunks.\n" -msgstr[0] "" -msgstr[1] "" - -#: git-add--interactive.perl:1748 -msgid "Sorry, cannot edit this hunk\n" -msgstr "" - -#. TRANSLATORS: please do not translate the command names -#. 'status', 'update', 'revert', etc. -#: git-add--interactive.perl:1813 -msgid "" -"status - show paths with changes\n" -"update - add working tree state to the staged set of changes\n" -"revert - revert staged set of changes back to the HEAD version\n" -"patch - pick hunks and update selectively\n" -"diff - view diff between HEAD and index\n" -"add untracked - add contents of untracked files to the staged set of " -"changes\n" -msgstr "" - -#: git-add--interactive.perl:1830 git-add--interactive.perl:1842 -#: git-add--interactive.perl:1845 git-add--interactive.perl:1852 -#: git-add--interactive.perl:1855 git-add--interactive.perl:1862 -#: git-add--interactive.perl:1866 git-add--interactive.perl:1872 -msgid "missing --" -msgstr "" - -#: git-add--interactive.perl:1868 -#, perl-format -msgid "unknown --patch mode: %s" -msgstr "" - -#: git-add--interactive.perl:1874 git-add--interactive.perl:1880 -#, perl-format -msgid "invalid argument %s, expecting --" -msgstr "" - -#: git-send-email.perl:159 -msgid "local zone differs from GMT by a non-minute interval\n" -msgstr "" - -#: git-send-email.perl:166 git-send-email.perl:172 -msgid "local time offset greater than or equal to 24 hours\n" -msgstr "" - -#: git-send-email.perl:244 -#, perl-format -msgid "fatal: command '%s' died with exit code %d" -msgstr "" - -#: git-send-email.perl:257 -msgid "the editor exited uncleanly, aborting everything" -msgstr "" - -#: git-send-email.perl:346 -#, perl-format -msgid "" -"'%s' contains an intermediate version of the email you were composing.\n" -msgstr "" - -#: git-send-email.perl:351 -#, perl-format -msgid "'%s.final' contains the composed email.\n" -msgstr "" - -#: git-send-email.perl:484 -msgid "--dump-aliases incompatible with other options\n" -msgstr "" - -#: git-send-email.perl:561 -msgid "" -"fatal: found configuration options for 'sendmail'\n" -"git-send-email is configured with the sendemail.* options - note the 'e'.\n" -"Set sendemail.forbidSendmailVariables to false to disable this check.\n" -msgstr "" - -#: git-send-email.perl:566 git-send-email.perl:782 -msgid "Cannot run git format-patch from outside a repository\n" -msgstr "" - -#: git-send-email.perl:569 -msgid "" -"`batch-size` and `relogin` must be specified together (via command-line or " -"configuration option)\n" -msgstr "" - -#: git-send-email.perl:582 -#, perl-format -msgid "Unknown --suppress-cc field: '%s'\n" -msgstr "" - -#: git-send-email.perl:613 -#, perl-format -msgid "Unknown --confirm setting: '%s'\n" -msgstr "" - -#: git-send-email.perl:653 -#, perl-format -msgid "warning: sendmail alias with quotes is not supported: %s\n" -msgstr "" - -#: git-send-email.perl:655 -#, perl-format -msgid "warning: `:include:` not supported: %s\n" -msgstr "" - -#: git-send-email.perl:657 -#, perl-format -msgid "warning: `/file` or `|pipe` redirection not supported: %s\n" -msgstr "" - -#: git-send-email.perl:662 -#, perl-format -msgid "warning: sendmail line is not recognized: %s\n" -msgstr "" - -#: git-send-email.perl:747 -#, perl-format -msgid "" -"File '%s' exists but it could also be the range of commits\n" -"to produce patches for. Please disambiguate by...\n" -"\n" -" * Saying \"./%s\" if you mean a file; or\n" -" * Giving --format-patch option if you mean a range.\n" -msgstr "" - -#: git-send-email.perl:768 -#, perl-format -msgid "Failed to opendir %s: %s" -msgstr "" - -#: git-send-email.perl:803 -msgid "" -"\n" -"No patch files specified!\n" -"\n" -msgstr "" - -#: git-send-email.perl:816 -#, perl-format -msgid "No subject line in %s?" -msgstr "" - -#: git-send-email.perl:827 -#, perl-format -msgid "Failed to open for writing %s: %s" -msgstr "" - -#: git-send-email.perl:838 -msgid "" -"Lines beginning in \"GIT:\" will be removed.\n" -"Consider including an overall diffstat or table of contents\n" -"for the patch you are writing.\n" -"\n" -"Clear the body content if you don't wish to send a summary.\n" -msgstr "" - -#: git-send-email.perl:862 -#, perl-format -msgid "Failed to open %s: %s" -msgstr "" - -#: git-send-email.perl:879 -#, perl-format -msgid "Failed to open %s.final: %s" -msgstr "" - -#: git-send-email.perl:922 -msgid "Summary email is empty, skipping it\n" -msgstr "" - -#. TRANSLATORS: please keep [y/N] as is. -#: git-send-email.perl:971 -#, perl-format -msgid "Are you sure you want to use <%s> [y/N]? " -msgstr "" - -#: git-send-email.perl:1026 -msgid "" -"The following files are 8bit, but do not declare a Content-Transfer-" -"Encoding.\n" -msgstr "" - -#: git-send-email.perl:1031 -msgid "Which 8bit encoding should I declare [UTF-8]? " -msgstr "" - -#: git-send-email.perl:1039 -#, perl-format -msgid "" -"Refusing to send because the patch\n" -"\t%s\n" -"has the template subject '*** SUBJECT HERE ***'. Pass --force if you really " -"want to send.\n" -msgstr "" - -#: git-send-email.perl:1058 -msgid "To whom should the emails be sent (if anyone)?" -msgstr "" - -#: git-send-email.perl:1076 -#, perl-format -msgid "fatal: alias '%s' expands to itself\n" -msgstr "" - -#: git-send-email.perl:1088 -msgid "Message-ID to be used as In-Reply-To for the first email (if any)? " -msgstr "" - -#: git-send-email.perl:1150 git-send-email.perl:1158 -#, perl-format -msgid "error: unable to extract a valid address from: %s\n" -msgstr "" - -#. TRANSLATORS: Make sure to include [q] [d] [e] in your -#. translation. The program will only accept English input -#. at this point. -#: git-send-email.perl:1162 -msgid "What to do with this address? ([q]uit|[d]rop|[e]dit): " -msgstr "" - -#: git-send-email.perl:1482 -#, perl-format -msgid "CA path \"%s\" does not exist" -msgstr "" - -#: git-send-email.perl:1565 -msgid "" -" The Cc list above has been expanded by additional\n" -" addresses found in the patch commit message. By default\n" -" send-email prompts before sending whenever this occurs.\n" -" This behavior is controlled by the sendemail.confirm\n" -" configuration setting.\n" -"\n" -" For additional information, run 'git send-email --help'.\n" -" To retain the current behavior, but squelch this message,\n" -" run 'git config --global sendemail.confirm auto'.\n" -"\n" -msgstr "" - -#. TRANSLATORS: Make sure to include [y] [n] [e] [q] [a] in your -#. translation. The program will only accept English input -#. at this point. -#: git-send-email.perl:1580 -msgid "Send this email? ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " -msgstr "" - -#: git-send-email.perl:1583 -msgid "Send this email reply required" -msgstr "" - -#: git-send-email.perl:1617 -msgid "The required SMTP server is not properly defined." -msgstr "" - -#: git-send-email.perl:1664 -#, perl-format -msgid "Server does not support STARTTLS! %s" -msgstr "" - -#: git-send-email.perl:1669 git-send-email.perl:1673 -#, perl-format -msgid "STARTTLS failed! %s" -msgstr "" - -#: git-send-email.perl:1682 -msgid "Unable to initialize SMTP properly. Check config and use --smtp-debug." -msgstr "" - -#: git-send-email.perl:1700 -#, perl-format -msgid "Failed to send %s\n" -msgstr "" - -#: git-send-email.perl:1703 -#, perl-format -msgid "Dry-Sent %s\n" -msgstr "" - -#: git-send-email.perl:1703 -#, perl-format -msgid "Sent %s\n" -msgstr "" - -#: git-send-email.perl:1705 -msgid "Dry-OK. Log says:\n" -msgstr "" - -#: git-send-email.perl:1705 -msgid "OK. Log says:\n" -msgstr "" - -#: git-send-email.perl:1724 -msgid "Result: " -msgstr "" - -#: git-send-email.perl:1727 -msgid "Result: OK\n" -msgstr "" - -#: git-send-email.perl:1744 -#, perl-format -msgid "can't open file %s" -msgstr "" - -#: git-send-email.perl:1792 git-send-email.perl:1812 -#, perl-format -msgid "(mbox) Adding cc: %s from line '%s'\n" -msgstr "" - -#: git-send-email.perl:1798 -#, perl-format -msgid "(mbox) Adding to: %s from line '%s'\n" -msgstr "" - -#: git-send-email.perl:1855 -#, perl-format -msgid "(non-mbox) Adding cc: %s from line '%s'\n" -msgstr "" - -#: git-send-email.perl:1890 -#, perl-format -msgid "(body) Adding cc: %s from line '%s'\n" -msgstr "" - -#: git-send-email.perl:2009 -#, perl-format -msgid "(%s) Could not execute '%s'" -msgstr "" - -#: git-send-email.perl:2016 -#, perl-format -msgid "(%s) Adding %s: %s from: '%s'\n" -msgstr "" - -#: git-send-email.perl:2020 -#, perl-format -msgid "(%s) failed to close pipe to '%s'" -msgstr "" - -#: git-send-email.perl:2050 -msgid "cannot send message as 7bit" -msgstr "" - -#: git-send-email.perl:2058 -msgid "invalid transfer encoding" -msgstr "" - -#: git-send-email.perl:2100 -#, perl-format -msgid "" -"fatal: %s: rejected by %s hook\n" -"%s\n" -"warning: no patches were sent\n" -msgstr "" - -#: git-send-email.perl:2110 git-send-email.perl:2163 git-send-email.perl:2173 -#, perl-format -msgid "unable to open %s: %s\n" -msgstr "" - -#: git-send-email.perl:2113 -#, perl-format -msgid "" -"fatal: %s:%d is longer than 998 characters\n" -"warning: no patches were sent\n" -msgstr "" - -#: git-send-email.perl:2131 -#, perl-format -msgid "Skipping %s with backup suffix '%s'.\n" -msgstr "" - -#. TRANSLATORS: please keep "[y|N]" as is. -#: git-send-email.perl:2135 -#, perl-format -msgid "Do you really want to send %s? [y|N]: " -msgstr "" diff --git a/promisor-remote.c b/promisor-remote.c index 8d6695681c..5b33f88bca 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -22,7 +22,7 @@ static int fetch_objects(struct repository *repo, child.git_cmd = 1; child.in = -1; if (repo != the_repository) - prepare_other_repo_env(&child.env_array, repo->gitdir); + prepare_other_repo_env(&child.env, repo->gitdir); strvec_pushl(&child.args, "-c", "fetch.negotiationAlgorithm=noop", "fetch", remote_name, "--no-tags", "--no-write-fetch-head", "--recurse-submodules=no", diff --git a/range-diff.c b/range-diff.c index b72eb9fdbe..f63b3ffc20 100644 --- a/range-diff.c +++ b/range-diff.c @@ -44,7 +44,7 @@ static int read_patches(const char *range, struct string_list *list, strvec_pushl(&cp.args, "log", "--no-color", "-p", "--no-merges", "--reverse", "--date-order", "--decorate=no", - "--no-prefix", + "--no-prefix", "--submodule=short", /* * Choose indicators that are not used anywhere * else in diffs, but still look reasonable @@ -596,6 +596,6 @@ int is_range_diff_range(const char *arg) } free(copy); - object_array_clear(&revs.pending); + release_revisions(&revs); return negative > 0 && positive > 0; } diff --git a/reachable.c b/reachable.c index b9f4ad886e..aba63ebeb3 100644 --- a/reachable.c +++ b/reachable.c @@ -13,6 +13,7 @@ #include "worktree.h" #include "object-store.h" #include "pack-bitmap.h" +#include "pack-mtimes.h" struct connectivity_progress { struct progress *progress; @@ -60,9 +61,13 @@ static void mark_commit(struct commit *c, void *data) struct recent_data { struct rev_info *revs; timestamp_t timestamp; + report_recent_object_fn *cb; + int ignore_in_core_kept_packs; }; static void add_recent_object(const struct object_id *oid, + struct packed_git *pack, + off_t offset, timestamp_t mtime, struct recent_data *data) { @@ -103,13 +108,29 @@ static void add_recent_object(const struct object_id *oid, die("unable to lookup %s", oid_to_hex(oid)); add_pending_object(data->revs, obj, ""); + if (data->cb) + data->cb(obj, pack, offset, mtime); +} + +static int want_recent_object(struct recent_data *data, + const struct object_id *oid) +{ + if (data->ignore_in_core_kept_packs && + has_object_kept_pack(oid, IN_CORE_KEEP_PACKS)) + return 0; + return 1; } static int add_recent_loose(const struct object_id *oid, const char *path, void *data) { struct stat st; - struct object *obj = lookup_object(the_repository, oid); + struct object *obj; + + if (!want_recent_object(data, oid)) + return 0; + + obj = lookup_object(the_repository, oid); if (obj && obj->flags & SEEN) return 0; @@ -126,7 +147,7 @@ static int add_recent_loose(const struct object_id *oid, return error_errno("unable to stat %s", oid_to_hex(oid)); } - add_recent_object(oid, st.st_mtime, data); + add_recent_object(oid, NULL, 0, st.st_mtime, data); return 0; } @@ -134,29 +155,49 @@ static int add_recent_packed(const struct object_id *oid, struct packed_git *p, uint32_t pos, void *data) { - struct object *obj = lookup_object(the_repository, oid); + struct object *obj; + timestamp_t mtime = p->mtime; + + if (!want_recent_object(data, oid)) + return 0; + + obj = lookup_object(the_repository, oid); if (obj && obj->flags & SEEN) return 0; - add_recent_object(oid, p->mtime, data); + if (p->is_cruft) { + if (load_pack_mtimes(p) < 0) + die(_("could not load cruft pack .mtimes")); + mtime = nth_packed_mtime(p, pos); + } + add_recent_object(oid, p, nth_packed_object_offset(p, pos), mtime, data); return 0; } int add_unseen_recent_objects_to_traversal(struct rev_info *revs, - timestamp_t timestamp) + timestamp_t timestamp, + report_recent_object_fn *cb, + int ignore_in_core_kept_packs) { struct recent_data data; + enum for_each_object_flags flags; int r; data.revs = revs; data.timestamp = timestamp; + data.cb = cb; + data.ignore_in_core_kept_packs = ignore_in_core_kept_packs; r = for_each_loose_object(add_recent_loose, &data, FOR_EACH_OBJECT_LOCAL_ONLY); if (r) return r; - return for_each_packed_object(add_recent_packed, &data, - FOR_EACH_OBJECT_LOCAL_ONLY); + + flags = FOR_EACH_OBJECT_LOCAL_ONLY | FOR_EACH_OBJECT_PACK_ORDER; + if (ignore_in_core_kept_packs) + flags |= FOR_EACH_OBJECT_SKIP_IN_CORE_KEPT_PACKS; + + return for_each_packed_object(add_recent_packed, &data, flags); } static int mark_object_seen(const struct object_id *oid, @@ -217,7 +258,8 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog, if (mark_recent) { revs->ignore_missing_links = 1; - if (add_unseen_recent_objects_to_traversal(revs, mark_recent)) + if (add_unseen_recent_objects_to_traversal(revs, mark_recent, + NULL, 0)) die("unable to mark recent objects"); if (prepare_revision_walk(revs)) die("revision walk setup failed"); diff --git a/reachable.h b/reachable.h index 5df932ad8f..020a887b99 100644 --- a/reachable.h +++ b/reachable.h @@ -3,9 +3,16 @@ struct progress; struct rev_info; +struct object; +struct packed_git; + +typedef void report_recent_object_fn(const struct object *, struct packed_git *, + off_t, time_t); int add_unseen_recent_objects_to_traversal(struct rev_info *revs, - timestamp_t timestamp); + timestamp_t timestamp, + report_recent_object_fn cb, + int ignore_in_core_kept_packs); void mark_reachable_objects(struct rev_info *revs, int mark_reflog, timestamp_t mark_recent, struct progress *); diff --git a/read-cache.c b/read-cache.c index 60355f5ad6..96ce489c7c 100644 --- a/read-cache.c +++ b/read-cache.c @@ -112,7 +112,7 @@ static const char *alternate_index_output; static void set_index_entry(struct index_state *istate, int nr, struct cache_entry *ce) { if (S_ISSPARSEDIR(ce->ce_mode)) - istate->sparse_index = 1; + istate->sparse_index = INDEX_COLLAPSED; istate->cache[nr] = ce; add_name_hash(istate, ce); @@ -1856,7 +1856,7 @@ static int read_index_extension(struct index_state *istate, break; case CACHE_EXT_SPARSE_DIRECTORIES: /* no content, only an indicator */ - istate->sparse_index = 1; + istate->sparse_index = INDEX_COLLAPSED; break; default: if (*ext < 'A' || 'Z' < *ext) @@ -3165,7 +3165,7 @@ static int do_write_locked_index(struct index_state *istate, struct lock_file *l unsigned flags) { int ret; - int was_full = !istate->sparse_index; + int was_full = istate->sparse_index == INDEX_EXPANDED; ret = convert_to_sparse(istate, 0); diff --git a/ref-filter.c b/ref-filter.c index 2413f889f4..d3c90e5dbe 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -2392,6 +2392,7 @@ static void reach_filter(struct ref_array *array, clear_commit_marks(merge_commit, ALL_REV_FLAGS); } + release_revisions(&revs); free(to_clear); } diff --git a/reflog-walk.c b/reflog-walk.c index 8ac4b284b6..7aa6595a51 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -8,7 +8,7 @@ struct complete_reflogs { char *ref; - const char *short_ref; + char *short_ref; struct reflog_info { struct object_id ooid, noid; char *email; @@ -51,9 +51,16 @@ static void free_complete_reflog(struct complete_reflogs *array) } free(array->items); free(array->ref); + free(array->short_ref); free(array); } +static void complete_reflogs_clear(void *util, const char *str) +{ + struct complete_reflogs *array = util; + free_complete_reflog(array); +} + static struct complete_reflogs *read_complete_reflog(const char *ref) { struct complete_reflogs *reflogs = @@ -116,6 +123,21 @@ void init_reflog_walk(struct reflog_walk_info **info) (*info)->complete_reflogs.strdup_strings = 1; } +void reflog_walk_info_release(struct reflog_walk_info *info) +{ + size_t i; + + if (!info) + return; + + for (i = 0; i < info->nr; i++) + free(info->logs[i]); + string_list_clear_func(&info->complete_reflogs, + complete_reflogs_clear); + free(info->logs); + free(info); +} + int add_reflog_for_walk(struct reflog_walk_info *info, struct commit *commit, const char *name) { diff --git a/reflog-walk.h b/reflog-walk.h index e9e00ffd47..8076f10d9f 100644 --- a/reflog-walk.h +++ b/reflog-walk.h @@ -8,6 +8,7 @@ struct reflog_walk_info; struct date_mode; void init_reflog_walk(struct reflog_walk_info **info); +void reflog_walk_info_release(struct reflog_walk_info *info); int add_reflog_for_walk(struct reflog_walk_info *info, struct commit *commit, const char *name); void show_reflog_message(struct reflog_walk_info *info, int, @@ -14,6 +14,7 @@ #include "strvec.h" #include "commit-reach.h" #include "advice.h" +#include "connect.h" enum map_direction { FROM_SRC, FROM_DST }; @@ -195,9 +196,6 @@ static struct branch *find_branch(struct remote_state *remote_state, struct branches_hash_key lookup; struct hashmap_entry lookup_entry, *e; - if (!len) - len = strlen(name); - lookup.str = name; lookup.len = len; hashmap_entry_init(&lookup_entry, memhash(name, len)); @@ -214,7 +212,8 @@ static void die_on_missing_branch(struct repository *repo, { /* branch == NULL is always valid because it represents detached HEAD. */ if (branch && - branch != find_branch(repo->remote_state, branch->name, 0)) + branch != find_branch(repo->remote_state, branch->name, + strlen(branch->name))) die("branch %s was not found in the repository", branch->name); } @@ -354,8 +353,12 @@ static int handle_config(const char *key, const char *value, void *cb) struct remote_state *remote_state = cb; if (parse_config_key(key, "branch", &name, &namelen, &subkey) >= 0) { + /* There is no subsection. */ if (!name) return 0; + /* There is a subsection, but it is empty. */ + if (!namelen) + return -1; branch = make_branch(remote_state, name, namelen); if (!strcmp(subkey, "remote")) { return git_config_string(&branch->remote_name, key, value); @@ -2174,6 +2177,7 @@ static int stat_branch_pair(const char *branch_name, const char *base, clear_commit_marks(theirs, ALL_REV_FLAGS); strvec_clear(&argv); + release_revisions(&revs); return 1; } @@ -2729,3 +2733,101 @@ void remote_state_clear(struct remote_state *remote_state) hashmap_clear_and_free(&remote_state->remotes_hash, struct remote, ent); hashmap_clear_and_free(&remote_state->branches_hash, struct remote, ent); } + +/* + * Returns 1 if it was the last chop before ':'. + */ +static int chop_last_dir(char **remoteurl, int is_relative) +{ + char *rfind = find_last_dir_sep(*remoteurl); + if (rfind) { + *rfind = '\0'; + return 0; + } + + rfind = strrchr(*remoteurl, ':'); + if (rfind) { + *rfind = '\0'; + return 1; + } + + if (is_relative || !strcmp(".", *remoteurl)) + die(_("cannot strip one component off url '%s'"), + *remoteurl); + + free(*remoteurl); + *remoteurl = xstrdup("."); + return 0; +} + +char *relative_url(const char *remote_url, const char *url, + const char *up_path) +{ + int is_relative = 0; + int colonsep = 0; + char *out; + char *remoteurl; + struct strbuf sb = STRBUF_INIT; + size_t len; + + if (!url_is_local_not_ssh(url) || is_absolute_path(url)) + return xstrdup(url); + + len = strlen(remote_url); + if (!len) + BUG("invalid empty remote_url"); + + remoteurl = xstrdup(remote_url); + if (is_dir_sep(remoteurl[len-1])) + remoteurl[len-1] = '\0'; + + if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl)) + is_relative = 0; + else { + is_relative = 1; + /* + * Prepend a './' to ensure all relative + * remoteurls start with './' or '../' + */ + if (!starts_with_dot_slash_native(remoteurl) && + !starts_with_dot_dot_slash_native(remoteurl)) { + strbuf_reset(&sb); + strbuf_addf(&sb, "./%s", remoteurl); + free(remoteurl); + remoteurl = strbuf_detach(&sb, NULL); + } + } + /* + * When the url starts with '../', remove that and the + * last directory in remoteurl. + */ + while (url) { + if (starts_with_dot_dot_slash_native(url)) { + url += 3; + colonsep |= chop_last_dir(&remoteurl, is_relative); + } else if (starts_with_dot_slash_native(url)) + url += 2; + else + break; + } + strbuf_reset(&sb); + strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url); + if (ends_with(url, "/")) + strbuf_setlen(&sb, sb.len - 1); + free(remoteurl); + + if (starts_with_dot_slash_native(sb.buf)) + out = xstrdup(sb.buf + 2); + else + out = xstrdup(sb.buf); + + if (!up_path || !is_relative) { + strbuf_release(&sb); + return out; + } + + strbuf_reset(&sb); + strbuf_addf(&sb, "%s%s", up_path, out); + free(out); + return strbuf_detach(&sb, NULL); +} @@ -409,4 +409,36 @@ int parseopt_push_cas_option(const struct option *, const char *arg, int unset); int is_empty_cas(const struct push_cas_option *); void apply_push_cas(struct push_cas_option *, struct remote *, struct ref *); +/* + * The `url` argument is the URL that navigates to the submodule origin + * repo. When relative, this URL is relative to the superproject origin + * URL repo. The `up_path` argument, if specified, is the relative + * path that navigates from the submodule working tree to the superproject + * working tree. Returns the origin URL of the submodule. + * + * Return either an absolute URL or filesystem path (if the superproject + * origin URL is an absolute URL or filesystem path, respectively) or a + * relative file system path (if the superproject origin URL is a relative + * file system path). + * + * When the output is a relative file system path, the path is either + * relative to the submodule working tree, if up_path is specified, or to + * the superproject working tree otherwise. + * + * NEEDSWORK: This works incorrectly on the domain and protocol part. + * remote_url url outcome expectation + * http://a.com/b ../c http://a.com/c as is + * http://a.com/b/ ../c http://a.com/c same as previous line, but + * ignore trailing slash in url + * http://a.com/b ../../c http://c error out + * http://a.com/b ../../../c http:/c error out + * http://a.com/b ../../../../c http:c error out + * http://a.com/b ../../../../../c .:c error out + * http://a.com/b http://d.org/e http://d.org/e as is + * NEEDSWORK: Given how chop_last_dir() works, this function is broken + * when a local part has a colon in its path component, too. + */ +char *relative_url(const char *remote_url, const char *url, + const char *up_path); + #endif diff --git a/revision.c b/revision.c index 090a967bf4..211352795c 100644 --- a/revision.c +++ b/revision.c @@ -606,6 +606,10 @@ static struct commit *one_relevant_parent(const struct rev_info *revs, * * 2. We saw anything except REV_TREE_NEW. */ +#define REV_TREE_SAME 0 +#define REV_TREE_NEW 1 /* Only new files */ +#define REV_TREE_OLD 2 /* Only files removed */ +#define REV_TREE_DIFFERENT 3 /* Mixed changes */ static int tree_difference = REV_TREE_SAME; static void file_add_remove(struct diff_options *options, @@ -1459,10 +1463,9 @@ static int limit_list(struct rev_info *revs) if (revs->left_only || revs->right_only) limit_left_right(newlist, revs); - if (bottom) { + if (bottom) limit_to_ancestry(bottom, newlist); - free_commit_list(bottom); - } + free_commit_list(bottom); /* * Check if any commits have become TREESAME by some of their parents @@ -2930,6 +2933,42 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s return left; } +static void release_revisions_cmdline(struct rev_cmdline_info *cmdline) +{ + unsigned int i; + + for (i = 0; i < cmdline->nr; i++) + free((char *)cmdline->rev[i].name); + free(cmdline->rev); +} + +static void release_revisions_mailmap(struct string_list *mailmap) +{ + if (!mailmap) + return; + clear_mailmap(mailmap); + free(mailmap); +} + +static void release_revisions_topo_walk_info(struct topo_walk_info *info); + +void release_revisions(struct rev_info *revs) +{ + free_commit_list(revs->commits); + object_array_clear(&revs->pending); + object_array_clear(&revs->boundary_commits); + release_revisions_cmdline(&revs->cmdline); + list_objects_filter_release(&revs->filter); + clear_pathspec(&revs->prune_data); + date_mode_release(&revs->date_mode); + release_revisions_mailmap(revs->mailmap); + free_grep_patterns(&revs->grep_filter); + /* TODO (need to handle "no_free"): diff_free(&revs->diffopt) */ + diff_free(&revs->pruning); + reflog_walk_info_release(revs->reflog_info); + release_revisions_topo_walk_info(revs->topo_walk_info); +} + static void add_child(struct rev_info *revs, struct commit *parent, struct commit *child) { struct commit_list *l = xcalloc(1, sizeof(*l)); @@ -3440,17 +3479,22 @@ static void compute_indegrees_to_depth(struct rev_info *revs, indegree_walk_step(revs); } -static void reset_topo_walk(struct rev_info *revs) +static void release_revisions_topo_walk_info(struct topo_walk_info *info) { - struct topo_walk_info *info = revs->topo_walk_info; - + if (!info) + return; clear_prio_queue(&info->explore_queue); clear_prio_queue(&info->indegree_queue); clear_prio_queue(&info->topo_queue); clear_indegree_slab(&info->indegree); clear_author_date_slab(&info->author_date); + free(info); +} - FREE_AND_NULL(revs->topo_walk_info); +static void reset_topo_walk(struct rev_info *revs) +{ + release_revisions_topo_walk_info(revs->topo_walk_info); + revs->topo_walk_info = NULL; } static void init_topo_walk(struct rev_info *revs) @@ -4090,10 +4134,8 @@ static void create_boundary_commit_list(struct rev_info *revs) * boundary commits anyway. (This is what the code has always * done.) */ - if (revs->commits) { - free_commit_list(revs->commits); - revs->commits = NULL; - } + free_commit_list(revs->commits); + revs->commits = NULL; /* * Put all of the actual boundary commits from revs->boundary_commits @@ -4230,10 +4272,8 @@ struct commit *get_revision(struct rev_info *revs) graph_update(revs->graph, c); if (!c) { free_saved_parents(revs); - if (revs->previous_parents) { - free_commit_list(revs->previous_parents); - revs->previous_parents = NULL; - } + free_commit_list(revs->previous_parents); + revs->previous_parents = NULL; } return c; } diff --git a/revision.h b/revision.h index e80c148b19..e576845cdd 100644 --- a/revision.h +++ b/revision.h @@ -330,31 +330,24 @@ struct rev_info { struct tmp_objdir *remerge_objdir; }; -int ref_excluded(struct string_list *, const char *path); -void clear_ref_exclusion(struct string_list **); -void add_ref_exclusion(struct string_list **, const char *exclude); - - -#define REV_TREE_SAME 0 -#define REV_TREE_NEW 1 /* Only new files */ -#define REV_TREE_OLD 2 /* Only files removed */ -#define REV_TREE_DIFFERENT 3 /* Mixed changes */ - -/* revision.c */ -typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *); -extern volatile show_early_output_fn_t show_early_output; - -struct setup_revision_opt { - const char *def; - void (*tweak)(struct rev_info *, struct setup_revision_opt *); - unsigned int assume_dashdash:1, - allow_exclude_promisor_objects:1; - unsigned revarg_opt; -}; - -#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS -#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix) -#endif +/** + * Initialize the "struct rev_info" structure with a macro. + * + * This will not fully initialize a "struct rev_info", the + * repo_init_revisions() function needs to be called before + * setup_revisions() and any revision walking takes place. + * + * Use REV_INFO_INIT to make the "struct rev_info" safe for passing to + * release_revisions() when it's inconvenient (e.g. due to a "goto + * cleanup" pattern) to arrange for repo_init_revisions() to be called + * before release_revisions() is called. + * + * Initializing with this REV_INFO_INIT is redundant to invoking + * repo_init_revisions(). If repo_init_revisions() is guaranteed to be + * called before release_revisions() the "struct rev_info" can be left + * uninitialized. + */ +#define REV_INFO_INIT { 0 } /** * Initialize a rev_info structure with default values. The third parameter may @@ -367,6 +360,9 @@ struct setup_revision_opt { void repo_init_revisions(struct repository *r, struct rev_info *revs, const char *prefix); +#ifndef NO_THE_REPOSITORY_COMPATIBILITY_MACROS +#define init_revisions(revs, prefix) repo_init_revisions(the_repository, revs, prefix) +#endif /** * Parse revision information, filling in the `rev_info` structure, and @@ -375,9 +371,22 @@ void repo_init_revisions(struct repository *r, * head of the argument list. The last parameter is used in case no * parameter given by the first two arguments. */ +struct setup_revision_opt { + const char *def; + void (*tweak)(struct rev_info *, struct setup_revision_opt *); + unsigned int assume_dashdash:1, + allow_exclude_promisor_objects:1; + unsigned revarg_opt; +}; int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct setup_revision_opt *); +/** + * Free data allocated in a "struct rev_info" after it's been + * initialized with repo_init_revisions() or REV_INFO_INIT. + */ +void release_revisions(struct rev_info *revs); + void parse_revision_opt(struct rev_info *revs, struct parse_opt_ctx_t *ctx, const struct option *options, const char * const usagestr[]); @@ -419,6 +428,14 @@ void mark_trees_uninteresting_sparse(struct repository *r, struct oidset *trees) void show_object_with_name(FILE *, struct object *, const char *); /** + * Helpers to check if a "struct string_list" item matches with + * wildmatch(). + */ +int ref_excluded(struct string_list *, const char *path); +void clear_ref_exclusion(struct string_list **); +void add_ref_exclusion(struct string_list **, const char *exclude); + +/** * This function can be used if you want to add commit objects as revision * information. You can use the `UNINTERESTING` object flag to indicate if * you want to include or exclude the given commit (and commits reachable @@ -473,4 +490,10 @@ int rewrite_parents(struct rev_info *revs, */ struct commit_list *get_saved_parents(struct rev_info *revs, const struct commit *commit); +/** + * Global for the (undocumented) "--early-output" flag for "git log". + */ +typedef void (*show_early_output_fn_t)(struct rev_info *, struct commit_list *); +extern volatile show_early_output_fn_t show_early_output; + #endif diff --git a/run-command.c b/run-command.c index a8501e38ce..8e36b8ee74 100644 --- a/run-command.c +++ b/run-command.c @@ -20,7 +20,7 @@ void child_process_init(struct child_process *child) void child_process_clear(struct child_process *child) { strvec_clear(&child->args); - strvec_clear(&child->env_array); + strvec_clear(&child->env); } struct child_to_clean { @@ -646,7 +646,7 @@ static void trace_run_command(const struct child_process *cp) sq_quote_buf_pretty(&buf, cp->dir); strbuf_addch(&buf, ';'); } - trace_add_env(&buf, cp->env_array.v); + trace_add_env(&buf, cp->env.v); if (cp->git_cmd) strbuf_addstr(&buf, " git"); sq_quote_argv_pretty(&buf, cp->args.v); @@ -751,7 +751,7 @@ fail_pipe: set_cloexec(null_fd); } - childenv = prep_childenv(cmd->env_array.v); + childenv = prep_childenv(cmd->env.v); atfork_prepare(&as); /* @@ -914,8 +914,9 @@ end_of_spawn: else if (cmd->use_shell) cmd->args.v = prepare_shell_cmd(&nargv, sargv); - cmd->pid = mingw_spawnvpe(cmd->args.v[0], cmd->args.v, (char**) cmd->env_array.v, - cmd->dir, fhin, fhout, fherr); + cmd->pid = mingw_spawnvpe(cmd->args.v[0], cmd->args.v, + (char**) cmd->env.v, + cmd->dir, fhin, fhout, fherr); failed_errno = errno; if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) error_errno("cannot spawn %s", cmd->args.v[0]); @@ -1031,7 +1032,7 @@ int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir, cmd.close_object_store = opt & RUN_CLOSE_OBJECT_STORE ? 1 : 0; cmd.dir = dir; if (env) - strvec_pushv(&cmd.env_array, (const char **)env); + strvec_pushv(&cmd.env, (const char **)env); cmd.trace2_child_class = tr2_class; return run_command(&cmd); } @@ -1471,6 +1472,7 @@ enum child_state { GIT_CP_WAIT_CLEANUP, }; +int run_processes_parallel_ungroup; struct parallel_processes { void *data; @@ -1494,6 +1496,7 @@ struct parallel_processes { struct pollfd *pfd; unsigned shutdown : 1; + unsigned ungroup : 1; int output_owner; struct strbuf buffered_output; /* of finished children */ @@ -1537,7 +1540,7 @@ static void pp_init(struct parallel_processes *pp, get_next_task_fn get_next_task, start_failure_fn start_failure, task_finished_fn task_finished, - void *data) + void *data, int ungroup) { int i; @@ -1559,15 +1562,21 @@ static void pp_init(struct parallel_processes *pp, pp->nr_processes = 0; pp->output_owner = 0; pp->shutdown = 0; + pp->ungroup = ungroup; CALLOC_ARRAY(pp->children, n); - CALLOC_ARRAY(pp->pfd, n); + if (pp->ungroup) + pp->pfd = NULL; + else + CALLOC_ARRAY(pp->pfd, n); strbuf_init(&pp->buffered_output, 0); for (i = 0; i < n; i++) { strbuf_init(&pp->children[i].err, 0); child_process_init(&pp->children[i].process); - pp->pfd[i].events = POLLIN | POLLHUP; - pp->pfd[i].fd = -1; + if (pp->pfd) { + pp->pfd[i].events = POLLIN | POLLHUP; + pp->pfd[i].fd = -1; + } } pp_for_signal = pp; @@ -1615,24 +1624,31 @@ static int pp_start_one(struct parallel_processes *pp) BUG("bookkeeping is hard"); code = pp->get_next_task(&pp->children[i].process, - &pp->children[i].err, + pp->ungroup ? NULL : &pp->children[i].err, pp->data, &pp->children[i].data); if (!code) { - strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); - strbuf_reset(&pp->children[i].err); + if (!pp->ungroup) { + strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); + strbuf_reset(&pp->children[i].err); + } return 1; } - pp->children[i].process.err = -1; - pp->children[i].process.stdout_to_stderr = 1; + if (!pp->ungroup) { + pp->children[i].process.err = -1; + pp->children[i].process.stdout_to_stderr = 1; + } pp->children[i].process.no_stdin = 1; if (start_command(&pp->children[i].process)) { - code = pp->start_failure(&pp->children[i].err, + code = pp->start_failure(pp->ungroup ? NULL : + &pp->children[i].err, pp->data, pp->children[i].data); - strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); - strbuf_reset(&pp->children[i].err); + if (!pp->ungroup) { + strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); + strbuf_reset(&pp->children[i].err); + } if (code) pp->shutdown = 1; return code; @@ -1640,7 +1656,8 @@ static int pp_start_one(struct parallel_processes *pp) pp->nr_processes++; pp->children[i].state = GIT_CP_WORKING; - pp->pfd[i].fd = pp->children[i].process.err; + if (pp->pfd) + pp->pfd[i].fd = pp->children[i].process.err; return 0; } @@ -1674,6 +1691,7 @@ static void pp_buffer_stderr(struct parallel_processes *pp, int output_timeout) static void pp_output(struct parallel_processes *pp) { int i = pp->output_owner; + if (pp->children[i].state == GIT_CP_WORKING && pp->children[i].err.len) { strbuf_write(&pp->children[i].err, stderr); @@ -1696,7 +1714,7 @@ static int pp_collect_finished(struct parallel_processes *pp) code = finish_command(&pp->children[i].process); - code = pp->task_finished(code, + code = pp->task_finished(code, pp->ungroup ? NULL : &pp->children[i].err, pp->data, pp->children[i].data); @@ -1707,10 +1725,13 @@ static int pp_collect_finished(struct parallel_processes *pp) pp->nr_processes--; pp->children[i].state = GIT_CP_FREE; - pp->pfd[i].fd = -1; + if (pp->pfd) + pp->pfd[i].fd = -1; child_process_init(&pp->children[i].process); - if (i != pp->output_owner) { + if (pp->ungroup) { + ; /* no strbuf_*() work to do here */ + } else if (i != pp->output_owner) { strbuf_addbuf(&pp->buffered_output, &pp->children[i].err); strbuf_reset(&pp->children[i].err); } else { @@ -1747,9 +1768,14 @@ int run_processes_parallel(int n, int i, code; int output_timeout = 100; int spawn_cap = 4; + int ungroup = run_processes_parallel_ungroup; struct parallel_processes pp; - pp_init(&pp, n, get_next_task, start_failure, task_finished, pp_cb); + /* unset for the next API user */ + run_processes_parallel_ungroup = 0; + + pp_init(&pp, n, get_next_task, start_failure, task_finished, pp_cb, + ungroup); while (1) { for (i = 0; i < spawn_cap && !pp.shutdown && @@ -1766,8 +1792,15 @@ int run_processes_parallel(int n, } if (!pp.nr_processes) break; - pp_buffer_stderr(&pp, output_timeout); - pp_output(&pp); + if (ungroup) { + int i; + + for (i = 0; i < pp.max_processes; i++) + pp.children[i].state = GIT_CP_WAIT_CLEANUP; + } else { + pp_buffer_stderr(&pp, output_timeout); + pp_output(&pp); + } code = pp_collect_finished(&pp); if (code) { pp.shutdown = 1; @@ -1815,16 +1848,16 @@ int run_auto_maintenance(int quiet) return run_command(&maint); } -void prepare_other_repo_env(struct strvec *env_array, const char *new_git_dir) +void prepare_other_repo_env(struct strvec *env, const char *new_git_dir) { const char * const *var; for (var = local_repo_env; *var; var++) { if (strcmp(*var, CONFIG_DATA_ENVIRONMENT) && strcmp(*var, CONFIG_COUNT_ENVIRONMENT)) - strvec_push(env_array, *var); + strvec_push(env, *var); } - strvec_pushf(env_array, "%s=%s", GIT_DIR_ENVIRONMENT, new_git_dir); + strvec_pushf(env, "%s=%s", GIT_DIR_ENVIRONMENT, new_git_dir); } enum start_bg_result start_bg_command(struct child_process *cmd, diff --git a/run-command.h b/run-command.h index 5bd0c933e8..0e85e5846a 100644 --- a/run-command.h +++ b/run-command.h @@ -58,7 +58,7 @@ struct child_process { struct strvec args; /** - * Like .args the .env_array is a `struct strvec'. + * Like .args the .env is a `struct strvec'. * * To modify the environment of the sub-process, specify an array of * environment settings. Each string in the array manipulates the @@ -70,10 +70,10 @@ struct child_process { * - If the string does not contain '=', it names an environment * variable that will be removed from the child process's environment. * - * The memory in .env_array will be cleaned up automatically during + * The memory in .env will be cleaned up automatically during * `finish_command` (or during `start_command` when it is unsuccessful). */ - struct strvec env_array; + struct strvec env; pid_t pid; int trace2_child_id; @@ -146,7 +146,7 @@ struct child_process { #define CHILD_PROCESS_INIT { \ .args = STRVEC_INIT, \ - .env_array = STRVEC_INIT, \ + .env = STRVEC_INIT, \ } /** @@ -405,6 +405,9 @@ void check_pipe(int err); * pp_cb is the callback cookie as passed to run_processes_parallel. * You can store a child process specific callback cookie in pp_task_cb. * + * See run_processes_parallel() below for a discussion of the "struct + * strbuf *out" parameter. + * * Even after returning 0 to indicate that there are no more processes, * this function will be called again until there are no more running * child processes. @@ -423,9 +426,8 @@ typedef int (*get_next_task_fn)(struct child_process *cp, * This callback is called whenever there are problems starting * a new process. * - * You must not write to stdout or stderr in this function. Add your - * message to the strbuf out instead, which will be printed without - * messing up the output of the other parallel processes. + * See run_processes_parallel() below for a discussion of the "struct + * strbuf *out" parameter. * * pp_cb is the callback cookie as passed into run_processes_parallel, * pp_task_cb is the callback cookie as passed into get_next_task_fn. @@ -441,9 +443,8 @@ typedef int (*start_failure_fn)(struct strbuf *out, /** * This callback is called on every child process that finished processing. * - * You must not write to stdout or stderr in this function. Add your - * message to the strbuf out instead, which will be printed without - * messing up the output of the other parallel processes. + * See run_processes_parallel() below for a discussion of the "struct + * strbuf *out" parameter. * * pp_cb is the callback cookie as passed into run_processes_parallel, * pp_task_cb is the callback cookie as passed into get_next_task_fn. @@ -464,11 +465,26 @@ typedef int (*task_finished_fn)(int result, * * The children started via this function run in parallel. Their output * (both stdout and stderr) is routed to stderr in a manner that output - * from different tasks does not interleave. + * from different tasks does not interleave (but see "ungroup" below). * * start_failure_fn and task_finished_fn can be NULL to omit any * special handling. + * + * If the "ungroup" option isn't specified, the API will set the + * "stdout_to_stderr" parameter in "struct child_process" and provide + * the callbacks with a "struct strbuf *out" parameter to write output + * to. In this case the callbacks must not write to stdout or + * stderr as such output will mess up the output of the other parallel + * processes. If "ungroup" option is specified callbacks will get a + * NULL "struct strbuf *out" parameter, and are responsible for + * emitting their own output, including dealing with any race + * conditions due to writing in parallel to stdout and stderr. + * The "ungroup" option can be enabled by setting the global + * "run_processes_parallel_ungroup" to "1" before invoking + * run_processes_parallel(), it will be set back to "0" as soon as the + * API reads that setting. */ +extern int run_processes_parallel_ungroup; int run_processes_parallel(int n, get_next_task_fn, start_failure_fn, @@ -479,14 +495,14 @@ int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn, const char *tr2_category, const char *tr2_label); /** - * Convenience function which prepares env_array for a command to be run in a - * new repo. This adds all GIT_* environment variables to env_array with the + * Convenience function which prepares env for a command to be run in a + * new repo. This adds all GIT_* environment variables to env with the * exception of GIT_CONFIG_PARAMETERS and GIT_CONFIG_COUNT (which cause the * corresponding environment variables to be unset in the subprocess) and adds * an environment variable pointing to new_git_dir. See local_repo_env in * cache.h for more information. */ -void prepare_other_repo_env(struct strvec *env_array, const char *new_git_dir); +void prepare_other_repo_env(struct strvec *env, const char *new_git_dir); /** * Possible return values for start_bg_command(). diff --git a/sequencer.c b/sequencer.c index 8c3ed3532a..950733af2a 100644 --- a/sequencer.c +++ b/sequencer.c @@ -919,7 +919,7 @@ static char *get_author(const char *message) return NULL; } -static const char *author_date_from_env_array(const struct strvec *env) +static const char *author_date_from_env(const struct strvec *env) { int i; const char *date; @@ -1000,7 +1000,7 @@ static int run_git_commit(const char *defmsg, if (is_rebase_i(opts) && ((opts->committer_date_is_author_date && !opts->ignore_date) || !(!defmsg && (flags & AMEND_MSG))) && - read_env_script(&cmd.env_array)) { + read_env_script(&cmd.env)) { const char *gpg_opt = gpg_sign_opt_quoted(opts); return error(_(staged_changes_advice), @@ -1008,12 +1008,12 @@ static int run_git_commit(const char *defmsg, } if (opts->committer_date_is_author_date) - strvec_pushf(&cmd.env_array, "GIT_COMMITTER_DATE=%s", + strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s", opts->ignore_date ? "" : - author_date_from_env_array(&cmd.env_array)); + author_date_from_env(&cmd.env)); if (opts->ignore_date) - strvec_push(&cmd.env_array, "GIT_AUTHOR_DATE="); + strvec_push(&cmd.env, "GIT_AUTHOR_DATE="); strvec_push(&cmd.args, "commit"); @@ -1346,6 +1346,7 @@ void print_commit_summary(struct repository *r, log_tree_commit(&rev, commit); } + release_revisions(&rev); strbuf_release(&format); } @@ -3414,6 +3415,7 @@ static int make_patch(struct repository *r, unuse_commit_buffer(commit, commit_buffer); } strbuf_release(&buf); + release_revisions(&log_tree_opt); return res; } @@ -3911,7 +3913,7 @@ static int do_merge(struct repository *r, /* Octopus merge */ struct child_process cmd = CHILD_PROCESS_INIT; - if (read_env_script(&cmd.env_array)) { + if (read_env_script(&cmd.env)) { const char *gpg_opt = gpg_sign_opt_quoted(opts); ret = error(_(staged_changes_advice), gpg_opt, gpg_opt); @@ -3919,12 +3921,12 @@ static int do_merge(struct repository *r, } if (opts->committer_date_is_author_date) - strvec_pushf(&cmd.env_array, "GIT_COMMITTER_DATE=%s", + strvec_pushf(&cmd.env, "GIT_COMMITTER_DATE=%s", opts->ignore_date ? "" : - author_date_from_env_array(&cmd.env_array)); + author_date_from_env(&cmd.env)); if (opts->ignore_date) - strvec_push(&cmd.env_array, "GIT_AUTHOR_DATE="); + strvec_push(&cmd.env, "GIT_AUTHOR_DATE="); cmd.git_cmd = 1; strvec_push(&cmd.args, "merge"); @@ -4524,6 +4526,7 @@ cleanup_head_ref: &log_tree_opt.diffopt); log_tree_diff_flush(&log_tree_opt); } + release_revisions(&log_tree_opt); } flush_rewritten_pending(); if (!stat(rebase_path_rewritten_list(), &st) && @@ -5350,6 +5353,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, int rebase_merges = flags & TODO_LIST_REBASE_MERGES; int reapply_cherry_picks = flags & TODO_LIST_REAPPLY_CHERRY_PICKS; int skipped_commit = 0; + int ret = 0; repo_init_revisions(r, &revs, NULL); revs.verbose_header = 1; @@ -5373,14 +5377,20 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, pp.fmt = revs.commit_format; pp.output_encoding = get_log_output_encoding(); - if (setup_revisions(argc, argv, &revs, NULL) > 1) - return error(_("make_script: unhandled options")); + if (setup_revisions(argc, argv, &revs, NULL) > 1) { + ret = error(_("make_script: unhandled options")); + goto cleanup; + } - if (prepare_revision_walk(&revs) < 0) - return error(_("make_script: error preparing revisions")); + if (prepare_revision_walk(&revs) < 0) { + ret = error(_("make_script: error preparing revisions")); + goto cleanup; + } - if (rebase_merges) - return make_script_with_merges(&pp, &revs, out, flags); + if (rebase_merges) { + ret = make_script_with_merges(&pp, &revs, out, flags); + goto cleanup; + } while ((commit = get_revision(&revs))) { int is_empty = is_original_commit_empty(commit); @@ -5404,7 +5414,9 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, if (skipped_commit) advise_if_enabled(ADVICE_SKIPPED_CHERRY_PICKS, _("use --reapply-cherry-picks to include skipped commits")); - return 0; +cleanup: + release_revisions(&revs); + return ret; } /* @@ -459,7 +459,16 @@ static void setup_original_cwd(void) */ /* Normalize the directory */ - strbuf_realpath(&tmp, tmp_original_cwd, 1); + if (!strbuf_realpath(&tmp, tmp_original_cwd, 0)) { + trace2_data_string("setup", the_repository, + "realpath-path", tmp_original_cwd); + trace2_data_string("setup", the_repository, + "realpath-failure", strerror(errno)); + free((char*)tmp_original_cwd); + tmp_original_cwd = NULL; + return; + } + free((char*)tmp_original_cwd); tmp_original_cwd = NULL; startup_info->original_cwd = strbuf_detach(&tmp, NULL); @@ -269,6 +269,7 @@ struct commit_list *get_shallow_commits_by_rev_list(int ac, const char **av, if ((o->flags & both_flags) == both_flags) o->flags &= ~not_shallow_flag; } + release_revisions(&revs); return result; } diff --git a/shared.mak b/shared.mak index 50d4596f0d..4330192e9c 100644 --- a/shared.mak +++ b/shared.mak @@ -62,7 +62,9 @@ ifndef V QUIET_BUILT_IN = @echo ' ' BUILTIN $@; QUIET_LNCP = @echo ' ' LN/CP $@; QUIET_XGETTEXT = @echo ' ' XGETTEXT $@; + QUIET_MSGINIT = @echo ' ' MSGINIT $@; QUIET_MSGFMT = @echo ' ' MSGFMT $@; + QUIET_MSGMERGE = @echo ' ' MSGMERGE $@; QUIET_GCOV = @echo ' ' GCOV $@; QUIET_SP = @echo ' ' SP $<; QUIET_HDR = @echo ' ' HDR $(<:hcc=h); diff --git a/sparse-index.c b/sparse-index.c index ffbab7d35f..e4a54ce194 100644 --- a/sparse-index.c +++ b/sparse-index.c @@ -9,6 +9,11 @@ #include "dir.h" #include "fsmonitor.h" +struct modify_index_context { + struct index_state *write; + struct pattern_list *pl; +}; + static struct cache_entry *construct_sparse_dir_entry( struct index_state *istate, const char *sparse_dir, @@ -173,7 +178,7 @@ int convert_to_sparse(struct index_state *istate, int flags) * If the index is already sparse, empty, or otherwise * cannot be converted to sparse, do not convert. */ - if (istate->sparse_index || !istate->cache_nr || + if (istate->sparse_index == INDEX_COLLAPSED || !istate->cache_nr || !is_sparse_index_allowed(istate, flags)) return 0; @@ -214,7 +219,7 @@ int convert_to_sparse(struct index_state *istate, int flags) FREE_AND_NULL(istate->fsmonitor_dirty); FREE_AND_NULL(istate->fsmonitor_last_update); - istate->sparse_index = 1; + istate->sparse_index = INDEX_COLLAPSED; trace2_region_leave("index", "convert_to_sparse", istate->repo); return 0; } @@ -231,56 +236,148 @@ static int add_path_to_index(const struct object_id *oid, struct strbuf *base, const char *path, unsigned int mode, void *context) { - struct index_state *istate = (struct index_state *)context; + struct modify_index_context *ctx = (struct modify_index_context *)context; struct cache_entry *ce; size_t len = base->len; - if (S_ISDIR(mode)) - return READ_TREE_RECURSIVE; + if (S_ISDIR(mode)) { + int dtype; + size_t baselen = base->len; + if (!ctx->pl) + return READ_TREE_RECURSIVE; + + /* + * Have we expanded to a point outside of the sparse-checkout? + * + * Artificially pad the path name with a slash "/" to + * indicate it as a directory, and add an arbitrary file + * name ("-") so we can consider base->buf as a file name + * to match against the cone-mode patterns. + * + * If we compared just "path", then we would expand more + * than we should. Since every file at root is always + * included, we would expand every directory at root at + * least one level deep instead of using sparse directory + * entries. + */ + strbuf_addstr(base, path); + strbuf_add(base, "/-", 2); + + if (path_matches_pattern_list(base->buf, base->len, + NULL, &dtype, + ctx->pl, ctx->write)) { + strbuf_setlen(base, baselen); + return READ_TREE_RECURSIVE; + } - strbuf_addstr(base, path); + /* + * The path "{base}{path}/" is a sparse directory. Create the correct + * name for inserting the entry into the index. + */ + strbuf_setlen(base, base->len - 1); + } else { + strbuf_addstr(base, path); + } - ce = make_cache_entry(istate, mode, oid, base->buf, 0, 0); + ce = make_cache_entry(ctx->write, mode, oid, base->buf, 0, 0); ce->ce_flags |= CE_SKIP_WORKTREE | CE_EXTENDED; - set_index_entry(istate, istate->cache_nr++, ce); + set_index_entry(ctx->write, ctx->write->cache_nr++, ce); strbuf_setlen(base, len); return 0; } -void ensure_full_index(struct index_state *istate) +void expand_index(struct index_state *istate, struct pattern_list *pl) { int i; struct index_state *full; struct strbuf base = STRBUF_INIT; + const char *tr_region; + struct modify_index_context ctx; - if (!istate || !istate->sparse_index) + /* + * If the index is already full, then keep it full. We will convert + * it to a sparse index on write, if possible. + */ + if (!istate || istate->sparse_index == INDEX_EXPANDED) return; + /* + * If our index is sparse, but our new pattern set does not use + * cone mode patterns, then we need to expand the index before we + * continue. A NULL pattern set indicates a full expansion to a + * full index. + */ + if (pl && !pl->use_cone_patterns) { + pl = NULL; + } else { + /* + * We might contract file entries into sparse-directory + * entries, and for that we will need the cache tree to + * be recomputed. + */ + cache_tree_free(&istate->cache_tree); + + /* + * If there is a problem creating the cache tree, then we + * need to expand to a full index since we cannot satisfy + * the current request as a sparse index. + */ + if (cache_tree_update(istate, 0)) + pl = NULL; + } + if (!istate->repo) istate->repo = the_repository; - trace2_region_enter("index", "ensure_full_index", istate->repo); + /* + * A NULL pattern set indicates we are expanding a full index, so + * we use a special region name that indicates the full expansion. + * This is used by test cases, but also helps to differentiate the + * two cases. + */ + tr_region = pl ? "expand_index" : "ensure_full_index"; + trace2_region_enter("index", tr_region, istate->repo); /* initialize basics of new index */ full = xcalloc(1, sizeof(struct index_state)); memcpy(full, istate, sizeof(struct index_state)); + /* + * This slightly-misnamed 'full' index might still be sparse if we + * are only modifying the list of sparse directories. This hinges + * on whether we have a non-NULL pattern list. + */ + full->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED; + /* then change the necessary things */ - full->sparse_index = 0; full->cache_alloc = (3 * istate->cache_alloc) / 2; full->cache_nr = 0; ALLOC_ARRAY(full->cache, full->cache_alloc); + ctx.write = full; + ctx.pl = pl; + for (i = 0; i < istate->cache_nr; i++) { struct cache_entry *ce = istate->cache[i]; struct tree *tree; struct pathspec ps; + int dtype; if (!S_ISSPARSEDIR(ce->ce_mode)) { set_index_entry(full, full->cache_nr++, ce); continue; } + + /* We now have a sparse directory entry. Should we expand? */ + if (pl && + path_matches_pattern_list(ce->name, ce->ce_namelen, + NULL, &dtype, + pl, istate) == NOT_MATCHED) { + set_index_entry(full, full->cache_nr++, ce); + continue; + } + if (!(ce->ce_flags & CE_SKIP_WORKTREE)) warning(_("index entry is a directory, but not sparse (%08x)"), ce->ce_flags); @@ -297,7 +394,7 @@ void ensure_full_index(struct index_state *istate) strbuf_add(&base, ce->name, strlen(ce->name)); read_tree_at(istate->repo, tree, &base, &ps, - add_path_to_index, full); + add_path_to_index, &ctx); /* free directory entries. full entries are re-used */ discard_cache_entry(ce); @@ -306,7 +403,7 @@ void ensure_full_index(struct index_state *istate) /* Copy back into original index. */ memcpy(&istate->name_hash, &full->name_hash, sizeof(full->name_hash)); memcpy(&istate->dir_hash, &full->dir_hash, sizeof(full->dir_hash)); - istate->sparse_index = 0; + istate->sparse_index = pl ? INDEX_PARTIALLY_SPARSE : INDEX_EXPANDED; free(istate->cache); istate->cache = full->cache; istate->cache_nr = full->cache_nr; @@ -322,7 +419,12 @@ void ensure_full_index(struct index_state *istate) cache_tree_free(&istate->cache_tree); cache_tree_update(istate, 0); - trace2_region_leave("index", "ensure_full_index", istate->repo); + trace2_region_leave("index", tr_region, istate->repo); +} + +void ensure_full_index(struct index_state *istate) +{ + expand_index(istate, NULL); } void ensure_correct_sparsity(struct index_state *istate) diff --git a/sparse-index.h b/sparse-index.h index f57c65d972..59a92d819e 100644 --- a/sparse-index.h +++ b/sparse-index.h @@ -24,4 +24,17 @@ void expand_to_path(struct index_state *istate, struct repository; int set_sparse_index_config(struct repository *repo, int enable); +struct pattern_list; + +/** + * Scan the given index and compare its entries to the given pattern list. + * If the index is sparse and the pattern list uses cone mode patterns, + * then modify the index to contain the all of the file entries within that + * new pattern list. This expands sparse directories only as far as needed. + * + * If the pattern list is NULL or does not use cone mode patterns, then the + * index is expanded to a full index. + */ +void expand_index(struct index_state *istate, struct pattern_list *pl); + #endif diff --git a/submodule-config.c b/submodule-config.c index 29668b0620..ce3beaf5d4 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -204,17 +204,17 @@ int check_submodule_name(const char *name) return -1; /* - * Look for '..' as a path component. Check both '/' and '\\' as + * Look for '..' as a path component. Check is_xplatform_dir_sep() as * separators rather than is_dir_sep(), because we want the name rules * to be consistent across platforms. */ goto in_component; /* always start inside component */ while (*name) { char c = *name++; - if (c == '/' || c == '\\') { + if (is_xplatform_dir_sep(c)) { in_component: if (name[0] == '.' && name[1] == '.' && - (!name[2] || name[2] == '/' || name[2] == '\\')) + (!name[2] || is_xplatform_dir_sep(name[2]))) return -1; } } diff --git a/submodule.c b/submodule.c index 86c8f0f89d..4e299f578f 100644 --- a/submodule.c +++ b/submodule.c @@ -619,7 +619,7 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path, struct object_id *one, struct object_id *two, unsigned dirty_submodule) { - struct rev_info rev; + struct rev_info rev = REV_INFO_INIT; struct commit *left = NULL, *right = NULL; struct commit_list *merge_bases = NULL; struct repository *sub; @@ -645,8 +645,8 @@ void show_submodule_diff_summary(struct diff_options *o, const char *path, print_submodule_diff_summary(sub, &rev, o); out: - if (merge_bases) - free_commit_list(merge_bases); + free_commit_list(merge_bases); + release_revisions(&rev); clear_commit_marks(left, ~0); clear_commit_marks(right, ~0); if (sub) { @@ -711,15 +711,15 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, if (!(dirty_submodule & DIRTY_SUBMODULE_MODIFIED)) strvec_push(&cp.args, oid_to_hex(new_oid)); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); if (!is_directory(path)) { /* fall back to absorbed git dir, if any */ if (!sub) goto done; cp.dir = sub->gitdir; - strvec_push(&cp.env_array, GIT_DIR_ENVIRONMENT "=."); - strvec_push(&cp.env_array, GIT_WORK_TREE_ENVIRONMENT "=."); + strvec_push(&cp.env, GIT_DIR_ENVIRONMENT "=."); + strvec_push(&cp.env, GIT_WORK_TREE_ENVIRONMENT "=."); } if (start_command(&cp)) { @@ -735,8 +735,7 @@ void show_submodule_inline_diff(struct diff_options *o, const char *path, done: strbuf_release(&sb); - if (merge_bases) - free_commit_list(merge_bases); + free_commit_list(merge_bases); if (left) clear_commit_marks(left, ~0); if (right) @@ -925,9 +924,11 @@ static void collect_changed_submodules(struct repository *r, diff_rev.diffopt.format_callback_data = &data; diff_rev.dense_combined_merges = 1; diff_tree_combined_merge(commit, &diff_rev); + release_revisions(&diff_rev); } reset_revision_walk(); + release_revisions(&rev); } static void free_submodules_data(struct string_list *submodules) @@ -1019,7 +1020,7 @@ static int submodule_has_commits(struct repository *r, oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); strvec_pushl(&cp.args, "--not", "--all", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -1060,7 +1061,7 @@ static int submodule_needs_pushing(struct repository *r, oid_array_for_each_unique(commits, append_oid_to_argv, &cp.args); strvec_pushl(&cp.args, "--not", "--remotes", "-n", "1" , NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -1146,7 +1147,7 @@ static int push_submodule(const char *path, strvec_push(&cp.args, rs->raw[i]); } - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -1177,7 +1178,7 @@ static void submodule_push_check(const char *path, const char *head, for (i = 0; i < rs->raw_nr; i++) strvec_push(&cp.args, rs->raw[i]); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stdout = 1; @@ -1678,7 +1679,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, child_process_init(cp); cp->dir = task->repo->gitdir; - prepare_submodule_repo_env_in_gitdir(&cp->env_array); + prepare_submodule_repo_env_in_gitdir(&cp->env); cp->git_cmd = 1; strvec_init(&cp->args); if (task->git_args.nr) @@ -1708,7 +1709,7 @@ static int get_next_submodule(struct child_process *cp, struct strbuf *err, spf->prefix, task->sub->path); child_process_init(cp); - prepare_submodule_repo_env_in_gitdir(&cp->env_array); + prepare_submodule_repo_env_in_gitdir(&cp->env); cp->git_cmd = 1; cp->dir = task->repo->gitdir; @@ -1882,7 +1883,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) if (ignore_untracked) strvec_push(&cp.args, "-uno"); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -1954,7 +1955,7 @@ int submodule_uses_gitfile(const char *path) "submodule", "foreach", "--quiet", "--recursive", "test -f .git", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stderr = 1; @@ -1997,7 +1998,7 @@ int bad_to_remove_submodule(const char *path, unsigned flags) if (!(flags & SUBMODULE_REMOVAL_IGNORE_IGNORED_UNTRACKED)) strvec_push(&cp.args, "--ignored"); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -2052,7 +2053,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; strvec_pushl(&cp.args, "diff-index", "--quiet", @@ -2069,7 +2070,7 @@ static int submodule_has_dirty_index(const struct submodule *sub) static void submodule_reset_index(const char *path) { struct child_process cp = CHILD_PROCESS_INIT; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; @@ -2153,7 +2154,7 @@ int submodule_move_head(const char *path, } } - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); cp.git_cmd = 1; cp.no_stdin = 1; @@ -2191,7 +2192,7 @@ int submodule_move_head(const char *path, cp.no_stdin = 1; cp.dir = path; - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); strvec_pushl(&cp.args, "update-ref", "HEAD", "--no-deref", new_head, NULL); @@ -2374,7 +2375,7 @@ void absorb_git_dir_into_superproject(const char *path, strvec_pushl(&cp.args, "--super-prefix", sb.buf, "submodule--helper", "absorb-git-dirs", NULL); - prepare_submodule_repo_env(&cp.env_array); + prepare_submodule_repo_env(&cp.env); if (run_command(&cp)) die(_("could not recurse into submodule '%s'"), path); @@ -2407,8 +2408,8 @@ int get_superproject_working_tree(struct strbuf *buf) subpath = relative_path(cwd, one_up.buf, &sb); strbuf_release(&one_up); - prepare_submodule_repo_env(&cp.env_array); - strvec_pop(&cp.env_array); + prepare_submodule_repo_env(&cp.env); + strvec_pop(&cp.env); strvec_pushl(&cp.args, "--literal-pathspecs", "-C", "..", "ls-files", "-z", "--stage", "--full-name", "--", diff --git a/submodule.h b/submodule.h index 437bc96e05..bfaa9da186 100644 --- a/submodule.h +++ b/submodule.h @@ -158,11 +158,11 @@ int submodule_move_head(const char *path, void submodule_unset_core_worktree(const struct submodule *sub); /* - * Prepare the "env_array" parameter of a "struct child_process" for executing + * Prepare the "env" parameter of a "struct child_process" for executing * a submodule by clearing any repo-specific environment variables, but * retaining any config in the environment. */ -void prepare_submodule_repo_env(struct strvec *out); +void prepare_submodule_repo_env(struct strvec *env); #define ABSORB_GITDIR_RECURSE_SUBMODULES (1<<0) void absorb_git_dir_into_superproject(const char *path, diff --git a/t/helper/test-fast-rebase.c b/t/helper/test-fast-rebase.c index fc2d460904..4e5553e202 100644 --- a/t/helper/test-fast-rebase.c +++ b/t/helper/test-fast-rebase.c @@ -99,6 +99,7 @@ int cmd__fast_rebase(int argc, const char **argv) struct merge_result result; struct strbuf reflog_msg = STRBUF_INIT; struct strbuf branch_name = STRBUF_INIT; + int ret = 0; /* * test-tool stuff doesn't set up the git directory by default; need to @@ -137,13 +138,17 @@ int cmd__fast_rebase(int argc, const char **argv) revs.topo_order = 1; strvec_pushl(&rev_walk_args, "", argv[4], "--not", argv[3], NULL); - if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) - return error(_("unhandled options")); + if (setup_revisions(rev_walk_args.nr, rev_walk_args.v, &revs, NULL) > 1) { + ret = error(_("unhandled options")); + goto cleanup; + } strvec_clear(&rev_walk_args); - if (prepare_revision_walk(&revs) < 0) - return error(_("error preparing revisions")); + if (prepare_revision_walk(&revs) < 0) { + ret = error(_("error preparing revisions")); + goto cleanup; + } init_merge_options(&merge_opt, the_repository); memset(&result, 0, sizeof(result)); @@ -201,8 +206,6 @@ int cmd__fast_rebase(int argc, const char **argv) } if (create_symref("HEAD", branch_name.buf, reflog_msg.buf) < 0) die(_("unable to update HEAD")); - strbuf_release(&reflog_msg); - strbuf_release(&branch_name); prime_cache_tree(the_repository, the_repository->index, result.tree); @@ -221,5 +224,11 @@ int cmd__fast_rebase(int argc, const char **argv) if (write_locked_index(&the_index, &lock, COMMIT_LOCK | SKIP_IF_UNCHANGED)) die(_("unable to write %s"), get_index_file()); - return (result.clean == 0); + + ret = (result.clean == 0); +cleanup: + strbuf_release(&reflog_msg); + strbuf_release(&branch_name); + release_revisions(&revs); + return ret; } diff --git a/t/helper/test-fsmonitor-client.c b/t/helper/test-fsmonitor-client.c index 3062c8a3c2..54a4856c48 100644 --- a/t/helper/test-fsmonitor-client.c +++ b/t/helper/test-fsmonitor-client.c @@ -7,6 +7,8 @@ #include "cache.h" #include "parse-options.h" #include "fsmonitor-ipc.h" +#include "thread-utils.h" +#include "trace2.h" #ifndef HAVE_FSMONITOR_DAEMON_BACKEND int cmd__fsmonitor_client(int argc, const char **argv) @@ -79,20 +81,121 @@ static int do_send_flush(void) return 0; } +struct hammer_thread_data +{ + pthread_t pthread_id; + int thread_nr; + + int nr_requests; + const char *token; + + int sum_successful; + int sum_errors; +}; + +static void *hammer_thread_proc(void *_hammer_thread_data) +{ + struct hammer_thread_data *data = _hammer_thread_data; + struct strbuf answer = STRBUF_INIT; + int k; + int ret; + + trace2_thread_start("hammer"); + + for (k = 0; k < data->nr_requests; k++) { + strbuf_reset(&answer); + + ret = fsmonitor_ipc__send_query(data->token, &answer); + if (ret < 0) + data->sum_errors++; + else + data->sum_successful++; + } + + strbuf_release(&answer); + trace2_thread_exit(); + return NULL; +} + +/* + * Start a pool of client threads that will each send a series of + * commands to the daemon. + * + * The goal is to overload the daemon with a sustained series of + * concurrent requests. + */ +static int do_hammer(const char *token, int nr_threads, int nr_requests) +{ + struct hammer_thread_data *data = NULL; + int k; + int sum_join_errors = 0; + int sum_commands = 0; + int sum_errors = 0; + + if (!token || !*token) + token = get_token_from_index(); + if (nr_threads < 1) + nr_threads = 1; + if (nr_requests < 1) + nr_requests = 1; + + CALLOC_ARRAY(data, nr_threads); + + for (k = 0; k < nr_threads; k++) { + struct hammer_thread_data *p = &data[k]; + p->thread_nr = k; + p->nr_requests = nr_requests; + p->token = token; + + if (pthread_create(&p->pthread_id, NULL, hammer_thread_proc, p)) { + warning("failed to create thread[%d] skipping remainder", k); + nr_threads = k; + break; + } + } + + for (k = 0; k < nr_threads; k++) { + struct hammer_thread_data *p = &data[k]; + + if (pthread_join(p->pthread_id, NULL)) + sum_join_errors++; + sum_commands += p->sum_successful; + sum_errors += p->sum_errors; + } + + fprintf(stderr, "HAMMER: [threads %d][requests %d] [ok %d][err %d][join %d]\n", + nr_threads, nr_requests, sum_commands, sum_errors, sum_join_errors); + + free(data); + + /* + * Return an error if any of the _send_query requests failed. + * We don't care about thread create/join errors. + */ + return sum_errors > 0; +} + int cmd__fsmonitor_client(int argc, const char **argv) { const char *subcmd; const char *token = NULL; + int nr_threads = 1; + int nr_requests = 1; const char * const fsmonitor_client_usage[] = { "test-tool fsmonitor-client query [<token>]", "test-tool fsmonitor-client flush", + "test-tool fsmonitor-client hammer [<token>] [<threads>] [<requests>]", NULL, }; struct option options[] = { OPT_STRING(0, "token", &token, "token", "command token to send to the server"), + + OPT_INTEGER(0, "threads", &nr_threads, "number of client threads"), + OPT_INTEGER(0, "requests", &nr_requests, "number of requests per thread"), + OPT_END() }; @@ -111,6 +214,9 @@ int cmd__fsmonitor_client(int argc, const char **argv) if (!strcmp(subcmd, "flush")) return !!do_send_flush(); + if (!strcmp(subcmd, "hammer")) + return !!do_hammer(token, nr_threads, nr_requests); + die("Unhandled subcommand: '%s'", subcmd); } #endif diff --git a/t/helper/test-hexdump.c b/t/helper/test-hexdump.c new file mode 100644 index 0000000000..811e89c1bc --- /dev/null +++ b/t/helper/test-hexdump.c @@ -0,0 +1,30 @@ +#include "test-tool.h" +#include "git-compat-util.h" + +/* + * Read stdin and print a hexdump to stdout. + */ +int cmd__hexdump(int argc, const char **argv) +{ + char buf[1024]; + ssize_t i, len; + int have_data = 0; + + for (;;) { + len = xread(0, buf, sizeof(buf)); + if (len < 0) + die_errno("failure reading stdin"); + if (!len) + break; + + have_data = 1; + + for (i = 0; i < len; i++) + printf("%02x ", (unsigned char)buf[i]); + } + + if (have_data) + putchar('\n'); + + return 0; +} diff --git a/t/helper/test-pack-mtimes.c b/t/helper/test-pack-mtimes.c new file mode 100644 index 0000000000..f7b79daf4c --- /dev/null +++ b/t/helper/test-pack-mtimes.c @@ -0,0 +1,56 @@ +#include "git-compat-util.h" +#include "test-tool.h" +#include "strbuf.h" +#include "object-store.h" +#include "packfile.h" +#include "pack-mtimes.h" + +static void dump_mtimes(struct packed_git *p) +{ + uint32_t i; + if (load_pack_mtimes(p) < 0) + die("could not load pack .mtimes"); + + for (i = 0; i < p->num_objects; i++) { + struct object_id oid; + if (nth_packed_object_id(&oid, p, i) < 0) + die("could not load object id at position %"PRIu32, i); + + printf("%s %"PRIu32"\n", + oid_to_hex(&oid), nth_packed_mtime(p, i)); + } +} + +static const char *pack_mtimes_usage = "\n" +" test-tool pack-mtimes <pack-name.mtimes>"; + +int cmd__pack_mtimes(int argc, const char **argv) +{ + struct strbuf buf = STRBUF_INIT; + struct packed_git *p; + + setup_git_directory(); + + if (argc != 2) + usage(pack_mtimes_usage); + + for (p = get_all_packs(the_repository); p; p = p->next) { + strbuf_addstr(&buf, basename(p->pack_name)); + strbuf_strip_suffix(&buf, ".pack"); + strbuf_addstr(&buf, ".mtimes"); + + if (!strcmp(buf.buf, argv[1])) + break; + + strbuf_reset(&buf); + } + + strbuf_release(&buf); + + if (!p) + die("could not find pack '%s'", argv[1]); + + dump_mtimes(p); + + return 0; +} diff --git a/t/helper/test-revision-walking.c b/t/helper/test-revision-walking.c index 625b2dbf82..4a45d5bac2 100644 --- a/t/helper/test-revision-walking.c +++ b/t/helper/test-revision-walking.c @@ -43,6 +43,7 @@ static int run_revision_walk(void) } reset_revision_walk(); + release_revisions(&rev); return got_revision; } diff --git a/t/helper/test-run-command.c b/t/helper/test-run-command.c index f3b90aa834..c9283b47af 100644 --- a/t/helper/test-run-command.c +++ b/t/helper/test-run-command.c @@ -31,7 +31,11 @@ static int parallel_next(struct child_process *cp, return 0; strvec_pushv(&cp->args, d->args.v); - strbuf_addstr(err, "preloaded output of a child\n"); + if (err) + strbuf_addstr(err, "preloaded output of a child\n"); + else + fprintf(stderr, "preloaded output of a child\n"); + number_callbacks++; return 1; } @@ -41,7 +45,10 @@ static int no_job(struct child_process *cp, void *cb, void **task_cb) { - strbuf_addstr(err, "no further jobs available\n"); + if (err) + strbuf_addstr(err, "no further jobs available\n"); + else + fprintf(stderr, "no further jobs available\n"); return 0; } @@ -50,7 +57,10 @@ static int task_finished(int result, void *pp_cb, void *pp_task_cb) { - strbuf_addstr(err, "asking for a quick stop\n"); + if (err) + strbuf_addstr(err, "asking for a quick stop\n"); + else + fprintf(stderr, "asking for a quick stop\n"); return 1; } @@ -390,7 +400,7 @@ int cmd__run_command(int argc, const char **argv) while (!strcmp(argv[1], "env")) { if (!argv[2]) die("env specifier without a value"); - strvec_push(&proc.env_array, argv[2]); + strvec_push(&proc.env, argv[2]); argv += 2; argc -= 2; } @@ -407,6 +417,12 @@ int cmd__run_command(int argc, const char **argv) if (!strcmp(argv[1], "run-command")) exit(run_command(&proc)); + if (!strcmp(argv[1], "--ungroup")) { + argv += 1; + argc -= 1; + run_processes_parallel_ungroup = 1; + } + jobs = atoi(argv[2]); strvec_clear(&proc.args); strvec_pushv(&proc.args, (const char **)argv + 3); diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 0424f7adf5..318fdbab0c 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -38,6 +38,7 @@ static struct test_cmd cmds[] = { { "getcwd", cmd__getcwd }, { "hashmap", cmd__hashmap }, { "hash-speed", cmd__hash_speed }, + { "hexdump", cmd__hexdump }, { "index-version", cmd__index_version }, { "json-writer", cmd__json_writer }, { "lazy-init-name-hash", cmd__lazy_init_name_hash }, @@ -48,6 +49,7 @@ static struct test_cmd cmds[] = { { "oidmap", cmd__oidmap }, { "oidtree", cmd__oidtree }, { "online-cpus", cmd__online_cpus }, + { "pack-mtimes", cmd__pack_mtimes }, { "parse-options", cmd__parse_options }, { "parse-pathspec-file", cmd__parse_pathspec_file }, { "partial-clone", cmd__partial_clone }, diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index c876e8246f..bb79927163 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -29,6 +29,7 @@ int cmd__genzeros(int argc, const char **argv); int cmd__getcwd(int argc, const char **argv); int cmd__hashmap(int argc, const char **argv); int cmd__hash_speed(int argc, const char **argv); +int cmd__hexdump(int argc, const char **argv); int cmd__index_version(int argc, const char **argv); int cmd__json_writer(int argc, const char **argv); int cmd__lazy_init_name_hash(int argc, const char **argv); @@ -38,6 +39,7 @@ int cmd__mktemp(int argc, const char **argv); int cmd__oidmap(int argc, const char **argv); int cmd__oidtree(int argc, const char **argv); int cmd__online_cpus(int argc, const char **argv); +int cmd__pack_mtimes(int argc, const char **argv); int cmd__parse_options(int argc, const char **argv); int cmd__parse_pathspec_file(int argc, const char** argv); int cmd__partial_clone(int argc, const char **argv); diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c index 59b124bb5f..180c7f53f3 100644 --- a/t/helper/test-trace2.c +++ b/t/helper/test-trace2.c @@ -198,7 +198,7 @@ static int ut_006data(int argc, const char **argv) return 0; } -static int ut_007bug(int argc, const char **argv) +static int ut_007BUG(int argc, const char **argv) { /* * Exercise BUG() to ensure that the message is printed to trace2. @@ -206,6 +206,28 @@ static int ut_007bug(int argc, const char **argv) BUG("the bug message"); } +static int ut_008bug(int argc, const char **argv) +{ + bug("a bug message"); + bug("another bug message"); + BUG_if_bug("an explicit BUG_if_bug() following bug() call(s) is nice, but not required"); + return 0; +} + +static int ut_009bug_BUG(int argc, const char **argv) +{ + bug("a bug message"); + bug("another bug message"); + /* The BUG_if_bug(...) isn't here, but we'll spot bug() calls on exit()! */ + return 0; +} + +static int ut_010bug_BUG(int argc, const char **argv) +{ + bug("a bug message"); + BUG("a BUG message"); +} + /* * Usage: * test-tool trace2 <ut_name_1> <ut_usage_1> @@ -222,7 +244,10 @@ static struct unit_test ut_table[] = { { ut_004child, "004child", "[<child_command_line>]" }, { ut_005exec, "005exec", "<git_command_args>" }, { ut_006data, "006data", "[<category> <key> <value>]+" }, - { ut_007bug, "007bug", "" }, + { ut_007BUG, "007bug", "" }, + { ut_008bug, "008bug", "" }, + { ut_009bug_BUG, "009bug_BUG","" }, + { ut_010bug_BUG, "010bug_BUG","" }, }; /* clang-format on */ diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index 2fde2353fd..ea28971e8e 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,3 +1,7 @@ +if test -z "$TEST_FAILS_SANITIZE_LEAK" +then + TEST_PASSES_SANITIZE_LEAK=true +fi . ./test-lib.sh if test -n "$NO_SVN_TESTS" diff --git a/t/lib-t3100.sh b/t/lib-t3100.sh new file mode 100644 index 0000000000..eabb5fd803 --- /dev/null +++ b/t/lib-t3100.sh @@ -0,0 +1,10 @@ +#!/bin/sh + +setup_basic_ls_tree_data () { + mkdir dir && + test_commit dir/sub-file && + test_commit top-file && + git clone . submodule && + git submodule add ./submodule && + git commit -m"add submodule" +} diff --git a/t/lib-unicode-nfc-nfd.sh b/t/lib-unicode-nfc-nfd.sh new file mode 100755 index 0000000000..22232247ef --- /dev/null +++ b/t/lib-unicode-nfc-nfd.sh @@ -0,0 +1,162 @@ +# Help detect how Unicode NFC and NFD are handled on the filesystem. + +# A simple character that has a NFD form. +# +# NFC: U+00e9 LATIN SMALL LETTER E WITH ACUTE +# UTF8(NFC): \xc3 \xa9 +# +# NFD: U+0065 LATIN SMALL LETTER E +# U+0301 COMBINING ACUTE ACCENT +# UTF8(NFD): \x65 + \xcc \x81 +# +utf8_nfc=$(printf "\xc3\xa9") +utf8_nfd=$(printf "\x65\xcc\x81") + +# Is the OS or the filesystem "Unicode composition sensitive"? +# +# That is, does the OS or the filesystem allow files to exist with +# both the NFC and NFD spellings? Or, does the OS/FS lie to us and +# tell us that the NFC and NFD forms are equivalent. +# +# This is or may be independent of what type of filesystem we have, +# since it might be handled by the OS at a layer above the FS. +# Testing shows on MacOS using APFS, HFS+, and FAT32 reports a +# collision, for example. +# +# This does not tell us how the Unicode pathname will be spelled +# on disk, but rather only that the two spelling "collide". We +# will examine the actual on disk spelling in a later prereq. +# +test_lazy_prereq UNICODE_COMPOSITION_SENSITIVE ' + mkdir trial_${utf8_nfc} && + mkdir trial_${utf8_nfd} +' + +# Is the spelling of an NFC pathname preserved on disk? +# +# On MacOS with HFS+ and FAT32, NFC paths are converted into NFD +# and on APFS, NFC paths are preserved. As we have established +# above, this is independent of "composition sensitivity". +# +test_lazy_prereq UNICODE_NFC_PRESERVED ' + mkdir c_${utf8_nfc} && + ls | test-tool hexdump >dump && + grep "63 5f c3 a9" dump +' + +# Is the spelling of an NFD pathname preserved on disk? +# +test_lazy_prereq UNICODE_NFD_PRESERVED ' + mkdir d_${utf8_nfd} && + ls | test-tool hexdump >dump && + grep "64 5f 65 cc 81" dump +' + +# The following _DOUBLE_ forms are more for my curiosity, +# but there may be quirks lurking when there are multiple +# combining characters in non-canonical order. + +# Unicode also allows multiple combining characters +# that can be decomposed in pieces. +# +# NFC: U+1f67 GREEK SMALL LETTER OMEGA WITH DASIA AND PERISPOMENI +# UTF8(NFC): \xe1 \xbd \xa7 +# +# NFD1: U+1f61 GREEK SMALL LETTER OMEGA WITH DASIA +# U+0342 COMBINING GREEK PERISPOMENI +# UTF8(NFD1): \xe1 \xbd \xa1 + \xcd \x82 +# +# But U+1f61 decomposes into +# NFD2: U+03c9 GREEK SMALL LETTER OMEGA +# U+0314 COMBINING REVERSED COMMA ABOVE +# UTF8(NFD2): \xcf \x89 + \xcc \x94 +# +# Yielding: \xcf \x89 + \xcc \x94 + \xcd \x82 +# +# Note that I've used the canonical ordering of the +# combinining 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 +# terminal (implying that the on-disk format also has +# them out of order). +# +greek_nfc=$(printf "\xe1\xbd\xa7") +greek_nfd1=$(printf "\xe1\xbd\xa1\xcd\x82") +greek_nfd2=$(printf "\xcf\x89\xcc\x94\xcd\x82") + +# See if a double decomposition also collides. +# +test_lazy_prereq UNICODE_DOUBLE_COMPOSITION_SENSITIVE ' + mkdir trial_${greek_nfc} && + mkdir trial_${greek_nfd2} +' + +# See if the NFC spelling appears on the disk. +# +test_lazy_prereq UNICODE_DOUBLE_NFC_PRESERVED ' + mkdir c_${greek_nfc} && + ls | test-tool hexdump >dump && + grep "63 5f e1 bd a7" dump +' + +# See if the NFD spelling appears on the disk. +# +test_lazy_prereq UNICODE_DOUBLE_NFD_PRESERVED ' + mkdir d_${greek_nfd2} && + ls | test-tool hexdump >dump && + grep "64 5f cf 89 cc 94 cd 82" dump +' + +# The following is for debugging. I found it useful when +# trying to understand the various (OS, FS) quirks WRT +# Unicode and how composition/decomposition is handled. +# For example, when trying to understand how (macOS, APFS) +# and (macOS, HFS) and (macOS, FAT32) compare. +# +# It is rather noisy, so it is disabled by default. +# +if test "$unicode_debug" = "true" +then + if test_have_prereq UNICODE_COMPOSITION_SENSITIVE + then + echo NFC and NFD are distinct on this OS/filesystem. + else + echo NFC and NFD are aliases on this OS/filesystem. + fi + + if test_have_prereq UNICODE_NFC_PRESERVED + then + echo NFC maintains original spelling. + else + echo NFC is modified. + fi + + if test_have_prereq UNICODE_NFD_PRESERVED + then + echo NFD maintains original spelling. + else + echo NFD is modified. + fi + + if test_have_prereq UNICODE_DOUBLE_COMPOSITION_SENSITIVE + then + echo DOUBLE NFC and NFD are distinct on this OS/filesystem. + else + echo DOUBLE NFC and NFD are aliases on this OS/filesystem. + fi + + if test_have_prereq UNICODE_DOUBLE_NFC_PRESERVED + then + echo Double NFC maintains original spelling. + else + echo Double NFC is modified. + fi + + if test_have_prereq UNICODE_DOUBLE_NFD_PRESERVED + then + echo Double NFD maintains original spelling. + else + echo Double NFD is modified. + fi +fi diff --git a/t/lib-unique-files.sh b/t/lib-unique-files.sh new file mode 100644 index 0000000000..a14080fe79 --- /dev/null +++ b/t/lib-unique-files.sh @@ -0,0 +1,34 @@ +# Helper to create files with unique contents + +# Create multiple files with unique contents within this test run. Takes the +# number of directories, the number of files in each directory, and the base +# directory. +# +# test_create_unique_files 2 3 my_dir -- Creates 2 directories with 3 files +# each in my_dir, all with contents +# different from previous invocations +# of this command in this run. + +test_create_unique_files () { + test "$#" -ne 3 && BUG "3 param" + + local dirs="$1" && + local files="$2" && + local basedir="$3" && + local counter="0" && + local i && + local j && + test_tick && + local basedata="$basedir$test_tick" && + rm -rf "$basedir" && + for i in $(test_seq $dirs) + do + local dir="$basedir/dir$i" && + mkdir -p "$dir" && + for j in $(test_seq $files) + do + counter=$((counter + 1)) && + echo "$basedata.$counter">"$dir/file$j.txt" + done + done +} diff --git a/t/perf/p0008-odb-fsync.sh b/t/perf/p0008-odb-fsync.sh new file mode 100755 index 0000000000..b3a90f30eb --- /dev/null +++ b/t/perf/p0008-odb-fsync.sh @@ -0,0 +1,82 @@ +#!/bin/sh +# +# This test measures the performance of adding new files to the object +# database. The test was originally added to measure the effect of the +# core.fsyncMethod=batch mode, which is why we are testing different values of +# that setting explicitly and creating a lot of unique objects. + +test_description="Tests performance of adding things to the object database" + +. ./perf-lib.sh + +. $TEST_DIRECTORY/lib-unique-files.sh + +test_perf_fresh_repo +test_checkout_worktree + +dir_count=10 +files_per_dir=50 +total_files=$((dir_count * files_per_dir)) + +populate_files () { + test_create_unique_files $dir_count $files_per_dir files +} + +setup_repo () { + (rm -rf .git || 1) && + git init && + test_commit first && + populate_files +} + +test_perf_fsync_cfgs () { + local method && + local cfg && + for method in none fsync batch writeout-only + do + case $method in + none) + cfg="-c core.fsync=none" + ;; + *) + cfg="-c core.fsync=loose-object -c core.fsyncMethod=$method" + esac && + + # Set GIT_TEST_FSYNC=1 explicitly since fsync is normally + # disabled by t/test-lib.sh. + if ! test_perf "$1 (fsyncMethod=$method)" \ + --setup "$2" \ + "GIT_TEST_FSYNC=1 git $cfg $3" + then + break + fi + done +} + +test_perf_fsync_cfgs "add $total_files files" \ + "setup_repo" \ + "add -- files" + +test_perf_fsync_cfgs "stash $total_files files" \ + "setup_repo" \ + "stash push -u -- files" + +test_perf_fsync_cfgs "unpack $total_files files" \ + " + setup_repo && + git -c core.fsync=none add -- files && + git -c core.fsync=none commit -q -m second && + echo HEAD | git pack-objects -q --stdout --revs >test_pack.pack && + setup_repo + " \ + "unpack-objects -q <test_pack.pack" + +test_perf_fsync_cfgs "commit $total_files files" \ + " + setup_repo && + git -c core.fsync=none add -- files && + populate_files + " \ + "commit -q -a -m test" + +test_done diff --git a/t/perf/p2000-sparse-operations.sh b/t/perf/p2000-sparse-operations.sh index 76710cbef3..c181110a43 100755 --- a/t/perf/p2000-sparse-operations.sh +++ b/t/perf/p2000-sparse-operations.sh @@ -112,6 +112,7 @@ test_perf_on_all git add -A test_perf_on_all git add . test_perf_on_all git commit -a -m A test_perf_on_all git checkout -f - +test_perf_on_all "git sparse-checkout add f2/f3/f1 && git sparse-checkout set $SPARSE_CONE" test_perf_on_all git reset test_perf_on_all git reset --hard test_perf_on_all git reset -- does-not-exist diff --git a/t/perf/p4220-log-grep-engines.sh b/t/perf/p4220-log-grep-engines.sh index 2bc47ded4d..03fbfbb85d 100755 --- a/t/perf/p4220-log-grep-engines.sh +++ b/t/perf/p4220-log-grep-engines.sh @@ -36,7 +36,8 @@ do else prereq="" fi - test_perf $prereq "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" " + test_perf "$engine log$GIT_PERF_4220_LOG_OPTS --grep='$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4220_LOG_OPTS --grep='$pattern' >'out.$engine' || : " done diff --git a/t/perf/p4221-log-grep-engines-fixed.sh b/t/perf/p4221-log-grep-engines-fixed.sh index 060971265a..0a6d6dfc21 100755 --- a/t/perf/p4221-log-grep-engines-fixed.sh +++ b/t/perf/p4221-log-grep-engines-fixed.sh @@ -26,7 +26,8 @@ do else prereq="" fi - test_perf $prereq "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" " + test_perf "$engine log$GIT_PERF_4221_LOG_OPTS --grep='$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine log --pretty=format:%h$GIT_PERF_4221_LOG_OPTS --grep='$pattern' >'out.$engine' || : " done diff --git a/t/perf/p5302-pack-index.sh b/t/perf/p5302-pack-index.sh index c16f6a3ff6..14c601bbf8 100755 --- a/t/perf/p5302-pack-index.sh +++ b/t/perf/p5302-pack-index.sh @@ -26,9 +26,8 @@ test_expect_success 'set up thread-counting tests' ' done ' -test_perf PERF_EXTRA 'index-pack 0 threads' ' - rm -rf repo.git && - git init --bare repo.git && +test_perf 'index-pack 0 threads' --prereq PERF_EXTRA \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git git index-pack --threads=1 --stdin < $PACK ' @@ -36,17 +35,15 @@ for t in $threads do THREADS=$t export THREADS - test_perf PERF_EXTRA "index-pack $t threads" ' - rm -rf repo.git && - git init --bare repo.git && + test_perf "index-pack $t threads" --prereq PERF_EXTRA \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git GIT_FORCE_THREADS=1 \ git index-pack --threads=$THREADS --stdin <$PACK ' done -test_perf 'index-pack default number of threads' ' - rm -rf repo.git && - git init --bare repo.git && +test_perf 'index-pack default number of threads' \ + --setup 'rm -rf repo.git && git init --bare repo.git' ' GIT_DIR=repo.git git index-pack --stdin < $PACK ' diff --git a/t/perf/p7519-fsmonitor.sh b/t/perf/p7519-fsmonitor.sh index 0b9129ca7b..b1cb23880f 100755 --- a/t/perf/p7519-fsmonitor.sh +++ b/t/perf/p7519-fsmonitor.sh @@ -60,18 +60,6 @@ then esac fi -if test -n "$GIT_PERF_7519_DROP_CACHE" -then - # When using GIT_PERF_7519_DROP_CACHE, GIT_PERF_REPEAT_COUNT must be 1 to - # generate valid results. Otherwise the caching that happens for the nth - # run will negate the validity of the comparisons. - if test "$GIT_PERF_REPEAT_COUNT" -ne 1 - then - echo "warning: Setting GIT_PERF_REPEAT_COUNT=1" >&2 - GIT_PERF_REPEAT_COUNT=1 - fi -fi - trace_start () { if test -n "$GIT_PERF_7519_TRACE" then @@ -175,10 +163,10 @@ setup_for_fsmonitor_hook () { test_perf_w_drop_caches () { if test -n "$GIT_PERF_7519_DROP_CACHE"; then - test-tool drop-caches + test_perf "$1" --setup "test-tool drop-caches" "$2" + else + test_perf "$@" fi - - test_perf "$@" } test_fsmonitor_suite () { diff --git a/t/perf/p7527-builtin-fsmonitor.sh b/t/perf/p7527-builtin-fsmonitor.sh new file mode 100755 index 0000000000..9338b9ea00 --- /dev/null +++ b/t/perf/p7527-builtin-fsmonitor.sh @@ -0,0 +1,257 @@ +#!/bin/sh + +test_description="Perf test for the builtin FSMonitor" + +. ./perf-lib.sh + +if ! test_have_prereq FSMONITOR_DAEMON +then + skip_all="fsmonitor--daemon is not supported on this platform" + test_done +fi + +test_lazy_prereq UNTRACKED_CACHE ' + { git update-index --test-untracked-cache; ret=$?; } && + test $ret -ne 1 +' + +# Lie to perf-lib and ask for a new empty repo and avoid +# the complaints about GIT_PERF_REPO not being big enough +# the perf hit when GIT_PERF_LARGE_REPO is copied into +# the trash directory. +# +# NEEDSWORK: It would be nice if perf-lib had an option to +# "borrow" an existing large repo (especially for gigantic +# monorepos) and use it in-place. For now, fake it here. +# +test_perf_fresh_repo + + +# Use a generated synthetic monorepo. If it doesn't exist, we will +# generate it. If it does exist, we will put it in a known state +# before we start our timings. +# +PARAM_D=5 +PARAM_W=10 +PARAM_F=9 + +PARAMS="$PARAM_D"."$PARAM_W"."$PARAM_F" + +BALLAST_BR=p0006-ballast +export BALLAST_BR + +TMP_BR=tmp_br +export TMP_BR + +REPO=../repos/gen-many-files-"$PARAMS".git +export REPO + +if ! test -d $REPO +then + (cd ../repos; ./many-files.sh -d $PARAM_D -w $PARAM_W -f $PARAM_F) +fi + + +enable_uc () { + git -C $REPO config core.untrackedcache true + git -C $REPO update-index --untracked-cache + git -C $REPO status >/dev/null 2>&1 +} + +disable_uc () { + git -C $REPO config core.untrackedcache false + git -C $REPO update-index --no-untracked-cache + git -C $REPO status >/dev/null 2>&1 +} + +start_fsm () { + git -C $REPO fsmonitor--daemon start + git -C $REPO fsmonitor--daemon status + git -C $REPO config core.fsmonitor true + git -C $REPO update-index --fsmonitor + git -C $REPO status >/dev/null 2>&1 +} + +stop_fsm () { + git -C $REPO config --unset core.fsmonitor + git -C $REPO update-index --no-fsmonitor + test_might_fail git -C $REPO fsmonitor--daemon stop 2>/dev/null + git -C $REPO status >/dev/null 2>&1 +} + + +# Ensure that FSMonitor is turned off on the borrowed repo. +# +test_expect_success "Setup borrowed repo (fsm+uc)" " + stop_fsm && + disable_uc +" + +# Also ensure that it starts in a known state. +# +# Because we assume that $GIT_PERF_REPEAT_COUNT > 1, we are not going to time +# the ballast checkout, since only the first invocation does any work and the +# subsequent ones just print "already on branch" and quit, so the reported +# 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. +# +test_expect_success "Setup borrowed repo (temp ballast branch)" " + test_might_fail git -C $REPO checkout $BALLAST_BR && + test_might_fail git -C $REPO reset --hard && + git -C $REPO clean -d -f && + test_might_fail git -C $REPO branch -D $TMP_BR && + git -C $REPO branch $TMP_BR $BALLAST_BR && + git -C $REPO checkout $TMP_BR +" + + +echo Data >data.txt + +# NEEDSWORK: We assume that $GIT_PERF_REPEAT_COUNT > 1. With +# FSMonitor enabled, we can get a skewed view of status times, since +# the index MAY (or may not) be updated after the first invocation +# which will update the FSMonitor Token, so the subsequent invocations +# may get a smaller response from the daemon. +# +do_status () { + msg=$1 + + test_perf "$msg" " + git -C $REPO status >/dev/null 2>&1 + " +} + +do_matrix () { + uc=$1 + fsm=$2 + + t="[uc $uc][fsm $fsm]" + MATRIX_BR="$TMP_BR-$uc-$fsm" + + test_expect_success "$t Setup matrix branch" " + git -C $REPO clean -d -f && + git -C $REPO checkout $TMP_BR && + test_might_fail git -C $REPO branch -D $MATRIX_BR && + git -C $REPO branch $MATRIX_BR $TMP_BR && + git -C $REPO checkout $MATRIX_BR + " + + if test $uc = true + then + enable_uc + else + disable_uc + fi + + if test $fsm = true + then + start_fsm + else + stop_fsm + fi + + do_status "$t status after checkout" + + # Modify many files in the matrix branch. + # Stage them. + # Commit them. + # Rollback. + # + test_expect_success "$t modify tracked files" " + find $REPO -name file1 -exec cp data.txt {} \\; + " + + do_status "$t status after big change" + + # Don't bother timing the "add" because _REPEAT_COUNT + # issue described above. + # + test_expect_success "$t add all" " + git -C $REPO add -A + " + + do_status "$t status after add all" + + test_expect_success "$t add dot" " + git -C $REPO add . + " + + do_status "$t status after add dot" + + test_expect_success "$t commit staged" " + git -C $REPO commit -a -m data + " + + do_status "$t status after commit" + + test_expect_success "$t reset HEAD~1 hard" " + git -C $REPO reset --hard HEAD~1 >/dev/null 2>&1 + " + + do_status "$t status after reset hard" + + # Create some untracked files. + # + test_expect_success "$t create untracked files" " + cp -R $REPO/ballast/dir1 $REPO/ballast/xxx1 + " + + do_status "$t status after create untracked files" + + # Remove the new untracked files. + # + test_expect_success "$t clean -df" " + git -C $REPO clean -d -f + " + + do_status "$t status after clean" + + if test $fsm = true + then + stop_fsm + fi +} + +# Begin testing each case in the matrix that we care about. +# +uc_values="false" +test_have_prereq UNTRACKED_CACHE && uc_values="false true" + +fsm_values="false true" + +for uc_val in $uc_values +do + for fsm_val in $fsm_values + do + do_matrix $uc_val $fsm_val + done +done + +cleanup () { + uc=$1 + fsm=$2 + + MATRIX_BR="$TMP_BR-$uc-$fsm" + + test_might_fail git -C $REPO branch -D $MATRIX_BR +} + + +# We're borrowing this repo. We should leave it in a clean state. +# +test_expect_success "Cleanup temp and matrix branches" " + git -C $REPO clean -d -f && + test_might_fail git -C $REPO checkout $BALLAST_BR && + test_might_fail git -C $REPO branch -D $TMP_BR && + for uc_val in $uc_values + do + for fsm_val in $fsm_values + do + cleanup $uc_val $fsm_val + done + done +" + +test_done diff --git a/t/perf/p7820-grep-engines.sh b/t/perf/p7820-grep-engines.sh index 8b09c5bf32..9bfb86842a 100755 --- a/t/perf/p7820-grep-engines.sh +++ b/t/perf/p7820-grep-engines.sh @@ -49,13 +49,15 @@ do fi if ! test_have_prereq PERF_GREP_ENGINES_THREADS then - test_perf $prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" " + test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern'" \ + --prereq "$prereq" " git -c grep.patternType=$engine grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine' || : " else for threads in $GIT_PERF_GREP_THREADS do - test_perf PTHREADS,$prereq "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads" " + test_perf "$engine grep$GIT_PERF_7820_GREP_OPTS '$pattern' with $threads threads" + --prereq PTHREADS,$prereq " git -c grep.patternType=$engine -c grep.threads=$threads grep$GIT_PERF_7820_GREP_OPTS -- '$pattern' >'out.$engine.$threads' || : " done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 932105cd12..ab3687c28d 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -189,19 +189,39 @@ exit $ret' >&3 2>&4 } test_wrapper_ () { - test_wrapper_func_=$1; shift + local test_wrapper_func_="$1"; shift + local test_title_="$1"; shift test_start_ - test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= - test "$#" = 2 || - BUG "not 2 or 3 parameters to test-expect-success" + test_prereq= + test_perf_setup_= + while test $# != 0 + do + case $1 in + --prereq) + test_prereq=$2 + shift + ;; + --setup) + test_perf_setup_=$2 + shift + ;; + *) + break + ;; + esac + shift + done + test "$#" = 1 || BUG "test_wrapper_ needs 2 positional parameters" export test_prereq - if ! test_skip "$@" + export test_perf_setup_ + + if ! test_skip "$test_title_" "$@" then base=$(basename "$0" .sh) echo "$test_count" >>"$perf_results_dir"/$base.subtests echo "$1" >"$perf_results_dir"/$base.$test_count.descr base="$perf_results_dir"/"$PERF_RESULTS_PREFIX$(basename "$0" .sh)"."$test_count" - "$test_wrapper_func_" "$@" + "$test_wrapper_func_" "$test_title_" "$@" fi test_finish_ @@ -214,6 +234,16 @@ test_perf_ () { echo "perf $test_count - $1:" fi for i in $(test_seq 1 $GIT_PERF_REPEAT_COUNT); do + if test -n "$test_perf_setup_" + then + say >&3 "setup: $test_perf_setup_" + if ! test_eval_ $test_perf_setup_ + then + test_failure_ "$test_perf_setup_" + break + fi + + fi say >&3 "running: $2" if test_run_perf_ "$2" then @@ -237,11 +267,24 @@ test_perf_ () { rm test_time.* } +# Usage: test_perf 'title' [options] 'perf-test' +# Run the performance test script specified in perf-test with +# optional prerequisite and setup steps. +# Options: +# --prereq prerequisites: Skip the test if prequisites aren't met +# --setup "setup-steps": Run setup steps prior to each measured iteration +# test_perf () { test_wrapper_ test_perf_ "$@" } test_size_ () { + if test -n "$test_perf_setup_" + then + say >&3 "setup: $test_perf_setup_" + test_eval_ $test_perf_setup_ + fi + say >&3 "running: $2" if test_eval_ "$2" 3>"$base".result; then test_ok_ "$1" @@ -250,6 +293,14 @@ test_size_ () { fi } +# Usage: test_size 'title' [options] 'size-test' +# Run the size test script specified in size-test with optional +# prerequisites and setup steps. Returns the numeric value +# returned by size-test. +# Options: +# --prereq prerequisites: Skip the test if prequisites aren't met +# --setup "setup-steps": Run setup steps prior to the size measurement + test_size () { test_wrapper_ test_size_ "$@" } diff --git a/t/t0056-git-C.sh b/t/t0056-git-C.sh index 2630e756da..752aa8c945 100755 --- a/t/t0056-git-C.sh +++ b/t/t0056-git-C.sh @@ -2,6 +2,7 @@ test_description='"-C <path>" option and its effects on other path-related options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success '"git -C <path>" runs git from the directory <path>' ' diff --git a/t/t0061-run-command.sh b/t/t0061-run-command.sh index ee281909bc..7b5423eebd 100755 --- a/t/t0061-run-command.sh +++ b/t/t0061-run-command.sh @@ -134,16 +134,34 @@ test_expect_success 'run_command runs in parallel with more jobs available than test_cmp expect actual ' +test_expect_success 'run_command runs ungrouped in parallel with more jobs available than tasks' ' + test-tool run-command --ungroup run-command-parallel 5 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>err && + test_line_count = 8 out && + test_line_count = 4 err +' + test_expect_success 'run_command runs in parallel with as many jobs as tasks' ' test-tool run-command run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && test_cmp expect actual ' +test_expect_success 'run_command runs ungrouped in parallel with as many jobs as tasks' ' + test-tool run-command --ungroup run-command-parallel 4 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>err && + test_line_count = 8 out && + test_line_count = 4 err +' + test_expect_success 'run_command runs in parallel with more tasks than jobs available' ' test-tool run-command run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" 2>actual && test_cmp expect actual ' +test_expect_success 'run_command runs ungrouped in parallel with more tasks than jobs available' ' + test-tool run-command --ungroup run-command-parallel 3 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>err && + test_line_count = 8 out && + test_line_count = 4 err +' + cat >expect <<-EOF preloaded output of a child asking for a quick stop @@ -158,6 +176,12 @@ test_expect_success 'run_command is asked to abort gracefully' ' test_cmp expect actual ' +test_expect_success 'run_command is asked to abort gracefully (ungroup)' ' + test-tool run-command --ungroup run-command-abort 3 false >out 2>err && + test_must_be_empty out && + test_line_count = 6 err +' + cat >expect <<-EOF no further jobs available EOF @@ -167,6 +191,12 @@ test_expect_success 'run_command outputs ' ' test_cmp expect actual ' +test_expect_success 'run_command outputs (ungroup) ' ' + test-tool run-command --ungroup run-command-no-jobs 3 sh -c "printf \"%s\n%s\n\" Hello World" >out 2>err && + test_must_be_empty out && + test_cmp expect err +' + test_trace () { expect="$1" shift diff --git a/t/t0062-revision-walking.sh b/t/t0062-revision-walking.sh index 8e215867b8..b9480c8178 100755 --- a/t/t0062-revision-walking.sh +++ b/t/t0062-revision-walking.sh @@ -5,6 +5,7 @@ test_description='Test revision walking api' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh cat >run_twice_expected <<-EOF diff --git a/t/t0100-previous.sh b/t/t0100-previous.sh index 69beb59f62..a16cc3d298 100755 --- a/t/t0100-previous.sh +++ b/t/t0100-previous.sh @@ -5,6 +5,7 @@ test_description='previous branch syntax @{-n}' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'branch -d @{-1}' ' diff --git a/t/t0101-at-syntax.sh b/t/t0101-at-syntax.sh index a1998b558f..878aadd64c 100755 --- a/t/t0101-at-syntax.sh +++ b/t/t0101-at-syntax.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='various @{whatever} syntax tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh index 37c359bd5a..80e76a4695 100755 --- a/t/t0210-trace2-normal.sh +++ b/t/t0210-trace2-normal.sh @@ -168,6 +168,82 @@ test_expect_success 'BUG messages are written to trace2' ' test_cmp expect actual ' +test_expect_success 'bug messages with BUG_if_bug() are written to trace2' ' + test_when_finished "rm trace.normal actual expect" && + test_expect_code 99 env GIT_TRACE2="$(pwd)/trace.normal" \ + test-tool trace2 008bug 2>err && + cat >expect <<-\EOF && + a bug message + another bug message + an explicit BUG_if_bug() following bug() call(s) is nice, but not required + EOF + sed "s/^.*: //" <err >actual && + test_cmp expect actual && + + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 008bug + cmd_name trace2 (trace2) + error a bug message + error another bug message + error an explicit BUG_if_bug() following bug() call(s) is nice, but not required + exit elapsed:_TIME_ code:99 + atexit elapsed:_TIME_ code:99 + EOF + test_cmp expect actual +' + +test_expect_success 'bug messages without explicit BUG_if_bug() are written to trace2' ' + test_when_finished "rm trace.normal actual expect" && + test_expect_code 99 env GIT_TRACE2="$(pwd)/trace.normal" \ + test-tool trace2 009bug_BUG 2>err && + cat >expect <<-\EOF && + a bug message + another bug message + had bug() call(s) in this process without explicit BUG_if_bug() + EOF + sed "s/^.*: //" <err >actual && + test_cmp expect actual && + + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 009bug_BUG + cmd_name trace2 (trace2) + error a bug message + error another bug message + error on exit(): had bug() call(s) in this process without explicit BUG_if_bug() + exit elapsed:_TIME_ code:99 + atexit elapsed:_TIME_ code:99 + EOF + test_cmp expect actual +' + +test_expect_success 'bug messages followed by BUG() are written to trace2' ' + test_when_finished "rm trace.normal actual expect" && + test_expect_code 99 env GIT_TRACE2="$(pwd)/trace.normal" \ + test-tool trace2 010bug_BUG 2>err && + cat >expect <<-\EOF && + a bug message + a BUG message + EOF + sed "s/^.*: //" <err >actual && + test_cmp expect actual && + + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 010bug_BUG + cmd_name trace2 (trace2) + error a bug message + error a BUG message + exit elapsed:_TIME_ code:99 + atexit elapsed:_TIME_ code:99 + EOF + test_cmp expect actual +' + sane_unset GIT_TRACE2_BRIEF # Now test without environment variables and get all Trace2 settings diff --git a/t/t1001-read-tree-m-2way.sh b/t/t1001-read-tree-m-2way.sh index 0710b1fb1e..516a6112fd 100755 --- a/t/t1001-read-tree-m-2way.sh +++ b/t/t1001-read-tree-m-2way.sh @@ -21,6 +21,7 @@ In the test, these paths are used: yomin - not in H or M ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1002-read-tree-m-u-2way.sh b/t/t1002-read-tree-m-u-2way.sh index 46cbd5514a..bd5313caec 100755 --- a/t/t1002-read-tree-m-u-2way.sh +++ b/t/t1002-read-tree-m-u-2way.sh @@ -9,6 +9,7 @@ This is identical to t1001, but uses -u to update the work tree as well. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-read-tree.sh diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh index bc89371f53..5b8e47e346 100755 --- a/t/t1060-object-corruption.sh +++ b/t/t1060-object-corruption.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='see how we handle various forms of corruption' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # convert "1234abcd" to ".git/objects/12/34abcd" diff --git a/t/t1091-sparse-checkout-builtin.sh b/t/t1091-sparse-checkout-builtin.sh index 9a90031018..de1ec89007 100755 --- a/t/t1091-sparse-checkout-builtin.sh +++ b/t/t1091-sparse-checkout-builtin.sh @@ -72,7 +72,7 @@ test_expect_success 'git sparse-checkout list (populated)' ' ' test_expect_success 'git sparse-checkout init' ' - git -C repo sparse-checkout init && + git -C repo sparse-checkout init --no-cone && cat >expect <<-\EOF && /* !/*/ @@ -111,6 +111,7 @@ test_expect_success 'init with existing sparse-checkout' ' test_expect_success 'clone --sparse' ' git clone --sparse "file://$(pwd)/repo" clone && + git -C clone sparse-checkout reapply --no-cone && git -C clone sparse-checkout list >actual && cat >expect <<-\EOF && /* @@ -124,7 +125,7 @@ test_expect_success 'switching to cone mode with non-cone mode patterns' ' git init bad-patterns && ( cd bad-patterns && - git sparse-checkout init && + git sparse-checkout init --no-cone && git sparse-checkout add dir && git config --worktree core.sparseCheckoutCone true && test_must_fail git sparse-checkout add dir 2>err && @@ -402,7 +403,7 @@ test_expect_success 'revert to old sparse-checkout on empty update' ' git sparse-checkout set nothing 2>err && test_i18ngrep ! "Sparse checkout leaves no entry on working directory" err && test_i18ngrep ! ".git/index.lock" err && - git sparse-checkout set file + git sparse-checkout set --no-cone file ) ' @@ -424,7 +425,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' git clone repo dirty && echo dirty >dirty/folder1/a && - git -C dirty sparse-checkout init 2>err && + git -C dirty sparse-checkout init --no-cone 2>err && test_i18ngrep "warning.*The following paths are not up to date" err && git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* 2>err && @@ -435,7 +436,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with dirty status' test_must_be_empty err && git -C dirty reset --hard && - git -C dirty sparse-checkout init && + git -C dirty sparse-checkout init --no-cone && git -C dirty sparse-checkout set /folder2/* /deep/deeper1/* && test_path_is_missing dirty/folder1/a && git -C dirty sparse-checkout disable && @@ -451,7 +452,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat EOF git -C unmerged update-index --index-info <input && - git -C unmerged sparse-checkout init 2>err && + git -C unmerged sparse-checkout init --no-cone 2>err && test_i18ngrep "warning.*The following paths are unmerged" err && git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* 2>err && @@ -462,7 +463,7 @@ test_expect_success 'sparse-checkout (init|set|disable) warns with unmerged stat test_i18ngrep "warning.*The following paths are unmerged" err && git -C unmerged reset --hard && - git -C unmerged sparse-checkout init && + git -C unmerged sparse-checkout init --no-cone && git -C unmerged sparse-checkout set /folder2/* /deep/deeper1/* && git -C unmerged sparse-checkout disable ' diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index 6f778cf28c..f9f8c988bb 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -205,36 +205,68 @@ test_sparse_unstaged () { done } -test_expect_success 'sparse-index contents' ' - init_repos && - +# Usage: test_sprase_checkout_set "<c1> ... <cN>" "<s1> ... <sM>" +# Verifies that "git sparse-checkout set <c1> ... <cN>" succeeds and +# leaves the sparse index in a state where <s1> ... <sM> are sparse +# directories (and <c1> ... <cN> are not). +test_sparse_checkout_set () { + CONE_DIRS=$1 && + SPARSE_DIRS=$2 && + git -C sparse-index sparse-checkout set --skip-checks $CONE_DIRS && git -C sparse-index ls-files --sparse --stage >cache && - for dir in folder1 folder2 x + + # Check that the directories outside of the sparse-checkout cone + # have sparse directory entries. + for dir in $SPARSE_DIRS do TREE=$(git -C sparse-index rev-parse HEAD:$dir) && grep "040000 $TREE 0 $dir/" cache \ || return 1 done && - git -C sparse-index sparse-checkout set folder1 && - - git -C sparse-index ls-files --sparse --stage >cache && - for dir in deep folder2 x + # Check that the directories in the sparse-checkout cone + # are not sparse directory entries. + for dir in $CONE_DIRS do - TREE=$(git -C sparse-index rev-parse HEAD:$dir) && - grep "040000 $TREE 0 $dir/" cache \ + # Allow TREE to not exist because + # $dir does not exist at HEAD. + TREE=$(git -C sparse-index rev-parse HEAD:$dir) || + ! grep "040000 $TREE 0 $dir/" cache \ || return 1 - done && + done +} - git -C sparse-index sparse-checkout set deep/deeper1 && +test_expect_success 'sparse-index contents' ' + init_repos && - git -C sparse-index ls-files --sparse --stage >cache && - for dir in deep/deeper2 folder1 folder2 x - do - TREE=$(git -C sparse-index rev-parse HEAD:$dir) && - grep "040000 $TREE 0 $dir/" cache \ - || return 1 - done && + # Remove deep, add three other directories. + test_sparse_checkout_set \ + "folder1 folder2 x" \ + "before deep" && + + # Remove folder1, add deep + test_sparse_checkout_set \ + "deep folder2 x" \ + "before folder1" && + + # Replace deep with deep/deeper2 (dropping deep/deeper1) + # Add folder1 + test_sparse_checkout_set \ + "deep/deeper2 folder1 folder2 x" \ + "before deep/deeper1" && + + # Replace deep/deeper2 with deep/deeper1 + # Replace folder1 with folder1/0/0 + # Replace folder2 with non-existent folder2/2/3 + # Add non-existent "bogus" + test_sparse_checkout_set \ + "bogus deep/deeper1 folder1/0/0 folder2/2/3 x" \ + "before deep/deeper2 folder2/0" && + + # Drop down to only files at root + test_sparse_checkout_set \ + "" \ + "before deep folder1 folder2 x" && # Disabling the sparse-index replaces tree entries with full ones git -C sparse-index sparse-checkout init --no-sparse-index && @@ -1628,6 +1660,31 @@ test_expect_success 'ls-files' ' ensure_not_expanded ls-files --sparse ' +test_expect_success 'sparse index is not expanded: sparse-checkout' ' + init_repos && + + ensure_not_expanded sparse-checkout set deep/deeper2 && + ensure_not_expanded sparse-checkout set deep/deeper1 && + ensure_not_expanded sparse-checkout set deep && + ensure_not_expanded sparse-checkout add folder1 && + ensure_not_expanded sparse-checkout set deep/deeper1 && + ensure_not_expanded sparse-checkout set folder2 && + + # Demonstrate that the checks that "folder1/a" is a file + # do not cause a sparse-index expansion (since it is in the + # sparse-checkout cone). + echo >>sparse-index/folder2/a && + git -C sparse-index add folder2/a && + + ensure_not_expanded sparse-checkout add folder1 && + + # Skip checks here, since deep/deeper1 is inside a sparse directory + # that must be expanded to check whether `deep/deeper1` is a file + # or not. + ensure_not_expanded sparse-checkout set --skip-checks deep/deeper1 && + ensure_not_expanded sparse-checkout set +' + # NEEDSWORK: a sparse-checkout behaves differently from a full checkout # in this scenario, but it shouldn't. test_expect_success 'reset mixed and checkout orphan' ' diff --git a/t/t1401-symbolic-ref.sh b/t/t1401-symbolic-ref.sh index 132a1b885a..9fb0b90f25 100755 --- a/t/t1401-symbolic-ref.sh +++ b/t/t1401-symbolic-ref.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='basic symbolic-ref tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # If the tests munging HEAD fail, they can break detection of diff --git a/t/t1411-reflog-show.sh b/t/t1411-reflog-show.sh index 975c4ea83a..da581ec19a 100755 --- a/t/t1411-reflog-show.sh +++ b/t/t1411-reflog-show.sh @@ -4,6 +4,7 @@ test_description='Test reflog display routines' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t1412-reflog-loop.sh b/t/t1412-reflog-loop.sh index 977603f7f1..ff30874f94 100755 --- a/t/t1412-reflog-loop.sh +++ b/t/t1412-reflog-loop.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='reflog walk shows repeated commits again' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup commits' ' diff --git a/t/t1415-worktree-refs.sh b/t/t1415-worktree-refs.sh index a3e6ea0808..3b531842dd 100755 --- a/t/t1415-worktree-refs.sh +++ b/t/t1415-worktree-refs.sh @@ -2,6 +2,7 @@ test_description='per-worktree refs' +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 26ed5e11bc..210f429887 100755 --- a/t/t1800-hook.sh +++ b/t/t1800-hook.sh @@ -4,6 +4,7 @@ test_description='git-hook command' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-terminal.sh test_expect_success 'git hook usage' ' test_expect_code 129 git hook && @@ -120,4 +121,34 @@ test_expect_success 'git -c core.hooksPath=<PATH> hook run' ' test_cmp expect actual ' +test_hook_tty () { + cat >expect <<-\EOF + STDOUT TTY + STDERR TTY + EOF + + test_when_finished "rm -rf repo" && + git init repo && + + test_commit -C repo A && + test_commit -C repo B && + git -C repo reset --soft HEAD^ && + + test_hook -C repo pre-commit <<-EOF && + test -t 1 && echo STDOUT TTY >>actual || echo STDOUT NO TTY >>actual && + test -t 2 && echo STDERR TTY >>actual || echo STDERR NO TTY >>actual + EOF + + test_terminal git -C repo "$@" && + test_cmp expect repo/actual +} + +test_expect_success TTY 'git hook run: stdout and stderr are connected to a TTY' ' + test_hook_tty hook run pre-commit +' + +test_expect_success TTY 'git commit: stdout and stderr are connected to a TTY' ' + test_hook_tty commit -m"B.new" +' + test_done diff --git a/t/t2015-checkout-unborn.sh b/t/t2015-checkout-unborn.sh index a9721215fa..9425aae639 100755 --- a/t/t2015-checkout-unborn.sh +++ b/t/t2015-checkout-unborn.sh @@ -4,6 +4,7 @@ test_description='checkout from unborn branch' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 0c38f8e356..be394f1131 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -14,6 +14,7 @@ only the updates to dir/sub. Also tested are "git add -u" without limiting, and "git add -u" without contents changes, and other conditions' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3104-ls-tree-format.sh b/t/t3104-ls-tree-format.sh index 0769a933d6..383896667b 100755 --- a/t/t3104-ls-tree-format.sh +++ b/t/t3104-ls-tree-format.sh @@ -4,6 +4,7 @@ test_description='ls-tree --format' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-t3100.sh test_expect_success 'ls-tree --format usage' ' test_expect_code 129 git ls-tree --format=fmt -l HEAD && @@ -12,9 +13,7 @@ test_expect_success 'ls-tree --format usage' ' ' test_expect_success 'setup' ' - mkdir dir && - test_commit dir/sub-file && - test_commit top-file + setup_basic_ls_tree_data ' test_ls_tree_format () { diff --git a/t/t3105-ls-tree-output.sh b/t/t3105-ls-tree-output.sh new file mode 100755 index 0000000000..ce2391e28b --- /dev/null +++ b/t/t3105-ls-tree-output.sh @@ -0,0 +1,192 @@ +#!/bin/sh + +test_description='ls-tree output' + +TEST_PASSES_SANITIZE_LEAK=true +. ./test-lib.sh +. "$TEST_DIRECTORY"/lib-t3100.sh + +test_expect_success 'ls-tree --format usage' ' + test_expect_code 129 git ls-tree --format=fmt -l HEAD && + test_expect_code 129 git ls-tree --format=fmt --name-only HEAD && + test_expect_code 129 git ls-tree --format=fmt --name-status HEAD +' + +test_expect_success 'setup' ' + setup_basic_ls_tree_data +' + +test_ls_tree_format_mode_output () { + local opts="$1" && + shift && + cat >expect && + + while test $# -gt 0 + do + local mode="$1" && + shift && + + test_expect_success "'ls-tree $opts${mode:+ $mode}' output" ' + git ls-tree ${mode:+$mode }$opts HEAD >actual && + test_cmp expect actual + ' + + case "$opts" in + --full-tree) + test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir, fails)" ' + test_must_fail git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../ + ' + ;; + *) + test_expect_success "'ls-tree $opts${mode:+ $mode}' output (via subdir)" ' + git -C dir ls-tree --full-name ${mode:+$mode }$opts HEAD -- ../ >actual && + test_cmp expect actual + ' + ;; + esac + done +} + +# test exact output of option (none, --long, ...) and mode (none and +# -d, -r -t) and combinations +test_expect_success 'setup: HEAD_* variables' ' + HEAD_gitmodules=$(git rev-parse HEAD:.gitmodules) && + HEAD_dir=$(git rev-parse HEAD:dir) && + HEAD_top_file=$(git rev-parse HEAD:top-file.t) && + HEAD_submodule=$(git rev-parse HEAD:submodule) && + HEAD_dir_sub_file=$(git rev-parse HEAD:dir/sub-file.t) +' +## opt = +test_ls_tree_format_mode_output "" "" "-t" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +test_ls_tree_format_mode_output "" "-d" <<-EOF + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + EOF +test_ls_tree_format_mode_output "" "-r" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 100644 blob $HEAD_dir_sub_file dir/sub-file.t + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +## opt = --long +test_ls_tree_format_mode_output "--long" "" "-t" <<-EOF + 100644 blob $HEAD_gitmodules 61 .gitmodules + 040000 tree $HEAD_dir - dir + 160000 commit $HEAD_submodule - submodule + 100644 blob $HEAD_top_file 9 top-file.t + EOF +test_ls_tree_format_mode_output "--long" "-d" <<-EOF + 040000 tree $HEAD_dir - dir + 160000 commit $HEAD_submodule - submodule + EOF +test_ls_tree_format_mode_output "--long" "-r" <<-EOF + 100644 blob $HEAD_gitmodules 61 .gitmodules + 100644 blob $HEAD_dir_sub_file 13 dir/sub-file.t + 160000 commit $HEAD_submodule - submodule + 100644 blob $HEAD_top_file 9 top-file.t + EOF +## opt = --name-only +test_ls_tree_format_mode_output "--name-only" "" "-t" <<-EOF + .gitmodules + dir + submodule + top-file.t + EOF +test_ls_tree_format_mode_output "--name-only" "-d" <<-EOF + dir + submodule + EOF +test_ls_tree_format_mode_output "--name-only" "-r" <<-EOF + .gitmodules + dir/sub-file.t + submodule + top-file.t + EOF +## opt = --object-only +test_ls_tree_format_mode_output "--object-only" "" "-t" <<-EOF + $HEAD_gitmodules + $HEAD_dir + $HEAD_submodule + $HEAD_top_file + EOF +test_ls_tree_format_mode_output "--object-only" "-d" <<-EOF + $HEAD_dir + $HEAD_submodule + EOF +test_ls_tree_format_mode_output "--object-only" "-r" <<-EOF + $HEAD_gitmodules + $HEAD_dir_sub_file + $HEAD_submodule + $HEAD_top_file + EOF +## opt = --object-only --abbrev +test_expect_success 'setup: HEAD_short_* variables' ' + HEAD_short_gitmodules=$(git rev-parse --short HEAD:.gitmodules) && + HEAD_short_dir=$(git rev-parse --short HEAD:dir) && + HEAD_short_top_file=$(git rev-parse --short HEAD:top-file.t) && + HEAD_short_submodule=$(git rev-parse --short HEAD:submodule) && + HEAD_short_dir_sub_file=$(git rev-parse --short HEAD:dir/sub-file.t) +' +test_ls_tree_format_mode_output "--object-only --abbrev" "" "-t" <<-EOF + $HEAD_short_gitmodules + $HEAD_short_dir + $HEAD_short_submodule + $HEAD_short_top_file + EOF +test_ls_tree_format_mode_output "--object-only --abbrev" "-d" <<-EOF + $HEAD_short_dir + $HEAD_short_submodule + EOF +test_ls_tree_format_mode_output "--object-only --abbrev" "-r" <<-EOF + $HEAD_short_gitmodules + $HEAD_short_dir_sub_file + $HEAD_short_submodule + $HEAD_short_top_file + EOF +## opt = --full-name +test_ls_tree_format_mode_output "--full-name" "" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +test_ls_tree_format_mode_output "--full-name" "-d" <<-EOF + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + EOF +test_ls_tree_format_mode_output "--full-name" "-r" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 100644 blob $HEAD_dir_sub_file dir/sub-file.t + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +test_ls_tree_format_mode_output "--full-name" "-t" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +## opt = --full-tree +test_ls_tree_format_mode_output "--full-tree" "" "-t" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF +test_ls_tree_format_mode_output "--full-tree" "-d" <<-EOF + 040000 tree $HEAD_dir dir + 160000 commit $HEAD_submodule submodule + EOF +test_ls_tree_format_mode_output "--full-tree" "-r" <<-EOF + 100644 blob $HEAD_gitmodules .gitmodules + 100644 blob $HEAD_dir_sub_file dir/sub-file.t + 160000 commit $HEAD_submodule submodule + 100644 blob $HEAD_top_file top-file.t + EOF + +test_done diff --git a/t/t3206-range-diff.sh b/t/t3206-range-diff.sh index e30bc48a29..d12e4e4cc6 100755 --- a/t/t3206-range-diff.sh +++ b/t/t3206-range-diff.sh @@ -772,4 +772,55 @@ test_expect_success '--left-only/--right-only' ' test_cmp expect actual ' +test_expect_success 'submodule changes are shown irrespective of diff.submodule' ' + git init sub-repo && + test_commit -C sub-repo sub-first && + sub_oid1=$(git -C sub-repo rev-parse HEAD) && + test_commit -C sub-repo sub-second && + sub_oid2=$(git -C sub-repo rev-parse HEAD) && + test_commit -C sub-repo sub-third && + sub_oid3=$(git -C sub-repo rev-parse HEAD) && + + git checkout -b main-sub topic && + git submodule add ./sub-repo sub && + git -C sub checkout --detach sub-first && + git commit -m "add sub" sub && + sup_oid1=$(git rev-parse --short HEAD) && + git checkout -b topic-sub && + git -C sub checkout sub-second && + git commit -m "change sub" sub && + sup_oid2=$(git rev-parse --short HEAD) && + git checkout -b modified-sub main-sub && + git -C sub checkout sub-third && + git commit -m "change sub" sub && + sup_oid3=$(git rev-parse --short HEAD) && + sup_oid0=$(test_oid __) && + + test_config diff.submodule log && + git range-diff topic topic-sub modified-sub >actual && + cat >expect <<-EOF && + 1: $sup_oid1 = 1: $sup_oid1 add sub + 2: $sup_oid2 < -: $sup_oid0 change sub + -: $sup_oid0 > 2: $sup_oid3 change sub + EOF + test_cmp expect actual && + test_config diff.submodule diff && + git range-diff topic topic-sub modified-sub >actual && + git range-diff --creation-factor=100 topic topic-sub modified-sub >actual && + cat >expect <<-EOF && + 1: $sup_oid1 = 1: $sup_oid1 add sub + 2: $sup_oid2 ! 2: $sup_oid3 change sub + @@ Commit message + ## sub ## + @@ + -Subproject commit $sub_oid1 + -+Subproject commit $sub_oid2 + ++Subproject commit $sub_oid3 + EOF + test_cmp expect actual && + test_config diff.submodule diff && + git range-diff --creation-factor=100 topic topic-sub modified-sub >actual && + test_cmp expect actual +' + test_done diff --git a/t/t3302-notes-index-expensive.sh b/t/t3302-notes-index-expensive.sh index bb5fea02a0..d0c4d38b4d 100755 --- a/t/t3302-notes-index-expensive.sh +++ b/t/t3302-notes-index-expensive.sh @@ -8,6 +8,7 @@ test_description='Test commit notes index (expensive!)' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh create_repo () { diff --git a/t/t3303-notes-subtrees.sh b/t/t3303-notes-subtrees.sh index eac193757b..bc9b791d1b 100755 --- a/t/t3303-notes-subtrees.sh +++ b/t/t3303-notes-subtrees.sh @@ -5,6 +5,7 @@ test_description='Test commit notes organized in subtrees' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh number_of_commits=100 diff --git a/t/t3305-notes-fanout.sh b/t/t3305-notes-fanout.sh index 9976d787f4..64a9915761 100755 --- a/t/t3305-notes-fanout.sh +++ b/t/t3305-notes-fanout.sh @@ -2,6 +2,7 @@ test_description='Test that adding/removing many notes triggers automatic fanout restructuring' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh path_has_fanout() { diff --git a/t/t3408-rebase-multi-line.sh b/t/t3408-rebase-multi-line.sh index cde3562e3a..7b4607d72f 100755 --- a/t/t3408-rebase-multi-line.sh +++ b/t/t3408-rebase-multi-line.sh @@ -5,6 +5,7 @@ test_description='rebasing a commit with multi-line first paragraph.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t3602-rm-sparse-checkout.sh b/t/t3602-rm-sparse-checkout.sh index 034ec01091..08580fd3dc 100755 --- a/t/t3602-rm-sparse-checkout.sh +++ b/t/t3602-rm-sparse-checkout.sh @@ -30,7 +30,7 @@ test_expect_success 'setup' " for opt in "" -f --dry-run do test_expect_success "rm${opt:+ $opt} does not remove sparse entries" ' - git sparse-checkout set a && + git sparse-checkout set --no-cone a && test_must_fail git rm $opt b 2>stderr && test_cmp b_error_and_hint stderr && git ls-files --error-unmatch b @@ -118,7 +118,7 @@ test_expect_success 'can remove files from non-sparse dir' ' test_commit w/f && test_commit x/y/f && - git sparse-checkout set w !/x y/ && + git sparse-checkout set --no-cone w !/x y/ && git rm w/f.t x/y/f.t 2>stderr && test_must_be_empty stderr ' @@ -128,7 +128,7 @@ test_expect_success 'refuse to remove non-skip-worktree file from sparse dir' ' git sparse-checkout disable && mkdir -p x/y/z && test_commit x/y/z/f && - git sparse-checkout set !/x y/ !x/y/z && + git sparse-checkout set --no-cone !/x y/ !x/y/z && git update-index --no-skip-worktree x/y/z/f.t && test_must_fail git rm x/y/z/f.t 2>stderr && diff --git a/t/t3700-add.sh b/t/t3700-add.sh index b1f90ba325..8979c8a5f0 100755 --- a/t/t3700-add.sh +++ b/t/t3700-add.sh @@ -8,6 +8,8 @@ test_description='Test of git add, including the -- option.' TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh + # Test the file mode "$1" of the file "$2" in the index. test_mode_in_index () { case "$(git ls-files -s "$2")" in @@ -34,6 +36,32 @@ test_expect_success \ 'Test that "git add -- -q" works' \ 'touch -- -q && git add -- -q' +BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' + +test_expect_success 'git add: core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir1 && + GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION add -- ./files_base_dir1/ && + git ls-files --stage files_base_dir1/ | + test_parse_ls_files_stage_oids >added_files_oids && + + # We created 2 subdirs with 4 files each (8 files total) above + test_line_count = 8 added_files_oids && + git cat-file --batch-check='%(objectname)' <added_files_oids >added_files_actual && + test_cmp added_files_oids added_files_actual +" + +test_expect_success 'git update-index: core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir2 && + find files_base_dir2 ! -type d -print | xargs git $BATCH_CONFIGURATION update-index --add -- && + git ls-files --stage files_base_dir2 | + test_parse_ls_files_stage_oids >added_files2_oids && + + # We created 2 subdirs with 4 files each (8 files total) above + test_line_count = 8 added_files2_oids && + git cat-file --batch-check='%(objectname)' <added_files2_oids >added_files2_actual && + test_cmp added_files2_oids added_files2_actual +" + test_expect_success \ 'git add: Test that executable bit is not used if core.filemode=0' \ 'git config core.filemode 0 && diff --git a/t/t3705-add-sparse-checkout.sh b/t/t3705-add-sparse-checkout.sh index 95609046c6..2bade9e804 100755 --- a/t/t3705-add-sparse-checkout.sh +++ b/t/t3705-add-sparse-checkout.sh @@ -166,7 +166,7 @@ test_expect_success 'do not warn when pathspec matches dense entries' ' test_expect_success 'git add fails outside of sparse-checkout definition' ' test_when_finished git sparse-checkout disable && test_commit a && - git sparse-checkout init && + git sparse-checkout init --no-cone && git sparse-checkout set a && echo >>sparse_entry && @@ -208,7 +208,7 @@ test_expect_success 'add obeys advice.updateSparsePath' ' ' test_expect_success 'add allows sparse entries with --sparse' ' - git sparse-checkout set a && + git sparse-checkout set --no-cone a && echo modified >sparse_entry && test_must_fail git add sparse_entry && test_sparse_entry_unchanged && diff --git a/t/t3903-stash.sh b/t/t3903-stash.sh index 4abbc8fcca..20e9488196 100755 --- a/t/t3903-stash.sh +++ b/t/t3903-stash.sh @@ -9,6 +9,7 @@ GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +. $TEST_DIRECTORY/lib-unique-files.sh test_expect_success 'usage on cmd and subcommand invalid option' ' test_expect_code 129 git stash --invalid-option 2>usage && @@ -1410,6 +1411,25 @@ test_expect_success 'stash handles skip-worktree entries nicely' ' git rev-parse --verify refs/stash:A.t ' + +BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' + +test_expect_success 'stash with core.fsyncmethod=batch' " + test_create_unique_files 2 4 files_base_dir && + GIT_TEST_FSYNC=1 git $BATCH_CONFIGURATION stash push -u -- ./files_base_dir/ && + + # The files were untracked, so use the third parent, + # which contains the untracked files + git ls-tree -r stash^3 -- ./files_base_dir/ | + test_parse_ls_tree_oids >stashed_files_oids && + + # We created 2 dirs with 4 files each (8 files total) above + test_line_count = 8 stashed_files_oids && + git cat-file --batch-check='%(objectname)' <stashed_files_oids >stashed_files_actual && + test_cmp stashed_files_oids stashed_files_actual +" + + test_expect_success 'git stash succeeds despite directory/file change' ' test_create_repo directory_file_switch_v1 && ( diff --git a/t/t4021-format-patch-numbered.sh b/t/t4021-format-patch-numbered.sh index 9be65fd444..1219aa226d 100755 --- a/t/t4021-format-patch-numbered.sh +++ b/t/t4021-format-patch-numbered.sh @@ -5,6 +5,7 @@ test_description='Format-patch numbering options' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4027-diff-submodule.sh b/t/t4027-diff-submodule.sh index 295da987cc..40164ae07d 100755 --- a/t/t4027-diff-submodule.sh +++ b/t/t4027-diff-submodule.sh @@ -2,6 +2,7 @@ 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 204ba673cb..60cb819c42 100755 --- a/t/t4028-format-patch-mime-headers.sh +++ b/t/t4028-format-patch-mime-headers.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='format-patch mime headers and extra headers do not conflict' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'create commit with utf-8 body' ' diff --git a/t/t4036-format-patch-signer-mime.sh b/t/t4036-format-patch-signer-mime.sh index 98d9713d8b..48655bcc78 100755 --- a/t/t4036-format-patch-signer-mime.sh +++ b/t/t4036-format-patch-signer-mime.sh @@ -2,6 +2,7 @@ test_description='format-patch -s should force MIME encoding as needed' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4039-diff-assume-unchanged.sh b/t/t4039-diff-assume-unchanged.sh index 0eb0314a8b..78090e6852 100755 --- a/t/t4039-diff-assume-unchanged.sh +++ b/t/t4039-diff-assume-unchanged.sh @@ -2,6 +2,7 @@ test_description='diff with assume-unchanged entries' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # external diff has been tested in t4020-diff-external.sh diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index 741e0803c1..73048d0a52 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -5,6 +5,7 @@ test_description='diff.context configuration' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4066-diff-emit-delay.sh b/t/t4066-diff-emit-delay.sh index a1de63b77f..0ecb391541 100755 --- a/t/t4066-diff-emit-delay.sh +++ b/t/t4066-diff-emit-delay.sh @@ -4,6 +4,7 @@ test_description='test combined/stat/moved interaction' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This test covers a weird 3-way interaction between "--cc -p", which will run diff --git a/t/t4122-apply-symlink-inside.sh b/t/t4122-apply-symlink-inside.sh index aa52de401b..9696537303 100755 --- a/t/t4122-apply-symlink-inside.sh +++ b/t/t4122-apply-symlink-inside.sh @@ -4,6 +4,7 @@ test_description='apply to deeper directory without getting fooled with symlink' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4126-apply-empty.sh b/t/t4126-apply-empty.sh index 33860d3829..ece9fae207 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 diff --git a/t/t4128-apply-root.sh b/t/t4128-apply-root.sh index f6db5a79dd..ed94c90204 100755 --- a/t/t4128-apply-root.sh +++ b/t/t4128-apply-root.sh @@ -2,6 +2,7 @@ test_description='apply same filename' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t4206-log-follow-harder-copies.sh b/t/t4206-log-follow-harder-copies.sh index 4871a5dc92..33ecf82c7f 100755 --- a/t/t4206-log-follow-harder-copies.sh +++ b/t/t4206-log-follow-harder-copies.sh @@ -6,6 +6,8 @@ test_description='Test --follow should always find copies hard in git log. ' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-diff.sh diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index b870942498..36ac6aff1e 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -8,6 +8,7 @@ test_description='Test for "git log --decorate" colors' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t4212-log-corrupt.sh b/t/t4212-log-corrupt.sh index 0244888a5a..30a219894b 100755 --- a/t/t4212-log-corrupt.sh +++ b/t/t4212-log-corrupt.sh @@ -2,6 +2,7 @@ test_description='git log with invalid commit headers' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t5003-archive-zip.sh b/t/t5003-archive-zip.sh index d726964307..3992d08158 100755 --- a/t/t5003-archive-zip.sh +++ b/t/t5003-archive-zip.sh @@ -206,6 +206,26 @@ test_expect_success 'git archive --format=zip --add-file' ' check_zip with_untracked check_added with_untracked untracked untracked +test_expect_success UNZIP 'git archive --format=zip --add-virtual-file' ' + if test_have_prereq FUNNYNAMES + then + PATHNAME="pathname with : colon" + else + PATHNAME="pathname without colon" + fi && + git archive --format=zip >with_file_with_content.zip \ + --add-virtual-file=\""$PATHNAME"\": \ + --add-virtual-file=hello:world $EMPTY_TREE && + test_when_finished "rm -rf tmp-unpack" && + mkdir tmp-unpack && ( + cd tmp-unpack && + "$GIT_UNZIP" ../with_file_with_content.zip && + test_path_is_file hello && + test_path_is_file "$PATHNAME" && + test world = $(cat hello) + ) +' + test_expect_success 'git archive --format=zip --add-file twice' ' echo untracked >untracked && git archive --format=zip --prefix=one/ --add-file=untracked \ diff --git a/t/t5300-pack-object.sh b/t/t5300-pack-object.sh index a11d61206a..f8a0f309e2 100755 --- a/t/t5300-pack-object.sh +++ b/t/t5300-pack-object.sh @@ -161,22 +161,27 @@ test_expect_success 'pack-objects with bogus arguments' ' ' check_unpack () { + local packname="$1" && + local object_list="$2" && + local git_config="$3" && test_when_finished "rm -rf git2" && - git init --bare git2 && - git -C git2 unpack-objects -n <"$1".pack && - git -C git2 unpack-objects <"$1".pack && - (cd .git && find objects -type f -print) | - while read path - do - cmp git2/$path .git/$path || { - echo $path differs. - return 1 - } - done + git $git_config init --bare git2 && + ( + git $git_config -C git2 unpack-objects -n <"$packname".pack && + git $git_config -C git2 unpack-objects <"$packname".pack && + git $git_config -C git2 cat-file --batch-check="%(objectname)" + ) <"$object_list" >current && + cmp "$object_list" current } test_expect_success 'unpack without delta' ' - check_unpack test-1-${packname_1} + check_unpack test-1-${packname_1} obj-list +' + +BATCH_CONFIGURATION='-c core.fsync=loose-object -c core.fsyncmethod=batch' + +test_expect_success 'unpack without delta (core.fsyncmethod=batch)' ' + check_unpack test-1-${packname_1} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'pack with REF_DELTA' ' @@ -185,7 +190,11 @@ test_expect_success 'pack with REF_DELTA' ' ' test_expect_success 'unpack with REF_DELTA' ' - check_unpack test-2-${packname_2} + check_unpack test-2-${packname_2} obj-list +' + +test_expect_success 'unpack with REF_DELTA (core.fsyncmethod=batch)' ' + check_unpack test-2-${packname_2} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'pack with OFS_DELTA' ' @@ -195,7 +204,11 @@ test_expect_success 'pack with OFS_DELTA' ' ' test_expect_success 'unpack with OFS_DELTA' ' - check_unpack test-3-${packname_3} + check_unpack test-3-${packname_3} obj-list +' + +test_expect_success 'unpack with OFS_DELTA (core.fsyncmethod=batch)' ' + check_unpack test-3-${packname_3} obj-list "$BATCH_CONFIGURATION" ' test_expect_success 'compare delta flavors' ' diff --git a/t/t5301-sliding-window.sh b/t/t5301-sliding-window.sh index 76f9798ab9..3ccaaeb397 100755 --- a/t/t5301-sliding-window.sh +++ b/t/t5301-sliding-window.sh @@ -4,6 +4,8 @@ # test_description='mmap sliding window tests' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success \ diff --git a/t/t5313-pack-bounds-checks.sh b/t/t5313-pack-bounds-checks.sh index 535313e4dc..cc4cfaa9d3 100755 --- a/t/t5313-pack-bounds-checks.sh +++ b/t/t5313-pack-bounds-checks.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='bounds-checking of access to mmapped on-disk file formats' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh clear_base () { diff --git a/t/t5316-pack-delta-depth.sh b/t/t5316-pack-delta-depth.sh index e9045009a1..eb4ef3dda4 100755 --- a/t/t5316-pack-delta-depth.sh +++ b/t/t5316-pack-delta-depth.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='pack-objects breaks long cross-pack delta chains' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # This mirrors a repeated push setup: diff --git a/t/t5317-pack-objects-filter-objects.sh b/t/t5317-pack-objects-filter-objects.sh index 33b740ce62..bb633c9b09 100755 --- a/t/t5317-pack-objects-filter-objects.sh +++ b/t/t5317-pack-objects-filter-objects.sh @@ -10,9 +10,6 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME # Test blob:none filter. test_expect_success 'setup r1' ' - echo "{print \$1}" >print_1.awk && - echo "{print \$2}" >print_2.awk && - git init r1 && for n in 1 2 3 4 5 do @@ -22,10 +19,13 @@ test_expect_success 'setup r1' ' done ' +parse_verify_pack_blob_oid () { + awk '{print $1}' - +} + test_expect_success 'verify blob count in normal packfile' ' - git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 | + test_parse_ls_files_stage_oids | sort >expected && git -C r1 pack-objects --revs --stdout >all.pack <<-EOF && @@ -35,7 +35,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r1 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -54,12 +54,12 @@ test_expect_success 'verify blob:none packfile has no blobs' ' test_expect_success 'verify normal and blob:none packfiles have same commits/trees' ' git -C r1 verify-pack -v ../all.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >expected && git -C r1 verify-pack -v ../filter.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -123,8 +123,8 @@ test_expect_success 'setup r2' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout >all.pack <<-EOF && @@ -134,7 +134,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r2 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -161,8 +161,8 @@ test_expect_success 'verify blob:limit=1000' ' ' test_expect_success 'verify blob:limit=1001' ' - git -C r2 ls-files -s large.1000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1001 >filter.pack <<-EOF && @@ -172,15 +172,15 @@ test_expect_success 'verify blob:limit=1001' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=10001' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=10001 >filter.pack <<-EOF && @@ -190,15 +190,15 @@ test_expect_success 'verify blob:limit=10001' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=1k' ' - git -C r2 ls-files -s large.1000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1k >filter.pack <<-EOF && @@ -208,15 +208,15 @@ test_expect_success 'verify blob:limit=1k' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify explicitly specifying oversized blob in input' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && echo HEAD >objects && @@ -226,15 +226,15 @@ test_expect_success 'verify explicitly specifying oversized blob in input' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify blob:limit=1m' ' - git -C r2 ls-files -s large.1000 large.10000 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r2 ls-files -s large.1000 large.10000 | + test_parse_ls_files_stage_oids | sort >expected && git -C r2 pack-objects --revs --stdout --filter=blob:limit=1m >filter.pack <<-EOF && @@ -244,7 +244,7 @@ test_expect_success 'verify blob:limit=1m' ' git -C r2 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -253,12 +253,12 @@ test_expect_success 'verify blob:limit=1m' ' test_expect_success 'verify normal and blob:limit packfiles have same commits/trees' ' git -C r2 verify-pack -v ../all.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >expected && git -C r2 verify-pack -v ../filter.pack >verify_result && grep -E "commit|tree" verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -289,9 +289,8 @@ test_expect_success 'setup r3' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r3 ls-files -s sparse1 sparse2 dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r3 pack-objects --revs --stdout >all.pack <<-EOF && @@ -301,7 +300,7 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r3 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -342,9 +341,8 @@ test_expect_success 'setup r4' ' ' test_expect_success 'verify blob count in normal packfile' ' - git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s pattern sparse1 sparse2 dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 pack-objects --revs --stdout >all.pack <<-EOF && @@ -354,19 +352,19 @@ test_expect_success 'verify blob count in normal packfile' ' git -C r4 verify-pack -v ../all.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify sparse:oid=OID' ' - git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 ls-files -s pattern >staged && - oid=$(awk -f print_2.awk staged) && + oid=$(test_parse_ls_files_stage_oids <staged) && git -C r4 pack-objects --revs --stdout --filter=sparse:oid=$oid >filter.pack <<-EOF && HEAD EOF @@ -374,15 +372,15 @@ test_expect_success 'verify sparse:oid=OID' ' git -C r4 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed ' test_expect_success 'verify sparse:oid=oid-ish' ' - git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r4 ls-files -s dir1/sparse1 dir1/sparse2 | + test_parse_ls_files_stage_oids | sort >expected && git -C r4 pack-objects --revs --stdout --filter=sparse:oid=main:pattern >filter.pack <<-EOF && @@ -392,7 +390,7 @@ test_expect_success 'verify sparse:oid=oid-ish' ' git -C r4 verify-pack -v ../filter.pack >verify_result && grep blob verify_result | - awk -f print_1.awk | + parse_verify_pack_blob_oid | sort >observed && test_cmp expected observed @@ -402,9 +400,8 @@ test_expect_success 'verify sparse:oid=oid-ish' ' # This models previously omitted objects that we did not receive. test_expect_success 'setup r1 - delete loose blobs' ' - git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 \ - >ls_files_result && - awk -f print_2.awk ls_files_result | + git -C r1 ls-files -s file.1 file.2 file.3 file.4 file.5 | + test_parse_ls_files_stage_oids | sort >expected && for id in `cat expected | sed "s|..|&/|"` diff --git a/t/t5320-delta-islands.sh b/t/t5320-delta-islands.sh index fea92a5777..124d47603d 100755 --- a/t/t5320-delta-islands.sh +++ b/t/t5320-delta-islands.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='exercise delta islands' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # returns true iff $1 is a delta based on $2 diff --git a/t/t5322-pack-objects-sparse.sh b/t/t5322-pack-objects-sparse.sh index d39958c066..770695c927 100755 --- a/t/t5322-pack-objects-sparse.sh +++ b/t/t5322-pack-objects-sparse.sh @@ -4,6 +4,7 @@ test_description='pack-objects object selection using sparse algorithm' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup repo' ' diff --git a/t/t5329-pack-objects-cruft.sh b/t/t5329-pack-objects-cruft.sh new file mode 100755 index 0000000000..b481224b93 --- /dev/null +++ b/t/t5329-pack-objects-cruft.sh @@ -0,0 +1,739 @@ +#!/bin/sh + +test_description='cruft pack related pack-objects tests' +. ./test-lib.sh + +objdir=.git/objects +packdir=$objdir/pack + +basic_cruft_pack_tests () { + expire="$1" + + test_expect_success "unreachable loose objects are packed (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + git repack -Ad && + test_commit loose && + + test-tool chmtime +2000 "$objdir/$(test_oid_to_path \ + $(git rev-parse loose:loose.t))" && + test-tool chmtime +1000 "$objdir/$(test_oid_to_path \ + $(git rev-parse loose^{tree}))" && + + ( + git rev-list --objects --no-object-names base..loose | + while read oid + do + path="$objdir/$(test_oid_to_path "$oid")" && + printf "%s %d\n" "$oid" "$(test-tool chmtime --get "$path")" + done | + sort -k1 + ) >expect && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration="$expire" $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "unreachable packed objects are packed (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + test_commit other && + + git rev-list --objects --no-object-names packed.. >objects && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + other="$(git pack-objects --delta-base-offset \ + $packdir/pack <objects)" && + git prune-packed && + + test-tool chmtime --get -100 "$packdir/pack-$other.pack" >expect && + + cruft="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF + $keep + -pack-$other.pack + EOF + )" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + cut -d" " -f2 <actual.raw | sort -u >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "unreachable cruft objects are repacked (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + test_commit other && + + git rev-list --objects --no-object-names packed.. >objects && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + + cruft_a="$(echo $keep | git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack)" && + git prune-packed && + cruft_b="$(git pack-objects --cruft --cruft-expiration="$expire" $packdir/pack <<-EOF + $keep + -pack-$cruft_a.pack + EOF + )" && + + test-tool pack-mtimes "pack-$cruft_a.mtimes" >expect.raw && + test-tool pack-mtimes "pack-$cruft_b.mtimes" >actual.raw && + + sort <expect.raw >expect && + sort <actual.raw >actual && + + test_cmp expect actual + ) + ' + + test_expect_success "multiple cruft packs (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + + test_commit cruft && + loose="$objdir/$(test_oid_to_path $(git rev-parse cruft))" && + + # generate three copies of the cruft object in different + # cruft packs, each with a unique mtime: + # - one expired (1000 seconds ago) + # - two non-expired (one 1000 seconds in the future, + # one 1500 seconds in the future) + test-tool chmtime =-1000 "$loose" && + git pack-objects --cruft $packdir/pack-A <<-EOF && + $keep + EOF + test-tool chmtime =+1000 "$loose" && + git pack-objects --cruft $packdir/pack-B <<-EOF && + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + EOF + test-tool chmtime =+1500 "$loose" && + git pack-objects --cruft $packdir/pack-C <<-EOF && + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + -$(basename $(ls $packdir/pack-B-*.pack)) + EOF + + # ensure the resulting cruft pack takes the most recent + # mtime among all copies + cruft="$(git pack-objects --cruft \ + --cruft-expiration="$expire" \ + $packdir/pack <<-EOF + $keep + -$(basename $(ls $packdir/pack-A-*.pack)) + -$(basename $(ls $packdir/pack-B-*.pack)) + -$(basename $(ls $packdir/pack-C-*.pack)) + EOF + )" && + + test-tool pack-mtimes "$(basename $(ls $packdir/pack-C-*.mtimes))" >expect.raw && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + sort expect.raw >expect && + sort actual.raw >actual && + test_cmp expect actual + ) + ' + + test_expect_success "cruft packs tolerate missing trees (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + + tree="$(git rev-parse cruft^{tree})" && + + git reset --hard reachable && + git tag -d cruft && + git reflog expire --all --expire=all && + + # remove the unreachable tree, but leave the commit + # which has it as its root tree intact + rm -fr "$objdir/$(test_oid_to_path "$tree")" && + + git repack -Ad && + basename $(ls $packdir/pack-*.pack) >in && + git pack-objects --cruft --cruft-expiration="$expire" \ + $packdir/pack <in + ) + ' + + test_expect_success "cruft packs tolerate missing blobs (expire $expire)" ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + + blob="$(git rev-parse cruft:cruft.t)" && + + git reset --hard reachable && + git tag -d cruft && + git reflog expire --all --expire=all && + + # remove the unreachable blob, but leave the commit (and + # the root tree of that commit) intact + rm -fr "$objdir/$(test_oid_to_path "$blob")" && + + git repack -Ad && + basename $(ls $packdir/pack-*.pack) >in && + git pack-objects --cruft --cruft-expiration="$expire" \ + $packdir/pack <in + ) + ' +} + +basic_cruft_pack_tests never +basic_cruft_pack_tests 2.weeks.ago + +test_expect_success 'cruft tags rescue tagged objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit tagged && + git tag -a annotated -m tag && + + git rev-list --objects --no-object-names packed.. >objects && + while read oid + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $oid)" + done <objects && + + test-tool chmtime -500 \ + "$objdir/$(test_oid_to_path $(git rev-parse annotated))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + cut -f1 -d" " <actual.raw | sort >actual && + + ( + cat objects && + git rev-parse annotated + ) >expect.raw && + sort <expect.raw >expect && + + test_cmp expect actual && + cat actual + ) +' + +test_expect_success 'cruft commits rescue parents, trees' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit old && + test_commit new && + + git rev-list --objects --no-object-names packed..new >objects && + while read object + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $object)" + done <objects && + test-tool chmtime +500 "$objdir/$(test_oid_to_path \ + $(git rev-parse HEAD))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + + cut -d" " -f1 <actual.raw | sort >actual && + sort <objects >expect && + + test_cmp expect actual + ) +' + +test_expect_success 'cruft trees rescue sub-trees, blobs' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + mkdir -p dir/sub && + echo foo >foo && + echo bar >dir/bar && + echo baz >dir/sub/baz && + + test_tick && + git add . && + git commit -m "pruned" && + + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD^{tree}))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:foo))" && + test-tool chmtime -500 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/bar))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub))" && + test-tool chmtime -1000 "$objdir/$(test_oid_to_path $(git rev-parse HEAD:dir/sub/baz))" && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + test-tool pack-mtimes "pack-$cruft.mtimes" >actual.raw && + cut -f1 -d" " <actual.raw | sort >actual && + + git rev-parse HEAD:dir HEAD:dir/bar HEAD:dir/sub HEAD:dir/sub/baz >expect.raw && + sort <expect.raw >expect && + + test_cmp expect actual + ) +' + +test_expect_success 'expired objects are pruned' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit packed && + git repack -Ad && + + test_commit pruned && + + git rev-list --objects --no-object-names packed..pruned >objects && + while read object + do + test-tool chmtime -1000 \ + "$objdir/$(test_oid_to_path $object)" + done <objects && + + keep="$(basename "$(ls $packdir/pack-*.pack)")" && + cruft="$(echo $keep | git pack-objects --cruft \ + --cruft-expiration=750.seconds.ago \ + $packdir/pack)" && + + test-tool pack-mtimes "pack-$cruft.mtimes" >actual && + test_must_be_empty actual + ) +' + +test_expect_success 'repack --cruft generates a cruft pack' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git branch -M main && + git checkout --orphan other && + test_commit unreachable && + + git checkout main && + git branch -D other && + git tag -d unreachable && + # objects are not cruft if they are contained in the reflogs + git reflog expire --all --expire=all && + + git rev-list --objects --all --no-object-names >reachable.raw && + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + sort <reachable.raw >reachable && + comm -13 reachable objects >unreachable && + + git repack --cruft -d && + + cruft=$(basename $(ls $packdir/pack-*.mtimes) .mtimes) && + pack=$(basename $(ls $packdir/pack-*.pack | grep -v $cruft) .pack) && + + git show-index <$packdir/$pack.idx >actual.raw && + cut -f2 -d" " actual.raw | sort >actual && + test_cmp reachable actual && + + git show-index <$packdir/$cruft.idx >actual.raw && + cut -f2 -d" " actual.raw | sort >actual && + test_cmp unreachable actual + ) +' + +test_expect_success 'loose objects mtimes upsert others' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + test_commit cruft && + # incremental repack, leaving existing objects loose (so + # they can be "freshened") + git repack && + + tip="$(git rev-parse cruft)" && + path="$objdir/$(test_oid_to_path "$tip")" && + test-tool chmtime --get +1000 "$path" >expect && + + git checkout main && + git branch -D other && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft -d && + + mtimes="$(basename $(ls $packdir/pack-*.mtimes))" && + test-tool pack-mtimes "$mtimes" >actual.raw && + grep "$tip" actual.raw | cut -d" " -f2 >actual && + test_cmp expect actual + ) +' + +test_expect_success 'expiring cruft objects with git gc' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git branch -M main && + git checkout --orphan other && + test_commit unreachable && + + git checkout main && + git branch -D other && + git tag -d unreachable && + # objects are not cruft if they are contained in the reflogs + git reflog expire --all --expire=all && + + git rev-list --objects --all --no-object-names >reachable.raw && + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + sort <reachable.raw >reachable && + comm -13 reachable objects >unreachable && + + git repack --cruft -d && + + mtimes=$(ls .git/objects/pack/pack-*.mtimes) && + test_path_is_file $mtimes && + + git gc --cruft --prune=now && + + git cat-file --batch-all-objects --batch-check="%(objectname)" >objects && + + comm -23 unreachable objects >removed && + test_cmp unreachable removed && + test_path_is_missing $mtimes + ) +' + +test_expect_success 'cruft packs are not included in geometric repack' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + test_commit cruft && + git repack -d && + + git checkout main && + git branch -D other && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft && + + find $packdir -type f | sort >before && + git repack --geometric=2 -d && + find $packdir -type f | sort >after && + + test_cmp before after + ) +' + +test_expect_success 'repack --geometric collects once-cruft objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + git repack -Ad && + git branch -M main && + + git checkout --orphan other && + git rm -rf . && + test_commit --no-tag cruft && + cruft="$(git rev-parse HEAD)" && + + git checkout main && + git branch -D other && + git reflog expire --all --expire=all && + + # Pack the objects created in the previous step into a cruft + # pack. Intentionally leave loose copies of those objects + # around so we can pick them up in a subsequent --geometric + # reapack. + git repack --cruft && + + # Now make those objects reachable, and ensure that they are + # packed into the new pack created via a --geometric repack. + git update-ref refs/heads/other $cruft && + + # Without this object, the set of unpacked objects is exactly + # the set of objects already in the cruft pack. Tweak that set + # to ensure we do not overwrite the cruft pack entirely. + test_commit reachable2 && + + find $packdir -name "pack-*.idx" | sort >before && + git repack --geometric=2 -d && + find $packdir -name "pack-*.idx" | sort >after && + + { + git rev-list --objects --no-object-names $cruft && + git rev-list --objects --no-object-names reachable..reachable2 + } >want.raw && + sort want.raw >want && + + pack=$(comm -13 before after) && + git show-index <$pack >objects.raw && + + cut -d" " -f2 objects.raw | sort >got && + + test_cmp want got + ) +' + +test_expect_success 'cruft repack with no reachable objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + git repack -ad && + + base="$(git rev-parse base)" && + + git for-each-ref --format="delete %(refname)" >in && + git update-ref --stdin <in && + git reflog expire --all --expire=all && + rm -fr .git/index && + + git repack --cruft -d && + + git cat-file -t $base + ) +' + +test_expect_success 'cruft repack ignores --max-pack-size' ' + git init max-pack-size && + ( + cd max-pack-size && + test_commit base && + # two cruft objects which exceed the maximum pack size + test-tool genrandom foo 1048576 | git hash-object --stdin -w && + test-tool genrandom bar 1048576 | git hash-object --stdin -w && + git repack --cruft --max-pack-size=1M && + find $packdir -name "*.mtimes" >cruft && + test_line_count = 1 cruft && + test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && + test_line_count = 2 objects + ) +' + +test_expect_success 'cruft repack ignores pack.packSizeLimit' ' + ( + cd max-pack-size && + # repack everything back together to remove the existing cruft + # pack (but to keep its objects) + git repack -adk && + git -c pack.packSizeLimit=1M repack --cruft && + # ensure the same post condition is met when --max-pack-size + # would otherwise be inferred from the configuration + find $packdir -name "*.mtimes" >cruft && + test_line_count = 1 cruft && + test-tool pack-mtimes "$(basename "$(cat cruft)")" >objects && + test_line_count = 2 objects + ) +' + +test_expect_success 'cruft repack respects repack.cruftWindow' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + + GIT_TRACE2_EVENT=$(pwd)/event.trace \ + git -c pack.window=1 -c repack.cruftWindow=2 repack \ + --cruft --window=3 && + + grep "pack-objects.*--window=2.*--cruft" event.trace + ) +' + +test_expect_success 'cruft repack respects --window by default' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + + GIT_TRACE2_EVENT=$(pwd)/event.trace \ + git -c pack.window=2 repack --cruft --window=3 && + + grep "pack-objects.*--window=3.*--cruft" event.trace + ) +' + +test_expect_success 'cruft repack respects --quiet' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit base && + GIT_PROGRESS_DELAY=0 git repack --cruft --quiet 2>err && + test_must_be_empty err + ) +' + +test_expect_success 'cruft --local drops unreachable objects' ' + git init alternate && + git init repo && + test_when_finished "rm -fr alternate repo" && + + test_commit -C alternate base && + # Pack all objects in alterate so that the cruft repack in "repo" sees + # the object it dropped due to `--local` as packed. Otherwise this + # object would not appear packed anywhere (since it is not packed in + # alternate and likewise not part of the cruft pack in the other repo + # because of `--local`). + git -C alternate repack -ad && + + ( + cd repo && + + object="$(git -C ../alternate rev-parse HEAD:base.t)" && + git -C ../alternate cat-file -p $object >contents && + + # Write some reachable objects and two unreachable ones: one + # that the alternate has and another that is unique. + test_commit other && + git hash-object -w -t blob contents && + cruft="$(echo cruft | git hash-object -w -t blob --stdin)" && + + ( cd ../alternate/.git/objects && pwd ) \ + >.git/objects/info/alternates && + + test_path_is_file $objdir/$(test_oid_to_path $cruft) && + test_path_is_file $objdir/$(test_oid_to_path $object) && + + git repack -d --cruft --local && + + test-tool pack-mtimes "$(basename $(ls $packdir/pack-*.mtimes))" \ + >objects && + ! grep $object objects && + grep $cruft objects + ) +' + +test_expect_success 'MIDX bitmaps tolerate reachable cruft objects' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + test_commit reachable && + test_commit cruft && + unreachable="$(git rev-parse cruft)" && + + git reset --hard $unreachable^ && + git tag -d cruft && + git reflog expire --all --expire=all && + + git repack --cruft -d && + + # resurrect the unreachable object via a new commit. the + # new commit will get selected for a bitmap, but be + # missing one of its parents from the selected packs. + git reset --hard $unreachable && + test_commit resurrect && + + git repack --write-midx --write-bitmap-index --geometric=2 -d + ) +' + +test_expect_success 'cruft objects are freshend via loose' ' + git init repo && + test_when_finished "rm -fr repo" && + ( + cd repo && + + echo "cruft" >contents && + blob="$(git hash-object -w -t blob contents)" && + loose="$objdir/$(test_oid_to_path $blob)" && + + test_commit base && + + git repack --cruft -d && + + test_path_is_missing "$loose" && + test-tool pack-mtimes "$(basename "$(ls $packdir/pack-*.mtimes)")" >cruft && + grep "$blob" cruft && + + # write the same object again + git hash-object -w -t blob contents && + + test_path_is_file "$loose" + ) +' + +test_done diff --git a/t/t5506-remote-groups.sh b/t/t5506-remote-groups.sh index 8f150c0793..5bac03ede8 100755 --- a/t/t5506-remote-groups.sh +++ b/t/t5506-remote-groups.sh @@ -4,6 +4,7 @@ test_description='git remote group handling' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh mark() { diff --git a/t/t5513-fetch-track.sh b/t/t5513-fetch-track.sh index 65d1e05bd6..c46c4dbaef 100755 --- a/t/t5513-fetch-track.sh +++ b/t/t5513-fetch-track.sh @@ -2,6 +2,7 @@ test_description='fetch follows remote-tracking branches correctly' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5515-fetch-merge-logic.sh b/t/t5515-fetch-merge-logic.sh index 320d26796d..c100a809c5 100755 --- a/t/t5515-fetch-merge-logic.sh +++ b/t/t5515-fetch-merge-logic.sh @@ -14,6 +14,7 @@ export GIT_TEST_PROTOCOL_VERSION GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh build_script () { diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 4dfb080433..e99c31f8c3 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -598,6 +598,26 @@ test_expect_success 'branch.*.pushremote config order is irrelevant' ' check_push_result two_repo $the_commit heads/main ' +test_expect_success 'push rejects empty branch name entries' ' + mk_test one_repo heads/main && + test_config remote.one.url one_repo && + test_config branch..remote one && + test_config branch..merge refs/heads/ && + test_config branch.main.remote one && + test_config branch.main.merge refs/heads/main && + test_must_fail git push 2>err && + grep "bad config variable .branch\.\." err +' + +test_expect_success 'push ignores "branch." config without subsection' ' + mk_test one_repo heads/main && + test_config remote.one.url one_repo && + test_config branch.autoSetupMerge true && + test_config branch.main.remote one && + test_config branch.main.merge refs/heads/main && + git push +' + test_expect_success 'push with dry-run' ' mk_test testrepo heads/main && diff --git a/t/t5518-fetch-exit-status.sh b/t/t5518-fetch-exit-status.sh index 5c4ac2556e..c13120088f 100755 --- a/t/t5518-fetch-exit-status.sh +++ b/t/t5518-fetch-exit-status.sh @@ -8,6 +8,7 @@ test_description='fetch exit status test' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t5532-fetch-proxy.sh b/t/t5532-fetch-proxy.sh index 9c2798603b..d664912799 100755 --- a/t/t5532-fetch-proxy.sh +++ b/t/t5532-fetch-proxy.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='fetching via git:// using core.gitproxy' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup remote repo' ' diff --git a/t/t5600-clone-fail-cleanup.sh b/t/t5600-clone-fail-cleanup.sh index 34b3df4027..c814afa565 100755 --- a/t/t5600-clone-fail-cleanup.sh +++ b/t/t5600-clone-fail-cleanup.sh @@ -13,6 +13,7 @@ Unless the directory already exists, in which case we clean up only what we wrote. ' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh corrupt_repo () { diff --git a/t/t5900-repo-selection.sh b/t/t5900-repo-selection.sh index 14e59c5b3e..a84faac242 100755 --- a/t/t5900-repo-selection.sh +++ b/t/t5900-repo-selection.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='selecting remote repo in ambiguous cases' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh reset() { diff --git a/t/t6002-rev-list-bisect.sh b/t/t6002-rev-list-bisect.sh index b95a0212ad..162cf50778 100755 --- a/t/t6002-rev-list-bisect.sh +++ b/t/t6002-rev-list-bisect.sh @@ -4,6 +4,7 @@ # test_description='Tests git rev-list --bisect functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions diff --git a/t/t6003-rev-list-topo-order.sh b/t/t6003-rev-list-topo-order.sh index 24d1836f41..1f7d7dd20c 100755 --- a/t/t6003-rev-list-topo-order.sh +++ b/t/t6003-rev-list-topo-order.sh @@ -5,6 +5,7 @@ test_description='Tests git rev-list --topo-order functionality' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh . "$TEST_DIRECTORY"/lib-t6000.sh # t6xxx specific functions diff --git a/t/t6005-rev-list-count.sh b/t/t6005-rev-list-count.sh index e960049f64..0729f800c3 100755 --- a/t/t6005-rev-list-count.sh +++ b/t/t6005-rev-list-count.sh @@ -2,6 +2,7 @@ test_description='git rev-list --max-count and --skip test' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6018-rev-list-glob.sh b/t/t6018-rev-list-glob.sh index 24b34add83..e1abc5c2b3 100755 --- a/t/t6018-rev-list-glob.sh +++ b/t/t6018-rev-list-glob.sh @@ -5,6 +5,7 @@ test_description='rev-list/rev-parse --glob' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh commit () { diff --git a/t/t6100-rev-list-in-order.sh b/t/t6100-rev-list-in-order.sh index e934bc239c..88ed7bd75a 100755 --- a/t/t6100-rev-list-in-order.sh +++ b/t/t6100-rev-list-in-order.sh @@ -2,6 +2,7 @@ test_description='rev-list testing in-commit-order' +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup a commit history with trees, blobs' ' diff --git a/t/t6101-rev-parse-parents.sh b/t/t6101-rev-parse-parents.sh index c571fa5179..a3a41c7a3e 100755 --- a/t/t6101-rev-parse-parents.sh +++ b/t/t6101-rev-parse-parents.sh @@ -8,6 +8,7 @@ test_description='Test git rev-parse with different parent options' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_cmp_rev_output () { diff --git a/t/t6110-rev-list-sparse.sh b/t/t6110-rev-list-sparse.sh index 13c1da5352..ddefc7f24e 100755 --- a/t/t6110-rev-list-sparse.sh +++ b/t/t6110-rev-list-sparse.sh @@ -4,6 +4,7 @@ test_description='operations that cull histories in unusual ways' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t6114-keep-packs.sh b/t/t6114-keep-packs.sh index 9239d8aa46..44246f8a63 100755 --- a/t/t6114-keep-packs.sh +++ b/t/t6114-keep-packs.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='rev-list with .keep packs' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success 'setup' ' diff --git a/t/t6131-pathspec-icase.sh b/t/t6131-pathspec-icase.sh index 39fc3f6769..770cce026c 100755 --- a/t/t6131-pathspec-icase.sh +++ b/t/t6131-pathspec-icase.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='test case insensitive pathspec limiting' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh if test_have_prereq CASE_INSENSITIVE_FS diff --git a/t/t6132-pathspec-exclude.sh b/t/t6132-pathspec-exclude.sh index 8ff1d76f79..9fdafeb1e9 100755 --- a/t/t6132-pathspec-exclude.sh +++ b/t/t6132-pathspec-exclude.sh @@ -195,6 +195,7 @@ test_expect_success 'multiple exclusions' ' ' test_expect_success 't_e_i() exclude case #8' ' + test_when_finished "rm -fr case8" && git init case8 && ( cd case8 && @@ -244,4 +245,184 @@ test_expect_success 'grep --untracked PATTERN :(exclude)*FILE' ' test_cmp expect-grep actual-grep ' +# Depending on the command, all negative pathspec needs to subtract +# either from the full tree, or from the current directory. +# +# The sample tree checked out at this point has: +# file +# sub/file +# sub/file2 +# sub/sub/file +# sub/sub/sub/file +# sub2/file +# +# but there may also be some cruft that interferes with "git clean" +# and "git add" tests. + +test_expect_success 'archive with all negative' ' + git reset --hard && + git clean -f && + git -C sub archive --format=tar HEAD -- ":!sub/" >archive && + "$TAR" tf archive >actual && + cat >expect <<-\EOF && + file + file2 + EOF + test_cmp expect actual +' + +test_expect_success 'add with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + git clean -f && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo smudge >>"$path" || return 1 + done && + git -C sub add -- ":!sub/" && + git diff --name-only --no-renames --cached >actual && + cat >expect <<-\EOF && + file + sub/file + sub2/file + EOF + test_cmp expect actual && + git diff --name-only --no-renames >actual && + echo sub/sub/file >expect && + test_cmp expect actual +' + +test_expect_success 'add -p with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + git clean -f && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo smudge >>"$path" || return 1 + done && + yes | git -C sub add -p -- ":!sub/" && + git diff --name-only --no-renames --cached >actual && + cat >expect <<-\EOF && + file + sub/file + sub2/file + EOF + test_cmp expect actual && + git diff --name-only --no-renames >actual && + echo sub/sub/file >expect && + test_cmp expect actual +' + +test_expect_success 'clean with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + test_when_finished "git reset --hard $H && git clean -f" && + git clean -f && + for path in file9 sub/file9 sub/sub/file9 sub2/file9 + do + echo cruft >"$path" || return 1 + done && + git -C sub clean -f -- ":!sub" && + test_path_is_file file9 && + test_path_is_missing sub/file9 && + test_path_is_file sub/sub/file9 && + test_path_is_file sub2/file9 +' + +test_expect_success 'commit with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo smudge >>"$path" || return 1 + done && + git -C sub commit -m sample -- ":!sub/" && + git diff --name-only --no-renames HEAD^ HEAD >actual && + cat >expect <<-\EOF && + file + sub/file + sub2/file + EOF + test_cmp expect actual && + git diff --name-only --no-renames HEAD >actual && + echo sub/sub/file >expect && + test_cmp expect actual +' + +test_expect_success 'reset with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo smudge >>"$path" && + git add "$path" || return 1 + done && + git -C sub reset --quiet -- ":!sub/" && + git diff --name-only --no-renames --cached >actual && + echo sub/sub/file >expect && + test_cmp expect actual +' + +test_expect_success 'grep with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo "needle $path" >>"$path" || return 1 + done && + git -C sub grep -h needle -- ":!sub/" >actual && + cat >expect <<-\EOF && + needle sub/file + EOF + test_cmp expect actual +' + +test_expect_success 'ls-files with all negative' ' + git reset --hard && + git -C sub ls-files -- ":!sub/" >actual && + cat >expect <<-\EOF && + file + file2 + EOF + test_cmp expect actual +' + +test_expect_success 'rm with all negative' ' + git reset --hard && + test_when_finished "git reset --hard" && + git -C sub rm -r --cached -- ":!sub/" >actual && + git diff --name-only --no-renames --diff-filter=D --cached >actual && + cat >expect <<-\EOF && + sub/file + sub/file2 + EOF + test_cmp expect actual +' + +test_expect_success 'stash with all negative' ' + H=$(git rev-parse HEAD) && + git reset --hard $H && + test_when_finished "git reset --hard $H" && + for path in file sub/file sub/sub/file sub2/file + do + echo smudge >>"$path" || return 1 + done && + git -C sub stash push -m sample -- ":!sub/" && + git diff --name-only --no-renames HEAD >actual && + echo sub/sub/file >expect && + test_cmp expect actual && + git stash show --name-only >actual && + cat >expect <<-\EOF && + file + sub/file + sub2/file + EOF + test_cmp expect actual +' + test_done diff --git a/t/t6428-merge-conflicts-sparse.sh b/t/t6428-merge-conflicts-sparse.sh index 142c9aaabc..064be1b629 100755 --- a/t/t6428-merge-conflicts-sparse.sh +++ b/t/t6428-merge-conflicts-sparse.sh @@ -87,7 +87,7 @@ test_expect_success 'conflicting entries written to worktree even if sparse' ' test_path_is_file numerals && git sparse-checkout init && - git sparse-checkout set README && + git sparse-checkout set --no-cone README && test_path_is_file README && test_path_is_missing numerals && @@ -123,7 +123,7 @@ test_expect_success 'present-despite-SKIP_WORKTREE handled reasonably' ' test_path_is_file numerals && git sparse-checkout init && - git sparse-checkout set README && + git sparse-checkout set --no-cone README && test_path_is_file README && test_path_is_missing numerals && diff --git a/t/t7002-mv-sparse-checkout.sh b/t/t7002-mv-sparse-checkout.sh index 1d3d2aca21..f0f7cbfcdb 100755 --- a/t/t7002-mv-sparse-checkout.sh +++ b/t/t7002-mv-sparse-checkout.sh @@ -27,7 +27,7 @@ test_expect_success 'setup' " test_expect_success 'mv refuses to move sparse-to-sparse' ' test_when_finished rm -f e && git reset --hard && - git sparse-checkout set a && + git sparse-checkout set --no-cone a && touch b && test_must_fail git mv b e 2>stderr && cat sparse_error_header >expect && diff --git a/t/t7008-filter-branch-null-sha1.sh b/t/t7008-filter-branch-null-sha1.sh index 9ba9f24ad2..93fbc92b8d 100755 --- a/t/t7008-filter-branch-null-sha1.sh +++ b/t/t7008-filter-branch-null-sha1.sh @@ -1,6 +1,7 @@ #!/bin/sh test_description='filter-branch removal of trees with null sha1' + . ./test-lib.sh test_expect_success 'setup: base commits' ' diff --git a/t/t7012-skip-worktree-writing.sh b/t/t7012-skip-worktree-writing.sh index cb9f1a6981..cd5c20fe51 100755 --- a/t/t7012-skip-worktree-writing.sh +++ b/t/t7012-skip-worktree-writing.sh @@ -151,7 +151,7 @@ test_expect_success 'stash restore in sparse checkout' ' git stash push && - git sparse-checkout set subdir && + git sparse-checkout set --no-cone subdir && # Ensure after sparse-checkout we only have expected files cat >expect <<-EOF && diff --git a/t/t7519-status-fsmonitor.sh b/t/t7519-status-fsmonitor.sh index d4f9c6a837..8348e3ae7d 100755 --- a/t/t7519-status-fsmonitor.sh +++ b/t/t7519-status-fsmonitor.sh @@ -55,6 +55,38 @@ test_lazy_prereq UNTRACKED_CACHE ' test $ret -ne 1 ' +# Test that we detect and disallow repos that are incompatible with FSMonitor. +test_expect_success 'incompatible bare repo' ' + test_when_finished "rm -rf ./bare-clone actual expect" && + git init --bare bare-clone && + + test_must_fail \ + git -C ./bare-clone -c core.fsmonitor=foo \ + update-index --fsmonitor 2>actual && + grep "bare repository .* is incompatible with fsmonitor" actual && + + test_must_fail \ + git -C ./bare-clone -c core.fsmonitor=true \ + update-index --fsmonitor 2>actual && + grep "bare repository .* is incompatible with fsmonitor" actual +' + +test_expect_success FSMONITOR_DAEMON 'run fsmonitor-daemon in bare repo' ' + test_when_finished "rm -rf ./bare-clone actual" && + git init --bare bare-clone && + test_must_fail git -C ./bare-clone fsmonitor--daemon run 2>actual && + grep "bare repository .* is incompatible with fsmonitor" actual +' + +test_expect_success MINGW,FSMONITOR_DAEMON 'run fsmonitor-daemon in virtual repo' ' + test_when_finished "rm -rf ./fake-virtual-clone actual" && + git init fake-virtual-clone && + test_must_fail git -C ./fake-virtual-clone \ + -c core.virtualfilesystem=true \ + fsmonitor--daemon run 2>actual && + grep "virtual repository .* is incompatible with fsmonitor" actual +' + test_expect_success 'setup' ' : >tracked && : >modified && diff --git a/t/t7527-builtin-fsmonitor.sh b/t/t7527-builtin-fsmonitor.sh index bd0c952a11..56c0dfffea 100755 --- a/t/t7527-builtin-fsmonitor.sh +++ b/t/t7527-builtin-fsmonitor.sh @@ -124,6 +124,36 @@ test_expect_success 'implicit daemon start' ' test_must_fail git -C test_implicit fsmonitor--daemon status ' +# Verify that the daemon has shutdown. Spin a few seconds to +# make the test a little more robust during CI testing. +# +# We're looking for an implicit shutdown, such as when we delete or +# rename the ".git" directory. Our delete/rename will cause a file +# system event that the daemon will see and the daemon will +# auto-shutdown as soon as it sees it. But this is racy with our `git +# fsmonitor--daemon status` commands (and we cannot use a cookie file +# here to help us). So spin a little and give the daemon a chance to +# see the event. (This is primarily for underpowered CI build/test +# machines (where it might take a moment to wake and reschedule the +# daemon process) to avoid false alarms during test runs.) +# +IMPLICIT_TIMEOUT=5 + +verify_implicit_shutdown () { + r=$1 && + + k=0 && + while test "$k" -lt $IMPLICIT_TIMEOUT + do + git -C $r fsmonitor--daemon status || return 0 + + sleep 1 + k=$(( $k + 1 )) + done && + + return 1 +} + test_expect_success 'implicit daemon stop (delete .git)' ' test_when_finished "stop_daemon_delete_repo test_implicit_1" && @@ -142,10 +172,9 @@ test_expect_success 'implicit daemon stop (delete .git)' ' # This would make the test result dependent upon whether we # were using fsmonitor on our development worktree. # - sleep 1 && mkdir test_implicit_1/.git && - test_must_fail git -C test_implicit_1 fsmonitor--daemon status + verify_implicit_shutdown test_implicit_1 ' test_expect_success 'implicit daemon stop (rename .git)' ' @@ -160,10 +189,70 @@ test_expect_success 'implicit daemon stop (rename .git)' ' # See [1] above. # - sleep 1 && mkdir test_implicit_2/.git && - test_must_fail git -C test_implicit_2 fsmonitor--daemon status + verify_implicit_shutdown test_implicit_2 +' + +# File systems on Windows may or may not have shortnames. +# This is a volume-specific setting on modern systems. +# "C:/" drives are required to have them enabled. Other +# hard drives default to disabled. +# +# This is a crude test to see if shortnames are enabled +# on the volume containing the test directory. It is +# crude, but it does not require elevation like `fsutil`. +# +test_lazy_prereq SHORTNAMES ' + mkdir .foo && + test -d "FOO~1" +' + +# Here we assume that the shortname of ".git" is "GIT~1". +test_expect_success MINGW,SHORTNAMES 'implicit daemon stop (rename GIT~1)' ' + test_when_finished "stop_daemon_delete_repo test_implicit_1s" && + + git init test_implicit_1s && + + start_daemon -C test_implicit_1s && + + # renaming the .git directory will implicitly stop the daemon. + # this moves {.git, GIT~1} to {.gitxyz, GITXYZ~1}. + # the rename-from FS Event will contain the shortname. + # + mv test_implicit_1s/GIT~1 test_implicit_1s/.gitxyz && + + # See [1] above. + # this moves {.gitxyz, GITXYZ~1} to {.git, GIT~1}. + mv test_implicit_1s/.gitxyz test_implicit_1s/.git && + + verify_implicit_shutdown test_implicit_1s +' + +# Here we first create a file with LONGNAME of "GIT~1" before +# we create the repo. This will cause the shortname of ".git" +# to be "GIT~2". +test_expect_success MINGW,SHORTNAMES 'implicit daemon stop (rename GIT~2)' ' + test_when_finished "stop_daemon_delete_repo test_implicit_1s2" && + + mkdir test_implicit_1s2 && + echo HELLO >test_implicit_1s2/GIT~1 && + git init test_implicit_1s2 && + + test_path_is_file test_implicit_1s2/GIT~1 && + test_path_is_dir test_implicit_1s2/GIT~2 && + + start_daemon -C test_implicit_1s2 && + + # renaming the .git directory will implicitly stop the daemon. + # the rename-from FS Event will contain the shortname. + # + mv test_implicit_1s2/GIT~2 test_implicit_1s2/.gitxyz && + + # See [1] above. + mv test_implicit_1s2/.gitxyz test_implicit_1s2/.git && + + verify_implicit_shutdown test_implicit_1s2 ' test_expect_success 'cannot start multiple daemons' ' @@ -209,6 +298,16 @@ test_expect_success 'setup' ' trace* EOF + mkdir -p T1/T2/T3/T4 && + echo 1 >T1/F1 && + echo 1 >T1/T2/F1 && + echo 1 >T1/T2/T3/F1 && + echo 1 >T1/T2/T3/T4/F1 && + echo 2 >T1/F2 && + echo 2 >T1/T2/F2 && + echo 2 >T1/T2/T3/F2 && + echo 2 >T1/T2/T3/T4/F2 && + git -c core.fsmonitor=false add . && test_tick && git -c core.fsmonitor=false commit -m initial && @@ -291,6 +390,19 @@ directory_to_file () { echo 1 >dir1 } +move_directory_contents_deeper() { + mkdir T1/_new_ && + mv T1/[A-Z]* T1/_new_ +} + +move_directory_up() { + mv T1/T2/T3 T1 +} + +move_directory() { + mv T1/T2/T3 T1/T2/NewT3 +} + # The next few test cases confirm that our fsmonitor daemon sees each type # of OS filesystem notification that we care about. At this layer we just # ensure we are getting the OS notifications and do not try to confirm what @@ -595,6 +707,10 @@ do matrix_try $uc_val $fsm_val file_to_directory matrix_try $uc_val $fsm_val directory_to_file + matrix_try $uc_val $fsm_val move_directory_contents_deeper + matrix_try $uc_val $fsm_val move_directory_up + matrix_try $uc_val $fsm_val move_directory + if test $fsm_val = true then test_expect_success "Matrix[uc:$uc_val][fsm:$fsm_val] disable fsmonitor at end" ' @@ -606,4 +722,281 @@ do done done +# Test Unicode UTF-8 characters in the pathname of the working +# directory root. Use of "*A()" routines rather than "*W()" routines +# on Windows can sometimes lead to odd failures. +# +u1=$(printf "u_c3_a6__\xC3\xA6") +u2=$(printf "u_e2_99_ab__\xE2\x99\xAB") +u_values="$u1 $u2" +for u in $u_values +do + test_expect_success "unicode in repo root path: $u" ' + test_when_finished "stop_daemon_delete_repo $u" && + + git init "$u" && + echo 1 >"$u"/file1 && + git -C "$u" add file1 && + git -C "$u" config core.fsmonitor true && + + start_daemon -C "$u" && + git -C "$u" status >actual && + grep "new file: file1" actual + ' +done + +# Test fsmonitor interaction with submodules. +# +# If we start the daemon in the super, it will see FS events for +# everything in the working directory cone and this includes any +# files/directories contained *within* the submodules. +# +# A `git status` at top level will get events for items within the +# submodule and ignore them, since they aren't named in the index +# of the super repo. This makes the fsmonitor response a little +# noisy, but it doesn't alter the correctness of the state of the +# super-proper. +# +# When we have submodules, `git status` normally does a recursive +# status on each of the submodules and adds a summary row for any +# dirty submodules. (See the "S..." bits in porcelain V2 output.) +# +# It is therefore important that the top level status not be tricked +# 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 +# submodule so that we get a summary of the status *within* the +# submodule. + +create_super () { + super="$1" && + + git init "$super" && + echo x >"$super/file_1" && + echo y >"$super/file_2" && + echo z >"$super/file_3" && + mkdir "$super/dir_1" && + echo a >"$super/dir_1/file_11" && + echo b >"$super/dir_1/file_12" && + mkdir "$super/dir_1/dir_2" && + echo a >"$super/dir_1/dir_2/file_21" && + echo b >"$super/dir_1/dir_2/file_22" && + git -C "$super" add . && + git -C "$super" commit -m "initial $super commit" +} + +create_sub () { + sub="$1" && + + git init "$sub" && + echo x >"$sub/file_x" && + echo y >"$sub/file_y" && + echo z >"$sub/file_z" && + mkdir "$sub/dir_x" && + echo a >"$sub/dir_x/file_a" && + echo b >"$sub/dir_x/file_b" && + mkdir "$sub/dir_x/dir_y" && + echo a >"$sub/dir_x/dir_y/file_a" && + echo b >"$sub/dir_x/dir_y/file_b" && + git -C "$sub" add . && + git -C "$sub" commit -m "initial $sub commit" +} + +my_match_and_clean () { + git -C super --no-optional-locks status --porcelain=v2 >actual.with && + git -C super --no-optional-locks -c core.fsmonitor=false \ + status --porcelain=v2 >actual.without && + test_cmp actual.with actual.without && + + git -C super/dir_1/dir_2/sub reset --hard && + git -C super/dir_1/dir_2/sub clean -d -f +} + +test_expect_success 'submodule always visited' ' + test_when_finished "git -C super fsmonitor--daemon stop; \ + rm -rf super; \ + rm -rf 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" && + + start_daemon -C super && + git -C super config core.fsmonitor true && + git -C super update-index --fsmonitor && + git -C super status && + + # Now run pairs of commands w/ and w/o FSMonitor while we make + # some dirt in the submodule and confirm matching output. + + # Completely clean status. + my_match_and_clean && + + # .M S..U + echo z >super/dir_1/dir_2/sub/dir_x/dir_y/foobar_u && + my_match_and_clean && + + # .M S.M. + echo z >super/dir_1/dir_2/sub/dir_x/dir_y/foobar_m && + git -C super/dir_1/dir_2/sub add . && + my_match_and_clean && + + # .M S.M. + echo z >>super/dir_1/dir_2/sub/dir_x/dir_y/file_a && + git -C super/dir_1/dir_2/sub add . && + my_match_and_clean && + + # .M SC.. + echo z >>super/dir_1/dir_2/sub/dir_x/dir_y/file_a && + git -C super/dir_1/dir_2/sub add . && + git -C super/dir_1/dir_2/sub commit -m "SC.." && + my_match_and_clean +' + +# If a submodule has a `sub/.git/` directory (rather than a file +# pointing to the super's `.git/modules/sub`) and `core.fsmonitor` +# turned on in the submodule and the daemon is not yet started in +# the submodule, and someone does a `git submodule absorbgitdirs` +# in the super, Git will recursively invoke `git submodule--helper` +# to do the work and this may try to read the index. This will +# try to start the daemon in the submodule *and* pass (either +# directly or via inheritance) the `--super-prefix` arg to the +# `git fsmonitor--daemon start` command inside the submodule. +# This causes a warning because fsmonitor--daemon does take that +# global arg (see the table in git.c) +# +# This causes a warning when trying to start the daemon that is +# somewhat confusing. It does not seem to hurt anything because +# the fsmonitor code maps the query failure into a trivial response +# and does the work anyway. +# +# It would be nice to silence the warning, however. + +have_t2_error_event () { + log=$1 + msg="fsmonitor--daemon doesnQt support --super-prefix" && + + tr '\047' Q <$1 | grep -e "$msg" +} + +test_expect_success "stray submodule super-prefix warning" ' + test_when_finished "rm -rf super; \ + rm -rf sub; \ + rm super-sub.trace" && + + create_super super && + create_sub sub && + + # Copy rather than submodule add so that we get a .git dir. + cp -R ./sub ./super/dir_1/dir_2/sub && + + git -C super/dir_1/dir_2/sub config core.fsmonitor true && + + git -C super submodule add ../sub ./dir_1/dir_2/sub && + git -C super commit -m "add sub" && + + test_path_is_dir super/dir_1/dir_2/sub/.git && + + GIT_TRACE2_EVENT="$PWD/super-sub.trace" \ + git -C super submodule absorbgitdirs && + + ! have_t2_error_event super-sub.trace +' + +# 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 the FS event. +# That is, does the FS event receive the spelling of the +# operation or does it receive the spelling preserved with +# the file/directory. +# +test_expect_success CASE_INSENSITIVE_FS 'case insensitive+preserving' ' +# test_when_finished "stop_daemon_delete_repo test_insensitive" && + + git init test_insensitive && + + start_daemon -C test_insensitive --tf "$PWD/insensitive.trace" && + + mkdir -p test_insensitive/abc/def && + echo xyz >test_insensitive/ABC/DEF/xyz && + + test_path_is_dir test_insensitive/.git && + test_path_is_dir test_insensitive/.GIT && + + # Rename .git using an alternate spelling to verify that that + # daemon detects it and automatically shuts down. + mv test_insensitive/.GIT test_insensitive/.FOO && + + # See [1] above. + mv test_insensitive/.FOO test_insensitive/.git && + + verify_implicit_shutdown test_insensitive && + + # Verify that events were reported using on-disk spellings of the + # directories and files that we touched. We may or may not get a + # trailing slash on modified directories. + # + egrep "^event: abc/?$" ./insensitive.trace && + egrep "^event: abc/def/?$" ./insensitive.trace && + egrep "^event: abc/def/xyz$" ./insensitive.trace +' + +# The variable "unicode_debug" is defined in the following library +# script to dump information about how the (OS, FS) handles Unicode +# composition. Uncomment the following line if you want to enable it. +# +# unicode_debug=true + +. "$TEST_DIRECTORY/lib-unicode-nfc-nfd.sh" + +# See if the OS or filesystem does NFC/NFD aliasing/munging. +# +# The daemon should err on the side of caution and send BOTH the +# NFC and NFD forms. It does not know the original spelling of +# the pathname (how the user thinks it should be spelled), so +# emit both and let the client decide (when necessary). This is +# similar to "core.precomposeUnicode". +# +test_expect_success !UNICODE_COMPOSITION_SENSITIVE 'Unicode nfc/nfd' ' + test_when_finished "stop_daemon_delete_repo test_unicode" && + + git init test_unicode && + + start_daemon -C test_unicode --tf "$PWD/unicode.trace" && + + # Create a directory using an NFC spelling. + # + mkdir test_unicode/nfc && + mkdir test_unicode/nfc/c_${utf8_nfc} && + + # Create a directory using an NFD spelling. + # + mkdir test_unicode/nfd && + mkdir test_unicode/nfd/d_${utf8_nfd} && + + git -C test_unicode fsmonitor--daemon stop && + + if test_have_prereq UNICODE_NFC_PRESERVED + then + # We should have seen NFC event from OS. + # We should not have synthesized an NFD event. + egrep "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace && + egrep -v "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace + else + # We should have seen NFD event from OS. + # We should have synthesized an NFC event. + egrep "^event: nfc/c_${utf8_nfd}/?$" ./unicode.trace && + egrep "^event: nfc/c_${utf8_nfc}/?$" ./unicode.trace + fi && + + # We assume UNICODE_NFD_PRESERVED. + # We should have seen explicit NFD from OS. + # We should have synthesized an NFC event. + egrep "^event: nfd/d_${utf8_nfd}/?$" ./unicode.trace && + egrep "^event: nfd/d_${utf8_nfc}/?$" ./unicode.trace +' + test_done diff --git a/t/t7702-repack-cyclic-alternate.sh b/t/t7702-repack-cyclic-alternate.sh index 93b74867ac..f3cdb98eec 100755 --- a/t/t7702-repack-cyclic-alternate.sh +++ b/t/t7702-repack-cyclic-alternate.sh @@ -4,6 +4,8 @@ # test_description='repack involving cyclic alternate' + +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh test_expect_success setup ' diff --git a/t/t7703-repack-geometric.sh b/t/t7703-repack-geometric.sh index bdbbcbf1ec..da87f8b2d8 100755 --- a/t/t7703-repack-geometric.sh +++ b/t/t7703-repack-geometric.sh @@ -7,6 +7,7 @@ test_description='git repack --geometric works correctly' GIT_TEST_MULTI_PACK_INDEX=0 objdir=.git/objects +packdir=$objdir/pack midx=$objdir/pack/multi-pack-index test_expect_success '--geometric with no packs' ' @@ -180,6 +181,34 @@ test_expect_success '--geometric ignores kept packs' ' ) ' +test_expect_success '--geometric ignores --keep-pack packs' ' + git init geometric && + test_when_finished "rm -fr geometric" && + ( + cd geometric && + + # Create two equal-sized packs + test_commit kept && # 3 objects + git repack -d && + test_commit pack && # 3 objects + git repack -d && + + find $objdir/pack -type f -name "*.pack" | sort >packs.before && + git repack --geometric 2 -dm \ + --keep-pack="$(basename "$(head -n 1 packs.before)")" >out && + find $objdir/pack -type f -name "*.pack" | sort >packs.after && + + # Packs should not have changed (only one non-kept pack, no + # loose objects), but $midx should now exist. + grep "Nothing new to pack" out && + test_path_is_file $midx && + + test_cmp packs.before packs.after && + + git fsck + ) +' + test_expect_success '--geometric chooses largest MIDX preferred pack' ' git init geometric && test_when_finished "rm -fr geometric" && @@ -202,4 +231,50 @@ test_expect_success '--geometric chooses largest MIDX preferred pack' ' ) ' +test_expect_success '--geometric with pack.packSizeLimit' ' + git init pack-rewrite && + test_when_finished "rm -fr pack-rewrite" && + ( + cd pack-rewrite && + + test-tool genrandom foo 1048576 >foo && + test-tool genrandom bar 1048576 >bar && + + git add foo bar && + test_tick && + git commit -m base && + + git rev-parse HEAD:foo HEAD:bar >p1.objects && + git rev-parse HEAD HEAD^{tree} >p2.objects && + + # These two packs each contain two objects, so the following + # `--geometric` repack will try to combine them. + p1="$(git pack-objects $packdir/pack <p1.objects)" && + p2="$(git pack-objects $packdir/pack <p2.objects)" && + + # Remove any loose objects in packs, since we do not want extra + # copies around (which would mask over potential object + # corruption issues). + git prune-packed && + + # Both p1 and p2 will be rolled up, but pack-objects will write + # three packs: + # + # - one containing object "foo", + # - another containing object "bar", + # - a final pack containing the commit and tree objects + # (identical to p2 above) + git repack --geometric 2 -d --max-pack-size=1048576 && + + # Ensure `repack` can detect that the third pack it wrote + # (containing just the tree and commit objects) was identical to + # one that was below the geometric split, so that we can save it + # from deletion. + # + # If `repack` fails to do that, we will incorrectly delete p2, + # causing object corruption. + git fsck + ) +' + test_done diff --git a/t/t9001-send-email.sh b/t/t9001-send-email.sh index 42694fe584..01c74b8b07 100755 --- a/t/t9001-send-email.sh +++ b/t/t9001-send-email.sh @@ -4,6 +4,7 @@ test_description='git send-email' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./test-lib.sh # May be altered later in the test diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index fea41b3c36..7c5b847f58 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -8,6 +8,7 @@ test_description='git svn basic tests' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh prepare_utf8_locale diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index 8b5681dd68..d043e80fc3 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -4,6 +4,8 @@ # test_description='git svn property tests' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh mkdir import diff --git a/t/t9104-git-svn-follow-parent.sh b/t/t9104-git-svn-follow-parent.sh index c7d8e0bf00..5cf2ef4b8b 100755 --- a/t/t9104-git-svn-follow-parent.sh +++ b/t/t9104-git-svn-follow-parent.sh @@ -4,6 +4,8 @@ # test_description='git svn fetching' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index aec45bca3b..3cab0b9720 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -2,6 +2,8 @@ # # Copyright (c) 2006 Eric Wong test_description='git svn commit-diff clobber' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9115-git-svn-dcommit-funky-renames.sh b/t/t9115-git-svn-dcommit-funky-renames.sh index 743fbe1fe4..419f055721 100755 --- a/t/t9115-git-svn-dcommit-funky-renames.sh +++ b/t/t9115-git-svn-dcommit-funky-renames.sh @@ -5,6 +5,7 @@ test_description='git svn dcommit can commit renames of files with ugly names' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'load repository with strange names' ' diff --git a/t/t9116-git-svn-log.sh b/t/t9116-git-svn-log.sh index 0a9f1ef366..d74d7b2de6 100755 --- a/t/t9116-git-svn-log.sh +++ b/t/t9116-git-svn-log.sh @@ -4,6 +4,7 @@ # test_description='git svn log tests' + . ./lib-git-svn.sh test_expect_success 'setup repository and import' ' diff --git a/t/t9122-git-svn-author.sh b/t/t9122-git-svn-author.sh index 9e8fe38e7e..527ba3d293 100755 --- a/t/t9122-git-svn-author.sh +++ b/t/t9122-git-svn-author.sh @@ -1,6 +1,8 @@ #!/bin/sh test_description='git svn authorship' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'setup svn repository' ' diff --git a/t/t9127-git-svn-partial-rebuild.sh b/t/t9127-git-svn-partial-rebuild.sh index 2e4789d061..97f495bd49 100755 --- a/t/t9127-git-svn-partial-rebuild.sh +++ b/t/t9127-git-svn-partial-rebuild.sh @@ -4,6 +4,7 @@ # test_description='git svn partial-rebuild tests' + . ./lib-git-svn.sh test_expect_success 'initialize svnrepo' ' diff --git a/t/t9129-git-svn-i18n-commitencoding.sh b/t/t9129-git-svn-i18n-commitencoding.sh index 01e1e8a8f7..185248a4cd 100755 --- a/t/t9129-git-svn-i18n-commitencoding.sh +++ b/t/t9129-git-svn-i18n-commitencoding.sh @@ -4,6 +4,7 @@ test_description='git svn honors i18n.commitEncoding in config' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh compare_git_head_with () { diff --git a/t/t9132-git-svn-broken-symlink.sh b/t/t9132-git-svn-broken-symlink.sh index aeceffaf7b..4d8d0584b7 100755 --- a/t/t9132-git-svn-broken-symlink.sh +++ b/t/t9132-git-svn-broken-symlink.sh @@ -2,6 +2,7 @@ test_description='test that git handles an svn repository with empty symlinks' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'load svn dumpfile' ' svnadmin load "$rawsvnrepo" <<EOF diff --git a/t/t9139-git-svn-non-utf8-commitencoding.sh b/t/t9139-git-svn-non-utf8-commitencoding.sh index 22d80b0be2..b7f756b2b7 100755 --- a/t/t9139-git-svn-non-utf8-commitencoding.sh +++ b/t/t9139-git-svn-non-utf8-commitencoding.sh @@ -4,6 +4,7 @@ test_description='git svn refuses to dcommit non-UTF8 messages' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh # ISO-2022-JP can pass for valid UTF-8, so skipping that in this test diff --git a/t/t9146-git-svn-empty-dirs.sh b/t/t9146-git-svn-empty-dirs.sh index 80cb55fee7..79c26ed69c 100755 --- a/t/t9146-git-svn-empty-dirs.sh +++ b/t/t9146-git-svn-empty-dirs.sh @@ -3,6 +3,8 @@ # Copyright (c) 2009 Eric Wong test_description='git svn creates empty directories' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9148-git-svn-propset.sh b/t/t9148-git-svn-propset.sh index aebb28995e..6cc76a07b3 100755 --- a/t/t9148-git-svn-propset.sh +++ b/t/t9148-git-svn-propset.sh @@ -5,6 +5,7 @@ test_description='git svn propset tests' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'setup propset via import' ' diff --git a/t/t9160-git-svn-preserve-empty-dirs.sh b/t/t9160-git-svn-preserve-empty-dirs.sh index 36c6b1a12f..9cf7a1427a 100755 --- a/t/t9160-git-svn-preserve-empty-dirs.sh +++ b/t/t9160-git-svn-preserve-empty-dirs.sh @@ -9,6 +9,7 @@ This test uses git to clone a Subversion repository that contains empty directories, and checks that corresponding directories are created in the local Git repository with placeholder files.' +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh GIT_REPO=git-svn-repo diff --git a/t/t9162-git-svn-dcommit-interactive.sh b/t/t9162-git-svn-dcommit-interactive.sh index e38d9fa37b..e2aa8ed88a 100755 --- a/t/t9162-git-svn-dcommit-interactive.sh +++ b/t/t9162-git-svn-dcommit-interactive.sh @@ -3,6 +3,8 @@ # Copyright (c) 2011 Frédéric Heitzmann test_description='git svn dcommit --interactive series' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh test_expect_success 'initialize repo' ' diff --git a/t/t9164-git-svn-dcommit-concurrent.sh b/t/t9164-git-svn-dcommit-concurrent.sh index 8466269bf5..1465156072 100755 --- a/t/t9164-git-svn-dcommit-concurrent.sh +++ b/t/t9164-git-svn-dcommit-concurrent.sh @@ -4,6 +4,8 @@ # test_description='concurrent git svn dcommit' + +TEST_FAILS_SANITIZE_LEAK=true . ./lib-git-svn.sh diff --git a/t/t9501-gitweb-standalone-http-status.sh b/t/t9501-gitweb-standalone-http-status.sh index 32814e75df..c900231079 100755 --- a/t/t9501-gitweb-standalone-http-status.sh +++ b/t/t9501-gitweb-standalone-http-status.sh @@ -13,6 +13,7 @@ code and message.' GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME=main export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME +TEST_PASSES_SANITIZE_LEAK=true . ./lib-gitweb.sh # diff --git a/t/t9502-gitweb-standalone-parse-output.sh b/t/t9502-gitweb-standalone-parse-output.sh index 8cb582f0e6..81d5625557 100755 --- a/t/t9502-gitweb-standalone-parse-output.sh +++ b/t/t9502-gitweb-standalone-parse-output.sh @@ -220,4 +220,18 @@ test_expect_success 'no http-equiv="content-type" in XHTML' ' no_http_equiv_content_type "p=.git;a=tree" ' +proper_doctype() { + gitweb_run "$@" && + grep -F "<!DOCTYPE html [" gitweb.body && + grep "<!ENTITY nbsp" gitweb.body && + grep "<!ENTITY sdot" gitweb.body +} + +test_expect_success 'Proper DOCTYPE with entity declarations' ' + proper_doctype && + proper_doctype "p=.git" && + proper_doctype "p=.git;a=log" && + proper_doctype "p=.git;a=tree" +' + test_done diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 93c03380d4..6da7273f1d 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -795,7 +795,7 @@ test_verify_prereq () { } test_expect_failure () { - test_start_ + test_start_ "$@" test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= test "$#" = 2 || BUG "not 2 or 3 parameters to test-expect-failure" @@ -803,6 +803,7 @@ test_expect_failure () { export test_prereq if ! test_skip "$@" then + test -n "$test_skip_test_preamble" || say >&3 "checking known breakage of $TEST_NUMBER.$test_count '$1': $2" if test_run_ "$2" expecting_failure then @@ -815,7 +816,7 @@ test_expect_failure () { } test_expect_success () { - test_start_ + test_start_ "$@" test "$#" = 3 && { test_prereq=$1; shift; } || test_prereq= test "$#" = 2 || BUG "not 2 or 3 parameters to test-expect-success" @@ -823,6 +824,7 @@ test_expect_success () { export test_prereq if ! test_skip "$@" then + test -n "$test_skip_test_preamble" || say >&3 "expecting success of $TEST_NUMBER.$test_count '$1': $2" if test_run_ "$2" then @@ -1782,6 +1784,16 @@ test_oid_to_path () { echo "${1%$basename}/$basename" } +# Parse oids from git ls-files --staged output +test_parse_ls_files_stage_oids () { + awk '{print $2}' - +} + +# Parse oids from git ls-tree output +test_parse_ls_tree_oids () { + awk '{print $3}' - +} + # Choose a port number based on the test script's number and store it in # the given variable name, unless that variable already contains a number. test_set_port () { diff --git a/t/test-lib-github-workflow-markup.sh b/t/test-lib-github-workflow-markup.sh new file mode 100644 index 0000000000..9c5339c577 --- /dev/null +++ b/t/test-lib-github-workflow-markup.sh @@ -0,0 +1,56 @@ +# Library of functions to mark up test scripts' output suitable for +# pretty-printing it in GitHub workflows. +# +# Copyright (c) 2022 Johannes Schindelin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# The idea is for `test-lib.sh` to source this file when run in GitHub +# workflows; these functions will then override (empty) functions +# that are are called at the appropriate times during the test runs. + +test_skip_test_preamble=t + +start_test_output () { + test -n "$GIT_TEST_TEE_OUTPUT_FILE" || + die "--github-workflow-markup requires --verbose-log" + github_markup_output="${GIT_TEST_TEE_OUTPUT_FILE%.out}.markup" + >$github_markup_output + GIT_TEST_TEE_OFFSET=0 +} + +# No need to override start_test_case_output + +finalize_test_case_output () { + test_case_result=$1 + shift + case "$test_case_result" in + failure) + echo >>$github_markup_output "::error::failed: $this_test.$test_count $1" + ;; + fixed) + echo >>$github_markup_output "::notice::fixed: $this_test.$test_count $1" + ;; + ok) + # Exit without printing the "ok" tests + return + ;; + esac + echo >>$github_markup_output "::group::$test_case_result: $this_test.$test_count $*" + test-tool >>$github_markup_output path-utils skip-n-bytes \ + "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET + echo >>$github_markup_output "::endgroup::" +} + +# No need to override finalize_test_output diff --git a/t/test-lib-junit.sh b/t/test-lib-junit.sh new file mode 100644 index 0000000000..c959183c7e --- /dev/null +++ b/t/test-lib-junit.sh @@ -0,0 +1,132 @@ +# Library of functions to format test scripts' output in JUnit XML +# format, to support Git's test suite result to be presented in an +# easily digestible way on Azure Pipelines. +# +# Copyright (c) 2022 Johannes Schindelin +# +# This program is free software: you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation, either version 2 of the License, or +# (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program. If not, see http://www.gnu.org/licenses/ . +# +# The idea is for `test-lib.sh` to source this file when the user asks +# for JUnit XML; these functions will then override (empty) functions +# that are are called at the appropriate times during the test runs. + +start_test_output () { + junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out" + mkdir -p "$junit_xml_dir" + junit_xml_base=${1##*/} + junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml" + junit_attrs="name=\"${junit_xml_base%.sh}\"" + junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \ + date +%Y-%m-%dT%H:%M:%S)\"" + write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" + junit_suite_start=$(test-tool date getnanos) + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + GIT_TEST_TEE_OFFSET=0 + fi +} + +start_test_case_output () { + junit_start=$(test-tool date getnanos) +} + +finalize_test_case_output () { + test_case_result=$1 + shift + case "$test_case_result" in + ok) + set "$*" + ;; + failure) + junit_insert="<failure message=\"not ok $test_count -" + junit_insert="$junit_insert $(xml_attr_encode --no-lf "$1")\">" + junit_insert="$junit_insert $(xml_attr_encode \ + "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + test-tool path-utils skip-n-bytes \ + "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET + else + printf '%s\n' "$@" | sed 1d + fi)")" + junit_insert="$junit_insert</failure>" + if test -n "$GIT_TEST_TEE_OUTPUT_FILE" + then + junit_insert="$junit_insert<system-err>$(xml_attr_encode \ + "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" + fi + set "$1" " $junit_insert" + ;; + fixed) + set "$* (breakage fixed)" + ;; + broken) + set "$* (known breakage)" + ;; + skip) + message="$(xml_attr_encode --no-lf "$skipped_reason")" + set "$1" " <skipped message=\"$message\" />" + ;; + esac + + junit_attrs="name=\"$(xml_attr_encode --no-lf "$this_test.$test_count $1")\"" + shift + junit_attrs="$junit_attrs classname=\"$this_test\"" + junit_attrs="$junit_attrs time=\"$(test-tool \ + date getnanos $junit_start)\"" + write_junit_xml "$(printf '%s\n' \ + " <testcase $junit_attrs>" "$@" " </testcase>")" + junit_have_testcase=t +} + +finalize_test_output () { + if test -n "$junit_xml_path" + then + test -n "$junit_have_testcase" || { + junit_start=$(test-tool date getnanos) + write_junit_xml_testcase "all tests skipped" + } + + # adjust the overall time + junit_time=$(test-tool date getnanos $junit_suite_start) + sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \ + -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \ + -e '/^ *<\/testsuite/d' \ + <"$junit_xml_path" >"$junit_xml_path.new" + mv "$junit_xml_path.new" "$junit_xml_path" + + write_junit_xml " </testsuite>" "</testsuites>" + write_junit_xml= + fi +} + +write_junit_xml () { + case "$1" in + --truncate) + >"$junit_xml_path" + junit_have_testcase= + shift + ;; + esac + printf '%s\n' "$@" >>"$junit_xml_path" +} + +xml_attr_encode () { + if test "x$1" = "x--no-lf" + then + shift + printf '%s' "$*" | test-tool xml-encode + else + printf '%s\n' "$@" | test-tool xml-encode + fi +} diff --git a/t/test-lib.sh b/t/test-lib.sh index 8ba5ca1534..736c6447ec 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -137,6 +137,12 @@ mark_option_requires_arg () { store_arg_to=$2 } +# These functions can be overridden e.g. to output JUnit XML +start_test_output () { :; } +start_test_case_output () { :; } +finalize_test_case_output () { :; } +finalize_test_output () { :; } + parse_option () { local opt="$1" @@ -196,7 +202,10 @@ parse_option () { tee=t ;; --write-junit-xml) - write_junit_xml=t + . "$TEST_DIRECTORY/test-lib-junit.sh" + ;; + --github-workflow-markup) + . "$TEST_DIRECTORY/test-lib-github-workflow-markup.sh" ;; --stress) stress=t ;; @@ -664,7 +673,7 @@ exec 6<&0 exec 7>&2 _error_exit () { - finalize_junit_xml + finalize_test_output GIT_EXIT_OK=t exit 1 } @@ -774,35 +783,13 @@ trap '{ code=$?; set +x; } 2>/dev/null; exit $code' INT TERM HUP # the test_expect_* functions instead. test_ok_ () { - if test -n "$write_junit_xml" - then - write_junit_xml_testcase "$*" - fi test_success=$(($test_success + 1)) say_color "" "ok $test_count - $@" + finalize_test_case_output ok "$@" } test_failure_ () { - if test -n "$write_junit_xml" - then - junit_insert="<failure message=\"not ok $test_count -" - junit_insert="$junit_insert $(xml_attr_encode "$1")\">" - junit_insert="$junit_insert $(xml_attr_encode \ - "$(if test -n "$GIT_TEST_TEE_OUTPUT_FILE" - then - test-tool path-utils skip-n-bytes \ - "$GIT_TEST_TEE_OUTPUT_FILE" $GIT_TEST_TEE_OFFSET - else - printf '%s\n' "$@" | sed 1d - fi)")" - junit_insert="$junit_insert</failure>" - if test -n "$GIT_TEST_TEE_OUTPUT_FILE" - then - junit_insert="$junit_insert<system-err>$(xml_attr_encode \ - "$(cat "$GIT_TEST_TEE_OUTPUT_FILE")")</system-err>" - fi - write_junit_xml_testcase "$1" " $junit_insert" - fi + failure_label=$1 test_failure=$(($test_failure + 1)) say_color error "not ok $test_count - $1" shift @@ -812,24 +799,19 @@ test_failure_ () { say_color error "1..$test_count" _error_exit fi + finalize_test_case_output failure "$failure_label" "$@" } test_known_broken_ok_ () { - if test -n "$write_junit_xml" - then - write_junit_xml_testcase "$* (breakage fixed)" - fi test_fixed=$(($test_fixed+1)) say_color error "ok $test_count - $@ # TODO known breakage vanished" + finalize_test_case_output fixed "$@" } test_known_broken_failure_ () { - if test -n "$write_junit_xml" - then - write_junit_xml_testcase "$* (known breakage)" - fi test_broken=$(($test_broken+1)) say_color warn "not ok $test_count - $@ # TODO known breakage" + finalize_test_case_output broken "$@" } test_debug () { @@ -1104,10 +1086,7 @@ test_start_ () { test_count=$(($test_count+1)) maybe_setup_verbose maybe_setup_valgrind - if test -n "$write_junit_xml" - then - junit_start=$(test-tool date getnanos) - fi + start_test_case_output "$@" } test_finish_ () { @@ -1158,15 +1137,10 @@ test_skip () { case "$to_skip" in t) - if test -n "$write_junit_xml" - then - message="$(xml_attr_encode "$skipped_reason")" - write_junit_xml_testcase "$1" \ - " <skipped message=\"$message\" />" - fi say_color skip "ok $test_count # skip $1 ($skipped_reason)" : true + finalize_test_case_output skip "$@" ;; *) false @@ -1179,53 +1153,6 @@ test_at_end_hook_ () { : } -write_junit_xml () { - case "$1" in - --truncate) - >"$junit_xml_path" - junit_have_testcase= - shift - ;; - esac - printf '%s\n' "$@" >>"$junit_xml_path" -} - -xml_attr_encode () { - printf '%s\n' "$@" | test-tool xml-encode -} - -write_junit_xml_testcase () { - junit_attrs="name=\"$(xml_attr_encode "$this_test.$test_count $1")\"" - shift - junit_attrs="$junit_attrs classname=\"$this_test\"" - junit_attrs="$junit_attrs time=\"$(test-tool \ - date getnanos $junit_start)\"" - write_junit_xml "$(printf '%s\n' \ - " <testcase $junit_attrs>" "$@" " </testcase>")" - junit_have_testcase=t -} - -finalize_junit_xml () { - if test -n "$write_junit_xml" && test -n "$junit_xml_path" - then - test -n "$junit_have_testcase" || { - junit_start=$(test-tool date getnanos) - write_junit_xml_testcase "all tests skipped" - } - - # adjust the overall time - junit_time=$(test-tool date getnanos $junit_suite_start) - sed -e "s/\(<testsuite.*\) time=\"[^\"]*\"/\1/" \ - -e "s/<testsuite [^>]*/& time=\"$junit_time\"/" \ - -e '/^ *<\/testsuite/d' \ - <"$junit_xml_path" >"$junit_xml_path.new" - mv "$junit_xml_path.new" "$junit_xml_path" - - write_junit_xml " </testsuite>" "</testsuites>" - write_junit_xml= - fi -} - test_atexit_cleanup=: test_atexit_handler () { # In a succeeding test script 'test_atexit_handler' is invoked @@ -1248,7 +1175,7 @@ test_done () { # removed, so the commands can access pidfiles and socket files. test_atexit_handler - finalize_junit_xml + finalize_test_output if test -z "$HARNESS_ACTIVE" then @@ -1539,22 +1466,7 @@ fi # in subprocesses like git equals our $PWD (for pathname comparisons). cd -P "$TRASH_DIRECTORY" || exit 1 -if test -n "$write_junit_xml" -then - junit_xml_dir="$TEST_OUTPUT_DIRECTORY/out" - mkdir -p "$junit_xml_dir" - junit_xml_base=${0##*/} - junit_xml_path="$junit_xml_dir/TEST-${junit_xml_base%.sh}.xml" - junit_attrs="name=\"${junit_xml_base%.sh}\"" - junit_attrs="$junit_attrs timestamp=\"$(TZ=UTC \ - date +%Y-%m-%dT%H:%M:%S)\"" - write_junit_xml --truncate "<testsuites>" " <testsuite $junit_attrs>" - junit_suite_start=$(test-tool date getnanos) - if test -n "$GIT_TEST_TEE_OUTPUT_FILE" - then - GIT_TEST_TEE_OFFSET=0 - fi -fi +start_test_output "$0" # Convenience # A regexp to match 5 and 35 hexdigits @@ -202,17 +202,15 @@ void trace2_cmd_start_fl(const char *file, int line, const char **argv) argv); } -int trace2_cmd_exit_fl(const char *file, int line, int code) +void trace2_cmd_exit_fl(const char *file, int line, int code) { struct tr2_tgt *tgt_j; int j; uint64_t us_now; uint64_t us_elapsed_absolute; - code &= 0xff; - if (!trace2_enabled) - return code; + return; trace_git_fsync_stats(); trace2_collect_process_info(TRACE2_PROCESS_INFO_EXIT); @@ -226,8 +224,6 @@ int trace2_cmd_exit_fl(const char *file, int line, int code) if (tgt_j->pfn_exit_fl) tgt_j->pfn_exit_fl(file, line, us_elapsed_absolute, code); - - return code; } void trace2_cmd_error_va_fl(const char *file, int line, const char *fmt, @@ -101,14 +101,8 @@ void trace2_cmd_start_fl(const char *file, int line, const char **argv); /* * Emit an 'exit' event. - * - * Write the exit-code that will be passed to exit() or returned - * from main(). - * - * Use this prior to actually calling exit(). - * See "#define exit()" in git-compat-util.h */ -int trace2_cmd_exit_fl(const char *file, int line, int code); +void trace2_cmd_exit_fl(const char *file, int line, int code); #define trace2_cmd_exit(code) (trace2_cmd_exit_fl(__FILE__, __LINE__, (code))) @@ -236,7 +236,7 @@ static char *apply_command(struct conf_info *conf, const char *arg) strbuf_replace(&cmd, TRAILER_ARG_STRING, arg); strvec_push(&cp.args, cmd.buf); } - strvec_pushv(&cp.env_array, (const char **)local_repo_env); + strvec_pushv(&cp.env, (const char **)local_repo_env); cp.no_stdin = 1; cp.use_shell = 1; diff --git a/transport-helper.c b/transport-helper.c index b4dbbabb0c..322c722478 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -135,7 +135,7 @@ static struct child_process *get_helper(struct transport *transport) helper->silent_exec_failure = 1; if (have_git_dir()) - strvec_pushf(&helper->env_array, "%s=%s", + strvec_pushf(&helper->env, "%s=%s", GIT_DIR_ENVIRONMENT, get_git_dir()); helper->trace2_child_class = helper->args.v[0]; /* "remote-<name>" */ diff --git a/transport.c b/transport.c index 01e24bd578..52db7a3cb0 100644 --- a/transport.c +++ b/transport.c @@ -1276,146 +1276,152 @@ int transport_push(struct repository *r, struct refspec *rs, int flags, unsigned int *reject_reasons) { + struct ref *remote_refs = NULL; + struct ref *local_refs = NULL; + int match_flags = MATCH_REFS_NONE; + int verbose = (transport->verbose > 0); + int quiet = (transport->verbose < 0); + int porcelain = flags & TRANSPORT_PUSH_PORCELAIN; + int pretend = flags & TRANSPORT_PUSH_DRY_RUN; + int push_ret, err; + int ret = -1; + struct transport_ls_refs_options transport_options = + TRANSPORT_LS_REFS_OPTIONS_INIT; + *reject_reasons = 0; if (transport_color_config() < 0) - return -1; - - if (transport->vtable->push_refs) { - struct ref *remote_refs; - struct ref *local_refs = get_local_heads(); - int match_flags = MATCH_REFS_NONE; - int verbose = (transport->verbose > 0); - int quiet = (transport->verbose < 0); - int porcelain = flags & TRANSPORT_PUSH_PORCELAIN; - int pretend = flags & TRANSPORT_PUSH_DRY_RUN; - int push_ret, ret, err; - struct transport_ls_refs_options transport_options = - TRANSPORT_LS_REFS_OPTIONS_INIT; - - if (check_push_refs(local_refs, rs) < 0) - return -1; - - refspec_ref_prefixes(rs, &transport_options.ref_prefixes); - - trace2_region_enter("transport_push", "get_refs_list", r); - remote_refs = transport->vtable->get_refs_list(transport, 1, - &transport_options); - trace2_region_leave("transport_push", "get_refs_list", r); - - transport_ls_refs_options_release(&transport_options); - - if (flags & TRANSPORT_PUSH_ALL) - match_flags |= MATCH_REFS_ALL; - if (flags & TRANSPORT_PUSH_MIRROR) - match_flags |= MATCH_REFS_MIRROR; - if (flags & TRANSPORT_PUSH_PRUNE) - match_flags |= MATCH_REFS_PRUNE; - if (flags & TRANSPORT_PUSH_FOLLOW_TAGS) - match_flags |= MATCH_REFS_FOLLOW_TAGS; - - if (match_push_refs(local_refs, &remote_refs, rs, match_flags)) - return -1; - - if (transport->smart_options && - transport->smart_options->cas && - !is_empty_cas(transport->smart_options->cas)) - apply_push_cas(transport->smart_options->cas, - transport->remote, remote_refs); - - set_ref_status_for_push(remote_refs, - flags & TRANSPORT_PUSH_MIRROR, - flags & TRANSPORT_PUSH_FORCE); - - if (!(flags & TRANSPORT_PUSH_NO_HOOK)) - if (run_pre_push_hook(transport, remote_refs)) - return -1; - - if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | - TRANSPORT_RECURSE_SUBMODULES_ONLY)) && - !is_bare_repository()) { - struct ref *ref = remote_refs; - struct oid_array commits = OID_ARRAY_INIT; - - trace2_region_enter("transport_push", "push_submodules", r); - for (; ref; ref = ref->next) - if (!is_null_oid(&ref->new_oid)) - oid_array_append(&commits, - &ref->new_oid); - - if (!push_unpushed_submodules(r, - &commits, - transport->remote, - rs, - transport->push_options, - pretend)) { - oid_array_clear(&commits); - trace2_region_leave("transport_push", "push_submodules", r); - die(_("failed to push all needed submodules")); - } + goto done; + + if (!transport->vtable->push_refs) + goto done; + + local_refs = get_local_heads(); + + if (check_push_refs(local_refs, rs) < 0) + goto done; + + refspec_ref_prefixes(rs, &transport_options.ref_prefixes); + + trace2_region_enter("transport_push", "get_refs_list", r); + remote_refs = transport->vtable->get_refs_list(transport, 1, + &transport_options); + trace2_region_leave("transport_push", "get_refs_list", r); + + transport_ls_refs_options_release(&transport_options); + + if (flags & TRANSPORT_PUSH_ALL) + match_flags |= MATCH_REFS_ALL; + if (flags & TRANSPORT_PUSH_MIRROR) + match_flags |= MATCH_REFS_MIRROR; + if (flags & TRANSPORT_PUSH_PRUNE) + match_flags |= MATCH_REFS_PRUNE; + if (flags & TRANSPORT_PUSH_FOLLOW_TAGS) + match_flags |= MATCH_REFS_FOLLOW_TAGS; + + if (match_push_refs(local_refs, &remote_refs, rs, match_flags)) + goto done; + + if (transport->smart_options && + transport->smart_options->cas && + !is_empty_cas(transport->smart_options->cas)) + apply_push_cas(transport->smart_options->cas, + transport->remote, remote_refs); + + set_ref_status_for_push(remote_refs, + flags & TRANSPORT_PUSH_MIRROR, + flags & TRANSPORT_PUSH_FORCE); + + if (!(flags & TRANSPORT_PUSH_NO_HOOK)) + if (run_pre_push_hook(transport, remote_refs)) + goto done; + + if ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | + TRANSPORT_RECURSE_SUBMODULES_ONLY)) && + !is_bare_repository()) { + struct ref *ref = remote_refs; + struct oid_array commits = OID_ARRAY_INIT; + + trace2_region_enter("transport_push", "push_submodules", r); + for (; ref; ref = ref->next) + if (!is_null_oid(&ref->new_oid)) + oid_array_append(&commits, + &ref->new_oid); + + if (!push_unpushed_submodules(r, + &commits, + transport->remote, + rs, + transport->push_options, + pretend)) { oid_array_clear(&commits); trace2_region_leave("transport_push", "push_submodules", r); + die(_("failed to push all needed submodules")); } + oid_array_clear(&commits); + trace2_region_leave("transport_push", "push_submodules", r); + } - if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) || - ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | - TRANSPORT_RECURSE_SUBMODULES_ONLY)) && - !pretend)) && !is_bare_repository()) { - struct ref *ref = remote_refs; - struct string_list needs_pushing = STRING_LIST_INIT_DUP; - struct oid_array commits = OID_ARRAY_INIT; - - trace2_region_enter("transport_push", "check_submodules", r); - for (; ref; ref = ref->next) - if (!is_null_oid(&ref->new_oid)) - oid_array_append(&commits, - &ref->new_oid); - - if (find_unpushed_submodules(r, - &commits, - transport->remote->name, - &needs_pushing)) { - oid_array_clear(&commits); - trace2_region_leave("transport_push", "check_submodules", r); - die_with_unpushed_submodules(&needs_pushing); - } - string_list_clear(&needs_pushing, 0); + if (((flags & TRANSPORT_RECURSE_SUBMODULES_CHECK) || + ((flags & (TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND | + TRANSPORT_RECURSE_SUBMODULES_ONLY)) && + !pretend)) && !is_bare_repository()) { + struct ref *ref = remote_refs; + struct string_list needs_pushing = STRING_LIST_INIT_DUP; + struct oid_array commits = OID_ARRAY_INIT; + + trace2_region_enter("transport_push", "check_submodules", r); + for (; ref; ref = ref->next) + if (!is_null_oid(&ref->new_oid)) + oid_array_append(&commits, + &ref->new_oid); + + if (find_unpushed_submodules(r, + &commits, + transport->remote->name, + &needs_pushing)) { oid_array_clear(&commits); trace2_region_leave("transport_push", "check_submodules", r); + die_with_unpushed_submodules(&needs_pushing); } + string_list_clear(&needs_pushing, 0); + oid_array_clear(&commits); + trace2_region_leave("transport_push", "check_submodules", r); + } - if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY)) { - trace2_region_enter("transport_push", "push_refs", r); - push_ret = transport->vtable->push_refs(transport, remote_refs, flags); - trace2_region_leave("transport_push", "push_refs", r); - } else - push_ret = 0; - err = push_had_errors(remote_refs); - ret = push_ret | err; - - if (!quiet || err) - transport_print_push_status(transport->url, remote_refs, - verbose | porcelain, porcelain, - reject_reasons); - - if (flags & TRANSPORT_PUSH_SET_UPSTREAM) - set_upstreams(transport, remote_refs, pretend); - - if (!(flags & (TRANSPORT_PUSH_DRY_RUN | - TRANSPORT_RECURSE_SUBMODULES_ONLY))) { - struct ref *ref; - for (ref = remote_refs; ref; ref = ref->next) - transport_update_tracking_ref(transport->remote, ref, verbose); - } + if (!(flags & TRANSPORT_RECURSE_SUBMODULES_ONLY)) { + trace2_region_enter("transport_push", "push_refs", r); + push_ret = transport->vtable->push_refs(transport, remote_refs, flags); + trace2_region_leave("transport_push", "push_refs", r); + } else + push_ret = 0; + err = push_had_errors(remote_refs); + ret = push_ret | err; + + if (!quiet || err) + transport_print_push_status(transport->url, remote_refs, + verbose | porcelain, porcelain, + reject_reasons); + + if (flags & TRANSPORT_PUSH_SET_UPSTREAM) + set_upstreams(transport, remote_refs, pretend); + + if (!(flags & (TRANSPORT_PUSH_DRY_RUN | + TRANSPORT_RECURSE_SUBMODULES_ONLY))) { + struct ref *ref; + for (ref = remote_refs; ref; ref = ref->next) + transport_update_tracking_ref(transport->remote, ref, verbose); + } - if (porcelain && !push_ret) - puts("Done"); - else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) - fprintf(stderr, "Everything up-to-date\n"); + if (porcelain && !push_ret) + puts("Done"); + else if (!quiet && !ret && !transport_refs_pushed(remote_refs)) + fprintf(stderr, "Everything up-to-date\n"); - return ret; - } - return 1; +done: + free_refs(local_refs); + free_refs(remote_refs); + return ret; } const struct ref *transport_get_remote_refs(struct transport *transport, diff --git a/unpack-trees.c b/unpack-trees.c index a1d0ff3a4d..d561ca01ed 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -19,6 +19,7 @@ #include "promisor-remote.h" #include "entry.h" #include "parallel-checkout.h" +#include "sparse-index.h" /* * Error messages expected by scripts out of plumbing commands such as @@ -1839,6 +1840,7 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options o->result.fsmonitor_last_update = xstrdup_or_null(o->src_index->fsmonitor_last_update); + o->result.fsmonitor_has_run_once = o->src_index->fsmonitor_has_run_once; if (!o->src_index->initialized && !repo->settings.command_requires_full_index && @@ -2024,6 +2026,9 @@ enum update_sparsity_result update_sparsity(struct unpack_trees_options *o) goto skip_sparse_checkout; } + /* Expand sparse directories as needed */ + expand_index(o->src_index, o->pl); + /* Set NEW_SKIP_WORKTREE on existing entries. */ mark_all_ce_unused(o->src_index); mark_new_skip_worktree(o->pl, o->src_index, 0, @@ -290,18 +290,24 @@ void warning(const char *warn, ...) /* Only set this, ever, from t/helper/, when verifying that bugs are caught. */ int BUG_exit_code; -static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params) +static void BUG_vfl_common(const char *file, int line, const char *fmt, + va_list params) { char prefix[256]; - va_list params_copy; - static int in_bug; - - va_copy(params_copy, params); /* truncation via snprintf is OK here */ snprintf(prefix, sizeof(prefix), "BUG: %s:%d: ", file, line); vreportf(prefix, fmt, params); +} + +static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_list params) +{ + va_list params_copy; + static int in_bug; + + va_copy(params_copy, params); + BUG_vfl_common(file, line, fmt, params); if (in_bug) abort(); @@ -317,11 +323,28 @@ static NORETURN void BUG_vfl(const char *file, int line, const char *fmt, va_lis NORETURN void BUG_fl(const char *file, int line, const char *fmt, ...) { va_list ap; + + bug_called_must_BUG = 0; + va_start(ap, fmt); BUG_vfl(file, line, fmt, ap); va_end(ap); } +int bug_called_must_BUG; +void bug_fl(const char *file, int line, const char *fmt, ...) +{ + va_list ap, cp; + + bug_called_must_BUG = 1; + + va_copy(cp, ap); + va_start(ap, fmt); + BUG_vfl_common(file, line, fmt, ap); + va_end(ap); + trace2_cmd_error_va(fmt, cp); +} + #ifdef SUPPRESS_ANNOTATED_LEAKS void unleak_memory(const void *ptr, size_t len) { diff --git a/wt-status.c b/wt-status.c index d33f9272b7..867e3e417e 100644 --- a/wt-status.c +++ b/wt-status.c @@ -616,7 +616,7 @@ static void wt_status_collect_changes_worktree(struct wt_status *s) rev.diffopt.rename_score = s->rename_score >= 0 ? s->rename_score : rev.diffopt.rename_score; copy_pathspec(&rev.prune_data, &s->pathspec); run_diff_files(&rev, 0); - clear_pathspec(&rev.prune_data); + release_revisions(&rev); } static void wt_status_collect_changes_index(struct wt_status *s) @@ -662,8 +662,7 @@ static void wt_status_collect_changes_index(struct wt_status *s) copy_pathspec(&rev.prune_data, &s->pathspec); run_diff_index(&rev, 1); - object_array_clear(&rev.pending); - clear_pathspec(&rev.prune_data); + release_revisions(&rev); } static int add_file_to_list(const struct object_id *oid, @@ -982,7 +981,7 @@ static void wt_longstatus_print_submodule_summary(struct wt_status *s, int uncom struct strbuf summary = STRBUF_INIT; char *summary_content; - strvec_pushf(&sm_summary.env_array, "GIT_INDEX_FILE=%s", s->index_file); + strvec_pushf(&sm_summary.env, "GIT_INDEX_FILE=%s", s->index_file); strvec_push(&sm_summary.args, "submodule"); strvec_push(&sm_summary.args, "summary"); @@ -1152,6 +1151,7 @@ static void wt_longstatus_print_verbose(struct wt_status *s) rev.diffopt.b_prefix = "w/"; run_diff_files(&rev, 0); } + release_revisions(&rev); } static void wt_longstatus_print_tracking(struct wt_status *s) @@ -2545,7 +2545,9 @@ int has_unstaged_changes(struct repository *r, int ignore_submodules) rev_info.diffopt.flags.quick = 1; diff_setup_done(&rev_info.diffopt); result = run_diff_files(&rev_info, 0); - return diff_result_code(&rev_info.diffopt, result); + result = diff_result_code(&rev_info.diffopt, result); + release_revisions(&rev_info); + return result; } /** @@ -2577,8 +2579,9 @@ int has_uncommitted_changes(struct repository *r, diff_setup_done(&rev_info.diffopt); result = run_diff_index(&rev_info, 1); - object_array_clear(&rev_info.pending); - return diff_result_code(&rev_info.diffopt, result); + result = diff_result_code(&rev_info.diffopt, result); + release_revisions(&rev_info); + return result; } /** |
