diff options
436 files changed, 17381 insertions, 13401 deletions
diff --git a/.gitignore b/.gitignore index a36ee94443..802ce70e48 100644 --- a/.gitignore +++ b/.gitignore @@ -140,6 +140,7 @@ /git-repack /git-replace /git-replay +/git-repo /git-request-pull /git-rerere /git-reset diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 528b42d1dd..224f0978a8 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -301,6 +301,14 @@ For C programs: . since late 2023 with 8277dbe987 we have been using the bool type from <stdbool.h>. + C99 features we have test balloons for: + + . since late 2024 with v2.48.0-rc0~20, we have test balloons for + compound literal syntax, e.g., (struct foo){ .member = value }; + our hope is that no platforms we care about have trouble using + them, and officially adopt its wider use in mid 2026. Do not add + more use of the syntax until that happens. + New C99 features that we cannot use yet: . %z and %zu as a printf() argument for a size_t (the %z being for @@ -616,8 +624,9 @@ For C programs: - `S_init()` initializes a structure without allocating the structure itself. - - `S_release()` releases a structure's contents without freeing the - structure. + - `S_release()` releases a structure's contents without reinitializing + the structure for immediate reuse, and without freeing the structure + itself. - `S_clear()` is equivalent to `S_release()` followed by `S_init()` such that the structure is directly usable after clearing it. When diff --git a/Documentation/Makefile b/Documentation/Makefile index df2ce187eb..6fb83d0c6e 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -497,9 +497,26 @@ $(LINT_DOCS_FSCK_MSGIDS): ../fsck.h fsck-msgids.adoc $(call mkdir_p_parent_template) $(QUIET_GEN)$(PERL_PATH) lint-fsck-msgids.perl \ ../fsck.h fsck-msgids.adoc $@ - lint-docs-fsck-msgids: $(LINT_DOCS_FSCK_MSGIDS) +## Lint: delimited sections +LINT_DOCS_DELIMITED_SECTIONS = $(patsubst %.adoc,.build/lint-docs/delimited-sections/%.ok,$(MAN_TXT)) +$(LINT_DOCS_DELIMITED_SECTIONS): lint-delimited-sections.perl +$(LINT_DOCS_DELIMITED_SECTIONS): .build/lint-docs/delimited-sections/%.ok: %.adoc + $(call mkdir_p_parent_template) + $(QUIET_LINT_DELIMSEC)$(PERL_PATH) lint-delimited-sections.perl $< >$@ +.PHONY: lint-docs-delimited-sections +lint-docs-delimited-sections: $(LINT_DOCS_DELIMITED_SECTIONS) + +## Lint: Documentation style +LINT_DOCS_DOC_STYLE = $(patsubst %.adoc,.build/lint-docs/doc-style/%.ok,$(DOC_DEP_TXT)) +$(LINT_DOCS_DOC_STYLE): lint-documentation-style.perl +$(LINT_DOCS_DOC_STYLE): .build/lint-docs/doc-style/%.ok: %.adoc + $(call mkdir_p_parent_template) + $(QUIET_LINT_DOCSTYLE)$(PERL_PATH) lint-documentation-style.perl $< >$@ +.PHONY: lint-docs-doc-style +lint-docs-doc-style: $(LINT_DOCS_DOC_STYLE) + lint-docs-manpages: $(QUIET_GEN)./lint-manpages.sh @@ -528,6 +545,8 @@ lint-docs: lint-docs-fsck-msgids lint-docs: lint-docs-gitlink lint-docs: lint-docs-man-end-blurb lint-docs: lint-docs-man-section-order +lint-docs: lint-docs-delimited-sections +lint-docs: lint-docs-doc-style lint-docs: lint-docs-manpages lint-docs: lint-docs-meson diff --git a/Documentation/MyFirstContribution.adoc b/Documentation/MyFirstContribution.adoc index aca7212cfe..02ba8ba5f6 100644 --- a/Documentation/MyFirstContribution.adoc +++ b/Documentation/MyFirstContribution.adoc @@ -52,6 +52,15 @@ respond to you. It's better to ask your questions in the channel so that you can be answered if you disconnect and so that others can learn from the conversation. +==== https://discord.gg/GRFVkzgxRd[#discord] on Discord +This is an unofficial Git Discord server for everyone, from people just +starting out with Git to those who develop it. It's a great place to ask +questions, share tips, and connect with the broader Git community in real time. + +The server has channels for general discussions and specific channels for those +who use Git and those who develop it. The server's search functionality also +allows you to find previous conversations and answers to common questions. + [[getting-started]] == Getting Started @@ -908,10 +917,13 @@ Now you should be able to go and check out your newly created branch on GitHub. === Sending a PR to GitGitGadget In order to have your code tested and formatted for review, you need to start by -opening a Pull Request against `gitgitgadget/git`. Head to -https://github.com/gitgitgadget/git and open a PR either with the "New pull -request" button or the convenient "Compare & pull request" button that may -appear with the name of your newly pushed branch. +opening a Pull Request against either `gitgitgadget/git` or `git/git`. Head to +https://github.com/gitgitgadget/git or https://github.com/git/git and open a PR +either with the "New pull request" button or the convenient "Compare & pull +request" button that may appear with the name of your newly pushed branch. + +The differences between using `gitgitgadget/git` and `git/git` as your base can +be found [here](https://gitgitgadget.github.io/#should-i-use-gitgitgadget-on-gitgitgadgets-git-fork-or-on-gits-github-mirror) Review the PR's title and description, as they're used by GitGitGadget respectively as the subject and body of the cover letter for your change. Refer diff --git a/Documentation/RelNotes/1.6.2.4.adoc b/Documentation/RelNotes/1.6.2.4.adoc index f4bf1d0986..053dbb604d 100644 --- a/Documentation/RelNotes/1.6.2.4.adoc +++ b/Documentation/RelNotes/1.6.2.4.adoc @@ -37,3 +37,4 @@ exec >/var/tmp/1 echo O=$(git describe maint) O=v1.6.2.3-38-g318b847 git shortlog --no-merges $O..maint +--- diff --git a/Documentation/RelNotes/2.51.0.adoc b/Documentation/RelNotes/2.51.0.adoc index f9e6a54109..a73ea3e808 100644 --- a/Documentation/RelNotes/2.51.0.adoc +++ b/Documentation/RelNotes/2.51.0.adoc @@ -53,6 +53,25 @@ UI, Workflows & Features * Clean up the way how signature on commit objects are exported to and imported from fast-import stream. + * Remove unsupported, unused, and unsupportable old option from "git + log". + + * Document recently added "git imap-send --list" with an example. + + * "git pull" learned to pay attention to pull.autostash configuration + variable, which overrides rebase/merge.autostash. + + * "git for-each-ref" learns "--start-after" option to help + applications that want to page its output. + + * "git switch" and "git restore" are declared to be no longer + experimental. + + * "git -c alias.foo=bar foo -h baz" reported "'foo' is aliased to + 'bar'" and then went on to run "git foo -h baz", which was + unexpected. Tighten the rule so that alias expansion is reported + only when "-h" is the sole option. + Performance, Internal Implementation, Development Support etc. -------------------------------------------------------------- @@ -78,8 +97,8 @@ Performance, Internal Implementation, Development Support etc. * "git push" and "git fetch" are taught to update refs in batches to gain performance. - * Some code paths in the "git prune" used to ignore passed in - repository object and used the_repository singleton instance + * Some code paths in "git prune" used to ignore the passed-in + repository object and used the `the_repository` singleton instance instead, which has been corrected. * Update ".clang-format" and ".editorconfig" to match our style guide @@ -107,6 +126,24 @@ Performance, Internal Implementation, Development Support etc. worst case performance characteristics, which has been optimized by using prio-queue data structure. + * Move structure definition from unrelated header file to where it + belongs. + + * To help our developers, document what C99 language features are + being considered for adoption, in addition to what past experiments + have already decided. + + * The reftable unit tests are now ported to the "clar" unit testing + framework. + + * Redefine where the multi-pack-index sits in the object subsystem, + which recently was restructured to allow multiple backends that + support a single object source that belongs to one repository. A + MIDX does span multiple "object sources". + + * Reduce implicit assumption and dependence on the_repository in the + object-file subsystem. + Fixes since v2.50 ----------------- @@ -234,6 +271,36 @@ including security updates, are included in this release. core.commentstring is set to 'auto'. (merge 92b7c7c9f5 ac/auto-comment-char-fix later to maint). + * "git rebase -i" with bogus rebase.instructionFormat configuration + failed to produce the todo file after recording the state files, + leading to confused "git status"; this has been corrected. + (merge ade14bffd7 ow/rebase-verify-insn-fmt-before-initializing-state later to maint). + + * A few file descriptors left unclosed upon program completion in a + few test helper programs are now closed. + (merge 0f1b33815b hl/test-helper-fd-close later to maint). + + * Interactive prompt code did not correctly strip CRLF from the end + of line on Windows. + (merge 711a20827b js/prompt-crlf-fix later to maint). + + * The config API had a set of convenience wrapper functions that + implicitly use the_repository instance; they have been removed and + inlined at the calling sites. + + * "git add/etc -p" now honor the diff.context configuration variable, + and also they learn to honor the -U<n> command-line option. + (merge 2b3ae04011 lm/add-p-context later to maint). + + * The case where a new submodule takes a path where there used to be a + completely different subproject is now dealt with a bit better than + before. + (merge 5ed8c5b465 kj/renamed-submodule later to maint). + + * The deflate codepath in "git archive --format=zip" had a + longstanding bug coming from misuse of zlib API, which has been + corrected. + * Other code cleanup, docfix, build fix, etc. (merge b257adb571 lo/my-first-ow-doc-update later to maint). (merge 8b34b6a220 ly/sequencer-update-squash-is-fixup-only later to maint). @@ -260,3 +327,15 @@ including security updates, are included in this release. (merge f4fa8a3687 rh/doc-glob-pathspec-fix later to maint). (merge b27be108c8 ja/doc-git-log-markup later to maint). (merge 14d7583beb pw/config-kvi-remove-path later to maint). + (merge f31abb421d jc/do-not-scan-argv-without-parsing later to maint). + (merge 26552cb62a jk/unleak-reflog-expire-entry later to maint). + (merge 339d95fda9 jc/ci-print-test-failures-fix later to maint). + (merge 8c3add51a8 cb/meson-avoid-broken-macos-pcre2 later to maint). + (merge 5247da07b8 ps/meson-clar-decls-fix later to maint). + (merge f3ef347bb2 ch/t7450-recursive-clone-test-fix later to maint). + (merge 4ac3302a1a jc/doc-release-vs-clear later to maint). + (merge 3bdd897413 ms/meson-with-ancient-git-wo-ls-files-dedup later to maint). + (merge cca758d324 kh/doc-fast-import-historical later to maint). + (merge 9b0781196a jc/test-hashmap-is-still-here later to maint). + (merge 1bad05bacc jk/revert-squelch-compiler-warning later to maint). + (merge 3a7e783d9c dl/squelch-maybe-uninitialized later to maint). diff --git a/Documentation/RelNotes/2.52.0.adoc b/Documentation/RelNotes/2.52.0.adoc new file mode 100644 index 0000000000..fa72515358 --- /dev/null +++ b/Documentation/RelNotes/2.52.0.adoc @@ -0,0 +1,145 @@ +Git v2.52 Release Notes +======================= + +UI, Workflows & Features +------------------------ + + * The "list" subcommand of "git refs" acts as a front-end for + "git for-each-ref". + + * "git cmd --help-all" now works outside repositories. + + * "git diff-tree" learned "--max-depth" option. + + * A new subcommand "git repo" gives users a way to grab various + repository characteristics. + + +Performance, Internal Implementation, Development Support etc. +-------------------------------------------------------------- + + * string_list_split*() family of functions have been extended to + simplify common use cases. + + * Arrays of strbuf is often a wrong data structure to use, and + strbuf_split*() family of functions that create them often have + better alternatives. Update several code paths and replace + strbuf_split*(). + + * Revision traversal limited with pathspec, like "git log dir/*", + used to ignore changed-paths Bloom filter when the pathspec + contained wildcards; now they take advantage of the filter when + they can. + + * Doc lint updates to encourage the newer and easier-to-use + `synopsis` format, with fixes to a handful of existing uses. + + * Remove dependency on the_repository and other globals from the + commit-graph code, and other changes unrelated to de-globaling. + + * Discord has been added to the first contribution documentation as + another way to ask for help. + + +Fixes since v2.51 +----------------- + +Unless otherwise noted, all the changes in 2.51.X maintenance track, +including security updates, are included in this release. + + * During interactive rebase, using 'drop' on a merge commit lead to + an error, which was incorrect. + (merge 4d491ade8f js/rebase-i-allow-drop-on-a-merge later to maint). + + * "git refs migrate" to migrate the reflog entries from a refs + backend to another had a handful of bugs squashed. + (merge 465eff81de ps/reflog-migrate-fixes later to maint). + + * "git remote rename origin upstream" failed to move origin/HEAD to + upstream/HEAD when origin/HEAD is unborn and performed other + renames extremely inefficiently, which has been corrected. + (merge 16c4fa26b9 ps/remote-rename-fix later to maint). + + * "git describe" has been optimized by using better data structure. + (merge 08bb69d70f rs/describe-with-prio-queue later to maint). + + * "git push" had a code path that led to BUG() but it should have + been a die(), as it is a response to a usual but invalid end-user + action to attempt pushing an object that does not exist. + (merge dfbfc2221b dl/push-missing-object-error later to maint). + + * Various bugs about rename handling in "ort" merge strategy have + been fixed. + (merge f6ecb603ff en/ort-rename-fixes later to maint). + + * "git jump" (in contrib/) fails to parse the diff header correctly + when a file has a space in its name, which has been corrected. + (merge 621ce9c1c6 gh/git-jump-pathname-with-sp later to maint). + + * "git diff --no-index" run inside a subdirectory under control of a + Git repository operated at the top of the working tree and stripped + the prefix from the output, and oddballs like "-" (stdin) did not + work correctly because of it. Correct the set-up by undoing what + the set-up sequence did to cwd and prefix. + (merge e1d3d61a45 jc/diff-no-index-in-subdir later to maint). + + * Various options to "git diff" that makes comparison ignore certain + aspects of the differences (like "space changes are ignored", + "differences in lines that match these regular expressions are + ignored") did not work well with "--name-only" and friends. + (merge b55e6d36eb ly/diff-name-only-with-diff-from-content later to maint). + + * Documentation for "git rebase" has been updated. + (merge 3f7f2b0359 je/doc-rebase later to maint). + + * The start_delayed_progress() function in the progress eye-candy API + did not clear its internal state, making an initial delay value + larger than 1 second ineffective, which has been corrected. + (merge 457534d041 js/progress-delay-fix later to maint). + + * The compatObjectFormat extension is used to hide an incomplete + feature that is not yet usable for any purpose other than + developing the feature further. Document it as such to discourage + its use by mere mortals. + (merge 716d905792 bc/doc-compat-object-format-not-working later to maint). + + * "git log -L..." compared trees of multiple parents with the tree of the + merge result in an unnecessarily inefficient way. + (merge 0a15bb634c sg/line-log-merge-optim later to maint). + + * Under a race against another process that is repacking the + repository, especially a partially cloned one, "git fetch" may + mistakenly think some objects we do have are missing, which has + been corrected. + (merge 8f32a5a6c0 jk/fetch-check-graph-objects-fix later to maint). + + * "git fetch" can clobber a symref that is dangling when the + remote-tracking HEAD is set to auto update, which has been + corrected. + + * "git describe <blob>" misbehaves and/or crashes in some corner + cases, which has been taught to exit with failure gracefully. + (merge 7c10e48e81 jk/describe-blob later to maint). + + * Manual page for "gitk" is updated with the current maintainer's + name. + (merge bcb20dda83 js/doc-gitk-history later to maint). + + * Update the instruction to use of GGG in the MyFirstContribution + document to say that a GitHub PR could be made against `git/git` + instead of `gitgitgadget/git`. + (merge 37001cdbc4 ds/doc-ggg-pr-fork-clarify later to maint). + + * Other code cleanup, docfix, build fix, etc. + (merge 823d537fa7 kh/doc-git-log-markup-fix later to maint). + (merge cf7efa4f33 rj/t6137-cygwin-fix later to maint). + (merge 529a60a885 ua/t1517-short-help-tests later to maint). + (merge 22d421fed9 ac/deglobal-fmt-merge-log-config later to maint). + (merge 741f36c7d9 kr/clone-synopsis-fix later to maint). + (merge a60203a015 dk/t7005-editor-updates later to maint). + (merge 7d4a5fef7d ds/doc-count-objects-fix later to maint). + (merge 16684b6fae ps/reftable-libgit2-cleanup later to maint). + (merge f38786baa7 ja/asciidoc-doctor-verbatim-fixes later to maint). + (merge 374579c6d4 kh/doc-interpret-trailers-markup-fix later to maint). + (merge 44dce6541c kh/doc-config-typofix later to maint). + (merge 785628b173 js/doc-sending-patch-via-thunderbird later to maint). diff --git a/Documentation/blame-options.adoc b/Documentation/blame-options.adoc index 19ea187238..1fb948fc76 100644 --- a/Documentation/blame-options.adoc +++ b/Documentation/blame-options.adoc @@ -75,7 +75,8 @@ include::line-range-format.adoc[] iso format is used. For supported values, see the discussion of the --date option at linkgit:git-log[1]. ---[no-]progress:: +--progress:: +--no-progress:: Progress status is reported on the standard error stream by default when it is attached to a terminal. This flag enables progress reporting even if not attached to a diff --git a/Documentation/config/core.adoc b/Documentation/config/core.adoc index 9fde1ab63a..3fbe83eef1 100644 --- a/Documentation/config/core.adoc +++ b/Documentation/config/core.adoc @@ -696,12 +696,6 @@ core.unsetenvvars:: Defaults to `PERL5LIB` to account for the fact that Git for Windows insists on using its own Perl interpreter. -core.restrictinheritedhandles:: - Windows-only: override whether spawned processes inherit only standard - file handles (`stdin`, `stdout` and `stderr`) or all handles. Can be - `auto`, `true` or `false`. Defaults to `auto`, which means `true` on - Windows 7 and later, and `false` on older Windows versions. - core.createObject:: You can set this to 'link', in which case a hardlink followed by a delete of the source are used to make sure that object creation diff --git a/Documentation/config/extensions.adoc b/Documentation/config/extensions.adoc index 9e2f321a6d..829f2523fc 100644 --- a/Documentation/config/extensions.adoc +++ b/Documentation/config/extensions.adoc @@ -14,6 +14,10 @@ compatObjectFormat:: compatObjectFormat. As well as being able to use oids encoded in compatObjectFormat in addition to oids encoded with objectFormat to locally specify objects. ++ +Note that the functionality enabled by this extension is incomplete and subject +to change. It currently exists only to allow development and testing of +the underlying feature and is not designed to be enabled by end users. noop:: This extension does not change git's behavior at all. It is useful only diff --git a/Documentation/config/log.adoc b/Documentation/config/log.adoc index 16e00e8d29..f20cc25cd7 100644 --- a/Documentation/config/log.adoc +++ b/Documentation/config/log.adoc @@ -23,14 +23,14 @@ be used. Print out the ref names of any commits that are shown by the log command. Possible values are: + ----- +-- `short`;; the ref name prefixes `refs/heads/`, `refs/tags/` and `refs/remotes/` are not printed. `full`;; the full ref name (including prefix) are printed. `auto`;; if the output is going to a terminal, the ref names are shown as if `short` were given, otherwise no ref names are shown. ----- +-- + This is the same as the `--decorate` option of the `git log`. diff --git a/Documentation/config/mergetool.adoc b/Documentation/config/mergetool.adoc index 6be506145c..7064f5a462 100644 --- a/Documentation/config/mergetool.adoc +++ b/Documentation/config/mergetool.adoc @@ -65,7 +65,7 @@ endif::[] During a merge, Git will automatically resolve as many conflicts as possible and write the `$MERGED` file containing conflict markers around any conflicts that it cannot resolve; `$LOCAL` and `$REMOTE` normally - are the versions of the file from before Git`s conflict + are the versions of the file from before Git's conflict resolution. This flag causes `$LOCAL` and `$REMOTE` to be overwritten so that only the unresolved conflicts are presented to the merge tool. Can be configured per-tool via the `mergetool.<tool>.hideResolved` diff --git a/Documentation/config/pull.adoc b/Documentation/config/pull.adoc index 9349e09261..125c930f72 100644 --- a/Documentation/config/pull.adoc +++ b/Documentation/config/pull.adoc @@ -29,5 +29,21 @@ pull.octopus:: The default merge strategy to use when pulling multiple branches at once. +pull.autoStash:: + When set to true, automatically create a temporary stash entry + to record the local changes before the operation begins, and + restore them after the operation completes. When your "git + pull" rebases (instead of merges), this may be convenient, since + unlike merging pull that tolerates local changes that do not + interfere with the merge, rebasing pull refuses to work with any + local changes. ++ +If `pull.autostash` is set (either to true or false), +`merge.autostash` and `rebase.autostash` are ignored. If +`pull.autostash` is not set at all, depending on the value of +`pull.rebase`, `merge.autostash` or `rebase.autostash` is used +instead. Can be overridden by the `--[no-]autostash` command line +option. + pull.twohead:: The default merge strategy to use when pulling a single branch. diff --git a/Documentation/diff-context-options.adoc b/Documentation/diff-context-options.adoc new file mode 100644 index 0000000000..e161260358 --- /dev/null +++ b/Documentation/diff-context-options.adoc @@ -0,0 +1,10 @@ +`-U<n>`:: +`--unified=<n>`:: + Generate diffs with _<n>_ lines of context. Defaults to `diff.context` + or 3 if the config option is unset. + +`--inter-hunk-context=<n>`:: + Show the context between diff hunks, up to the specified _<number>_ + of lines, thereby fusing hunks that are close to each other. + Defaults to `diff.interHunkContext` or 0 if the config option + is unset. diff --git a/Documentation/diff-format.adoc b/Documentation/diff-format.adoc index 80e36e153d..9f7e988241 100644 --- a/Documentation/diff-format.adoc +++ b/Documentation/diff-format.adoc @@ -103,6 +103,7 @@ if the file was renamed on any side of history. With followed by the name of the path in the merge commit. Examples for `-c` and `--cc` without `--combined-all-paths`: + ------------------------------------------------ ::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c ::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM bar.sh diff --git a/Documentation/diff-options.adoc b/Documentation/diff-options.adoc index f3a35d8141..ae31520f7f 100644 --- a/Documentation/diff-options.adoc +++ b/Documentation/diff-options.adoc @@ -505,7 +505,8 @@ endif::git-format-patch[] Turn off rename detection, even when the configuration file gives the default to do so. -`--[no-]rename-empty`:: +`--rename-empty`:: +`--no-rename-empty`:: Whether to use empty blobs as rename source. ifndef::git-format-patch[] @@ -893,5 +894,33 @@ endif::git-format-patch[] reverted with `--ita-visible-in-index`. Both options are experimental and could be removed in future. +--max-depth=<depth>:: + For each pathspec given on command line, descend at most `<depth>` + levels of directories. A value of `-1` means no limit. + Cannot be combined with wildcards in the pathspec. + Given a tree containing `foo/bar/baz`, the following list shows the + matches generated by each set of options: ++ +-- + - `--max-depth=0 -- foo`: `foo` + + - `--max-depth=1 -- foo`: `foo/bar` + + - `--max-depth=1 -- foo/bar`: `foo/bar/baz` + + - `--max-depth=1 -- foo foo/bar`: `foo/bar/baz` + + - `--max-depth=2 -- foo`: `foo/bar/baz` +-- ++ +If no pathspec is given, the depth is measured as if all +top-level entries were specified. Note that this is different +than measuring from the root, in that `--max-depth=0` would +still return `foo`. This allows you to still limit depth while +asking for a subset of the top-level entries. ++ +Note that this option is only supported for diffs between tree objects, +not against the index or working tree. + For more detailed explanation on these common options, see also linkgit:gitdiffcore[7]. diff --git a/Documentation/fetch-options.adoc b/Documentation/fetch-options.adoc index b01372e4b3..d3ac31f4e2 100644 --- a/Documentation/fetch-options.adoc +++ b/Documentation/fetch-options.adoc @@ -1,4 +1,5 @@ ---[no-]all:: +--all:: +--no-all:: Fetch all remotes, except for the ones that has the `remote.<name>.skipFetchAll` configuration variable set. This overrides the configuration variable fetch.all`. @@ -88,7 +89,8 @@ This is incompatible with `--recurse-submodules=[yes|on-demand]` and takes precedence over the `fetch.output` config option. ifndef::git-pull[] ---[no-]write-fetch-head:: +--write-fetch-head:: +--no-write-fetch-head:: Write the list of remote refs fetched in the `FETCH_HEAD` file directly under `$GIT_DIR`. This is the default. Passing `--no-write-fetch-head` from the command line tells @@ -118,13 +120,16 @@ ifndef::git-pull[] Allow several <repository> and <group> arguments to be specified. No <refspec>s may be specified. ---[no-]auto-maintenance:: ---[no-]auto-gc:: +--auto-maintenance:: +--no-auto-maintenance:: +--auto-gc:: +--no-auto-gc:: Run `git maintenance run --auto` at the end to perform automatic repository maintenance if needed. (`--[no-]auto-gc` is a synonym.) This is enabled by default. ---[no-]write-commit-graph:: +--write-commit-graph:: +--no-write-commit-graph:: Write a commit-graph after fetching. This overrides the config setting `fetch.writeCommitGraph`. endif::git-pull[] diff --git a/Documentation/for-each-ref-options.adoc b/Documentation/for-each-ref-options.adoc new file mode 100644 index 0000000000..f13efb5f25 --- /dev/null +++ b/Documentation/for-each-ref-options.adoc @@ -0,0 +1,85 @@ +`<pattern>...`:: + If one or more _<pattern>_ parameters are given, only refs are shown that + match against at least one pattern, either using `fnmatch`(3) or + literally, in the latter case matching completely or from the + beginning up to a slash. + +`--stdin`:: + The list of patterns is read from standard input instead of from + the argument list. + +`--count=<count>`:: + Stop after showing _<count>_ refs. + +`--sort=<key>`:: + Sort on the field name _<key>_. Prefix `-` to sort in + descending order of the value. When unspecified, + `refname` is used. You may use the `--sort=<key>` option + multiple times, in which case the last key becomes the primary + key. + +`--format[=<format>]`:: + A string that interpolates `%(fieldname)` from a ref being shown and + the object it points at. In addition, the string literal `%%` + renders as `%` and `%xx` - where `xx` are hex digits - renders as + the character with hex code `xx`. For example, `%00` interpolates to + `\0` (_NUL_), `%09` to `\t` (_TAB_), and `%0a` to `\n` (_LF_). + +When unspecified, _<format>_ defaults to `%(objectname) SPC %(objecttype) +TAB %(refname)`. + +`--color[=<when>]`:: + Respect any colors specified in the `--format` option. The + _<when__ field must be one of `always`, `never`, or `auto` (if + `<when>` is absent, behave as if `always` was given). + +`--shell`:: +`--perl`:: +`--python`:: +`--tcl`:: + If given, strings that substitute `%(fieldname)` + placeholders are quoted as string literals suitable for + the specified host language. This is meant to produce + a scriptlet that can directly be "eval"ed. + +`--points-at=<object>`:: + Only list refs which points at the given object. + +`--merged[=<object>]`:: + Only list refs whose tips are reachable from the + specified commit (`HEAD` if not specified). + +`--no-merged[=<object>]`:: + Only list refs whose tips are not reachable from _<object>_(`HEAD` if not + specified). + +`--contains[=<object>]`:: + Only list refs which contain _<object>_(`HEAD` if not specified). + +`--no-contains[=<object>]`:: + Only list refs which don't contain _<object>_ (`HEAD` + if not specified). + +`--ignore-case`:: + Sorting and filtering refs are case insensitive. + +`--omit-empty`:: + Do not print a newline after formatted refs where the format expands + to the empty string. + +`--exclude=<excluded-pattern>`:: + If one or more `--exclude` options are given, only refs which do not + match any _<excluded-pattern>_ parameters are shown. Matching is done + using the same rules as _<pattern>_ above. + +`--include-root-refs`:: + List root refs (`HEAD` and pseudorefs) apart from regular refs. + +`--start-after=<marker>`:: + Allows paginating the output by skipping references up to and including the + specified marker. When paging, it should be noted that references may be + deleted, modified or added between invocations. Output will only yield those + references which follow the marker lexicographically. Output begins from the + first reference that would come after the marker alphabetically. Cannot be + used with `--sort=<key>` or `--stdin` options, or the _<pattern>_ argument(s) + to limit the refs. diff --git a/Documentation/git-add.adoc b/Documentation/git-add.adoc index eba0b419ce..b7a735824d 100644 --- a/Documentation/git-add.adoc +++ b/Documentation/git-add.adoc @@ -104,6 +104,8 @@ This effectively runs `add --interactive`, but bypasses the initial command menu and directly jumps to the `patch` subcommand. See ``Interactive mode'' for details. +include::diff-context-options.adoc[] + `-e`:: `--edit`:: Open the diff vs. the index in an editor and let the user diff --git a/Documentation/git-am.adoc b/Documentation/git-am.adoc index 221070de48..b23b4fba20 100644 --- a/Documentation/git-am.adoc +++ b/Documentation/git-am.adoc @@ -48,7 +48,8 @@ OPTIONS --keep-non-patch:: Pass `-b` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]). ---[no-]keep-cr:: +--keep-cr:: +--no-keep-cr:: With `--keep-cr`, call 'git mailsplit' (see linkgit:git-mailsplit[1]) with the same option, to prevent it from stripping CR at the end of lines. `am.keepcr` configuration variable can be used to specify the diff --git a/Documentation/git-backfill.adoc b/Documentation/git-backfill.adoc index 95623051f7..b8394dcf22 100644 --- a/Documentation/git-backfill.adoc +++ b/Documentation/git-backfill.adoc @@ -57,7 +57,8 @@ OPTIONS blobs seen at a given path. The default minimum batch size is 50,000. -`--[no-]sparse`:: +`--sparse`:: +`--no-sparse`:: Only download objects if they appear at a path that matches the current sparse-checkout. If the sparse-checkout feature is enabled, then `--sparse` is assumed and can be disabled with `--no-sparse`. diff --git a/Documentation/git-cat-file.adoc b/Documentation/git-cat-file.adoc index 180d1ad363..c139f55a16 100644 --- a/Documentation/git-cat-file.adoc +++ b/Documentation/git-cat-file.adoc @@ -62,8 +62,10 @@ OPTIONS or to ask for a "blob" with `<object>` being a tag object that points at it. ---[no-]mailmap:: ---[no-]use-mailmap:: +--mailmap:: +--no-mailmap:: +--use-mailmap:: +--no-use-mailmap:: Use mailmap file to map author, committer and tagger names and email addresses to canonical real names and email addresses. See linkgit:git-shortlog[1]. diff --git a/Documentation/git-check-attr.adoc b/Documentation/git-check-attr.adoc index 503b644657..15a37a38e3 100644 --- a/Documentation/git-check-attr.adoc +++ b/Documentation/git-check-attr.adoc @@ -19,7 +19,8 @@ For every pathname, this command will list if each attribute is 'unspecified', OPTIONS ------- --a, --all:: +-a:: +--all:: List all attributes that are associated with the specified paths. If this option is used, then 'unspecified' attributes will not be included in the output. diff --git a/Documentation/git-check-ignore.adoc b/Documentation/git-check-ignore.adoc index 3e3b4e3446..a6c6c1b6e5 100644 --- a/Documentation/git-check-ignore.adoc +++ b/Documentation/git-check-ignore.adoc @@ -25,11 +25,13 @@ subject to exclude rules; but see `--no-index'. OPTIONS ------- --q, --quiet:: +-q:: +--quiet:: Don't output anything, just set exit status. This is only valid with a single pathname. --v, --verbose:: +-v:: +--verbose:: Instead of printing the paths that are excluded, for each path that matches an exclude pattern, print the exclude pattern together with the path. (Matching an exclude pattern usually @@ -49,7 +51,8 @@ linkgit:gitignore[5]. below). If `--stdin` is also given, input paths are separated with a NUL character instead of a linefeed character. --n, --non-matching:: +-n:: +--non-matching:: Show given paths which don't match any pattern. This only makes sense when `--verbose` is enabled, otherwise it would not be possible to distinguish between paths which match a diff --git a/Documentation/git-check-ref-format.adoc b/Documentation/git-check-ref-format.adoc index 2aacfd1808..0c3abf9146 100644 --- a/Documentation/git-check-ref-format.adoc +++ b/Documentation/git-check-ref-format.adoc @@ -98,7 +98,8 @@ a branch. OPTIONS ------- ---[no-]allow-onelevel:: +--allow-onelevel:: +--no-allow-onelevel:: Controls whether one-level refnames are accepted (i.e., refnames that do not contain multiple `/`-separated components). The default is `--no-allow-onelevel`. diff --git a/Documentation/git-checkout.adoc b/Documentation/git-checkout.adoc index ee83b6d9ba..ff1cb29bc1 100644 --- a/Documentation/git-checkout.adoc +++ b/Documentation/git-checkout.adoc @@ -289,6 +289,8 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode. Note that this option uses the no overlay mode by default (see also `--overlay`), and currently doesn't support overlay mode. +include::diff-context-options.adoc[] + `--ignore-other-worktrees`:: `git checkout` refuses when the wanted branch is already checked out or otherwise in use by another worktree. This option makes @@ -332,7 +334,7 @@ Note that this option uses the no overlay mode by default (see also separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). -<branch>:: +`<branch>`:: Branch to checkout; if it refers to a branch (i.e., a name that, when prepended with "refs/heads/", is a valid ref), then that branch is checked out. Otherwise, if it refers to a valid diff --git a/Documentation/git-clone.adoc b/Documentation/git-clone.adoc index 222d558290..57cdfb7620 100644 --- a/Documentation/git-clone.adoc +++ b/Documentation/git-clone.adoc @@ -16,7 +16,7 @@ git clone [--template=<template-directory>] [--depth <depth>] [--[no-]single-branch] [--[no-]tags] [--recurse-submodules[=<pathspec>]] [--[no-]shallow-submodules] [--[no-]remote-submodules] [--jobs <n>] [--sparse] [--[no-]reject-shallow] - [--filter=<filter-spec>] [--also-filter-submodules]] [--] <repository> + [--filter=<filter-spec> [--also-filter-submodules]] [--] <repository> [<directory>] DESCRIPTION @@ -272,7 +272,8 @@ corresponding `--mirror` and `--no-tags` options instead. reachable from a specified remote branch or tag. This option can be specified multiple times. -`--[no-]single-branch`:: +`--single-branch`:: +`--no-single-branch`:: Clone only the history leading to the tip of a single branch, either specified by the `--branch` option or the primary branch remote's `HEAD` points at. @@ -282,7 +283,8 @@ corresponding `--mirror` and `--no-tags` options instead. branch when `--single-branch` clone was made, no remote-tracking branch is created. -`--[no-]tags`:: +`--tags`:: +`--no-tags`:: Control whether or not tags will be cloned. When `--no-tags` is given, the option will be become permanent by setting the `remote.<remote>.tagOpt=--no-tags` configuration. This ensures that @@ -313,10 +315,12 @@ the clone is finished. This option is ignored if the cloned repository does not have a worktree/checkout (i.e. if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) -`--[no-]shallow-submodules`:: +`--shallow-submodules`:: +`--no-shallow-submodules`:: All submodules which are cloned will be shallow with a depth of 1. -`--[no-]remote-submodules`:: +`--remote-submodules`:: +`--no-remote-submodules`:: All submodules which are cloned will use the status of the submodule's remote-tracking branch to update the submodule, rather than the superproject's recorded SHA-1. Equivalent to passing `--remote` to diff --git a/Documentation/git-commit-graph.adoc b/Documentation/git-commit-graph.adoc index 50b5016804..e9558173c0 100644 --- a/Documentation/git-commit-graph.adoc +++ b/Documentation/git-commit-graph.adoc @@ -34,7 +34,8 @@ OPTIONS object directory, `git commit-graph ...` will exit with non-zero status. ---[no-]progress:: +--progress:: +--no-progress:: Turn progress on/off explicitly. If neither is specified, progress is shown if standard error is connected to a terminal. diff --git a/Documentation/git-commit.adoc b/Documentation/git-commit.adoc index dc219025f1..54c207ad45 100644 --- a/Documentation/git-commit.adoc +++ b/Documentation/git-commit.adoc @@ -76,6 +76,8 @@ OPTIONS which changes to commit. See linkgit:git-add[1] for details. +include::diff-context-options.adoc[] + `-C <commit>`:: `--reuse-message=<commit>`:: Take an existing _<commit>_ object, and reuse the log message @@ -212,7 +214,8 @@ include::signoff-option.adoc[] each trailer would appear, and other details. `-n`:: -`--[no-]verify`:: +`--verify`:: +`--no-verify`:: Bypass the `pre-commit` and `commit-msg` hooks. See also linkgit:githooks[5]. @@ -279,6 +282,7 @@ variable (see linkgit:git-config[1]). + -- It is a rough equivalent for: + ------ $ git reset --soft HEAD^ $ ... do something else to come up with the right tree ... diff --git a/Documentation/git-config.adoc b/Documentation/git-config.adoc index 511b2e26bf..36d2845152 100644 --- a/Documentation/git-config.adoc +++ b/Documentation/git-config.adoc @@ -295,7 +295,8 @@ Valid `<type>`'s include: When the color setting for `name` is undefined, the command uses `color.ui` as fallback. ---[no-]includes:: +--includes:: +--no-includes:: Respect `include.*` directives in config files when looking up values. Defaults to `off` when a specific file is given (e.g., using `--file`, `--global`, etc) and `on` when searching all diff --git a/Documentation/git-count-objects.adoc b/Documentation/git-count-objects.adoc index 97f9f12610..eeee6b9f7f 100644 --- a/Documentation/git-count-objects.adoc +++ b/Documentation/git-count-objects.adoc @@ -28,6 +28,8 @@ size: disk space consumed by loose objects, in KiB (unless -H is specified) + in-pack: the number of in-pack objects + +packs: the number of pack files ++ size-pack: disk space consumed by the packs, in KiB (unless -H is specified) + prune-packable: the number of loose objects that are also present in diff --git a/Documentation/git-difftool.adoc b/Documentation/git-difftool.adoc index d596205eaf..064bc68347 100644 --- a/Documentation/git-difftool.adoc +++ b/Documentation/git-difftool.adoc @@ -77,7 +77,8 @@ with custom merge tool commands and has the same value as `$MERGED`. --tool-help:: Print a list of diff tools that may be used with `--tool`. ---[no-]symlinks:: +--symlinks:: +--no-symlinks:: 'git difftool''s default behavior is to create symlinks to the working tree when run in `--dir-diff` mode and the right-hand side of the comparison yields the same content as the file in @@ -94,7 +95,8 @@ instead. `--no-symlinks` is the default on Windows. Additionally, `$BASE` is set in the environment. -g:: ---[no-]gui:: +--gui:: +--no-gui:: When 'git-difftool' is invoked with the `-g` or `--gui` option the default diff tool will be read from the configured `diff.guitool` variable instead of `diff.tool`. This may be @@ -104,7 +106,8 @@ instead. `--no-symlinks` is the default on Windows. fallback in the order of `merge.guitool`, `diff.tool`, `merge.tool` until a tool is found. ---[no-]trust-exit-code:: +--trust-exit-code:: +--no-trust-exit-code:: Errors reported by the diff tool are ignored by default. Use `--trust-exit-code` to make 'git-difftool' exit when an invoked diff tool returns a non-zero exit code. diff --git a/Documentation/git-fast-import.adoc b/Documentation/git-fast-import.adoc index d232784200..3144ffcdb6 100644 --- a/Documentation/git-fast-import.adoc +++ b/Documentation/git-fast-import.adoc @@ -111,7 +111,8 @@ Locations of Marks Files Like --import-marks but instead of erroring out, silently skips the file if it does not exist. ---[no-]relative-marks:: +--relative-marks:: +--no-relative-marks:: After specifying --relative-marks the paths specified with --import-marks= and --export-marks= are relative to an internal directory in the current repository. @@ -182,7 +183,7 @@ amount of memory usage and processing time. Assuming the frontend is able to keep up with fast-import and feed it a constant stream of data, import times for projects holding 10+ years of history and containing 100,000+ individual commits are generally completed in just 1-2 -hours on quite modest (~$2,000 USD) hardware. +hours on quite modest hardware (~$2,000 USD in 2007). Most bottlenecks appear to be in foreign source data access (the source just cannot extract revisions fast enough) or disk IO (fast-import @@ -605,9 +606,11 @@ Marks must be declared (via `mark`) before they can be used. The special case of restarting an incremental import from the current branch value should be written as: + ---- from refs/heads/branch^0 ---- + The `^0` suffix is necessary as fast-import does not permit a branch to start from itself, and the branch is created in memory before the `from` command is even read from the input. Adding `^0` will force diff --git a/Documentation/git-fmt-merge-msg.adoc b/Documentation/git-fmt-merge-msg.adoc index 0f3328956d..6d91620be9 100644 --- a/Documentation/git-fmt-merge-msg.adoc +++ b/Documentation/git-fmt-merge-msg.adoc @@ -35,7 +35,8 @@ OPTIONS Do not list one-line descriptions from the actual commits being merged. ---[no-]summary:: +--summary:: +--no-summary:: Synonyms to --log and --no-log; these are deprecated and will be removed in the future. diff --git a/Documentation/git-for-each-ref.adoc b/Documentation/git-for-each-ref.adoc index 5ef89fc0fe..c02cb7f886 100644 --- a/Documentation/git-for-each-ref.adoc +++ b/Documentation/git-for-each-ref.adoc @@ -7,106 +7,28 @@ git-for-each-ref - Output information on each ref SYNOPSIS -------- -[verse] -'git for-each-ref' [--count=<count>] [--shell|--perl|--python|--tcl] +[synopsis] +git for-each-ref [--count=<count>] [--shell|--perl|--python|--tcl] [(--sort=<key>)...] [--format=<format>] - [--include-root-refs] [ --stdin | <pattern>... ] - [--points-at=<object>] + [--include-root-refs] [--points-at=<object>] [--merged[=<object>]] [--no-merged[=<object>]] [--contains[=<object>]] [--no-contains[=<object>]] - [--exclude=<pattern> ...] + [(--exclude=<pattern>)...] [--start-after=<marker>] + [ --stdin | (<pattern>...)] DESCRIPTION ----------- -Iterate over all refs that match `<pattern>` and show them -according to the given `<format>`, after sorting them according -to the given set of `<key>`. If `<count>` is given, stop after -showing that many refs. The interpolated values in `<format>` +Iterate over all refs that match _<pattern>_ and show them +according to the given _<format>_, after sorting them according +to the given set of _<key>_. If _<count>_ is given, stop after +showing that many refs. The interpolated values in _<format>_ can optionally be quoted as string literals in the specified host language allowing their direct evaluation in that language. OPTIONS ------- -<pattern>...:: - If one or more patterns are given, only refs are shown that - match against at least one pattern, either using fnmatch(3) or - literally, in the latter case matching completely or from the - beginning up to a slash. - ---stdin:: - If `--stdin` is supplied, then the list of patterns is read from - standard input instead of from the argument list. - ---count=<count>:: - By default the command shows all refs that match - `<pattern>`. This option makes it stop after showing - that many refs. - ---sort=<key>:: - A field name to sort on. Prefix `-` to sort in - descending order of the value. When unspecified, - `refname` is used. You may use the --sort=<key> option - multiple times, in which case the last key becomes the primary - key. - ---format=<format>:: - A string that interpolates `%(fieldname)` from a ref being shown and - the object it points at. In addition, the string literal `%%` - renders as `%` and `%xx` - where `xx` are hex digits - renders as - the character with hex code `xx`. For example, `%00` interpolates to - `\0` (NUL), `%09` to `\t` (TAB), and `%0a` to `\n` (LF). -+ -When unspecified, `<format>` defaults to `%(objectname) SPC %(objecttype) -TAB %(refname)`. - ---color[=<when>]:: - Respect any colors specified in the `--format` option. The - `<when>` field must be one of `always`, `never`, or `auto` (if - `<when>` is absent, behave as if `always` was given). - ---shell:: ---perl:: ---python:: ---tcl:: - If given, strings that substitute `%(fieldname)` - placeholders are quoted as string literals suitable for - the specified host language. This is meant to produce - a scriptlet that can directly be `eval`ed. - ---points-at=<object>:: - Only list refs which points at the given object. - ---merged[=<object>]:: - Only list refs whose tips are reachable from the - specified commit (HEAD if not specified). - ---no-merged[=<object>]:: - Only list refs whose tips are not reachable from the - specified commit (HEAD if not specified). - ---contains[=<object>]:: - Only list refs which contain the specified commit (HEAD if not - specified). - ---no-contains[=<object>]:: - Only list refs which don't contain the specified commit (HEAD - if not specified). - ---ignore-case:: - Sorting and filtering refs are case insensitive. - ---omit-empty:: - Do not print a newline after formatted refs where the format expands - to the empty string. - ---exclude=<pattern>:: - If one or more patterns are given, only refs which do not match - any excluded pattern(s) are shown. Matching is done using the - same rules as `<pattern>` above. - ---include-root-refs:: - List root refs (HEAD and pseudorefs) apart from regular refs. +include::for-each-ref-options.adoc[] FIELD NAMES ----------- @@ -117,44 +39,44 @@ keys. For all objects, the following names can be used: -refname:: - The name of the ref (the part after $GIT_DIR/). +`refname`:: + The name of the ref (the part after `$GIT_DIR/`). For a non-ambiguous short name of the ref append `:short`. - The option core.warnAmbiguousRefs is used to select the strict - abbreviation mode. If `lstrip=<N>` (`rstrip=<N>`) is appended, strips `<N>` + The option `core.warnAmbiguousRefs` is used to select the strict + abbreviation mode. If `lstrip=<n>` (`rstrip=<n>`) is appended, strip _<n>_ slash-separated path components from the front (back) of the refname (e.g. `%(refname:lstrip=2)` turns `refs/tags/foo` into `foo` and `%(refname:rstrip=2)` turns `refs/tags/foo` into `refs`). - If `<N>` is a negative number, strip as many path components as - necessary from the specified end to leave `-<N>` path components + If _<n>_ is a negative number, strip as many path components as + necessary from the specified end to leave `-<n>` path components (e.g. `%(refname:lstrip=-2)` turns `refs/tags/foo` into `tags/foo` and `%(refname:rstrip=-1)` turns `refs/tags/foo` into `refs`). When the ref does not have enough components, the result becomes an empty string if - stripping with positive <N>, or it becomes the full refname if - stripping with negative <N>. Neither is an error. + stripping with positive _<n>_, or it becomes the full refname if + stripping with negative _<N>_. Neither is an error. + `strip` can be used as a synonym to `lstrip`. -objecttype:: +`objecttype`:: The type of the object (`blob`, `tree`, `commit`, `tag`). -objectsize:: +`objectsize`:: The size of the object (the same as 'git cat-file -s' reports). Append `:disk` to get the size, in bytes, that the object takes up on - disk. See the note about on-disk sizes in the `CAVEATS` section below. -objectname:: + disk. See the note about on-disk sizes in the 'CAVEATS' section below. +`objectname`:: The object name (aka SHA-1). For a non-ambiguous abbreviation of the object name append `:short`. For an abbreviation of the object name with desired length append - `:short=<length>`, where the minimum length is MINIMUM_ABBREV. The + `:short=<length>`, where the minimum length is `MINIMUM_ABBREV`. The length may be exceeded to ensure unique object names. -deltabase:: +`deltabase`:: This expands to the object name of the delta base for the given object, if it is stored as a delta. Otherwise it expands to the null object name (all zeroes). -upstream:: +`upstream`:: The name of a local ref which can be considered ``upstream'' from the displayed ref. Respects `:short`, `:lstrip` and `:rstrip` in the same way as `refname` above. Additionally @@ -176,100 +98,103 @@ Has no effect if the ref does not have tracking information associated with it. All the options apart from `nobracket` are mutually exclusive, but if used together the last option is selected. -push:: +`push`:: The name of a local ref which represents the `@{push}` location for the displayed ref. Respects `:short`, `:lstrip`, `:rstrip`, `:track`, `:trackshort`, `:remotename`, and `:remoteref` options as `upstream` does. Produces an empty string if no `@{push}` ref is configured. -HEAD:: - '*' if HEAD matches current ref (the checked out branch), ' ' +`HEAD`:: + `*` if `HEAD` matches current ref (the checked out branch), ' ' otherwise. -color:: +`color`:: Change output color. Followed by `:<colorname>`, where color names are described under Values in the "CONFIGURATION FILE" section of linkgit:git-config[1]. For example, `%(color:bold red)`. -align:: +`align`:: Left-, middle-, or right-align the content between - %(align:...) and %(end). The "align:" is followed by + `%(align:...)` and `%(end)`. The "`align:`" is followed by `width=<width>` and `position=<position>` in any order - separated by a comma, where the `<position>` is either left, - right or middle, default being left and `<width>` is the total + separated by a comma, where the _<position>_ is either `left`, + `right` or `middle`, default being `left` and _<width>_ is the total length of the content with alignment. For brevity, the "width=" and/or "position=" prefixes may be omitted, and bare - <width> and <position> used instead. For instance, + _<width>_ and _<position>_ used instead. For instance, `%(align:<width>,<position>)`. If the contents length is more than the width then no alignment is performed. If used with - `--quote` everything in between %(align:...) and %(end) is + `--quote` everything in between `%(align:...)` and `%(end)` is quoted, but if nested then only the topmost level performs quoting. -if:: - Used as %(if)...%(then)...%(end) or - %(if)...%(then)...%(else)...%(end). If there is an atom with - value or string literal after the %(if) then everything after - the %(then) is printed, else if the %(else) atom is used, then +`if`:: + Used as `%(if)...%(then)...%(end)` or + `%(if)...%(then)...%(else)...%(end)`. If there is an atom with + value or string literal after the `%(if)` then everything after + the `%(then)` is printed, else if the `%(else)` atom is used, then everything after %(else) is printed. We ignore space when - evaluating the string before %(then), this is useful when we - use the %(HEAD) atom which prints either "*" or " " and we - want to apply the 'if' condition only on the 'HEAD' ref. - Append ":equals=<string>" or ":notequals=<string>" to compare - the value between the %(if:...) and %(then) atoms with the + evaluating the string before `%(then)`, this is useful when we + use the `%(HEAD)` atom which prints either "`*`" or " " and we + want to apply the 'if' condition only on the `HEAD` ref. + Append "`:equals=<string>`" or "`:notequals=<string>`" to compare + the value between the `%(if:...)` and `%(then)` atoms with the given string. -symref:: +`symref`:: The ref which the given symbolic ref refers to. If not a symbolic ref, nothing is printed. Respects the `:short`, `:lstrip` and `:rstrip` options in the same way as `refname` above. -signature:: +`signature`:: The GPG signature of a commit. -signature:grade:: - Show "G" for a good (valid) signature, "B" for a bad - signature, "U" for a good signature with unknown validity, "X" - for a good signature that has expired, "Y" for a good - signature made by an expired key, "R" for a good signature - made by a revoked key, "E" if the signature cannot be - checked (e.g. missing key) and "N" for no signature. - -signature:signer:: +`signature:grade`:: + Show +`G`;; for a good (valid) signature +`B`;; for a bad signature +`U`;; for a good signature with unknown validity +`X`;; for a good signature that has expired +`Y`;; for a good signature made by an expired key +`R`;; for a good signature made by a revoked key +`E`;; if the signature cannot be checked (e.g. missing key) +`N`;; for no signature. + +`signature:signer`:: The signer of the GPG signature of a commit. -signature:key:: +`signature:key`:: The key of the GPG signature of a commit. -signature:fingerprint:: +`signature:fingerprint`:: The fingerprint of the GPG signature of a commit. -signature:primarykeyfingerprint:: +`signature:primarykeyfingerprint`:: The primary key fingerprint of the GPG signature of a commit. -signature:trustlevel:: +`signature:trustlevel`:: The trust level of the GPG signature of a commit. Possible outputs are `ultimate`, `fully`, `marginal`, `never` and `undefined`. -worktreepath:: +`worktreepath`:: The absolute path to the worktree in which the ref is checked out, if it is checked out in any linked worktree. Empty string otherwise. -ahead-behind:<committish>:: +`ahead-behind:<commit-ish>`:: Two integers, separated by a space, demonstrating the number of commits ahead and behind, respectively, when comparing the output - ref to the `<committish>` specified in the format. + ref to the _<committish>_ specified in the format. -is-base:<committish>:: - In at most one row, `(<committish>)` will appear to indicate the ref +`is-base:<commit-ish>`:: + In at most one row, `(<commit-ish>)` will appear to indicate the ref that is most likely the ref used as a starting point for the branch - that produced `<committish>`. This choice is made using a heuristic: + that produced _<commit-ish>_. This choice is made using a heuristic: choose the ref that minimizes the number of commits in the - first-parent history of `<committish>` and not in the first-parent + first-parent history of _<commit-ish>_ and not in the first-parent history of the ref. + For example, consider the following figure of first-parent histories of @@ -303,29 +228,29 @@ common first-parent ancestor of `B` and `C` and ties are broken by the earliest ref in the sorted order. + Note that this token will not appear if the first-parent history of -`<committish>` does not intersect the first-parent histories of the +_<commit-ish>_ does not intersect the first-parent histories of the filtered refs. -describe[:options]:: +`describe[:<option>,...]`:: A human-readable name, like linkgit:git-describe[1]; empty string for undescribable commits. The `describe` string may be followed by a colon and one or more comma-separated options. + -- -tags=<bool-value>;; +`tags=<bool-value>`;; Instead of only considering annotated tags, consider lightweight tags as well; see the corresponding option in linkgit:git-describe[1] for details. -abbrev=<number>;; - Use at least <number> hexadecimal digits; see the corresponding +`abbrev=<number>`;; + Use at least _<number>_ hexadecimal digits; see the corresponding option in linkgit:git-describe[1] for details. -match=<pattern>;; - Only consider tags matching the given `glob(7)` pattern, - excluding the "refs/tags/" prefix; see the corresponding option +`match=<pattern>`;; + Only consider tags matching the `glob`(7) _<pattern>_, + excluding the `refs/tags/` prefix; see the corresponding option in linkgit:git-describe[1] for details. -exclude=<pattern>;; - Do not consider tags matching the given `glob(7)` pattern, - excluding the "refs/tags/" prefix; see the corresponding option +`exclude=<pattern>`;; + Do not consider tags matching the `glob`(7) _<pattern>_, + excluding the `refs/tags/` prefix; see the corresponding option in linkgit:git-describe[1] for details. -- @@ -357,7 +282,7 @@ variable (see linkgit:gitmailmap[5]). The raw data in an object is `raw`. -raw:size:: +`raw:size`:: The raw data size of the object. Note that `--format=%(raw)` can not be used with `--python`, `--shell`, `--tcl`, @@ -367,10 +292,10 @@ variable type. The message in a commit or a tag object is `contents`, from which `contents:<part>` can be used to extract various parts out of: -contents:size:: +`contents:size`:: The size in bytes of the commit or tag message. -contents:subject:: +`contents:subject`:: The first paragraph of the message, which typically is a single line, is taken as the "subject" of the commit or the tag message. @@ -378,19 +303,19 @@ contents:subject:: obtain same results. `:sanitize` can be appended to `subject` for subject line suitable for filename. -contents:body:: +`contents:body`:: The remainder of the commit or the tag message that follows the "subject". -contents:signature:: +`contents:signature`:: The optional GPG signature of the tag. -contents:lines=N:: - The first `N` lines of the message. +`contents:lines=<n>`:: + The first _<n>_ lines of the message. Additionally, the trailers as interpreted by linkgit:git-interpret-trailers[1] -are obtained as `trailers[:options]` (or by using the historical alias -`contents:trailers[:options]`). For valid [:option] values see `trailers` +are obtained as `trailers[:<option>,...]` (or by using the historical alias +`contents:trailers[:<option>,...]`). For valid _<option>_ values see `trailers` section of linkgit:git-log[1]. For sorting purposes, fields with numeric values sort in numeric order @@ -410,8 +335,8 @@ option to linkgit:git-rev-list[1] takes). If this formatting is provided in a `--sort` key, references will be sorted according to the byte-value of the formatted string rather than the numeric value of the underlying timestamp. -Some atoms like %(align) and %(if) always require a matching %(end). -We call them "opening atoms" and sometimes denote them as %($open). +Some atoms like `%(align)` and `%(if)` always require a matching `%(end)`. +We call them "opening atoms" and sometimes denote them as `%($open)`. When a scripting language specific quoting is in effect, everything between a top-level opening atom and its matching %(end) is evaluated @@ -429,7 +354,7 @@ An example directly producing formatted text. Show the most recent #!/bin/sh git for-each-ref --count=3 --sort='-*authordate' \ ---format='From: %(*authorname) %(*authoremail) +`--format='From: %(*authorname) %(*authoremail) Subject: %(*subject) Date: %(*authordate) Ref: %(*refname) @@ -440,7 +365,7 @@ Ref: %(*refname) A simple example showing the use of shell eval on the output, -demonstrating the use of --shell. List the prefixes of all heads: +demonstrating the use of `--shell`. List the prefixes of all heads: ------------ #!/bin/sh @@ -508,7 +433,7 @@ eval "$eval" ------------ -An example to show the usage of %(if)...%(then)...%(else)...%(end). +An example to show the usage of `%(if)...%(then)...%(else)...%(end)`. This prefixes the current branch with a star. ------------ @@ -516,7 +441,7 @@ git for-each-ref --format="%(if)%(HEAD)%(then)* %(else) %(end)%(refname:short)" ------------ -An example to show the usage of %(if)...%(then)...%(end). +An example to show the usage of `%(if)...%(then)...%(end)`. This prints the authorname, if present. ------------ diff --git a/Documentation/git-format-patch.adoc b/Documentation/git-format-patch.adoc index a8b53db9a6..9a7807ca71 100644 --- a/Documentation/git-format-patch.adoc +++ b/Documentation/git-format-patch.adoc @@ -295,7 +295,8 @@ header). Note also that `git send-email` already handles this transformation for you, and this option should not be used if you are feeding the result to `git send-email`. ---[no-]force-in-body-from:: +--force-in-body-from:: +--no-force-in-body-from:: With the e-mail sender specified via the `--from` option, by default, an in-body "From:" to identify the real author of the commit is added at the top of the commit log message if @@ -314,7 +315,8 @@ feeding the result to `git send-email`. `Cc:`, and custom) headers added so far from config or command line. ---[no-]cover-letter:: +--cover-letter:: +--no-cover-letter:: In addition to the patches, generate a cover letter file containing the branch description, shortlog and the overall diffstat. You can fill in a description in the file before sending it out. @@ -379,7 +381,8 @@ configuration options in linkgit:git-notes[1] to use this workflow). The default is `--no-notes`, unless the `format.notes` configuration is set. ---[no-]signature=<signature>:: +--signature=<signature>:: +--no-signature:: Add a signature to each message produced. Per RFC 3676 the signature is separated from the body by a line with '-- ' on it. If the signature option is omitted the signature defaults to the Git version @@ -411,7 +414,8 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. Output an all-zero hash in each patch's From header instead of the hash of the commit. ---[no-]base[=<commit>]:: +--no-base:: +--base[=<commit>]:: Record the base tree information to identify the state the patch series applies to. See the BASE TREE INFORMATION section below for details. If <commit> is "auto", a base commit is @@ -587,13 +591,19 @@ an external editor to keep Thunderbird from mangling the patches. Approach #1 (add-on) ^^^^^^^^^^^^^^^^^^^^ -Install the Toggle Word Wrap add-on that is available from -https://addons.mozilla.org/thunderbird/addon/toggle-word-wrap/ -It adds a menu entry "Enable Word Wrap" in the composer's "Options" menu +Install the Toggle Line Wrap add-on that is available from +https://addons.thunderbird.net/thunderbird/addon/toggle-line-wrap +It adds a button "Line Wrap" to the composer's toolbar that you can tick off. Now you can compose the message as you otherwise do (cut + paste, 'git format-patch' | 'git imap-send', etc), but you have to insert line breaks manually in any text that you type. +As a bonus feature, the add-on can detect patch text in the composer +and warns when line wrapping has not yet been turned off. + +The add-on requires a few tweaks of the advanced configuration +(about:config). These are listed on the download page. + Approach #2 (configuration) ^^^^^^^^^^^^^^^^^^^^^^^^^^^ Three steps: diff --git a/Documentation/git-fsck.adoc b/Documentation/git-fsck.adoc index 11203ba925..1751f692d4 100644 --- a/Documentation/git-fsck.adoc +++ b/Documentation/git-fsck.adoc @@ -31,7 +31,8 @@ index file, all SHA-1 references in the `refs` namespace, and all reflogs Print out objects that exist but that aren't reachable from any of the reference nodes. ---[no-]dangling:: +--dangling:: +--no-dangling:: Print objects that exist but that are never 'directly' used (default). `--no-dangling` can be used to omit this information from the output. @@ -97,14 +98,16 @@ care about this output and want to speed it up further. compatible with linkgit:git-rev-parse[1], e.g. `HEAD@{1234567890}~25^2:src/`. ---[no-]progress:: +--progress:: +--no-progress:: Progress status is reported on the standard error stream by default when it is attached to a terminal, unless --no-progress or --verbose is specified. --progress forces progress status even if the standard error stream is not directed to a terminal. ---[no-]references:: +--references:: +--no-references:: Control whether to check the references database consistency via 'git refs verify'. See linkgit:git-refs[1] for details. The default is to check the references database. diff --git a/Documentation/git-gc.adoc b/Documentation/git-gc.adoc index 526ce01463..6fed646dd8 100644 --- a/Documentation/git-gc.adoc +++ b/Documentation/git-gc.adoc @@ -53,11 +53,13 @@ configuration options such as `gc.auto` and `gc.autoPackLimit`, all other housekeeping tasks (e.g. rerere, working trees, reflog...) will be performed as well. ---[no-]detach:: +--detach:: +--no-detach:: Run in the background if the system supports it. This option overrides the `gc.autoDetach` config. ---[no-]cruft:: +--cruft:: +--no-cruft:: When expiring unreachable objects, pack them separately into a cruft pack instead of storing them as loose objects. `--cruft` is on by default. diff --git a/Documentation/git-http-fetch.adoc b/Documentation/git-http-fetch.adoc index 4ec7c68d3b..2200f073c4 100644 --- a/Documentation/git-http-fetch.adoc +++ b/Documentation/git-http-fetch.adoc @@ -25,8 +25,11 @@ commit-id:: Either the hash or the filename under [URL]/refs/ to pull. --a, -c, -t:: +-a:: +-c:: +-t:: These options are ignored for historical reasons. + -v:: Report what is downloaded. diff --git a/Documentation/git-imap-send.adoc b/Documentation/git-imap-send.adoc index 17147f93c3..278e5ccd36 100644 --- a/Documentation/git-imap-send.adoc +++ b/Documentation/git-imap-send.adoc @@ -68,6 +68,34 @@ include::includes/cmd-config-section-rest.adoc[] include::config/imap.adoc[] +GETTING A LIST OF AVAILABLE FOLDERS +----------------------------------- + +In order to send an email to a specific folder, you need to know the correct name of +intended folder in your mailbox. The names like "Junk", "Trash" etc. displayed by +various email clients need not be the actual names of the folders stored in the mail +server of your email provider. + +In order to get the correct folder name to be used with `git imap-send`, you can run +`git imap-send --list`. This will display a list of valid folder names. An example +of such an output when run on a Gmail account is: + +......................... +* LIST (\HasNoChildren) "/" "INBOX" +* LIST (\HasChildren \Noselect) "/" "[Gmail]" +* LIST (\All \HasNoChildren) "/" "[Gmail]/All Mail" +* LIST (\Drafts \HasNoChildren) "/" "[Gmail]/Drafts" +* LIST (\HasNoChildren \Important) "/" "[Gmail]/Important" +* LIST (\HasNoChildren \Sent) "/" "[Gmail]/Sent Mail" +* LIST (\HasNoChildren \Junk) "/" "[Gmail]/Spam" +* LIST (\Flagged \HasNoChildren) "/" "[Gmail]/Starred" +* LIST (\HasNoChildren \Trash) "/" "[Gmail]/Trash" +......................... + +Here, you can observe that the correct name for the "Junk" folder is `[Gmail]/Spam` +and for the "Trash" folder is `[Gmail]/Trash`. Similar logic can be used to determine +other folders as well. + EXAMPLES -------- Using tunnel mode: diff --git a/Documentation/git-index-pack.adoc b/Documentation/git-index-pack.adoc index 270056cf63..18036953c0 100644 --- a/Documentation/git-index-pack.adoc +++ b/Documentation/git-index-pack.adoc @@ -36,7 +36,8 @@ OPTIONS fails if the name of packed archive does not end with .pack). ---[no-]rev-index:: +--rev-index:: +--no-rev-index:: When this flag is provided, generate a reverse index (a `.rev` file) corresponding to the given pack. If `--verify` is given, ensure that the existing diff --git a/Documentation/git-interpret-trailers.adoc b/Documentation/git-interpret-trailers.adoc index 82c8780d93..fd335fe772 100644 --- a/Documentation/git-interpret-trailers.adoc +++ b/Documentation/git-interpret-trailers.adoc @@ -142,8 +142,8 @@ OPTIONS provided with '--if-exists' overrides the `trailer.ifExists` and any applicable `trailer.<keyAlias>.ifExists` configuration variables and applies to all '--trailer' options until the next occurrence of - '--if-exists' or '--no-if-exists'. Upon encountering '--no-if-exists, clear the - effect of any previous use of '--if-exists, such that the relevant configuration + '--if-exists' or '--no-if-exists'. Upon encountering '--no-if-exists', clear the + effect of any previous use of '--if-exists', such that the relevant configuration variables are no longer overridden. Possible actions are `addIfDifferent`, `addIfDifferentNeighbor`, `add`, `replace` and `doNothing`. @@ -154,8 +154,8 @@ OPTIONS provided with '--if-missing' overrides the `trailer.ifMissing` and any applicable `trailer.<keyAlias>.ifMissing` configuration variables and applies to all '--trailer' options until the next occurrence of - '--if-missing' or '--no-if-missing'. Upon encountering '--no-if-missing, - clear the effect of any previous use of '--if-missing, such that the relevant + '--if-missing' or '--no-if-missing'. Upon encountering '--no-if-missing', + clear the effect of any previous use of '--if-missing', such that the relevant configuration variables are no longer overridden. Possible actions are `doNothing` or `add`. diff --git a/Documentation/git-log.adoc b/Documentation/git-log.adoc index b6f3d92c43..e304739c5e 100644 --- a/Documentation/git-log.adoc +++ b/Documentation/git-log.adoc @@ -73,8 +73,10 @@ used as decoration if they match `HEAD`, `refs/heads/`, `refs/remotes/`, Print out the ref name given on the command line by which each commit was reached. -`--[no-]mailmap`:: -`--[no-]use-mailmap`:: +`--mailmap`:: +`--no-mailmap`:: +`--use-mailmap`:: +`--no-use-mailmap`:: Use mailmap file to map author and committer names and email addresses to canonical real names and email addresses. See linkgit:git-shortlog[1]. diff --git a/Documentation/git-merge-tree.adoc b/Documentation/git-merge-tree.adoc index f824eea61f..271ab220e8 100644 --- a/Documentation/git-merge-tree.adoc +++ b/Documentation/git-merge-tree.adoc @@ -59,7 +59,8 @@ OPTIONS do not list filenames multiple times if they have multiple conflicting stages). ---[no-]messages:: +--messages:: +--no-messages:: Write any informational messages such as "Auto-merging <path>" or CONFLICT notices to the end of stdout. If unspecified, the default is to include these messages if there are merge diff --git a/Documentation/git-multi-pack-index.adoc b/Documentation/git-multi-pack-index.adoc index b6cd0d7f85..e8073bc272 100644 --- a/Documentation/git-multi-pack-index.adoc +++ b/Documentation/git-multi-pack-index.adoc @@ -25,7 +25,8 @@ OPTIONS + `<dir>` must be an alternate of the current repository. ---[no-]progress:: +--progress:: +--no-progress:: Turn progress on/off explicitly. If neither is specified, progress is shown if standard error is connected to a terminal. Supported by sub-commands `write`, `verify`, `expire`, and `repack. diff --git a/Documentation/git-p4.adoc b/Documentation/git-p4.adoc index f97b786bf9..59edd24134 100644 --- a/Documentation/git-p4.adoc +++ b/Documentation/git-p4.adoc @@ -66,6 +66,7 @@ Clone ~~~~~ Generally, 'git p4 clone' is used to create a new Git directory from an existing p4 repository: + ------------ $ git p4 clone //depot/path/project ------------ diff --git a/Documentation/git-pack-objects.adoc b/Documentation/git-pack-objects.adoc index eba014c406..71b9682485 100644 --- a/Documentation/git-pack-objects.adoc +++ b/Documentation/git-pack-objects.adoc @@ -243,7 +243,8 @@ depth is 4095. Add --no-reuse-object if you want to force a uniform compression level on all data no matter the source. ---[no-]sparse:: +--sparse:: +--no-sparse:: Toggle the "sparse" algorithm to determine which objects to include in the pack, when combined with the "--revs" option. This algorithm only walks trees that appear in paths that introduce new objects. diff --git a/Documentation/git-pull.adoc b/Documentation/git-pull.adoc index 3f4ecc4730..48e924a10a 100644 --- a/Documentation/git-pull.adoc +++ b/Documentation/git-pull.adoc @@ -87,7 +87,8 @@ OPTIONS --verbose:: Pass --verbose to git-fetch and git-merge. ---[no-]recurse-submodules[=(yes|on-demand|no)]:: +--recurse-submodules[=(yes|on-demand|no)]:: +--no-recurse-submodules:: This option controls if new commits of populated submodules should be fetched, and if the working trees of active submodules should be updated, too (see linkgit:git-fetch[1], linkgit:git-config[1] and diff --git a/Documentation/git-push.adoc b/Documentation/git-push.adoc index d1978650d6..5f5408e2c0 100644 --- a/Documentation/git-push.adoc +++ b/Documentation/git-push.adoc @@ -197,7 +197,8 @@ already exists on the remote side. with configuration variable `push.followTags`. For more information, see `push.followTags` in linkgit:git-config[1]. ---[no-]signed:: +--signed:: +--no-signed:: --signed=(true|false|if-asked):: GPG-sign the push request to update refs on the receiving side, to allow it to be checked by the hooks and/or be @@ -208,7 +209,8 @@ already exists on the remote side. will also fail if the actual call to `gpg --sign` fails. See linkgit:git-receive-pack[1] for the details on the receiving end. ---[no-]atomic:: +--atomic:: +--no-atomic:: Use an atomic transaction on the remote side if available. Either all refs are updated, or on error, no refs are updated. If the server does not support atomic pushes the push will fail. @@ -232,7 +234,8 @@ already exists on the remote side. repository over ssh, and you do not have the program in a directory on the default $PATH. ---[no-]force-with-lease:: +--force-with-lease:: +--no-force-with-lease:: --force-with-lease=<refname>:: --force-with-lease=<refname>:<expect>:: Usually, "git push" refuses to update a remote ref that is @@ -350,7 +353,8 @@ one branch, use a `+` in front of the refspec to push (e.g `git push origin +master` to force a push to the `master` branch). See the `<refspec>...` section above for details. ---[no-]force-if-includes:: +--force-if-includes:: +--no-force-if-includes:: Force an update only if the tip of the remote-tracking ref has been integrated locally. + @@ -377,7 +381,8 @@ Specifying `--no-force-if-includes` disables this behavior. linkgit:git-pull[1] and other commands. For more information, see `branch.<name>.merge` in linkgit:git-config[1]. ---[no-]thin:: +--thin:: +--no-thin:: These options are passed to linkgit:git-send-pack[1]. A thin transfer significantly reduces the amount of sent data when the sender and receiver share many of the same objects in common. The default is @@ -419,7 +424,8 @@ When using 'on-demand' or 'only', if a submodule has a "push.recurseSubmodules={on-demand,only}" or "submodule.recurse" configuration, further recursion will occur. In this case, "only" is treated as "on-demand". ---[no-]verify:: +--verify:: +--no-verify:: Toggle the pre-push hook (see linkgit:githooks[5]). The default is --verify, giving the hook a chance to prevent the push. With --no-verify, the hook is bypassed completely. diff --git a/Documentation/git-range-diff.adoc b/Documentation/git-range-diff.adoc index db0e4279b5..b5e85d37f1 100644 --- a/Documentation/git-range-diff.adoc +++ b/Documentation/git-range-diff.adoc @@ -96,7 +96,8 @@ diff. --remerge-diff:: Convenience option, equivalent to `--diff-merges=remerge`. ---[no-]notes[=<ref>]:: +--notes[=<ref>]:: +--no-notes:: This flag is passed to the `git log` program (see linkgit:git-log[1]) that generates the patches. diff --git a/Documentation/git-read-tree.adoc b/Documentation/git-read-tree.adoc index 1c48c28996..1c04bba2b7 100644 --- a/Documentation/git-read-tree.adoc +++ b/Documentation/git-read-tree.adoc @@ -100,7 +100,8 @@ OPTIONS directories the index file and index output file are located in. ---[no-]recurse-submodules:: +--recurse-submodules:: +--no-recurse-submodules:: Using --recurse-submodules will update the content of all active submodules according to the commit recorded in the superproject by calling read-tree recursively, also setting the submodules' HEAD to be diff --git a/Documentation/git-rebase.adoc b/Documentation/git-rebase.adoc index 956d3048f5..005caf6164 100644 --- a/Documentation/git-rebase.adoc +++ b/Documentation/git-rebase.adoc @@ -16,49 +16,12 @@ SYNOPSIS DESCRIPTION ----------- -If `<branch>` is specified, `git rebase` will perform an automatic -`git switch <branch>` before doing anything else. Otherwise -it remains on the current branch. +Transplant a series of commits onto a different starting point. +You can also use `git rebase` to reorder or combine commits: see INTERACTIVE +MODE below for how to do that. -If `<upstream>` is not specified, the upstream configured in -`branch.<name>.remote` and `branch.<name>.merge` options will be used (see -linkgit:git-config[1] for details) and the `--fork-point` option is -assumed. If you are currently not on any branch or if the current -branch does not have a configured upstream, the rebase will abort. - -All changes made by commits in the current branch but that are not -in `<upstream>` are saved to a temporary area. This is the same set -of commits that would be shown by `git log <upstream>..HEAD`; or by -`git log 'fork_point'..HEAD`, if `--fork-point` is active (see the -description on `--fork-point` below); or by `git log HEAD`, if the -`--root` option is specified. - -The current branch is reset to `<upstream>` or `<newbase>` if the -`--onto` option was supplied. This has the exact same effect as -`git reset --hard <upstream>` (or `<newbase>`). `ORIG_HEAD` is set -to point at the tip of the branch before the reset. - -[NOTE] -`ORIG_HEAD` is not guaranteed to still point to the previous branch tip -at the end of the rebase if other commands that write that pseudo-ref -(e.g. `git reset`) are used during the rebase. The previous branch tip, -however, is accessible using the reflog of the current branch -(i.e. `@{1}`, see linkgit:gitrevisions[7]). - -The commits that were previously saved into the temporary area are -then reapplied to the current branch, one by one, in order. Note that -any commits in `HEAD` which introduce the same textual changes as a commit -in `HEAD..<upstream>` are omitted (i.e., a patch already accepted upstream -with a different commit message or timestamp will be skipped). - -It is possible that a merge failure will prevent this process from being -completely automatic. You will have to resolve any such merge failure -and run `git rebase --continue`. Another option is to bypass the commit -that caused the merge failure with `git rebase --skip`. To check out the -original `<branch>` and remove the `.git/rebase-apply` working files, use -the command `git rebase --abort` instead. - -Assume the following history exists and the current branch is "topic": +For example, imagine that you have been working on the `topic` branch in this +history, and you want to "catch up" to the work done on the `master` branch. ------------ A---B---C topic @@ -66,13 +29,11 @@ Assume the following history exists and the current branch is "topic": D---E---F---G master ------------ -From this point, the result of either of the following commands: - - - git rebase master - git rebase master topic - -would be: +You want to transplant the commits you made on `topic` since it diverged from +`master` (i.e. A, B, and C), on top of the current `master`. You can do this +by running `git rebase master` while the `topic` branch is checked out. If you +want to rebase `topic` while on another branch, `git rebase master topic` is a +shortcut for `git checkout topic && git rebase master`. ------------ A'--B'--C' topic @@ -80,30 +41,56 @@ would be: D---E---F---G master ------------ -*NOTE:* The latter form is just a short-hand of `git checkout topic` -followed by `git rebase master`. When rebase exits `topic` will -remain the checked-out branch. -If the upstream branch already contains a change you have made (e.g., -because you mailed a patch which was applied upstream), then that commit -will be skipped and warnings will be issued (if the 'merge' backend is -used). For example, running `git rebase master` on the following -history (in which `A'` and `A` introduce the same set of changes, but -have different committer information): +If there is a merge conflict during this process, `git rebase` will stop at the +first problematic commit and leave conflict markers. If this happens, you can do +one of these things: ------------- - A---B---C topic - / - D---E---A'---F master ------------- +1. Resolve the conflict. You can use `git diff` to find the markers (<<<<<<) + and make edits to resolve the conflict. For each file you edit, you need to + tell Git that the conflict has been resolved. You can mark the conflict as + resolved with `git add <filename>`. After resolving all of the conflicts, + you can continue the rebasing process with -will result in: + git rebase --continue ------------- - B'---C' topic - / - D---E---A'---F master ------------- +2. Stop the `git rebase` and return your branch to its original state with + + git rebase --abort + +3. Skip the commit that caused the merge conflict with + + git rebase --skip + +If you don't specify an `<upstream>` to rebase onto, the upstream configured in +`branch.<name>.remote` and `branch.<name>.merge` options will be used (see +linkgit:git-config[1] for details) and the `--fork-point` option is +assumed. If you are currently not on any branch or if the current +branch does not have a configured upstream, the rebase will abort. + +Here is a simplified description of what `git rebase <upstream>` does: + +1. Make a list of all commits on your current branch since it branched + off from `<upstream>` that do not have an equivalent commit in + `<upstream>`. +2. Check out `<upstream>` with the equivalent of + `git checkout --detach <upstream>`. +3. Replay the commits, one by one, in order. This is similar to running + `git cherry-pick <commit>` for each commit. See REBASING MERGES for how merges + are handled. +4. Update your branch to point to the final commit with the equivalent + of `git checkout -B <branch>`. + +[NOTE] +When starting the rebase, `ORIG_HEAD` is set to point to the commit at the tip +of the to-be-rebased branch. However, `ORIG_HEAD` is not guaranteed to still +point to that commit at the end of the rebase if other commands that change +`ORIG_HEAD` (like `git reset`) are used during the rebase. The previous branch +tip, however, is accessible using the reflog of the current branch (i.e. `@{1}`, +see linkgit:gitrevisions[7]. + +TRANSPLANTING A TOPIC BRANCH WITH --ONTO +---------------------------------------- Here is how you would transplant a topic branch based on one branch to another, to pretend that you forked the topic branch @@ -186,28 +173,6 @@ This is useful if F and G were flawed in some way, or should not be part of topicA. Note that the argument to `--onto` and the `<upstream>` parameter can be any valid commit-ish. -In case of conflict, `git rebase` will stop at the first problematic commit -and leave conflict markers in the tree. You can use `git diff` to locate -the markers (<<<<<<) and make edits to resolve the conflict. For each -file you edit, you need to tell Git that the conflict has been resolved, -typically this would be done with - - - git add <filename> - - -After resolving the conflict manually and updating the index with the -desired resolution, you can continue the rebasing process with - - - git rebase --continue - - -Alternatively, you can undo the 'git rebase' with - - - git rebase --abort - MODE OPTIONS ------------ @@ -253,6 +218,8 @@ As a special case, you may use "A\...B" as a shortcut for the merge base of A and B if there is exactly one merge base. You can leave out at most one of A and B, in which case it defaults to HEAD. +See TRANSPLANTING A TOPIC BRANCH WITH --ONTO above for examples. + --keep-base:: Set the starting point at which to create the new commits to the merge base of `<upstream>` and `<branch>`. Running @@ -687,7 +654,7 @@ In addition, the following pairs of options are incompatible: * --fork-point and --root BEHAVIORAL DIFFERENCES ------------------------ +---------------------- `git rebase` has two primary backends: 'apply' and 'merge'. (The 'apply' backend used to be known as the 'am' backend, but the name led to diff --git a/Documentation/git-reflog.adoc b/Documentation/git-reflog.adoc index 412f06b8fe..38af0c977a 100644 --- a/Documentation/git-reflog.adoc +++ b/Documentation/git-reflog.adoc @@ -8,16 +8,17 @@ git-reflog - Manage reflog information SYNOPSIS -------- -[verse] -'git reflog' [show] [<log-options>] [<ref>] -'git reflog list' -'git reflog expire' [--expire=<time>] [--expire-unreachable=<time>] +[synopsis] +git reflog [show] [<log-options>] [<ref>] +git reflog list +git reflog exists <ref> +git reflog write <ref> <old-oid> <new-oid> <message> +git reflog delete [--rewrite] [--updateref] + [--dry-run | -n] [--verbose] <ref>@{<specifier>}... +git reflog drop [--all [--single-worktree] | <refs>...] +git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...] -'git reflog delete' [--rewrite] [--updateref] - [--dry-run | -n] [--verbose] <ref>@{<specifier>}... -'git reflog drop' [--all [--single-worktree] | <refs>...] -'git reflog exists' <ref> DESCRIPTION ----------- @@ -43,11 +44,15 @@ actions, and in addition the `HEAD` reflog records branch switching. The "list" subcommand lists all refs which have a corresponding reflog. -The "expire" subcommand prunes older reflog entries. Entries older -than `expire` time, or entries older than `expire-unreachable` time -and not reachable from the current tip, are removed from the reflog. -This is typically not used directly by end users -- instead, see -linkgit:git-gc[1]. +The "exists" subcommand checks whether a ref has a reflog. It exits +with zero status if the reflog exists, and non-zero status if it does +not. + +The "write" subcommand writes a single entry to the reflog of a given +reference. This new entry is appended to the reflog and will thus become +the most recent entry. The reference name must be fully qualified. Both the old +and new object IDs must not be abbreviated and must point to existing objects. +The reflog message gets normalized. The "delete" subcommand deletes single entries from the reflog, but not the reflog itself. Its argument must be an _exact_ entry (e.g. "`git @@ -58,9 +63,11 @@ The "drop" subcommand completely removes the reflog for the specified references. This is in contrast to "expire" and "delete", both of which can be used to delete reflog entries, but not the reflog itself. -The "exists" subcommand checks whether a ref has a reflog. It exits -with zero status if the reflog exists, and non-zero status if it does -not. +The "expire" subcommand prunes older reflog entries. Entries older +than `expire` time, or entries older than `expire-unreachable` time +and not reachable from the current tip, are removed from the reflog. +This is typically not used directly by end users -- instead, see +linkgit:git-gc[1]. OPTIONS ------- @@ -71,18 +78,37 @@ Options for `show` `git reflog show` accepts any of the options accepted by `git log`. +Options for `delete` +~~~~~~~~~~~~~~~~~~~~ + +`git reflog delete` accepts options `--updateref`, `--rewrite`, `-n`, +`--dry-run`, and `--verbose`, with the same meanings as when they are +used with `expire`. + +Options for `drop` +~~~~~~~~~~~~~~~~~~ + +`--all`:: + Drop the reflogs of all references from all worktrees. + +`--single-worktree`:: + By default when `--all` is specified, reflogs from all working + trees are dropped. This option limits the processing to reflogs + from the current working tree only. + + Options for `expire` ~~~~~~~~~~~~~~~~~~~~ ---all:: +`--all`:: Process the reflogs of all references. ---single-worktree:: +`--single-worktree`:: By default when `--all` is specified, reflogs from all working trees are processed. This option limits the processing to reflogs from the current working tree only. ---expire=<time>:: +`--expire=<time>`:: Prune entries older than the specified time. If this option is not specified, the expiration time is taken from the configuration setting `gc.reflogExpire`, which in turn @@ -90,7 +116,7 @@ Options for `expire` of their age; `--expire=never` turns off pruning of reachable entries (but see `--expire-unreachable`). ---expire-unreachable=<time>:: +`--expire-unreachable=<time>`:: Prune entries older than `<time>` that are not reachable from the current tip of the branch. If this option is not specified, the expiration time is taken from the configuration @@ -100,17 +126,17 @@ Options for `expire` turns off early pruning of unreachable entries (but see `--expire`). ---updateref:: +`--updateref`:: Update the reference to the value of the top reflog entry (i.e. <ref>@\{0\}) if the previous top entry was pruned. (This option is ignored for symbolic references.) ---rewrite:: +`--rewrite`:: If a reflog entry's predecessor is pruned, adjust its "old" SHA-1 to be equal to the "new" SHA-1 field of the entry that now precedes it. ---stale-fix:: +`--stale-fix`:: Prune any reflog entries that point to "broken commits". A broken commit is a commit that is not reachable from any of the reference tips and that refers, directly or indirectly, to @@ -121,33 +147,15 @@ has the same cost as 'git prune'. It is primarily intended to fix corruption caused by garbage collecting using older versions of Git, which didn't protect objects referred to by reflogs. --n:: ---dry-run:: +`-n`:: +`--dry-run`:: Do not actually prune any entries; just show what would have been pruned. ---verbose:: +`--verbose`:: Print extra information on screen. -Options for `delete` -~~~~~~~~~~~~~~~~~~~~ - -`git reflog delete` accepts options `--updateref`, `--rewrite`, `-n`, -`--dry-run`, and `--verbose`, with the same meanings as when they are -used with `expire`. - -Options for `drop` -~~~~~~~~~~~~~~~~~~ - ---all:: - Drop the reflogs of all references from all worktrees. - ---single-worktree:: - By default when `--all` is specified, reflogs from all working - trees are dropped. This option limits the processing to reflogs - from the current working tree only. - GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-refs.adoc b/Documentation/git-refs.adoc index 4d6dc994f9..d462953fb5 100644 --- a/Documentation/git-refs.adoc +++ b/Documentation/git-refs.adoc @@ -11,6 +11,13 @@ SYNOPSIS [synopsis] git refs migrate --ref-format=<format> [--no-reflog] [--dry-run] git refs verify [--strict] [--verbose] +git refs list [--count=<count>] [--shell|--perl|--python|--tcl] + [(--sort=<key>)...] [--format=<format>] + [--include-root-refs] [--points-at=<object>] + [--merged[=<object>]] [--no-merged[=<object>]] + [--contains[=<object>]] [--no-contains[=<object>]] + [(--exclude=<pattern>)...] [--start-after=<marker>] + [ --stdin | (<pattern>...)] DESCRIPTION ----------- @@ -20,43 +27,52 @@ This command provides low-level access to refs. COMMANDS -------- -migrate:: +`migrate`:: Migrate ref store between different formats. -verify:: +`verify`:: Verify reference database consistency. +list:: + List references in the repository with support for filtering, + formatting, and sorting. This subcommand is an alias for + linkgit:git-for-each-ref[1] and offers identical functionality. + OPTIONS ------- -The following options are specific to 'git refs migrate': +The following options are specific to `git refs migrate`: ---ref-format=<format>:: +`--ref-format=<format>`:: The ref format to migrate the ref store to. Can be one of: + include::ref-storage-format.adoc[] ---dry-run:: +`--dry-run`:: Perform the migration, but do not modify the repository. The migrated refs will be written into a separate directory that can be inspected separately. The name of the directory will be reported on stdout. This can be used to double check that the migration works as expected before performing the actual migration. ---reflog:: ---no-reflog:: +`--reflog`:: +`--no-reflog`:: Choose between migrating the reflog data to the new backend, and discarding them. The default is "--reflog", to migrate. -The following options are specific to 'git refs verify': +The following options are specific to `git refs verify`: ---strict:: +`--strict`:: Enable stricter error checking. This will cause warnings to be reported as errors. See linkgit:git-fsck[1]. ---verbose:: +`--verbose`:: When verifying the reference database consistency, be chatty. +The following options are specific to 'git refs list': + +include::for-each-ref-options.adoc[] + KNOWN LIMITATIONS ----------------- diff --git a/Documentation/git-repo.adoc b/Documentation/git-repo.adoc new file mode 100644 index 0000000000..2870828d93 --- /dev/null +++ b/Documentation/git-repo.adoc @@ -0,0 +1,84 @@ +git-repo(1) +=========== + +NAME +---- +git-repo - Retrieve information about the repository + +SYNOPSIS +-------- +[synopsis] +git repo info [--format=(keyvalue|nul)] [<key>...] + +DESCRIPTION +----------- +Retrieve information about the repository. + +THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. + +COMMANDS +-------- +`info [--format=(keyvalue|nul)] [<key>...]`:: + Retrieve metadata-related information about the current repository. Only + the requested data will be returned based on their keys (see "INFO KEYS" + section below). ++ +The values are returned in the same order in which their respective keys were +requested. ++ +The output format can be chosen through the flag `--format`. Two formats are +supported: ++ +`keyvalue`::: + output key-value pairs one per line using the `=` character as + the delimiter between the key and the value. Values containing "unusual" + characters are quoted as explained for the configuration variable + `core.quotePath` (see linkgit:git-config[1]). This is the default. + +`nul`::: + similar to `keyvalue`, but using a newline character as the delimiter + between the key and the value and using a NUL character after each value. + This format is better suited for being parsed by another applications than + `keyvalue`. Unlike in the `keyvalue` format, the values are never quoted. + +INFO KEYS +--------- +In order to obtain a set of values from `git repo info`, you should provide +the keys that identify them. Here's a list of the available keys and the +values that they return: + +`layout.bare`:: + `true` if this is a bare repository, otherwise `false`. + +`layout.shallow`:: + `true` if this is a shallow repository, otherwise `false`. + +`references.format`:: + The reference storage format. The valid values are: ++ +include::ref-storage-format.adoc[] + +EXAMPLES +-------- + +* Retrieves the reference format of the current repository: ++ +------------ +git repo info references.format +------------ ++ + +* Retrieves whether the current repository is bare and whether it is shallow +using the `nul` format: ++ +------------ +git repo info --format=nul layout.bare layout.shallow +------------ + +SEE ALSO +-------- +linkgit:git-rev-parse[1] + +GIT +--- +Part of the linkgit:git[1] suite diff --git a/Documentation/git-reset.adoc b/Documentation/git-reset.adoc index 53ab88c545..3b9ba9aee9 100644 --- a/Documentation/git-reset.adoc +++ b/Documentation/git-reset.adoc @@ -90,7 +90,8 @@ but carries forward unmerged index entries. If a file that is different between _<commit>_ and `HEAD` has local changes, reset is aborted. -`--[no-]recurse-submodules`:: +`--recurse-submodules`:: +`--no-recurse-submodules`:: When the working tree is updated, using `--recurse-submodules` will also recursively reset the working tree of all active submodules according to the commit recorded in the superproject, also setting @@ -125,6 +126,8 @@ OPTIONS separated with _NUL_ character and all other characters are taken literally (including newlines and quotes). +include::diff-context-options.adoc[] + `--`:: Do not interpret any more arguments as options. diff --git a/Documentation/git-restore.adoc b/Documentation/git-restore.adoc index 877b7772e6..961eef0137 100644 --- a/Documentation/git-restore.adoc +++ b/Documentation/git-restore.adoc @@ -28,8 +28,6 @@ otherwise from the index. Use `--source` to restore from a different commit. See "Reset, restore and revert" in linkgit:git[1] for the differences between the three commands. -THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. - OPTIONS ------- `-s <tree>`:: @@ -52,6 +50,8 @@ leave out at most one of _<rev-A>__ and _<rev-B>_, in which case it defaults to Mode" section of linkgit:git-add[1] to learn how to operate the `--patch` mode. +include::diff-context-options.adoc[] + `-W`:: `--worktree`:: `-S`:: diff --git a/Documentation/git-send-email.adoc b/Documentation/git-send-email.adoc index 5335502d68..11b1ab1a07 100644 --- a/Documentation/git-send-email.adoc +++ b/Documentation/git-send-email.adoc @@ -115,7 +115,8 @@ illustration below where `[PATCH v2 0/3]` is in reply to `[PATCH 0/2]`: Only necessary if `--compose` is also set. If `--compose` is not set, this will be prompted for. ---[no-]outlook-id-fix:: +--outlook-id-fix:: +--no-outlook-id-fix:: Microsoft Outlook SMTP servers discard the Message-ID sent via email and assign a new random Message-ID, thus breaking threads. + @@ -350,7 +351,8 @@ Automating --no-header-cmd:: Disable any header command in use. ---[no-]chain-reply-to:: +--chain-reply-to:: +--no-chain-reply-to:: If this is set, each email will be sent as a reply to the previous email sent. If disabled with `--no-chain-reply-to`, all emails after the first will be sent as replies to the first email sent. When using @@ -364,19 +366,22 @@ Automating values in the `sendemail` section. The default identity is the value of `sendemail.identity`. ---[no-]signed-off-by-cc:: +--signed-off-by-cc:: +--no-signed-off-by-cc:: If this is set, add emails found in the `Signed-off-by` trailer or `Cc:` lines to the cc list. Default is the value of `sendemail.signedOffByCc` configuration value; if that is unspecified, default to `--signed-off-by-cc`. ---[no-]cc-cover:: +--cc-cover:: +--no-cc-cover:: If this is set, emails found in `Cc:` headers in the first patch of the series (typically the cover letter) are added to the cc list for each email set. Default is the value of `sendemail.ccCover` configuration value; if that is unspecified, default to `--no-cc-cover`. ---[no-]to-cover:: +--to-cover:: +--no-to-cover:: If this is set, emails found in `To:` headers in the first patch of the series (typically the cover letter) are added to the to list for each email set. Default is the value of `sendemail.toCover` @@ -407,12 +412,14 @@ Default is the value of `sendemail.suppressCc` configuration value; if that is unspecified, default to `self` if `--suppress-from` is specified, as well as `body` if `--no-signed-off-cc` is specified. ---[no-]suppress-from:: +--suppress-from:: +--no-suppress-from:: If this is set, do not add the `From:` address to the `Cc:` list. Default is the value of `sendemail.suppressFrom` configuration value; if that is unspecified, default to `--no-suppress-from`. ---[no-]thread:: +--thread:: +--no-thread:: If this is set, the `In-Reply-To` and `References` headers will be added to each email sent. Whether each mail refers to the previous email (`deep` threading per `git format-patch` @@ -430,7 +437,8 @@ exists when `git send-email` is asked to add it (especially note that Failure to do so may not produce the expected result in the recipient's MUA. ---[no-]mailmap:: +--mailmap:: +--no-mailmap:: Use the mailmap file (see linkgit:gitmailmap[5]) to map all addresses to their canonical real name and email address. Additional mailmap data specific to `git send-email` may be provided using the @@ -459,7 +467,8 @@ have been specified, in which case default to `compose`. --dry-run:: Do everything except actually send the emails. ---[no-]format-patch:: +--format-patch:: +--no-format-patch:: When an argument may be understood either as a reference or as a file name, choose to understand it as a format-patch argument (`--format-patch`) or as a file name (`--no-format-patch`). By default, when such a conflict @@ -469,7 +478,8 @@ have been specified, in which case default to `compose`. Make `git send-email` less verbose. One line per email should be all that is output. ---[no-]validate:: +--validate:: +--no-validate:: Perform sanity checks on patches. Currently, validation means the following: + diff --git a/Documentation/git-send-pack.adoc b/Documentation/git-send-pack.adoc index b9e73f2e77..811193f16c 100644 --- a/Documentation/git-send-pack.adoc +++ b/Documentation/git-send-pack.adoc @@ -71,7 +71,8 @@ be in a separate packet, and the list must end with a flush packet. fails to update then the entire push will fail without changing any refs. ---[no-]signed:: +--signed:: +--no-signed:: --signed=(true|false|if-asked):: GPG-sign the push request to update refs on the receiving side, to allow it to be checked by the hooks and/or be diff --git a/Documentation/git-stash.adoc b/Documentation/git-stash.adoc index e5e6c9d37f..e2300a19a2 100644 --- a/Documentation/git-stash.adoc +++ b/Documentation/git-stash.adoc @@ -222,6 +222,8 @@ to learn how to operate the `--patch` mode. The `--patch` option implies `--keep-index`. You can use `--no-keep-index` to override this. +include::diff-context-options.adoc[] + -S:: --staged:: This option is only valid for `push` and `save` commands. diff --git a/Documentation/git-submodule.adoc b/Documentation/git-submodule.adoc index 87d8e0f0c5..95beaee561 100644 --- a/Documentation/git-submodule.adoc +++ b/Documentation/git-submodule.adoc @@ -307,6 +307,13 @@ OPTIONS --force:: This option is only valid for add, deinit and update commands. When running add, allow adding an otherwise ignored submodule path. + This option is also used to bypass a check that the submodule's name + is not already in use. By default, 'git submodule add' will fail if + the proposed name (which is derived from the path) is already registered + for another submodule in the repository. Using '--force' allows the command + to proceed by automatically generating a unique name by appending a number + to the conflicting name (e.g., if a submodule named 'child' exists, it will + try 'child1', and so on). When running deinit the submodule working trees will be removed even if they contain local changes. When running update (only effective with the checkout procedure), @@ -435,7 +442,8 @@ options carefully. clone with a history truncated to the specified number of revisions. See linkgit:git-clone[1] ---[no-]recommend-shallow:: +--recommend-shallow:: +--no-recommend-shallow:: This option is only valid for the update command. The initial clone of a submodule will use the recommended `submodule.<name>.shallow` as provided by the `.gitmodules` file @@ -447,7 +455,8 @@ options carefully. Clone new submodules in parallel with as many jobs. Defaults to the `submodule.fetchJobs` option. ---[no-]single-branch:: +--single-branch:: +--no-single-branch:: This option is only valid for the update command. Clone only one branch during update: HEAD or one specified by --branch. diff --git a/Documentation/git-svn.adoc b/Documentation/git-svn.adoc index bcf7d84a87..c26c12bab3 100644 --- a/Documentation/git-svn.adoc +++ b/Documentation/git-svn.adoc @@ -1012,9 +1012,11 @@ branch. If you do merge, note the following rule: 'git svn dcommit' will attempt to commit on top of the SVN commit named in + ------------------------------------------------------------------------ git log --grep=^git-svn-id: --first-parent -1 ------------------------------------------------------------------------ + You 'must' therefore ensure that the most recent commit of the branch you want to dcommit to is the 'first' parent of the merge. Chaos will ensue otherwise, especially if the first parent is an older commit on diff --git a/Documentation/git-switch.adoc b/Documentation/git-switch.adoc index 9f62abf9e2..87707e9265 100644 --- a/Documentation/git-switch.adoc +++ b/Documentation/git-switch.adoc @@ -29,8 +29,6 @@ Switching branches does not require a clean index and working tree however if the operation leads to loss of local changes, unless told otherwise with `--discard-changes` or `--merge`. -THIS COMMAND IS EXPERIMENTAL. THE BEHAVIOR MAY CHANGE. - OPTIONS ------- _<branch>_:: diff --git a/Documentation/git-update-index.adoc b/Documentation/git-update-index.adoc index 7128aed540..9bea9fab9a 100644 --- a/Documentation/git-update-index.adoc +++ b/Documentation/git-update-index.adoc @@ -86,7 +86,8 @@ OPTIONS --chmod=(+|-)x:: Set the execute permissions on the updated files. ---[no-]assume-unchanged:: +--assume-unchanged:: +--no-assume-unchanged:: When this flag is specified, the object names recorded for the paths are not updated. Instead, this option sets/unsets the "assume unchanged" bit for the @@ -108,18 +109,21 @@ you will need to handle the situation manually. Like `--refresh`, but checks stat information unconditionally, without regard to the "assume unchanged" setting. ---[no-]skip-worktree:: +--skip-worktree:: +--no-skip-worktree:: When one of these flags is specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "skip-worktree" bit for the paths. See section "Skip-worktree bit" below for more information. ---[no-]ignore-skip-worktree-entries:: +--ignore-skip-worktree-entries:: +--no-ignore-skip-worktree-entries:: Do not remove skip-worktree (AKA "index-only") entries even when the `--remove` option was specified. ---[no-]fsmonitor-valid:: +--fsmonitor-valid:: +--no-fsmonitor-valid:: When one of these flags is specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "fsmonitor valid" bit for the paths. See diff --git a/Documentation/git-upload-pack.adoc b/Documentation/git-upload-pack.adoc index 516d1639d9..9167a321d0 100644 --- a/Documentation/git-upload-pack.adoc +++ b/Documentation/git-upload-pack.adoc @@ -25,7 +25,8 @@ repository. For push operations, see 'git send-pack'. OPTIONS ------- ---[no-]strict:: +--strict:: +--no-strict:: Do not try <directory>/.git/ if <directory> is not a Git directory. --timeout=<n>:: diff --git a/Documentation/git-worktree.adoc b/Documentation/git-worktree.adoc index 8340b7f028..389e669ac0 100644 --- a/Documentation/git-worktree.adoc +++ b/Documentation/git-worktree.adoc @@ -200,13 +200,15 @@ To remove a locked worktree, specify `--force` twice. With `add`, detach `HEAD` in the new worktree. See "DETACHED HEAD" in linkgit:git-checkout[1]. ---[no-]checkout:: +--checkout:: +--no-checkout:: By default, `add` checks out `<commit-ish>`, however, `--no-checkout` can be used to suppress checkout in order to make customizations, such as configuring sparse-checkout. See "Sparse checkout" in linkgit:git-read-tree[1]. ---[no-]guess-remote:: +--guess-remote:: +--no-guess-remote:: With `worktree add <path>`, without `<commit-ish>`, instead of creating a new branch from `HEAD`, if there exists a tracking branch in exactly one remote matching the basename of `<path>`, @@ -216,7 +218,8 @@ To remove a locked worktree, specify `--force` twice. This can also be set up as the default behaviour by using the `worktree.guessRemote` config option. ---[no-]relative-paths:: +--relative-paths:: +--no-relative-paths:: Link worktrees using relative paths or absolute paths (default). Overrides the `worktree.useRelativePaths` config option, see linkgit:git-config[1]. @@ -224,7 +227,8 @@ This can also be set up as the default behaviour by using the With `repair`, the linking files will be updated if there's an absolute/relative mismatch, even if the links are correct. ---[no-]track:: +--track:: +--no-track:: When creating a new branch, if `<commit-ish>` is a branch, mark it as "upstream" from the new branch. This is the default if `<commit-ish>` is a remote-tracking branch. See diff --git a/Documentation/git.adoc b/Documentation/git.adoc index 743b7b00e4..03e9e69d25 100644 --- a/Documentation/git.adoc +++ b/Documentation/git.adoc @@ -684,7 +684,7 @@ other `GIT_PROGRESS_DELAY`:: A number controlling how many seconds to delay before showing - optional progress indicators. Defaults to 2. + optional progress indicators. Defaults to 1. `GIT_EDITOR`:: This environment variable overrides `$EDITOR` and `$VISUAL`. diff --git a/Documentation/gitk.adoc b/Documentation/gitk.adoc index 58ce40ddb1..5b34dcd077 100644 --- a/Documentation/gitk.adoc +++ b/Documentation/gitk.adoc @@ -163,16 +163,16 @@ used by default. If '$XDG_CONFIG_HOME' is not set it defaults to History ------- -Gitk was the first graphical repository browser. It's written in -tcl/tk. +Gitk was the first graphical repository browser, written by +Paul Mackerras in Tcl/Tk. 'gitk' is actually maintained as an independent project, but stable versions are distributed as part of the Git suite for the convenience of end users. -gitk-git/ comes from Paul Mackerras's gitk project: +`gitk-git/` comes from Johannes Sixt's gitk project: - git://ozlabs.org/~paulus/gitk + https://github.com/j6t/gitk SEE ALSO -------- diff --git a/Documentation/gitprotocol-http.adoc b/Documentation/gitprotocol-http.adoc index ec40a550cc..d024010414 100644 --- a/Documentation/gitprotocol-http.adoc +++ b/Documentation/gitprotocol-http.adoc @@ -318,7 +318,7 @@ Extra Parameter. Smart Service git-upload-pack ------------------------------- +----------------------------- This service reads from the repository pointed to by `$GIT_URL`. Clients MUST first perform ref discovery with diff --git a/Documentation/gitsubmodules.adoc b/Documentation/gitsubmodules.adoc index f7b5a25a0c..2082296199 100644 --- a/Documentation/gitsubmodules.adoc +++ b/Documentation/gitsubmodules.adoc @@ -8,6 +8,7 @@ gitsubmodules - Mounting one repository inside another SYNOPSIS -------- .gitmodules, $GIT_DIR/config + ------------------ git submodule git <command> --recurse-submodules @@ -240,7 +241,7 @@ Workflow for a third party library Workflow for an artificially split repo --------------------------------------- +--------------------------------------- # Enable recursion for relevant commands, such that # regular commands recurse into submodules by default diff --git a/Documentation/gitweb.conf.adoc b/Documentation/gitweb.conf.adoc index 1348e9b125..64bebb811c 100644 --- a/Documentation/gitweb.conf.adoc +++ b/Documentation/gitweb.conf.adoc @@ -178,7 +178,7 @@ $export_ok:: Show repository only if this file exists (in repository). Only effective if this variable evaluates to true. Can be set when building gitweb by setting `GITWEB_EXPORT_OK`. This path is - relative to `GIT_DIR`. git-daemon[1] uses 'git-daemon-export-ok', + relative to `GIT_DIR`. linkgit:git-daemon[1] uses 'git-daemon-export-ok', unless started with `--export-all`. By default this variable is not set, which means that this feature is turned off. diff --git a/Documentation/lint-delimited-sections.perl b/Documentation/lint-delimited-sections.perl new file mode 100755 index 0000000000..140b852e5d --- /dev/null +++ b/Documentation/lint-delimited-sections.perl @@ -0,0 +1,48 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($msg) = @_; + print STDERR "$ARGV:$.: $msg\n"; + $exit_code = 1; +} + +my $line_length = 0; +my $in_section = 0; +my $section_header = ""; + + +while (my $line = <>) { + if (($line =~ /^\+?$/) || + ($line =~ /^\[.*\]$/) || + ($line =~ /^ifdef::/)) { + $line_length = 0; + } elsif ($line =~ /^[^-.]/) { + $line_length = length($line); + } elsif (($line =~ /^-{3,}$/) || ($line =~ /^\.{3,}$/)) { + if ($in_section) { + if ($line eq $section_header) { + $in_section = 0; + } + next; + } + if ($line_length == 0) { + $in_section = 1; + $section_header = $line; + next; + } + if (($line_length != 0) && (length($line) != $line_length)) { + report("section delimiter not preceded by an empty line"); + } + $line_length = 0; + } +} + +if ($in_section) { + report("section not finished"); +} + +exit $exit_code; diff --git a/Documentation/lint-documentation-style.perl b/Documentation/lint-documentation-style.perl new file mode 100755 index 0000000000..d7ab732293 --- /dev/null +++ b/Documentation/lint-documentation-style.perl @@ -0,0 +1,33 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +my $exit_code = 0; +sub report { + my ($line, $msg) = @_; + chomp $line; + print STDERR "$ARGV:$.: '$line' $msg\n"; + $exit_code = 1; +} + +my $synopsis_style = 0; + +while (my $line = <>) { + if ($line =~ /^[ \t]*`?[-a-z0-9.]+`?(, `?[-a-z0-9.]+`?)+(::|;;)$/) { + + report($line, "multiple parameters in a definition list item"); + } + if ($line =~ /^`?--\[no-\][a-z0-9-]+.*(::|;;)$/) { + report($line, "definition list item with a `--[no-]` parameter"); + } + if ($line =~ /^\[synopsis\]$/) { + $synopsis_style = 1; + } + if (($line =~ /^(-[-a-z].*|<[-a-z0-9]+>(\.{3})?)(::|;;)$/) && ($synopsis_style)) { + report($line, "synopsis style and definition list item not backquoted"); + } +} + + +exit $exit_code; diff --git a/Documentation/lint-gitlink.perl b/Documentation/lint-gitlink.perl index aea564dad7..f183a18df2 100755 --- a/Documentation/lint-gitlink.perl +++ b/Documentation/lint-gitlink.perl @@ -41,6 +41,13 @@ die "BUG: No list of valid linkgit:* files given" unless @ARGV; @ARGV = $to_check; while (<>) { my $line = $_; + while ($line =~ m/(.{,8})((git[-a-z]+|scalar)\[(\d)*\])/g) { + my $pos = pos $line; + my ($macro, $target, $page, $section) = ($1, $2, $3, $4); + if ( $macro ne "linkgit:" && $macro !~ "ifn?def::" && $macro ne "endif::" ) { + report($pos, $line, $target, "linkgit: macro expected"); + } + } while ($line =~ m/linkgit:((.*?)\[(\d)\])/g) { my $pos = pos $line; my ($target, $page, $section) = ($1, $2, $3); diff --git a/Documentation/merge-options.adoc b/Documentation/merge-options.adoc index 95ef491be1..9d433265b2 100644 --- a/Documentation/merge-options.adoc +++ b/Documentation/merge-options.adoc @@ -135,7 +135,8 @@ ifdef::git-pull[] Only useful when merging. endif::git-pull[] -`--[no-]verify`:: +`--verify`:: +`--no-verify`:: By default, the pre-merge and commit-msg hooks are run. When `--no-verify` is given, these are bypassed. See also linkgit:githooks[5]. diff --git a/Documentation/mergetools/vimdiff.adoc b/Documentation/mergetools/vimdiff.adoc index abfd426f74..b4ab83a510 100644 --- a/Documentation/mergetools/vimdiff.adoc +++ b/Documentation/mergetools/vimdiff.adoc @@ -3,6 +3,7 @@ Description When specifying `--tool=vimdiff` in `git mergetool` Git will open Vim with a 4 windows layout distributed in the following way: + .... ------------------------------------------ | | | | @@ -56,6 +57,7 @@ needed in this case. The next layout definition is equivalent: + -- If, for some reason, we are not interested in the `BASE` buffer. + .... ------------------------------------------ | | | | @@ -72,6 +74,7 @@ If, for some reason, we are not interested in the `BASE` buffer. Only the `MERGED` buffer will be shown. Note, however, that all the other ones are still loaded in vim, and you can access them with the "buffers" command. + .... ------------------------------------------ | | @@ -88,6 +91,7 @@ command. When `MERGED` is not present in the layout, you must "mark" one of the buffers with an arobase (`@`). That will become the buffer you need to edit and save after resolving the conflicts. + .... ------------------------------------------ | | | @@ -106,6 +110,7 @@ save after resolving the conflicts. Three tabs will open: the first one is a copy of the default layout, while the other two only show the differences between (`BASE` and `LOCAL`) and (`BASE` and `REMOTE`) respectively. + .... ------------------------------------------ | <TAB #1> | TAB #2 | TAB #3 | | @@ -119,6 +124,7 @@ the other two only show the differences between (`BASE` and `LOCAL`) and | | ------------------------------------------ .... + .... ------------------------------------------ | TAB #1 | <TAB #2> | TAB #3 | | @@ -132,6 +138,7 @@ the other two only show the differences between (`BASE` and `LOCAL`) and | | | ------------------------------------------ .... + .... ------------------------------------------ | TAB #1 | TAB #2 | <TAB #3> | | @@ -151,6 +158,7 @@ the other two only show the differences between (`BASE` and `LOCAL`) and -- Same as the previous example, but adds a fourth tab with the same information as the first tab, with a different layout. + .... --------------------------------------------- | TAB #1 | TAB #2 | TAB #3 | <TAB #4> | diff --git a/Documentation/meson.build b/Documentation/meson.build index a8ac5285f0..e34965c5b0 100644 --- a/Documentation/meson.build +++ b/Documentation/meson.build @@ -117,6 +117,7 @@ manpages = { 'git-repack.adoc' : 1, 'git-replace.adoc' : 1, 'git-replay.adoc' : 1, + 'git-repo.adoc' : 1, 'git-request-pull.adoc' : 1, 'git-rerere.adoc' : 1, 'git-reset.adoc' : 1, diff --git a/Documentation/pretty-formats.adoc b/Documentation/pretty-formats.adoc index 9ed0417fc8..618ddc4a0c 100644 --- a/Documentation/pretty-formats.adoc +++ b/Documentation/pretty-formats.adoc @@ -233,11 +233,11 @@ colon and zero or more comma-separated options. Option values may contain literal formatting codes. These must be used for commas (`%x2C`) and closing parentheses (`%x29`), due to their role in the option syntax. + -** `prefix=<value>`: Shown before the list of ref names. Defaults to "{nbsp}+(+". +** `prefix=<value>`: Shown before the list of ref names. Defaults to "{nbsp}++(++". ** `suffix=<value>`: Shown after the list of ref names. Defaults to "+)+". ** `separator=<value>`: Shown between ref names. Defaults to "+,+{nbsp}". ** `pointer=<value>`: Shown between HEAD and the branch it points to, if any. - Defaults to "{nbsp}+->+{nbsp}". + Defaults to "{nbsp}++->++{nbsp}". ** `tag=<value>`: Shown before tag names. Defaults to "`tag:`{nbsp}". + diff --git a/Documentation/scalar.adoc b/Documentation/scalar.adoc index 4bd5b150e8..f81b2832f8 100644 --- a/Documentation/scalar.adoc +++ b/Documentation/scalar.adoc @@ -71,7 +71,8 @@ HEAD[:<directory>]`. Instead of checking out the branch pointed to by the cloned repository's HEAD, check out the `<name>` branch instead. ---[no-]single-branch:: +--single-branch:: +--no-single-branch:: Clone only the history leading to the tip of a single branch, either specified by the `--branch` option or the primary branch remote's `HEAD` points at. @@ -81,23 +82,27 @@ remote-tracking branch for the branch this option was used for the initial cloning. If the HEAD at the remote did not point at any branch when `--single-branch` clone was made, no remote-tracking branch is created. ---[no-]src:: +--src:: +--no-src:: By default, `scalar clone` places the cloned repository within a `<entlistment>/src` directory. Use `--no-src` to place the cloned repository directly in the `<enlistment>` directory. ---[no-]tags:: +--tags:: +--no-tags:: By default, `scalar clone` will fetch the tag objects advertised by the remote and future `git fetch` commands will do the same. Use `--no-tags` to avoid fetching tags in `scalar clone` and to configure the repository to avoid fetching tags in the future. To fetch tags after cloning with `--no-tags`, run `git fetch --tags`. ---[no-]full-clone:: +--full-clone:: +--no-full-clone:: A sparse-checkout is initialized by default. This behavior can be turned off via `--full-clone`. ---[no-]maintenance:: +--maintenance:: +--no-maintenance:: By default, `scalar clone` configures the enlistment to use Git's background maintenance feature. Use the `--no-maintenance` to skip this configuration. @@ -122,7 +127,8 @@ Note: when this subcommand is called in a worktree that is called `src/`, its parent directory is considered to be the Scalar enlistment. If the worktree is _not_ called `src/`, it itself will be considered to be the Scalar enlistment. ---[no-]maintenance:: +--maintenance:: +--no-maintenance:: By default, `scalar register` configures the enlistment to use Git's background maintenance feature. Use the `--no-maintenance` to skip this configuration. This does not disable any maintenance that may diff --git a/Documentation/technical/api-path-walk.adoc b/Documentation/technical/api-path-walk.adoc index 34c905eb9c..a67de1b143 100644 --- a/Documentation/technical/api-path-walk.adoc +++ b/Documentation/technical/api-path-walk.adoc @@ -39,7 +39,10 @@ It is also important that you do not specify the `--objects` flag for the the objects will be walked in a separate way based on those starting commits. -`commits`, `blobs`, `trees`, `tags`:: +`commits`:: +`blobs`:: +`trees`:: +`tags`:: By default, these members are enabled and signal that the path-walk API should call the `path_fn` on objects of these types. Specialized applications could disable some options to make it simpler to walk diff --git a/Documentation/technical/long-running-process-protocol.adoc b/Documentation/technical/long-running-process-protocol.adoc index 6f33654b42..39bd89d467 100644 --- a/Documentation/technical/long-running-process-protocol.adoc +++ b/Documentation/technical/long-running-process-protocol.adoc @@ -24,6 +24,7 @@ After the version negotiation Git sends a list of all capabilities that it supports and a flush packet. Git expects to read a list of desired capabilities, which must be a subset of the supported capabilities list, and a flush packet as response: + ------------------------ packet: git> git-filter-client packet: git> version=2 diff --git a/Documentation/user-manual.adoc b/Documentation/user-manual.adoc index 8d00a9e822..7696987117 100644 --- a/Documentation/user-manual.adoc +++ b/Documentation/user-manual.adoc @@ -4270,7 +4270,7 @@ So, look into `builtin/cat-file.c`, search for `cmd_cat_file()` and look what it does. ------------------------------------------------------------------ - git_config(git_default_config); + repo_config(the_repository, git_default_config); if (argc != 3) usage("git cat-file [-t|-s|-e|-p|<type>] <sha1>"); if (get_sha1(argv[2], sha1)) diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 63463c8773..b16db85e77 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,6 +1,6 @@ #!/bin/sh -DEF_VER=v2.50.GIT +DEF_VER=v2.51.GIT LF=' ' @@ -1307,6 +1307,7 @@ BUILTIN_OBJS += builtin/remote.o BUILTIN_OBJS += builtin/repack.o BUILTIN_OBJS += builtin/replace.o BUILTIN_OBJS += builtin/replay.o +BUILTIN_OBJS += builtin/repo.o BUILTIN_OBJS += builtin/rerere.o BUILTIN_OBJS += builtin/reset.o BUILTIN_OBJS += builtin/rev-list.o @@ -1355,6 +1356,7 @@ THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/% THIRD_PARTY_SOURCES += $(UNIT_TEST_DIR)/clar/clar/% CLAR_TEST_SUITES += u-ctype +CLAR_TEST_SUITES += u-dir CLAR_TEST_SUITES += u-example-decorate CLAR_TEST_SUITES += u-hash CLAR_TEST_SUITES += u-hashmap @@ -1363,6 +1365,13 @@ CLAR_TEST_SUITES += u-oid-array CLAR_TEST_SUITES += u-oidmap CLAR_TEST_SUITES += u-oidtree CLAR_TEST_SUITES += u-prio-queue +CLAR_TEST_SUITES += u-reftable-basics +CLAR_TEST_SUITES += u-reftable-block +CLAR_TEST_SUITES += u-reftable-merged +CLAR_TEST_SUITES += u-reftable-pq +CLAR_TEST_SUITES += u-reftable-readwrite +CLAR_TEST_SUITES += u-reftable-stack +CLAR_TEST_SUITES += u-reftable-table CLAR_TEST_SUITES += u-reftable-tree CLAR_TEST_SUITES += u-strbuf CLAR_TEST_SUITES += u-strcmp-offset @@ -1373,20 +1382,11 @@ CLAR_TEST_SUITES += u-urlmatch-normalization CLAR_TEST_PROG = $(UNIT_TEST_BIN)/unit-tests$(X) CLAR_TEST_OBJS = $(patsubst %,$(UNIT_TEST_DIR)/%.o,$(CLAR_TEST_SUITES)) CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/clar/clar.o -CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/lib-oid.o +CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o +CLAR_TEST_OBJS += $(UNIT_TEST_DIR)/unit-test.o -UNIT_TEST_PROGRAMS += t-reftable-basics -UNIT_TEST_PROGRAMS += t-reftable-block -UNIT_TEST_PROGRAMS += t-reftable-merged -UNIT_TEST_PROGRAMS += t-reftable-pq -UNIT_TEST_PROGRAMS += t-reftable-readwrite -UNIT_TEST_PROGRAMS += t-reftable-record -UNIT_TEST_PROGRAMS += t-reftable-stack -UNIT_TEST_PROGRAMS += t-reftable-table -UNIT_TEST_PROGS = $(patsubst %,$(UNIT_TEST_BIN)/%$X,$(UNIT_TEST_PROGRAMS)) UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/test-lib.o -UNIT_TEST_OBJS += $(UNIT_TEST_DIR)/lib-reftable.o # xdiff and reftable libs may in turn depend on what is in libgit.a GITLIBS = common-main.o $(LIB_FILE) $(XDIFF_LIB) $(REFTABLE_LIB) $(LIB_FILE) @@ -3946,13 +3946,12 @@ unit-tests: $(UNIT_TEST_PROGS) $(CLAR_TEST_PROG) t/helper/test-tool$X $(MAKE) -C t/ unit-tests .PHONY: libgit-sys libgit-rs -libgit-sys libgit-rs: - $(QUIET)(\ - cd contrib/$@ && \ - cargo build \ - ) +libgit-sys: + $(QUIET)cargo build --manifest-path contrib/libgit-sys/Cargo.toml +libgit-rs: libgit-sys + $(QUIET)cargo build --manifest-path contrib/libgit-rs/Cargo.toml ifdef INCLUDE_LIBGIT_RS -all:: libgit-sys libgit-rs +all:: libgit-rs endif LIBGIT_PUB_OBJS += contrib/libgit-sys/public_symbol_export.o @@ -1 +1 @@ -Documentation/RelNotes/2.51.0.adoc
\ No newline at end of file +Documentation/RelNotes/2.52.0.adoc
\ No newline at end of file diff --git a/add-interactive.c b/add-interactive.c index 97ff35b6f1..3e692b47ec 100644 --- a/add-interactive.c +++ b/add-interactive.c @@ -36,11 +36,14 @@ static void init_color(struct repository *r, struct add_i_state *s, free(key); } -void init_add_i_state(struct add_i_state *s, struct repository *r) +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt) { const char *value; s->r = r; + s->context = -1; + s->interhunkcontext = -1; if (repo_config_get_value(r, "color.interactive", &value)) s->use_color = -1; @@ -78,9 +81,27 @@ void init_add_i_state(struct add_i_state *s, struct repository *r) repo_config_get_string(r, "diff.algorithm", &s->interactive_diff_algorithm); + if (!repo_config_get_int(r, "diff.context", &s->context)) + if (s->context < 0) + die(_("%s cannot be negative"), "diff.context"); + if (!repo_config_get_int(r, "diff.interHunkContext", &s->interhunkcontext)) + if (s->interhunkcontext < 0) + die(_("%s cannot be negative"), "diff.interHunkContext"); + repo_config_get_bool(r, "interactive.singlekey", &s->use_single_key); if (s->use_single_key) setbuf(stdin, NULL); + + if (add_p_opt->context != -1) { + if (add_p_opt->context < 0) + die(_("%s cannot be negative"), "--unified"); + s->context = add_p_opt->context; + } + if (add_p_opt->interhunkcontext != -1) { + if (add_p_opt->interhunkcontext < 0) + die(_("%s cannot be negative"), "--inter-hunk-context"); + s->interhunkcontext = add_p_opt->interhunkcontext; + } } void clear_add_i_state(struct add_i_state *s) @@ -969,6 +990,10 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, opts->prompt = N_("Patch update"); count = list_and_choose(s, files, opts); if (count > 0) { + struct add_p_opt add_p_opt = { + .context = s->context, + .interhunkcontext = s->interhunkcontext, + }; struct strvec args = STRVEC_INIT; struct pathspec ps_selected = { 0 }; @@ -979,7 +1004,7 @@ static int run_patch(struct add_i_state *s, const struct pathspec *ps, parse_pathspec(&ps_selected, PATHSPEC_ALL_MAGIC & ~PATHSPEC_LITERAL, PATHSPEC_LITERAL_PATH, "", args.v); - res = run_add_p(s->r, ADD_P_ADD, NULL, &ps_selected); + res = run_add_p(s->r, ADD_P_ADD, &add_p_opt, NULL, &ps_selected); strvec_clear(&args); clear_pathspec(&ps_selected); } @@ -1014,10 +1039,13 @@ static int run_diff(struct add_i_state *s, const struct pathspec *ps, if (count > 0) { struct child_process cmd = CHILD_PROCESS_INIT; - strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", - oid_to_hex(!is_initial ? &oid : - s->r->hash_algo->empty_tree), - "--", NULL); + strvec_pushl(&cmd.args, "git", "diff", "-p", "--cached", NULL); + if (s->context != -1) + strvec_pushf(&cmd.args, "--unified=%i", s->context); + if (s->interhunkcontext != -1) + strvec_pushf(&cmd.args, "--inter-hunk-context=%i", s->interhunkcontext); + strvec_pushl(&cmd.args, oid_to_hex(!is_initial ? &oid : + s->r->hash_algo->empty_tree), "--", NULL); for (i = 0; i < files->items.nr; i++) if (files->selected[i]) strvec_push(&cmd.args, @@ -1110,7 +1138,8 @@ static void command_prompt_help(struct add_i_state *s) _("(empty) select nothing")); } -int run_add_i(struct repository *r, const struct pathspec *ps) +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt) { struct add_i_state s = { NULL }; struct print_command_item_data data = { "[", "]" }; @@ -1153,7 +1182,7 @@ int run_add_i(struct repository *r, const struct pathspec *ps) ->util = util; } - init_add_i_state(&s, r); + init_add_i_state(&s, r, add_p_opt); /* * When color was asked for, use the prompt color for diff --git a/add-interactive.h b/add-interactive.h index 693f125e8e..4213dcd67b 100644 --- a/add-interactive.h +++ b/add-interactive.h @@ -3,6 +3,13 @@ #include "color.h" +struct add_p_opt { + int context; + int interhunkcontext; +}; + +#define ADD_P_OPT_INIT { .context = -1, .interhunkcontext = -1 } + struct add_i_state { struct repository *r; int use_color; @@ -18,14 +25,17 @@ struct add_i_state { int use_single_key; char *interactive_diff_filter, *interactive_diff_algorithm; + int context, interhunkcontext; }; -void init_add_i_state(struct add_i_state *s, struct repository *r); +void init_add_i_state(struct add_i_state *s, struct repository *r, + struct add_p_opt *add_p_opt); void clear_add_i_state(struct add_i_state *s); struct repository; struct pathspec; -int run_add_i(struct repository *r, const struct pathspec *ps); +int run_add_i(struct repository *r, const struct pathspec *ps, + struct add_p_opt *add_p_opt); enum add_p_mode { ADD_P_ADD, @@ -36,6 +46,7 @@ enum add_p_mode { }; int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps); + struct add_p_opt *o, const char *revision, + const struct pathspec *ps); #endif diff --git a/add-patch.c b/add-patch.c index 95c67d8c80..302e6ba7d9 100644 --- a/add-patch.c +++ b/add-patch.c @@ -414,7 +414,6 @@ static int normalize_marker(const char *p) static int parse_diff(struct add_p_state *s, const struct pathspec *ps) { struct strvec args = STRVEC_INIT; - const char *diff_algorithm = s->s.interactive_diff_algorithm; struct strbuf *plain = &s->plain, *colored = NULL; struct child_process cp = CHILD_PROCESS_INIT; char *p, *pend, *colored_p = NULL, *colored_pend = NULL, marker = '\0'; @@ -424,8 +423,12 @@ static int parse_diff(struct add_p_state *s, const struct pathspec *ps) int res; strvec_pushv(&args, s->mode->diff_cmd); - if (diff_algorithm) - strvec_pushf(&args, "--diff-algorithm=%s", diff_algorithm); + if (s->s.context != -1) + strvec_pushf(&args, "--unified=%i", s->s.context); + if (s->s.interhunkcontext != -1) + strvec_pushf(&args, "--inter-hunk-context=%i", s->s.interhunkcontext); + if (s->s.interactive_diff_algorithm) + strvec_pushf(&args, "--diff-algorithm=%s", s->s.interactive_diff_algorithm); if (s->revision) { struct object_id oid; strvec_push(&args, @@ -1760,14 +1763,15 @@ soft_increment: } int run_add_p(struct repository *r, enum add_p_mode mode, - const char *revision, const struct pathspec *ps) + struct add_p_opt *o, const char *revision, + const struct pathspec *ps) { struct add_p_state s = { { r }, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT, STRBUF_INIT }; size_t i, binary_count = 0; - init_add_i_state(&s.s, r); + init_add_i_state(&s.s, r, o); if (mode == ADD_P_STASH) s.mode = &patch_mode_stash; @@ -48,9 +48,9 @@ struct gitdiff_data { static void git_apply_config(void) { - git_config_get_string("apply.whitespace", &apply_default_whitespace); - git_config_get_string("apply.ignorewhitespace", &apply_default_ignorewhitespace); - git_config(git_xmerge_config, NULL); + repo_config_get_string(the_repository, "apply.whitespace", &apply_default_whitespace); + repo_config_get_string(the_repository, "apply.ignorewhitespace", &apply_default_ignorewhitespace); + repo_config(the_repository, git_xmerge_config, NULL); } static int parse_whitespace_option(struct apply_state *state, const char *option) @@ -3621,7 +3621,7 @@ static int try_threeway(struct apply_state *state, /* Preimage the patch was prepared for */ if (patch->is_new) - write_object_file("", 0, OBJ_BLOB, &pre_oid); + odb_write_object(the_repository->objects, "", 0, OBJ_BLOB, &pre_oid); else if (repo_get_oid(the_repository, patch->old_oid_prefix, &pre_oid) || read_blob_object(&buf, &pre_oid, patch->old_mode)) return error(_("repository lacks the necessary blob to perform 3-way merge.")); @@ -3637,7 +3637,8 @@ static int try_threeway(struct apply_state *state, return -1; } /* post_oid is theirs */ - write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &post_oid); + odb_write_object(the_repository->objects, tmp_image.buf.buf, + tmp_image.buf.len, OBJ_BLOB, &post_oid); image_clear(&tmp_image); /* our_oid is ours */ @@ -3650,7 +3651,8 @@ static int try_threeway(struct apply_state *state, return error(_("cannot read the current contents of '%s'"), patch->old_name); } - write_object_file(tmp_image.buf.buf, tmp_image.buf.len, OBJ_BLOB, &our_oid); + odb_write_object(the_repository->objects, tmp_image.buf.buf, + tmp_image.buf.len, OBJ_BLOB, &our_oid); image_clear(&tmp_image); /* in-core three-way merge between post and our using pre as base */ @@ -4360,7 +4362,8 @@ static int add_index_file(struct apply_state *state, } fill_stat_cache_info(state->repo->index, ce, &st); } - if (write_object_file(buf, size, OBJ_BLOB, &ce->oid) < 0) { + if (odb_write_object(the_repository->objects, buf, size, + OBJ_BLOB, &ce->oid) < 0) { discard_cache_entry(ce); return error(_("unable to create backing store " "for newly created file %s"), path); diff --git a/archive-tar.c b/archive-tar.c index 249164ea77..73b63ddc41 100644 --- a/archive-tar.c +++ b/archive-tar.c @@ -537,7 +537,7 @@ void init_tar_archiver(void) tar_filter_config("tar.tgz.remote", "true", NULL); tar_filter_config("tar.tar.gz.command", internal_gzip_command, NULL); tar_filter_config("tar.tar.gz.remote", "true", NULL); - git_config(git_tar_config, NULL); + repo_config(the_repository, git_tar_config, NULL); for (i = 0; i < nr_tar_filters; i++) { /* omit any filters that never had a command configured */ if (tar_filters[i]->filter_command) diff --git a/archive-zip.c b/archive-zip.c index df8866d5ba..bea5bdd43d 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -492,14 +492,22 @@ static int write_zip_entry(struct archiver_args *args, zstream.next_in = buf; zstream.avail_in = 0; - result = git_deflate(&zstream, Z_FINISH); - if (result != Z_STREAM_END) - die("deflate error (%d)", result); + + do { + result = git_deflate(&zstream, Z_FINISH); + if (result != Z_OK && result != Z_STREAM_END) + die("deflate error (%d)", result); + + out_len = zstream.next_out - compressed; + if (out_len > 0) { + write_or_die(1, compressed, out_len); + compressed_size += out_len; + zstream.next_out = compressed; + zstream.avail_out = sizeof(compressed); + } + } while (result != Z_STREAM_END); git_deflate_end(&zstream); - out_len = zstream.next_out - compressed; - write_or_die(1, compressed, out_len); - compressed_size += out_len; zip_offset += compressed_size; write_zip_data_desc(size, compressed_size, crc); @@ -632,7 +640,7 @@ static int write_zip_archive(const struct archiver *ar UNUSED, { int err; - git_config(archive_zip_config, NULL); + repo_config(the_repository, archive_zip_config, NULL); dos_time(&args->time, &zip_date, &zip_time); @@ -760,8 +760,8 @@ int write_archive(int argc, const char **argv, const char *prefix, const char **argv_copy; int rc; - git_config_get_bool("uploadarchive.allowunreachable", &remote_allow_unreachable); - git_config(git_default_config, NULL); + repo_config_get_bool(the_repository, "uploadarchive.allowunreachable", &remote_allow_unreachable); + repo_config(the_repository, git_default_config, NULL); describe_status.max_invocations = 1; ctx.date_mode.type = DATE_NORMAL; @@ -27,14 +27,6 @@ struct commit_list *filter_skipped(struct commit_list *list, #define FIND_BISECTION_ALL (1u<<0) #define FIND_BISECTION_FIRST_PARENT_ONLY (1u<<1) -struct rev_list_info { - struct rev_info *revs; - int flags; - int show_timestamp; - int hdr_termination; - const char *header_prefix; -}; - /* * enum bisect_error represents the following return codes: * BISECT_OK: success code. Internally, it means that next @@ -116,7 +116,7 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, } strbuf_addf(&key, "branch.%s.remote", local); - if (git_config_set_gently(key.buf, origin ? origin : ".") < 0) + if (repo_config_set_gently(the_repository, key.buf, origin ? origin : ".") < 0) goto out_err; strbuf_reset(&key); @@ -127,16 +127,16 @@ static int install_branch_config_multiple_remotes(int flag, const char *local, * more than one is provided, use CONFIG_REGEX_NONE to preserve what * we've written so far. */ - if (git_config_set_gently(key.buf, NULL) < 0) + if (repo_config_set_gently(the_repository, key.buf, NULL) < 0) goto out_err; for_each_string_list_item(item, remotes) - if (git_config_set_multivar_gently(key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0) + if (repo_config_set_multivar_gently(the_repository, key.buf, item->string, CONFIG_REGEX_NONE, 0) < 0) goto out_err; if (rebasing) { strbuf_reset(&key); strbuf_addf(&key, "branch.%s.rebase", local); - if (git_config_set_gently(key.buf, "true") < 0) + if (repo_config_set_gently(the_repository, key.buf, "true") < 0) goto out_err; } strbuf_release(&key); @@ -355,7 +355,7 @@ int read_branch_desc(struct strbuf *buf, const char *branch_name) char *v = NULL; struct strbuf name = STRBUF_INIT; strbuf_addf(&name, "branch.%s.description", branch_name); - if (git_config_get_string(name.buf, &v)) { + if (repo_config_get_string(the_repository, name.buf, &v)) { strbuf_release(&name); return -1; } @@ -217,6 +217,7 @@ int cmd_remote_ext(int argc, const char **argv, const char *prefix, struct repos int cmd_remote_fd(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_repack(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_replay(int argc, const char **argv, const char *prefix, struct repository *repo); +int cmd_repo(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_rerere(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_reset(int argc, const char **argv, const char *prefix, struct repository *repo); int cmd_restore(int argc, const char **argv, const char *prefix, struct repository *repo); diff --git a/builtin/add.c b/builtin/add.c index 7c292ffdc6..0235854f80 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "lockfile.h" #include "editor.h" #include "dir.h" @@ -29,6 +30,7 @@ static const char * const builtin_add_usage[] = { NULL }; static int patch_interactive, add_interactive, edit_interactive; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int take_worktree_changes; static int add_renormalize; static int pathspec_file_nul; @@ -157,7 +159,7 @@ static int refresh(struct repository *repo, int verbose, const struct pathspec * int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch) + int patch, struct add_p_opt *add_p_opt) { struct pathspec pathspec; int ret; @@ -169,9 +171,9 @@ int interactive_add(struct repository *repo, prefix, argv); if (patch) - ret = !!run_add_p(repo, ADD_P_ADD, NULL, &pathspec); + ret = !!run_add_p(repo, ADD_P_ADD, add_p_opt, NULL, &pathspec); else - ret = !!run_add_i(repo, &pathspec); + ret = !!run_add_i(repo, &pathspec, add_p_opt); clear_pathspec(&pathspec); return ret; @@ -253,6 +255,8 @@ static struct option builtin_add_options[] = { OPT_GROUP(""), OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")), OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")), OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files"), 0), OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")), @@ -394,6 +398,11 @@ int cmd_add(int argc, prepare_repo_settings(repo); repo->settings.command_requires_full_index = 0; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (patch_interactive) add_interactive = 1; if (add_interactive) { @@ -401,7 +410,12 @@ int cmd_add(int argc, die(_("options '%s' and '%s' cannot be used together"), "--dry-run", "--interactive/--patch"); if (pathspec_from_file) die(_("options '%s' and '%s' cannot be used together"), "--pathspec-from-file", "--interactive/--patch"); - exit(interactive_add(repo, argv + 1, prefix, patch_interactive)); + exit(interactive_add(repo, argv + 1, prefix, patch_interactive, &add_p_opt)); + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } if (edit_interactive) { diff --git a/builtin/am.c b/builtin/am.c index c9d925f7b9..6073d64ae9 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -162,18 +162,18 @@ static void am_state_init(struct am_state *state) state->prec = 4; - git_config_get_bool("am.threeway", &state->threeway); + repo_config_get_bool(the_repository, "am.threeway", &state->threeway); state->utf8 = 1; - git_config_get_bool("am.messageid", &state->message_id); + repo_config_get_bool(the_repository, "am.messageid", &state->message_id); state->scissors = SCISSORS_UNSET; state->quoted_cr = quoted_cr_unset; strvec_init(&state->git_apply_opts); - if (!git_config_get_bool("commit.gpgsign", &gpgsign)) + if (!repo_config_get_bool(the_repository, "commit.gpgsign", &gpgsign)) state->sign_commit = gpgsign ? "" : NULL; } @@ -965,7 +965,7 @@ static int split_mail(struct am_state *state, enum patch_format patch_format, { if (keep_cr < 0) { keep_cr = 0; - git_config_get_bool("am.keepcr", &keep_cr); + repo_config_get_bool(the_repository, "am.keepcr", &keep_cr); } switch (patch_format) { @@ -2445,7 +2445,7 @@ int cmd_am(int argc, show_usage_with_options_if_asked(argc, argv, usage, options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); am_state_init(&state); diff --git a/builtin/blame.c b/builtin/blame.c index 91586e6852..2703820258 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -197,9 +197,7 @@ static void commit_info_destroy(struct commit_info *ci) strbuf_release(&ci->summary); } -static void get_commit_info(struct commit *commit, - struct commit_info *ret, - int detailed) +static void get_commit_info(struct commit *commit, struct commit_info *ret) { int len; const char *subject, *encoding; @@ -211,11 +209,6 @@ static void get_commit_info(struct commit *commit, &ret->author, &ret->author_mail, &ret->author_time, &ret->author_tz); - if (!detailed) { - repo_unuse_commit_buffer(the_repository, commit, message); - return; - } - get_ac_line(message, "\ncommitter ", &ret->committer, &ret->committer_mail, &ret->committer_time, &ret->committer_tz); @@ -263,7 +256,7 @@ static int emit_one_suspect_detail(struct blame_origin *suspect, int repeat) return 0; suspect->commit->object.flags |= METAINFO_SHOWN; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); printf("author %s\n", ci.author.buf); printf("author-mail %s\n", ci.author_mail.buf); printf("author-time %"PRItime"\n", ci.author_time); @@ -420,7 +413,7 @@ static void parse_color_fields(const char *s) colorfield_nr = 0; /* Ideally this would be stripped and split at the same time? */ - string_list_split(&l, s, ',', -1); + string_list_split(&l, s, ",", -1); ALLOC_GROW(colorfield, colorfield_nr + 1, colorfield_alloc); for_each_string_list_item(item, &l) { @@ -471,7 +464,7 @@ static void emit_other(struct blame_scoreboard *sb, struct blame_entry *ent, int int show_raw_time = !!(opt & OUTPUT_RAW_TIMESTAMP); const char *default_color = NULL, *color = NULL, *reset = NULL; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); oid_to_hex_r(hex, &suspect->commit->object.oid); cp = blame_nth_line(sb, ent->lno); @@ -665,7 +658,7 @@ static void find_alignment(struct blame_scoreboard *sb, int *option) if (!(suspect->commit->object.flags & METAINFO_SHOWN)) { struct commit_info ci = COMMIT_INFO_INIT; suspect->commit->object.flags |= METAINFO_SHOWN; - get_commit_info(suspect->commit, &ci, 1); + get_commit_info(suspect->commit, &ci); if (*option & OUTPUT_SHOW_EMAIL) num = utf8_strwidth(ci.author_mail.buf); else @@ -947,7 +940,7 @@ int cmd_blame(int argc, const char *const *opt_usage = cmd_is_annotate ? annotate_opt_usage : blame_opt_usage; setup_default_color_by_age(); - git_config(git_blame_config, &output_option); + repo_config(the_repository, git_blame_config, &output_option); repo_init_revisions(the_repository, &revs, NULL); revs.date_mode = blame_date_mode; revs.diffopt.flags.allow_textconv = 1; diff --git a/builtin/branch.c b/builtin/branch.c index c150131bd9..fa5ced452e 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -699,7 +699,7 @@ static int edit_branch_description(const char *branch_name) strbuf_addf(&name, "branch.%s.description", branch_name); if (buf.len || exists) - git_config_set(name.buf, buf.len ? buf.buf : NULL); + repo_config_set(the_repository, name.buf, buf.len ? buf.buf : NULL); strbuf_release(&name); strbuf_release(&buf); @@ -791,7 +791,7 @@ int cmd_branch(int argc, * Try to set sort keys from config. If config does not set any, * fall back on default (refname) sorting. */ - git_config(git_branch_config, &sorting_options); + repo_config(the_repository, git_branch_config, &sorting_options); if (!sorting_options.nr) string_list_append(&sorting_options, "refname"); @@ -987,10 +987,10 @@ int cmd_branch(int argc, strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.remote", branch->name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.merge", branch->name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); strbuf_release(&buf); } else if (!noncreate_actions && argc > 0 && argc <= 2) { const char *branch_name = argv[0]; diff --git a/builtin/cat-file.c b/builtin/cat-file.c index 2492a0b6f3..fce0b06451 100644 --- a/builtin/cat-file.c +++ b/builtin/cat-file.c @@ -848,7 +848,7 @@ static void batch_each_object(struct batch_options *opt, }; struct bitmap_index *bitmap = prepare_bitmap_git(the_repository); - for_each_loose_object(batch_one_object_loose, &payload, 0); + for_each_loose_object(the_repository->objects, batch_one_object_loose, &payload, 0); if (bitmap && !for_each_bitmapped_object(bitmap, &opt->objects_filter, batch_one_object_bitmapped, &payload)) { @@ -1095,7 +1095,7 @@ int cmd_cat_file(int argc, OPT_END() }; - git_config(git_cat_file_config, NULL); + repo_config(the_repository, git_cat_file_config, NULL); batch.buffer_output = -1; diff --git a/builtin/check-attr.c b/builtin/check-attr.c index 7cf275b893..51ed48ce43 100644 --- a/builtin/check-attr.c +++ b/builtin/check-attr.c @@ -119,7 +119,7 @@ int cmd_check_attr(int argc, if (!is_bare_repository()) setup_work_tree(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_attr_options, check_attr_usage, PARSE_OPT_KEEP_DASHDASH); diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 7b7831d13a..644c9a414f 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "quote.h" #include "pathspec.h" @@ -159,7 +160,7 @@ int cmd_check_ignore(int argc, int num_ignored; struct dir_struct dir = DIR_INIT; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_ignore_options, check_ignore_usage, 0); diff --git a/builtin/check-mailmap.c b/builtin/check-mailmap.c index be2cebe121..9cc5c59830 100644 --- a/builtin/check-mailmap.c +++ b/builtin/check-mailmap.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "ident.h" #include "mailmap.h" @@ -56,7 +57,7 @@ int cmd_check_mailmap(int argc, int i; struct string_list mailmap = STRING_LIST_INIT_NODUP; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, check_mailmap_options, check_mailmap_usage, 0); if (argc == 0 && !use_stdin) diff --git a/builtin/checkout--worker.c b/builtin/checkout--worker.c index da9345a44b..e0772b718b 100644 --- a/builtin/checkout--worker.c +++ b/builtin/checkout--worker.c @@ -4,6 +4,7 @@ #include "builtin.h" #include "config.h" #include "entry.h" +#include "environment.h" #include "gettext.h" #include "parallel-checkout.h" #include "parse-options.h" @@ -132,7 +133,7 @@ int cmd_checkout__worker(int argc, checkout_worker_usage, checkout_worker_options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, checkout_worker_options, checkout_worker_usage, 0); if (argc > 0) diff --git a/builtin/checkout-index.c b/builtin/checkout-index.c index 7f74bc702f..188128aebd 100644 --- a/builtin/checkout-index.c +++ b/builtin/checkout-index.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "lockfile.h" #include "quote.h" diff --git a/builtin/checkout.c b/builtin/checkout.c index 0a90b86a72..f9453473fe 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -61,6 +61,8 @@ static const char * const restore_usage[] = { struct checkout_opts { int patch_mode; + int patch_context; + int patch_interhunk_context; int quiet; int merge; int force; @@ -104,7 +106,12 @@ struct checkout_opts { struct tree *source_tree; }; -#define CHECKOUT_OPTS_INIT { .conflict_style = -1, .merge = -1 } +#define CHECKOUT_OPTS_INIT { \ + .conflict_style = -1, \ + .merge = -1, \ + .patch_context = -1, \ + .patch_interhunk_context = -1, \ +} struct branch_info { char *name; /* The short name used */ @@ -291,7 +298,7 @@ static int checkout_merged(int pos, const struct checkout *state, read_mmblob(&ours, &threeway[1]); read_mmblob(&theirs, &threeway[2]); - git_config_get_bool("merge.renormalize", &renormalize); + repo_config_get_bool(the_repository, "merge.renormalize", &renormalize); ll_opts.renormalize = renormalize; ll_opts.conflict_style = conflict_style; merge_status = ll_merge(&result_buf, path, &ancestor, "base", @@ -320,7 +327,7 @@ static int checkout_merged(int pos, const struct checkout *state, * (it also writes the merge result to the object database even * when it may contain conflicts). */ - if (write_object_file(result_buf.ptr, result_buf.size, OBJ_BLOB, &oid)) + if (odb_write_object(the_repository->objects, result_buf.ptr, result_buf.size, OBJ_BLOB, &oid)) die(_("Unable to add merge result for '%s'"), path); free(result_buf.ptr); ce = make_transient_cache_entry(mode, &oid, path, 2, ce_mem_pool); @@ -539,6 +546,10 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->patch_mode) { enum add_p_mode patch_mode; + struct add_p_opt add_p_opt = { + .context = opts->patch_context, + .interhunkcontext = opts->patch_interhunk_context, + }; const char *rev = new_branch_info->name; char rev_oid[GIT_MAX_HEXSZ + 1]; @@ -564,8 +575,8 @@ static int checkout_paths(const struct checkout_opts *opts, else BUG("either flag must have been set, worktree=%d, index=%d", opts->checkout_worktree, opts->checkout_index); - return !!run_add_p(the_repository, patch_mode, rev, - &opts->pathspec); + return !!run_add_p(the_repository, patch_mode, &add_p_opt, + rev, &opts->pathspec); } repo_hold_locked_index(the_repository, &lock_file, LOCK_DIE_ON_ERROR); @@ -1738,6 +1749,8 @@ static struct option *add_checkout_path_options(struct checkout_opts *opts, N_("checkout their version for unmerged files"), 3, PARSE_OPT_NONEG), OPT_BOOL('p', "patch", &opts->patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&opts->patch_context), + OPT_DIFF_INTERHUNK_CONTEXT(&opts->patch_interhunk_context), OPT_BOOL(0, "ignore-skip-worktree-bits", &opts->ignore_skipworktree, N_("do not limit pathspecs to sparse entries only")), OPT_PATHSPEC_FROM_FILE(&opts->pathspec_from_file), @@ -1764,7 +1777,7 @@ static int checkout_main(int argc, const char **argv, const char *prefix, opts->prefix = prefix; opts->show_progress = -1; - git_config(git_checkout_config, opts); + repo_config(the_repository, git_checkout_config, opts); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -1780,6 +1793,18 @@ static int checkout_main(int argc, const char **argv, const char *prefix, argc = parse_options(argc, argv, prefix, options, usagestr, parseopt_flags); + if (opts->patch_context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (opts->patch_interhunk_context < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!opts->patch_mode) { + if (opts->patch_context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (opts->patch_interhunk_context != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + if (opts->show_progress < 0) { if (opts->quiet) opts->show_progress = 0; diff --git a/builtin/clean.c b/builtin/clean.c index 053c94fc6b..38b67923a6 100644 --- a/builtin/clean.c +++ b/builtin/clean.c @@ -13,6 +13,7 @@ #include "abspath.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "path.h" @@ -477,43 +478,39 @@ static int find_unique(const char *choice, struct menu_stuff *menu_stuff) */ static int parse_choice(struct menu_stuff *menu_stuff, int is_single, - struct strbuf input, + char *input, int **chosen) { - struct strbuf **choice_list, **ptr; + struct string_list choice = STRING_LIST_INIT_NODUP; + struct string_list_item *item; int nr = 0; int i; - if (is_single) { - choice_list = strbuf_split_max(&input, '\n', 0); - } else { - char *p = input.buf; - do { - if (*p == ',') - *p = ' '; - } while (*p++); - choice_list = strbuf_split_max(&input, ' ', 0); - } + string_list_split_in_place_f(&choice, input, + is_single ? "\n" : ", ", -1, + STRING_LIST_SPLIT_TRIM); - for (ptr = choice_list; *ptr; ptr++) { - char *p; - int choose = 1; + for_each_string_list_item(item, &choice) { + const char *string; + int choose; int bottom = 0, top = 0; int is_range, is_number; - strbuf_trim(*ptr); - if (!(*ptr)->len) + string = item->string; + if (!*string) continue; /* Input that begins with '-'; unchoose */ - if (*(*ptr)->buf == '-') { + if (string[0] == '-') { choose = 0; - strbuf_remove((*ptr), 0, 1); + string++; + } else { + choose = 1; } is_range = 0; is_number = 1; - for (p = (*ptr)->buf; *p; p++) { + for (const char *p = string; *p; p++) { if ('-' == *p) { if (!is_range) { is_range = 1; @@ -531,27 +528,27 @@ static int parse_choice(struct menu_stuff *menu_stuff, } if (is_number) { - bottom = atoi((*ptr)->buf); + bottom = atoi(string); top = bottom; } else if (is_range) { - bottom = atoi((*ptr)->buf); + bottom = atoi(string); /* a range can be specified like 5-7 or 5- */ - if (!*(strchr((*ptr)->buf, '-') + 1)) + if (!*(strchr(string, '-') + 1)) top = menu_stuff->nr; else - top = atoi(strchr((*ptr)->buf, '-') + 1); - } else if (!strcmp((*ptr)->buf, "*")) { + top = atoi(strchr(string, '-') + 1); + } else if (!strcmp(string, "*")) { bottom = 1; top = menu_stuff->nr; } else { - bottom = find_unique((*ptr)->buf, menu_stuff); + bottom = find_unique(string, menu_stuff); top = bottom; } if (top <= 0 || bottom <= 0 || top > menu_stuff->nr || bottom > top || (is_single && bottom != top)) { clean_print_color(CLEAN_COLOR_ERROR); - printf(_("Huh (%s)?\n"), (*ptr)->buf); + printf(_("Huh (%s)?\n"), string); clean_print_color(CLEAN_COLOR_RESET); continue; } @@ -560,7 +557,7 @@ static int parse_choice(struct menu_stuff *menu_stuff, (*chosen)[i-1] = choose; } - strbuf_list_free(choice_list); + string_list_clear(&choice, 0); for (i = 0; i < menu_stuff->nr; i++) nr += (*chosen)[i]; @@ -630,7 +627,7 @@ static int *list_and_choose(struct menu_opts *opts, struct menu_stuff *stuff) nr = parse_choice(stuff, opts->flags & MENU_OPTS_SINGLETON, - choice, + choice.buf, &chosen); if (opts->flags & MENU_OPTS_SINGLETON) { @@ -678,12 +675,13 @@ static int filter_by_patterns_cmd(void) { struct dir_struct dir = DIR_INIT; struct strbuf confirm = STRBUF_INIT; - struct strbuf **ignore_list; - struct string_list_item *item; struct pattern_list *pl; int changed = -1, i; for (;;) { + struct string_list ignore_list = STRING_LIST_INIT_NODUP; + struct string_list_item *item; + if (!del_list.nr) break; @@ -701,14 +699,15 @@ static int filter_by_patterns_cmd(void) break; pl = add_pattern_list(&dir, EXC_CMDL, "manual exclude"); - ignore_list = strbuf_split_max(&confirm, ' ', 0); - for (i = 0; ignore_list[i]; i++) { - strbuf_trim(ignore_list[i]); - if (!ignore_list[i]->len) - continue; + string_list_split_in_place_f(&ignore_list, confirm.buf, " ", -1, + STRING_LIST_SPLIT_TRIM); - add_pattern(ignore_list[i]->buf, "", 0, pl, -(i+1)); + for (i = 0; i < ignore_list.nr; i++) { + item = &ignore_list.items[i]; + if (!*item->string) + continue; + add_pattern(item->string, "", 0, pl, -(i+1)); } changed = 0; @@ -729,7 +728,7 @@ static int filter_by_patterns_cmd(void) clean_print_color(CLEAN_COLOR_RESET); } - strbuf_list_free(ignore_list); + string_list_clear(&ignore_list, 0); dir_clear(&dir); } @@ -949,7 +948,7 @@ int cmd_clean(int argc, OPT_END() }; - git_config(git_clean_config, NULL); + repo_config(the_repository, git_clean_config, NULL); argc = parse_options(argc, argv, prefix, options, builtin_clean_usage, 0); diff --git a/builtin/clone.c b/builtin/clone.c index 6d08abed37..c990f398ef 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -762,16 +762,16 @@ static int write_one_config(const char *key, const char *value, { /* * give git_clone_config a chance to write config values back to the - * environment, since git_config_set_multivar_gently only deals with + * environment, since repo_config_set_multivar_gently only deals with * config-file writes */ int apply_failed = git_clone_config(key, value, ctx, data); if (apply_failed) return apply_failed; - return git_config_set_multivar_gently(key, - value ? value : "true", - CONFIG_REGEX_NONE, 0); + return repo_config_set_multivar_gently(the_repository, key, + value ? value : "true", + CONFIG_REGEX_NONE, 0); } static void write_config(struct string_list *config) @@ -822,12 +822,12 @@ static void write_refspec_config(const char *src_ref_prefix, /* Configure the remote */ if (value.len) { strbuf_addf(&key, "remote.%s.fetch", remote_name); - git_config_set_multivar(key.buf, value.buf, "^$", 0); + repo_config_set_multivar(the_repository, key.buf, value.buf, "^$", 0); strbuf_reset(&key); if (option_mirror) { strbuf_addf(&key, "remote.%s.mirror", remote_name); - git_config_set(key.buf, "true"); + repo_config_set(the_repository, key.buf, "true"); strbuf_reset(&key); } } @@ -1001,7 +1001,7 @@ int cmd_clone(int argc, packet_trace_identity("clone"); - git_config(git_clone_config, NULL); + repo_config(the_repository, git_clone_config, NULL); argc = parse_options(argc, argv, prefix, builtin_clone_options, builtin_clone_usage, 0); @@ -1150,7 +1150,7 @@ int cmd_clone(int argc, strbuf_reset(&sb); } - if (!git_config_get_bool("submodule.stickyRecursiveClone", &val) && + if (!repo_config_get_bool(the_repository, "submodule.stickyRecursiveClone", &val) && val) string_list_append(&option_config, "submodule.recurse=true"); @@ -1242,7 +1242,7 @@ int cmd_clone(int argc, * re-read config after init_db and write_config to pick up any config * injected by --template and --config, respectively. */ - git_config(git_clone_config, NULL); + repo_config(the_repository, git_clone_config, NULL); /* * If option_reject_shallow is specified from CLI option, @@ -1294,18 +1294,18 @@ int cmd_clone(int argc, src_ref_prefix = "refs/"; strbuf_addstr(&branch_top, src_ref_prefix); - git_config_set("core.bare", "true"); + repo_config_set(the_repository, "core.bare", "true"); } else if (!option_rev) { strbuf_addf(&branch_top, "refs/remotes/%s/", remote_name); } strbuf_addf(&key, "remote.%s.url", remote_name); - git_config_set(key.buf, repo); + repo_config_set(the_repository, key.buf, repo); strbuf_reset(&key); if (!option_tags) { strbuf_addf(&key, "remote.%s.tagOpt", remote_name); - git_config_set(key.buf, "--no-tags"); + repo_config_set(the_repository, key.buf, "--no-tags"); strbuf_reset(&key); } @@ -1467,7 +1467,7 @@ int cmd_clone(int argc, warning(_("failed to fetch objects from bundle URI '%s'"), bundle_uri); else if (has_heuristic) - git_config_set_gently("fetch.bundleuri", bundle_uri); + repo_config_set_gently(the_repository, "fetch.bundleuri", bundle_uri); remote_state_clear(the_repository->remote_state); free(the_repository->remote_state); diff --git a/builtin/column.c b/builtin/column.c index ce6443d5fa..87dce3c6e5 100644 --- a/builtin/column.c +++ b/builtin/column.c @@ -42,9 +42,9 @@ int cmd_column(int argc, /* This one is special and must be the first one */ if (argc > 1 && starts_with(argv[1], "--command=")) { command = argv[1] + 10; - git_config(column_config, (void *)command); + repo_config(the_repository, column_config, (void *)command); } else - git_config(column_config, NULL); + repo_config(the_repository, column_config, NULL); memset(&copts, 0, sizeof(copts)); copts.padding = 1; diff --git a/builtin/commit-graph.c b/builtin/commit-graph.c index 25018a0b9d..6656187f90 100644 --- a/builtin/commit-graph.c +++ b/builtin/commit-graph.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "commit.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "parse-options.h" @@ -108,7 +109,8 @@ static int graph_verify(int argc, const char **argv, const char *prefix, opened = OPENED_GRAPH; else if (errno != ENOENT) die_errno(_("Could not open commit-graph '%s'"), graph_name); - else if (open_commit_graph_chain(chain_name, &fd, &st)) + else if (open_commit_graph_chain(chain_name, &fd, &st, + the_repository->hash_algo)) opened = OPENED_CHAIN; else if (errno != ENOENT) die_errno(_("could not open commit-graph chain '%s'"), chain_name); @@ -120,15 +122,15 @@ static int graph_verify(int argc, const char **argv, const char *prefix, if (opened == OPENED_NONE) return 0; else if (opened == OPENED_GRAPH) - graph = load_commit_graph_one_fd_st(the_repository, fd, &st, source); + graph = load_commit_graph_one_fd_st(source, fd, &st); else - graph = load_commit_graph_chain_fd_st(the_repository, fd, &st, + graph = load_commit_graph_chain_fd_st(the_repository->objects, fd, &st, &incomplete_chain); if (!graph) return 1; - ret = verify_commit_graph(the_repository, graph, flags); + ret = verify_commit_graph(graph, flags); free_commit_graph(graph); if (incomplete_chain) { @@ -265,7 +267,7 @@ static int graph_write(int argc, const char **argv, const char *prefix, trace2_cmd_mode("write"); - git_config(git_commit_graph_write_config, &opts); + repo_config(the_repository, git_commit_graph_write_config, &opts); argc = parse_options(argc, argv, prefix, options, @@ -347,7 +349,7 @@ int cmd_commit_graph(int argc, }; struct option *options = parse_options_concat(builtin_commit_graph_options, common_opts); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); disable_replace_refs(); save_commit_buffer = 0; diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 31cfd9bd15..5189e685a7 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" @@ -125,7 +126,7 @@ int cmd_commit_tree(int argc, }; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); show_usage_with_options_if_asked(argc, argv, commit_tree_usage, options); diff --git a/builtin/commit.c b/builtin/commit.c index 63e7158e98..8a5dee384d 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -19,6 +19,7 @@ #include "environment.h" #include "diff.h" #include "commit.h" +#include "add-interactive.h" #include "gettext.h" #include "revision.h" #include "wt-status.h" @@ -122,6 +123,7 @@ static const char *edit_message, *use_message; static char *fixup_message, *fixup_commit, *squash_message; static const char *fixup_prefix; static int all, also, interactive, patch_interactive, only, amend, signoff; +static struct add_p_opt add_p_opt = ADD_P_OPT_INIT; static int edit_flag = -1; /* unspecified */ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; static int config_commit_verbose = -1; /* unspecified */ @@ -207,9 +209,9 @@ static void status_init_config(struct wt_status *s, config_fn_t fn) { wt_status_prepare(the_repository, s); init_diff_ui_defaults(); - git_config(fn, s); + repo_config(the_repository, fn, s); determine_whence(s); - s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after git_config() */ + s->hints = advice_enabled(ADVICE_STATUS_HINTS); /* must come after repo_config() */ } static void rollback_index_files(void) @@ -354,6 +356,11 @@ static const char *prepare_index(const char **argv, const char *prefix, const char *ret; char *path = NULL; + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + if (is_status) refresh_flags |= REFRESH_UNMERGED; parse_pathspec(&pathspec, 0, @@ -400,7 +407,7 @@ static const char *prepare_index(const char **argv, const char *prefix, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - if (interactive_add(the_repository, argv, prefix, patch_interactive) != 0) + if (interactive_add(the_repository, argv, prefix, patch_interactive, &add_p_opt) != 0) die(_("interactive add failed")); the_repository->index_file = old_repo_index_file; @@ -424,6 +431,11 @@ static const char *prepare_index(const char **argv, const char *prefix, commit_style = COMMIT_NORMAL; ret = get_lock_file_path(&index_lock); goto out; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--interactive/--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--interactive/--patch"); } /* @@ -1726,6 +1738,8 @@ int cmd_commit(int argc, OPT_BOOL('i', "include", &also, N_("add specified files to index for commit")), OPT_BOOL(0, "interactive", &interactive, N_("interactively add files")), OPT_BOOL('p', "patch", &patch_interactive, N_("interactively add changes")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('o', "only", &only, N_("commit only specified files")), OPT_BOOL('n', "no-verify", &no_verify, N_("bypass pre-commit and commit-msg hooks")), OPT_BOOL(0, "dry-run", &dry_run, N_("show what would be committed")), @@ -1933,7 +1947,7 @@ int cmd_commit(int argc, "new index file. Check that disk is not full and quota is\n" "not exceeded, and then \"git restore --staged :/\" to recover.")); - git_test_write_commit_graph_or_die(); + git_test_write_commit_graph_or_die(the_repository->objects->sources); repo_rerere(the_repository, 0); run_auto_maintenance(quiet); diff --git a/builtin/config.c b/builtin/config.c index 5efe273010..59fb113b07 100644 --- a/builtin/config.c +++ b/builtin/config.c @@ -966,12 +966,12 @@ static int cmd_config_set(int argc, const char **argv, const char *prefix, value = normalize_value(argv[0], argv[1], type, &default_kvi); if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) { - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, value_pattern, - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, value_pattern, + comment, flags); } else { - ret = git_config_set_in_file_gently(location_opts.source.file, - argv[0], comment, value); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, + argv[0], comment, value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); @@ -1010,12 +1010,12 @@ static int cmd_config_unset(int argc, const char **argv, const char *prefix, check_write(&location_opts.source); if ((flags & CONFIG_FLAGS_MULTI_REPLACE) || value_pattern) - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, value_pattern, - NULL, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, value_pattern, + NULL, flags); else - ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], - NULL, NULL); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], + NULL, NULL); location_options_release(&location_opts); return ret; @@ -1091,7 +1091,7 @@ static int show_editor(struct config_location_options *opts) die(_("editing stdin is not supported")); if (opts->source.blob) die(_("editing blobs is not supported")); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); config_file = opts->source.file ? xstrdup(opts->source.file) : repo_git_path(the_repository, "config"); @@ -1296,7 +1296,7 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_in_file_gently(location_opts.source.file, argv[0], comment, value); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, argv[0], comment, value); if (ret == CONFIG_NOTHING_SET) error(_("cannot overwrite multiple values with a single value\n" " Use a regexp, --add or --replace-all to change %s."), argv[0]); @@ -1305,26 +1305,26 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, argv[2], - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, argv[2], + comment, flags); } else if (actions == ACTION_ADD) { check_write(&location_opts.source); check_argc(argc, 2, 2); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, - CONFIG_REGEX_NONE, - comment, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, + CONFIG_REGEX_NONE, + comment, flags); } else if (actions == ACTION_REPLACE_ALL) { check_write(&location_opts.source); check_argc(argc, 2, 3); value = normalize_value(argv[0], argv[1], display_opts.type, &default_kvi); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], value, argv[2], - comment, flags | CONFIG_FLAGS_MULTI_REPLACE); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], value, argv[2], + comment, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_GET) { check_argc(argc, 1, 2); @@ -1350,19 +1350,19 @@ static int cmd_config_actions(int argc, const char **argv, const char *prefix) check_write(&location_opts.source); check_argc(argc, 1, 2); if (argc == 2) - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, argv[1], - NULL, flags); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, argv[1], + NULL, flags); else - ret = git_config_set_in_file_gently(location_opts.source.file, - argv[0], NULL, NULL); + ret = repo_config_set_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, NULL); } else if (actions == ACTION_UNSET_ALL) { check_write(&location_opts.source); check_argc(argc, 1, 2); - ret = git_config_set_multivar_in_file_gently(location_opts.source.file, - argv[0], NULL, argv[1], - NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); + ret = repo_config_set_multivar_in_file_gently(the_repository, location_opts.source.file, + argv[0], NULL, argv[1], + NULL, flags | CONFIG_FLAGS_MULTI_REPLACE); } else if (actions == ACTION_RENAME_SECTION) { check_write(&location_opts.source); diff --git a/builtin/count-objects.c b/builtin/count-objects.c index f687647931..a61d3b46aa 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "path.h" #include "parse-options.h" @@ -106,7 +107,7 @@ int cmd_count_objects(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, count_objects_usage, 0); /* we do not take arguments other than flags for now */ @@ -117,7 +118,7 @@ int cmd_count_objects(int argc, report_linked_checkout_garbage(the_repository); } - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, count_loose, count_cruft, NULL, NULL); if (verbose) { diff --git a/builtin/credential-cache--daemon.c b/builtin/credential-cache--daemon.c index 5065ff4660..65cc619bec 100644 --- a/builtin/credential-cache--daemon.c +++ b/builtin/credential-cache--daemon.c @@ -307,7 +307,7 @@ int cmd_credential_cache_daemon(int argc, OPT_END() }; - git_config_get_bool("credentialcache.ignoresighup", &ignore_sighup); + repo_config_get_bool(the_repository, "credentialcache.ignoresighup", &ignore_sighup); argc = parse_options(argc, argv, prefix, options, usage, 0); socket_path = argv[0]; diff --git a/builtin/credential-store.c b/builtin/credential-store.c index e669e99dbf..b74e06cc93 100644 --- a/builtin/credential-store.c +++ b/builtin/credential-store.c @@ -66,7 +66,7 @@ static void rewrite_credential_file(const char *fn, struct credential *c, { int timeout_ms = 1000; - git_config_get_int("credentialstore.locktimeoutms", &timeout_ms); + repo_config_get_int(the_repository, "credentialstore.locktimeoutms", &timeout_ms); if (hold_lock_file_for_update_timeout(&credential_lock, fn, 0, timeout_ms) < 0) die_errno(_("unable to get credential storage lock in %d ms"), timeout_ms); if (extra) diff --git a/builtin/credential.c b/builtin/credential.c index 2e11b15dde..a295c80b36 100644 --- a/builtin/credential.c +++ b/builtin/credential.c @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "credential.h" #include "builtin.h" +#include "environment.h" #include "config.h" static const char usage_msg[] = @@ -16,7 +17,7 @@ int cmd_credential(int argc, const char *op; struct credential c = CREDENTIAL_INIT; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); show_usage_if_asked(argc, argv, usage_msg); if (argc != 2) diff --git a/builtin/describe.c b/builtin/describe.c index fbf305d762..fbe78ace66 100644 --- a/builtin/describe.c +++ b/builtin/describe.c @@ -23,6 +23,7 @@ #include "list-objects.h" #include "commit-slab.h" #include "wildmatch.h" +#include "prio-queue.h" #define MAX_TAGS (FLAG_BITS - 1) #define DEFAULT_CANDIDATES 10 @@ -249,24 +250,62 @@ static int compare_pt(const void *a_, const void *b_) return 0; } -static unsigned long finish_depth_computation( - struct commit_list **list, - struct possible_tag *best) +struct lazy_queue { + struct prio_queue queue; + bool get_pending; +}; + +#define LAZY_QUEUE_INIT { { compare_commits_by_commit_date }, false } + +static void *lazy_queue_get(struct lazy_queue *queue) +{ + if (queue->get_pending) + prio_queue_get(&queue->queue); + else + queue->get_pending = true; + return prio_queue_peek(&queue->queue); +} + +static void lazy_queue_put(struct lazy_queue *queue, void *thing) +{ + if (queue->get_pending) + prio_queue_replace(&queue->queue, thing); + else + prio_queue_put(&queue->queue, thing); + queue->get_pending = false; +} + +static bool lazy_queue_empty(const struct lazy_queue *queue) +{ + return queue->queue.nr == (queue->get_pending ? 1 : 0); +} + +static void lazy_queue_clear(struct lazy_queue *queue) +{ + clear_prio_queue(&queue->queue); + queue->get_pending = false; +} + +static bool all_have_flag(const struct lazy_queue *queue, unsigned flag) +{ + for (size_t i = queue->get_pending ? 1 : 0; i < queue->queue.nr; i++) { + struct commit *commit = queue->queue.array[i].data; + if (!(commit->object.flags & flag)) + return false; + } + return true; +} + +static unsigned long finish_depth_computation(struct lazy_queue *queue, + struct possible_tag *best) { unsigned long seen_commits = 0; - while (*list) { - struct commit *c = pop_commit(list); + while (!lazy_queue_empty(queue)) { + struct commit *c = lazy_queue_get(queue); struct commit_list *parents = c->parents; seen_commits++; if (c->object.flags & best->flag_within) { - struct commit_list *a = *list; - while (a) { - struct commit *i = a->item; - if (!(i->object.flags & best->flag_within)) - break; - a = a->next; - } - if (!a) + if (all_have_flag(queue, best->flag_within)) break; } else best->depth++; @@ -274,7 +313,7 @@ static unsigned long finish_depth_computation( struct commit *p = parents->item; repo_parse_commit(the_repository, p); if (!(p->object.flags & SEEN)) - commit_list_insert_by_date(p, list); + lazy_queue_put(queue, p); p->object.flags |= c->object.flags; parents = parents->next; } @@ -313,18 +352,16 @@ static void append_suffix(int depth, const struct object_id *oid, struct strbuf repo_find_unique_abbrev(the_repository, oid, abbrev)); } -static void describe_commit(struct object_id *oid, struct strbuf *dst) +static void describe_commit(struct commit *cmit, struct strbuf *dst) { - struct commit *cmit, *gave_up_on = NULL; - struct commit_list *list; + struct commit *gave_up_on = NULL; + struct lazy_queue queue = LAZY_QUEUE_INIT; struct commit_name *n; struct possible_tag all_matches[MAX_TAGS]; unsigned int match_cnt = 0, annotated_cnt = 0, cur_match; unsigned long seen_commits = 0; unsigned int unannotated_cnt = 0; - cmit = lookup_commit_reference(the_repository, oid); - n = find_commit_name(&cmit->object.oid); if (n && (tags || all || n->prio == 2)) { /* @@ -332,7 +369,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) */ append_name(n, dst); if (n->misnamed || longformat) - append_suffix(0, n->tag ? get_tagged_oid(n->tag) : oid, dst); + append_suffix(0, n->tag ? get_tagged_oid(n->tag) : &cmit->object.oid, dst); if (suffix) strbuf_addstr(dst, suffix); return; @@ -359,11 +396,10 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) have_util = 1; } - list = NULL; cmit->object.flags = SEEN; - commit_list_insert(cmit, &list); - while (list) { - struct commit *c = pop_commit(&list); + lazy_queue_put(&queue, cmit); + while (!lazy_queue_empty(&queue)) { + struct commit *c = lazy_queue_get(&queue); struct commit_list *parents = c->parents; struct commit_name **slot; @@ -397,7 +433,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) t->depth++; } /* Stop if last remaining path already covered by best candidate(s) */ - if (annotated_cnt && !list) { + if (annotated_cnt && lazy_queue_empty(&queue)) { int best_depth = INT_MAX; unsigned best_within = 0; for (cur_match = 0; cur_match < match_cnt; cur_match++) { @@ -420,7 +456,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) struct commit *p = parents->item; repo_parse_commit(the_repository, p); if (!(p->object.flags & SEEN)) - commit_list_insert_by_date(p, &list); + lazy_queue_put(&queue, p); p->object.flags |= c->object.flags; parents = parents->next; @@ -435,6 +471,7 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) strbuf_add_unique_abbrev(dst, cmit_oid, abbrev); if (suffix) strbuf_addstr(dst, suffix); + lazy_queue_clear(&queue); return; } if (unannotated_cnt) @@ -450,11 +487,11 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) QSORT(all_matches, match_cnt, compare_pt); if (gave_up_on) { - commit_list_insert_by_date(gave_up_on, &list); + lazy_queue_put(&queue, gave_up_on); seen_commits--; } - seen_commits += finish_depth_computation(&list, &all_matches[0]); - free_commit_list(list); + seen_commits += finish_depth_computation(&queue, &all_matches[0]); + lazy_queue_clear(&queue); if (debug) { static int label_width = -1; @@ -489,8 +526,8 @@ static void describe_commit(struct object_id *oid, struct strbuf *dst) } struct process_commit_data { - struct object_id current_commit; - struct object_id looking_for; + struct commit *current_commit; + const struct object_id *looking_for; struct strbuf *dst; struct rev_info *revs; }; @@ -498,30 +535,38 @@ struct process_commit_data { static void process_commit(struct commit *commit, void *data) { struct process_commit_data *pcd = data; - pcd->current_commit = commit->object.oid; + pcd->current_commit = commit; } static void process_object(struct object *obj, const char *path, void *data) { struct process_commit_data *pcd = data; - if (oideq(&pcd->looking_for, &obj->oid) && !pcd->dst->len) { + if (oideq(pcd->looking_for, &obj->oid) && !pcd->dst->len) { reset_revision_walk(); - describe_commit(&pcd->current_commit, pcd->dst); - strbuf_addf(pcd->dst, ":%s", path); + if (pcd->current_commit) { + describe_commit(pcd->current_commit, pcd->dst); + strbuf_addf(pcd->dst, ":%s", path); + } free_commit_list(pcd->revs->commits); pcd->revs->commits = NULL; } } -static void describe_blob(struct object_id oid, struct strbuf *dst) +static void describe_blob(const struct object_id *oid, struct strbuf *dst) { struct rev_info revs; struct strvec args = STRVEC_INIT; - struct process_commit_data pcd = { *null_oid(the_hash_algo), oid, dst, &revs}; + struct object_id head_oid; + struct process_commit_data pcd = { NULL, oid, dst, &revs}; + + if (repo_get_oid(the_repository, "HEAD", &head_oid)) + die(_("cannot search for blob '%s' on an unborn branch"), + oid_to_hex(oid)); strvec_pushl(&args, "internal: The first arg is not parsed", - "--objects", "--in-commit-order", "--reverse", "HEAD", + "--objects", "--in-commit-order", "--reverse", + oid_to_hex(&head_oid), NULL); repo_init_revisions(the_repository, &revs, NULL); @@ -535,6 +580,9 @@ static void describe_blob(struct object_id oid, struct strbuf *dst) reset_revision_walk(); release_revisions(&revs); strvec_clear(&args); + + if (!dst->len) + die(_("blob '%s' not reachable from HEAD"), oid_to_hex(oid)); } static void describe(const char *arg, int last_one) @@ -551,10 +599,10 @@ static void describe(const char *arg, int last_one) cmit = lookup_commit_reference_gently(the_repository, &oid, 1); if (cmit) - describe_commit(&oid, &sb); + describe_commit(cmit, &sb); else if (odb_read_object_info(the_repository->objects, &oid, NULL) == OBJ_BLOB) - describe_blob(oid, &sb); + describe_blob(&oid, &sb); else die(_("%s is neither a commit nor blob"), arg); @@ -623,7 +671,7 @@ int cmd_describe(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, describe_usage, 0); if (abbrev < 0) abbrev = DEFAULT_ABBREV; diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 99b1749723..ea91347ce2 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -31,7 +31,7 @@ int cmd_diff_files(int argc, show_usage_if_asked(argc, argv, diff_files_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff-index.c b/builtin/diff-index.c index 81c0bc8ed7..522dacfc4c 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -28,7 +28,7 @@ int cmd_diff_index(int argc, show_usage_if_asked(argc, argv, diff_cache_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index e31cc797fe..49dd4d00eb 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -124,7 +124,7 @@ int cmd_diff_tree(int argc, show_usage_if_asked(argc, argv, diff_tree_usage); - git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ + repo_config(the_repository, git_diff_basic_config, NULL); /* no "diff" UI options */ prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/diff.c b/builtin/diff.c index eebffe36cc..0b23c41456 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -486,7 +486,22 @@ int cmd_diff(int argc, repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT); init_diff_ui_defaults(); - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); + + /* + * If we are ignoring the fact that our current directory may + * be part of a working tree controlled by a Git repository to + * pretend to be a "better GNU diff", we should undo the + * effect of the setup code that did a chdir() to the top of + * the working tree. Where we came from is recorded in the + * prefix. + */ + if (no_index && prefix) { + if (chdir(prefix)) + die(_("cannot come back to cwd")); + prefix = NULL; + } + prefix = precompose_argv_prefix(argc, argv, prefix); repo_init_revisions(the_repository, &rev, prefix); diff --git a/builtin/fast-export.c b/builtin/fast-export.c index f4169dc5f3..c06ee0b213 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" @@ -1361,7 +1362,7 @@ int cmd_fast_export(int argc, usage_with_options (fast_export_usage, options); /* we handle encodings */ - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); init_revision_sources(&revision_sources); diff --git a/builtin/fast-import.c b/builtin/fast-import.c index 6e7d0c3449..2c35f9345d 100644 --- a/builtin/fast-import.c +++ b/builtin/fast-import.c @@ -822,11 +822,11 @@ static char *keep_pack(const char *curr_index_name) die_errno("failed to write keep file"); odb_pack_name(pack_data->repo, &name, pack_data->hash, "pack"); - if (finalize_object_file(pack_data->pack_name, name.buf)) + if (finalize_object_file(pack_data->repo, pack_data->pack_name, name.buf)) die("cannot store pack file"); odb_pack_name(pack_data->repo, &name, pack_data->hash, "idx"); - if (finalize_object_file(curr_index_name, name.buf)) + if (finalize_object_file(pack_data->repo, curr_index_name, name.buf)) die("cannot store index file"); free((void *)curr_index_name); return strbuf_detach(&name, NULL); @@ -3592,25 +3592,25 @@ static void git_pack_config(void) int limit; unsigned long packsizelimit_value; - if (!git_config_get_ulong("pack.depth", &max_depth)) { + if (!repo_config_get_ulong(the_repository, "pack.depth", &max_depth)) { if (max_depth > MAX_DEPTH) max_depth = MAX_DEPTH; } - if (!git_config_get_int("pack.indexversion", &indexversion_value)) { + if (!repo_config_get_int(the_repository, "pack.indexversion", &indexversion_value)) { pack_idx_opts.version = indexversion_value; if (pack_idx_opts.version > 2) git_die_config(the_repository, "pack.indexversion", "bad pack.indexVersion=%"PRIu32, pack_idx_opts.version); } - if (!git_config_get_ulong("pack.packsizelimit", &packsizelimit_value)) + if (!repo_config_get_ulong(the_repository, "pack.packsizelimit", &packsizelimit_value)) max_packsize = packsizelimit_value; - if (!git_config_get_int("fastimport.unpacklimit", &limit)) + if (!repo_config_get_int(the_repository, "fastimport.unpacklimit", &limit)) unpack_limit = limit; - else if (!git_config_get_int("transfer.unpacklimit", &limit)) + else if (!repo_config_get_int(the_repository, "transfer.unpacklimit", &limit)) unpack_limit = limit; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } static const char fast_import_usage[] = diff --git a/builtin/fetch.c b/builtin/fetch.c index 87a0cca799..24645c4653 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -1995,7 +1995,7 @@ static int add_remote_or_group(const char *name, struct string_list *list) struct remote_group_data g; g.name = name; g.list = list; - git_config(get_remote_group, &g); + repo_config(the_repository, get_remote_group, &g); if (list->nr == prev_nr) { struct remote *remote = remote_get(name); if (!remote_is_configured(remote, 0)) @@ -2417,7 +2417,7 @@ int cmd_fetch(int argc, free(anon); } - git_config(git_fetch_config, &config); + repo_config(the_repository, git_fetch_config, &config); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -2508,7 +2508,7 @@ int cmd_fetch(int argc, if (!max_jobs) max_jobs = online_cpus(); - if (!git_config_get_string_tmp("fetch.bundleuri", &bundle_uri) && + if (!repo_config_get_string_tmp(the_repository, "fetch.bundleuri", &bundle_uri) && fetch_bundle_uri(the_repository, bundle_uri, NULL)) warning(_("failed to fetch bundles from '%s'"), bundle_uri); @@ -2683,12 +2683,12 @@ int cmd_fetch(int argc, * but respect config settings disabling it. */ int opt_val; - if (git_config_get_int("gc.autopacklimit", &opt_val)) + if (repo_config_get_int(the_repository, "gc.autopacklimit", &opt_val)) opt_val = -1; if (opt_val != 0) git_config_push_parameter("gc.autoPackLimit=1"); - if (git_config_get_int("maintenance.incremental-repack.auto", &opt_val)) + if (repo_config_get_int(the_repository, "maintenance.incremental-repack.auto", &opt_val)) opt_val = -1; if (opt_val != 0) git_config_push_parameter("maintenance.incremental-repack.auto=-1"); diff --git a/builtin/fmt-merge-msg.c b/builtin/fmt-merge-msg.c index 3b6aac2cf7..cf4273a52c 100644 --- a/builtin/fmt-merge-msg.c +++ b/builtin/fmt-merge-msg.c @@ -1,4 +1,3 @@ -#define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" #include "fmt-merge-msg.h" @@ -13,12 +12,13 @@ static const char * const fmt_merge_msg_usage[] = { int cmd_fmt_merge_msg(int argc, const char **argv, const char *prefix, - struct repository *repo UNUSED) + struct repository *repo) { char *inpath = NULL; const char *message = NULL; char *into_name = NULL; int shortlog_len = -1; + int merge_log_config = -1; struct option options[] = { { .type = OPTION_INTEGER, @@ -53,7 +53,7 @@ int cmd_fmt_merge_msg(int argc, int ret; struct fmt_merge_msg_opts opts; - git_config(fmt_merge_msg_config, NULL); + repo_config(repo, fmt_merge_msg_config, &merge_log_config); argc = parse_options(argc, argv, prefix, options, fmt_merge_msg_usage, 0); if (argc > 0) diff --git a/builtin/for-each-ref.c b/builtin/for-each-ref.c index 3d2207ec77..4a2fc421db 100644 --- a/builtin/for-each-ref.c +++ b/builtin/for-each-ref.c @@ -1,6 +1,8 @@ #include "builtin.h" #include "commit.h" #include "config.h" +#include "environment.h" +#include "for-each-ref.h" #include "gettext.h" #include "object.h" #include "parse-options.h" @@ -8,18 +10,7 @@ #include "strbuf.h" #include "strvec.h" -static char const * const for_each_ref_usage[] = { - N_("git for-each-ref [<options>] [<pattern>]"), - N_("git for-each-ref [--points-at <object>]"), - N_("git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]"), - N_("git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]"), - NULL -}; - -int cmd_for_each_ref(int argc, - const char **argv, - const char *prefix, - struct repository *repo) +int for_each_ref_core(int argc, const char **argv, const char *prefix, struct repository *repo, const char *const *usage) { struct ref_sorting *sorting; struct string_list sorting_options = STRING_LIST_INIT_DUP; @@ -44,6 +35,7 @@ int cmd_for_each_ref(int argc, OPT_GROUP(""), OPT_INTEGER( 0 , "count", &format.array_opts.max_count, N_("show only <n> matched refs")), OPT_STRING( 0 , "format", &format.format, N_("format"), N_("format to use for the output")), + OPT_STRING( 0 , "start-after", &filter.start_after, N_("marker"), N_("start iteration after the provided marker")), OPT__COLOR(&format.use_color, N_("respect format colors")), OPT_REF_FILTER_EXCLUDE(&filter), OPT_REF_SORT(&sorting_options), @@ -67,17 +59,20 @@ int cmd_for_each_ref(int argc, /* Set default (refname) sorting */ string_list_append(&sorting_options, "refname"); - parse_options(argc, argv, prefix, opts, for_each_ref_usage, 0); + parse_options(argc, argv, prefix, opts, usage, 0); if (format.array_opts.max_count < 0) { error("invalid --count argument: `%d'", format.array_opts.max_count); - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); } if (HAS_MULTI_BITS(format.quote_style)) { error("more than one quoting style?"); - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); } if (verify_ref_format(&format)) - usage_with_options(for_each_ref_usage, opts); + usage_with_options(usage, opts); + + if (filter.start_after && sorting_options.nr > 1) + die(_("cannot use --start-after with custom sort options")); sorting = ref_sorting_options(&sorting_options); ref_sorting_set_sort_flags_all(sorting, REF_SORTING_ICASE, icase); @@ -100,6 +95,9 @@ int cmd_for_each_ref(int argc, filter.name_patterns = argv; } + if (filter.start_after && filter.name_patterns && filter.name_patterns[0]) + die(_("cannot use --start-after with patterns")); + if (include_root_refs) flags |= FILTER_REFS_ROOT_REFS | FILTER_REFS_DETACHED_HEAD; @@ -111,3 +109,16 @@ int cmd_for_each_ref(int argc, strvec_clear(&vec); return 0; } + +int cmd_for_each_ref(int argc, + const char **argv, + const char *prefix, + struct repository *repo) +{ + static char const * const for_each_ref_usage[] = { + N_("git for-each-ref " COMMON_USAGE_FOR_EACH_REF), + NULL + }; + + return for_each_ref_core(argc, argv, prefix, repo, for_each_ref_usage); +} diff --git a/builtin/fsck.c b/builtin/fsck.c index 0084cf7400..d2eb9d4fbe 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -393,7 +393,8 @@ static void check_connectivity(void) * and ignore any that weren't present in our earlier * traversal. */ - for_each_loose_object(mark_loose_unreachable_referents, NULL, 0); + for_each_loose_object(the_repository->objects, + mark_loose_unreachable_referents, NULL, 0); for_each_packed_object(the_repository, mark_packed_unreachable_referents, NULL, @@ -502,13 +503,12 @@ static void fsck_handle_reflog_oid(const char *refname, struct object_id *oid, } } -static int fsck_handle_reflog_ent(struct object_id *ooid, struct object_id *noid, +static int fsck_handle_reflog_ent(const char *refname, + struct object_id *ooid, struct object_id *noid, const char *email UNUSED, timestamp_t timestamp, int tz UNUSED, - const char *message UNUSED, void *cb_data) + const char *message UNUSED, void *cb_data UNUSED) { - const char *refname = cb_data; - if (verbose) fprintf_ln(stderr, _("Checking reflog %s->%s"), oid_to_hex(ooid), oid_to_hex(noid)); @@ -525,7 +525,7 @@ static int fsck_handle_reflog(const char *logname, void *cb_data) strbuf_worktree_ref(cb_data, &refname, logname); refs_for_each_reflog_ent(get_main_ref_store(the_repository), refname.buf, fsck_handle_reflog_ent, - refname.buf); + NULL); strbuf_release(&refname); return 0; } @@ -632,7 +632,7 @@ static int fsck_loose(const struct object_id *oid, const char *path, oi.sizep = &size; oi.typep = &type; - if (read_loose_object(path, oid, &real_oid, &contents, &oi) < 0) { + if (read_loose_object(the_repository, path, oid, &real_oid, &contents, &oi) < 0) { if (contents && !oideq(&real_oid, oid)) err = error(_("%s: hash-path mismatch, found at: %s"), oid_to_hex(&real_oid), path); @@ -687,7 +687,7 @@ static int fsck_subdir(unsigned int nr, const char *path UNUSED, void *data) return 0; } -static void fsck_object_dir(const char *path) +static void fsck_source(struct odb_source *source) { struct progress *progress = NULL; struct for_each_loose_cb cb_data = { @@ -701,8 +701,8 @@ static void fsck_object_dir(const char *path) progress = start_progress(the_repository, _("Checking object directories"), 256); - for_each_loose_file_in_objdir(path, fsck_loose, fsck_cruft, fsck_subdir, - &cb_data); + for_each_loose_file_in_source(source, fsck_loose, + fsck_cruft, fsck_subdir, &cb_data); display_progress(progress, 256); stop_progress(&progress); } @@ -987,20 +987,21 @@ int cmd_fsck(int argc, if (name_objects) fsck_enable_object_names(&fsck_walk_options); - git_config(git_fsck_config, &fsck_obj_options); + repo_config(the_repository, git_fsck_config, &fsck_obj_options); prepare_repo_settings(the_repository); if (check_references) fsck_refs(the_repository); if (connectivity_only) { - for_each_loose_object(mark_loose_for_connectivity, NULL, 0); + for_each_loose_object(the_repository->objects, + mark_loose_for_connectivity, NULL, 0); for_each_packed_object(the_repository, mark_packed_for_connectivity, NULL, 0); } else { odb_prepare_alternates(the_repository->objects); for (source = the_repository->objects->sources; source; source = source->next) - fsck_object_dir(source->path); + fsck_source(source); if (check_full) { struct packed_git *p; diff --git a/builtin/fsmonitor--daemon.c b/builtin/fsmonitor--daemon.c index 0820e524f1..242c594646 100644 --- a/builtin/fsmonitor--daemon.c +++ b/builtin/fsmonitor--daemon.c @@ -5,6 +5,7 @@ #include "abspath.h" #include "config.h" #include "dir.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "fsmonitor-ll.h" @@ -1547,7 +1548,7 @@ int cmd_fsmonitor__daemon(int argc, OPT_END() }; - git_config(fsmonitor_config, NULL); + repo_config(the_repository, fsmonitor_config, NULL); argc = parse_options(argc, argv, prefix, options, builtin_fsmonitor__daemon_usage, 0); diff --git a/builtin/gc.c b/builtin/gc.c index fab8f4dd4f..03ae4926b2 100644 --- a/builtin/gc.c +++ b/builtin/gc.c @@ -114,7 +114,7 @@ static int gc_config_is_timestamp_never(const char *var) const char *value; timestamp_t expire; - if (!git_config_get_value(var, &value) && value) { + if (!repo_config_get_value(the_repository, var, &value) && value) { if (parse_expiry_date(value, &expire)) die(_("failed to parse '%s' value '%s'"), var, value); return expire == 0; @@ -178,7 +178,7 @@ static void gc_config(struct gc_config *cfg) char *owned = NULL; unsigned long ulongval; - if (!git_config_get_value("gc.packrefs", &value)) { + if (!repo_config_get_value(the_repository, "gc.packrefs", &value)) { if (value && !strcmp(value, "notbare")) cfg->pack_refs = -1; else @@ -189,13 +189,13 @@ static void gc_config(struct gc_config *cfg) gc_config_is_timestamp_never("gc.reflogexpireunreachable")) cfg->prune_reflogs = 0; - git_config_get_int("gc.aggressivewindow", &cfg->aggressive_window); - git_config_get_int("gc.aggressivedepth", &cfg->aggressive_depth); - git_config_get_int("gc.auto", &cfg->gc_auto_threshold); - git_config_get_int("gc.autopacklimit", &cfg->gc_auto_pack_limit); - git_config_get_bool("gc.autodetach", &cfg->detach_auto); - git_config_get_bool("gc.cruftpacks", &cfg->cruft_packs); - git_config_get_ulong("gc.maxcruftsize", &cfg->max_cruft_size); + repo_config_get_int(the_repository, "gc.aggressivewindow", &cfg->aggressive_window); + repo_config_get_int(the_repository, "gc.aggressivedepth", &cfg->aggressive_depth); + repo_config_get_int(the_repository, "gc.auto", &cfg->gc_auto_threshold); + repo_config_get_int(the_repository, "gc.autopacklimit", &cfg->gc_auto_pack_limit); + repo_config_get_bool(the_repository, "gc.autodetach", &cfg->detach_auto); + repo_config_get_bool(the_repository, "gc.cruftpacks", &cfg->cruft_packs); + repo_config_get_ulong(the_repository, "gc.maxcruftsize", &cfg->max_cruft_size); if (!repo_config_get_expiry(the_repository, "gc.pruneexpire", &owned)) { free(cfg->prune_expire); @@ -212,23 +212,23 @@ static void gc_config(struct gc_config *cfg) cfg->gc_log_expire = owned; } - git_config_get_ulong("gc.bigpackthreshold", &cfg->big_pack_threshold); - git_config_get_ulong("pack.deltacachesize", &cfg->max_delta_cache_size); + repo_config_get_ulong(the_repository, "gc.bigpackthreshold", &cfg->big_pack_threshold); + repo_config_get_ulong(the_repository, "pack.deltacachesize", &cfg->max_delta_cache_size); - if (!git_config_get_ulong("core.deltabasecachelimit", &ulongval)) + if (!repo_config_get_ulong(the_repository, "core.deltabasecachelimit", &ulongval)) cfg->delta_base_cache_limit = ulongval; - if (!git_config_get_string("gc.repackfilter", &owned)) { + if (!repo_config_get_string(the_repository, "gc.repackfilter", &owned)) { free(cfg->repack_filter); cfg->repack_filter = owned; } - if (!git_config_get_string("gc.repackfilterto", &owned)) { + if (!repo_config_get_string(the_repository, "gc.repackfilterto", &owned)) { free(cfg->repack_filter_to); cfg->repack_filter_to = owned; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } enum schedule_priority { @@ -312,7 +312,8 @@ struct count_reflog_entries_data { size_t limit; }; -static int count_reflog_entries(struct object_id *old_oid, struct object_id *new_oid, +static int count_reflog_entries(const char *refname UNUSED, + struct object_id *old_oid, struct object_id *new_oid, const char *committer, timestamp_t timestamp, int tz, const char *msg, void *cb_data) { @@ -332,7 +333,7 @@ static int reflog_expire_condition(struct gc_config *cfg UNUSED) }; int limit = 100; - git_config_get_int("maintenance.reflog-expire.auto", &limit); + repo_config_get_int(the_repository, "maintenance.reflog-expire.auto", &limit); if (!limit) return 0; if (limit < 0) @@ -346,6 +347,7 @@ static int reflog_expire_condition(struct gc_config *cfg UNUSED) count_reflog_entries, &data); reflog_expiry_cleanup(&data.policy); + reflog_clear_expire_config(&data.policy.opts); return data.count >= data.limit; } @@ -378,7 +380,7 @@ static int worktree_prune_condition(struct gc_config *cfg) struct dirent *d; DIR *dir = NULL; - git_config_get_int("maintenance.worktree-prune.auto", &limit); + repo_config_get_int(the_repository, "maintenance.worktree-prune.auto", &limit); if (limit <= 0) { should_prune = limit < 0; goto out; @@ -423,7 +425,7 @@ static int rerere_gc_condition(struct gc_config *cfg UNUSED) int should_gc = 0, limit = 1; DIR *dir = NULL; - git_config_get_int("maintenance.rerere-gc.auto", &limit); + repo_config_get_int(the_repository, "maintenance.rerere-gc.auto", &limit); if (limit <= 0) { should_gc = limit < 0; goto out; @@ -1161,8 +1163,8 @@ static int should_write_commit_graph(struct gc_config *cfg UNUSED) data.num_not_in_graph = 0; data.limit = 100; - git_config_get_int("maintenance.commit-graph.auto", - &data.limit); + repo_config_get_int(the_repository, "maintenance.commit-graph.auto", + &data.limit); if (!data.limit) return 0; @@ -1300,15 +1302,15 @@ static int loose_object_auto_condition(struct gc_config *cfg UNUSED) { int count = 0; - git_config_get_int("maintenance.loose-objects.auto", - &loose_object_auto_limit); + repo_config_get_int(the_repository, "maintenance.loose-objects.auto", + &loose_object_auto_limit); if (!loose_object_auto_limit) return 0; if (loose_object_auto_limit < 0) return 1; - return for_each_loose_file_in_objdir(the_repository->objects->sources->path, + return for_each_loose_file_in_source(the_repository->objects->sources, loose_object_count, NULL, NULL, &count); } @@ -1343,7 +1345,7 @@ static int pack_loose(struct maintenance_run_opts *opts) * Do not start pack-objects process * if there are no loose objects. */ - if (!for_each_loose_file_in_objdir(r->objects->sources->path, + if (!for_each_loose_file_in_source(r->objects->sources, bail_on_loose, NULL, NULL, NULL)) return 0; @@ -1383,11 +1385,9 @@ static int pack_loose(struct maintenance_run_opts *opts) else if (data.batch_size > 0) data.batch_size--; /* Decrease for equality on limit. */ - for_each_loose_file_in_objdir(r->objects->sources->path, + for_each_loose_file_in_source(r->objects->sources, write_loose_object_to_stdin, - NULL, - NULL, - &data); + NULL, NULL, &data); fclose(data.in); @@ -1415,8 +1415,8 @@ static int incremental_repack_auto_condition(struct gc_config *cfg UNUSED) if (!the_repository->settings.core_multi_pack_index) return 0; - git_config_get_int("maintenance.incremental-repack.auto", - &incremental_repack_auto_limit); + repo_config_get_int(the_repository, "maintenance.incremental-repack.auto", + &incremental_repack_auto_limit); if (!incremental_repack_auto_limit) return 0; @@ -1765,7 +1765,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, if (opts->schedule) { strategy = none_strategy; - if (!git_config_get_string_tmp("maintenance.strategy", &config_str)) { + if (!repo_config_get_string_tmp(the_repository, "maintenance.strategy", &config_str)) { if (!strcasecmp(config_str, "incremental")) strategy = incremental_strategy; } @@ -1779,7 +1779,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, strbuf_reset(&config_name); strbuf_addf(&config_name, "maintenance.%s.enabled", tasks[i].name); - if (!git_config_get_bool(config_name.buf, &config_value)) + if (!repo_config_get_bool(the_repository, config_name.buf, &config_value)) strategy.tasks[i].enabled = config_value; if (!strategy.tasks[i].enabled) continue; @@ -1788,7 +1788,7 @@ static void initialize_task_config(struct maintenance_run_opts *opts, strbuf_reset(&config_name); strbuf_addf(&config_name, "maintenance.%s.schedule", tasks[i].name); - if (!git_config_get_string_tmp(config_name.buf, &config_str)) + if (!repo_config_get_string_tmp(the_repository, config_name.buf, &config_str)) strategy.tasks[i].schedule = parse_schedule(config_str); if (strategy.tasks[i].schedule < opts->schedule) continue; @@ -1913,13 +1913,13 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, options); /* Disable foreground maintenance */ - git_config_set("maintenance.auto", "false"); + repo_config_set(the_repository, "maintenance.auto", "false"); /* Set maintenance strategy, if unset */ - if (git_config_get("maintenance.strategy")) - git_config_set("maintenance.strategy", "incremental"); + if (repo_config_get(the_repository, "maintenance.strategy")) + repo_config_set(the_repository, "maintenance.strategy", "incremental"); - if (!git_config_get_string_multi(key, &list)) { + if (!repo_config_get_string_multi(the_repository, key, &list)) { for_each_string_list_item(item, list) { if (!strcmp(maintpath, item->string)) { found = 1; @@ -1938,7 +1938,7 @@ static int maintenance_register(int argc, const char **argv, const char *prefix, } if (!config_file) die(_("$HOME not set")); - rc = git_config_set_multivar_in_file_gently( + rc = repo_config_set_multivar_in_file_gently(the_repository, config_file, "maintenance.repo", maintpath, CONFIG_REGEX_NONE, NULL, 0); free(global_config_file); @@ -1988,7 +1988,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi } if (!(config_file ? git_configset_get_string_multi(&cs, key, &list) - : git_config_get_string_multi(key, &list))) { + : repo_config_get_string_multi(the_repository, key, &list))) { for_each_string_list_item(item, list) { if (!strcmp(maintpath, item->string)) { found = 1; @@ -2007,7 +2007,7 @@ static int maintenance_unregister(int argc, const char **argv, const char *prefi } if (!config_file) die(_("$HOME not set")); - rc = git_config_set_multivar_in_file_gently( + rc = repo_config_set_multivar_in_file_gently(the_repository, config_file, key, NULL, maintpath, NULL, CONFIG_FLAGS_MULTI_REPLACE | CONFIG_FLAGS_FIXED_VALUE); free(global_config_file); @@ -2344,7 +2344,7 @@ static int launchctl_schedule_plist(const char *exec_path, enum schedule_priorit die(_("failed to create directories for '%s'"), filename); if ((long)lock_file_timeout_ms < 0 && - git_config_get_ulong("gc.launchctlplistlocktimeoutms", + repo_config_get_ulong(the_repository, "gc.launchctlplistlocktimeoutms", &lock_file_timeout_ms)) lock_file_timeout_ms = 150; diff --git a/builtin/grep.c b/builtin/grep.c index 39273d9c0f..5df6537333 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "abspath.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "config.h" @@ -1035,7 +1036,7 @@ int cmd_grep(int argc, grep_prefix = prefix; grep_init(&opt, the_repository); - git_config(grep_cmd_config, &opt); + repo_config(the_repository, grep_cmd_config, &opt); /* * If there is no -- then the paths must exist in the working @@ -1058,7 +1059,7 @@ int cmd_grep(int argc, if (use_index && !startup_info->have_repository) { int fallback = 0; - git_config_get_bool("grep.fallbacktonoindex", &fallback); + repo_config_get_bool(the_repository, "grep.fallbacktonoindex", &fallback); if (fallback) use_index = 0; else diff --git a/builtin/hash-object.c b/builtin/hash-object.c index ddf281413a..5d900a6b8c 100644 --- a/builtin/hash-object.c +++ b/builtin/hash-object.c @@ -8,6 +8,7 @@ #include "builtin.h" #include "abspath.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-file.h" @@ -111,7 +112,7 @@ int cmd_hash_object(int argc, vpath = vpath_free; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (stdin_paths) { if (hashstdin) diff --git a/builtin/help.c b/builtin/help.c index c257079ceb..c09cbc8912 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -6,6 +6,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "exec-cmd.h" #include "gettext.h" #include "pager.h" @@ -210,7 +211,7 @@ static enum help_format parse_help_format(const char *format) if (!strcmp(format, "web") || !strcmp(format, "html")) return HELP_FORMAT_WEB; /* - * Please update _git_config() in git-completion.bash when you + * Please update _repo_config() in git-completion.bash when you * add new help formats. */ die(_("unrecognized help format '%s'"), format); @@ -706,7 +707,7 @@ int cmd_help(int argc, } setup_git_directory_gently(&nongit); - git_config(git_help_config, NULL); + repo_config(the_repository, git_help_config, NULL); if (parsed_help_format != HELP_FORMAT_NONE) help_format = parsed_help_format; diff --git a/builtin/hook.c b/builtin/hook.c index 672d2e37e8..7afec380d2 100644 --- a/builtin/hook.c +++ b/builtin/hook.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hook.h" #include "parse-options.h" @@ -55,7 +56,7 @@ static int run(int argc, const char **argv, const char *prefix, strvec_push(&opt.args, argv[i]); /* Need to take into account core.hooksPath */ - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); hook_name = argv[0]; if (!ignore_missing) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 0a5c8a1ac8..f91c301bba 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1598,7 +1598,7 @@ static void rename_tmp_packfile(const char **final_name, if (!*final_name || strcmp(*final_name, curr_name)) { if (!*final_name) *final_name = odb_pack_name(the_repository, name, hash, ext); - if (finalize_object_file(curr_name, *final_name)) + if (finalize_object_file(the_repository, curr_name, *final_name)) die(_("unable to rename temporary '*.%s' file to '%s'"), ext, *final_name); } else if (make_read_only_if_same) { @@ -1917,7 +1917,7 @@ int cmd_index_pack(int argc, reset_pack_idx_option(&opts); opts.flags |= WRITE_REV; - git_config(git_index_pack_config, &opts); + repo_config(the_repository, git_index_pack_config, &opts); if (prefix && chdir(prefix)) die(_("Cannot come back to cwd")); diff --git a/builtin/interpret-trailers.c b/builtin/interpret-trailers.c index 44d8ccddc9..41b0750e5a 100644 --- a/builtin/interpret-trailers.c +++ b/builtin/interpret-trailers.c @@ -6,6 +6,7 @@ */ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "string-list.h" @@ -220,7 +221,7 @@ int cmd_interpret_trailers(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_interpret_trailers_usage, 0); diff --git a/builtin/last-modified.c b/builtin/last-modified.c index 82c5739827..886ba12cb5 100644 --- a/builtin/last-modified.c +++ b/builtin/last-modified.c @@ -4,6 +4,7 @@ #include "commit-graph.h" #include "commit.h" #include "config.h" +#include "environment.h" #include "diff.h" #include "diffcore.h" #include "environment.h" diff --git a/builtin/log.c b/builtin/log.c index 24a57c20a4..c2f8bbf863 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -221,7 +221,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f struct string_list *include = decoration_filter->include_ref_pattern; const struct string_list *config_exclude; - if (!git_config_get_string_multi("log.excludeDecoration", + if (!repo_config_get_string_multi(the_repository, "log.excludeDecoration", &config_exclude)) { struct string_list_item *item; for_each_string_list_item(item, config_exclude) @@ -235,7 +235,7 @@ static void set_default_decoration_filter(struct decoration_filter *decoration_f * since the command-line takes precedent. */ if (use_default_decoration_filter && - !git_config_get_string("log.initialdecorationset", &value) && + !repo_config_get_string(the_repository, "log.initialdecorationset", &value) && !strcmp("all", value)) use_default_decoration_filter = 0; free(value); @@ -391,129 +391,6 @@ static void cmd_log_init(int argc, const char **argv, const char *prefix, cmd_log_init_finish(argc, argv, prefix, rev, opt, cfg); } -/* - * This gives a rough estimate for how many commits we - * will print out in the list. - */ -static int estimate_commit_count(struct commit_list *list) -{ - int n = 0; - - while (list) { - struct commit *commit = list->item; - unsigned int flags = commit->object.flags; - list = list->next; - if (!(flags & (TREESAME | UNINTERESTING))) - n++; - } - return n; -} - -static void show_early_header(struct rev_info *rev, const char *stage, int nr) -{ - if (rev->shown_one) { - rev->shown_one = 0; - if (rev->commit_format != CMIT_FMT_ONELINE) - putchar(rev->diffopt.line_termination); - } - fprintf(rev->diffopt.file, _("Final output: %d %s\n"), nr, stage); -} - -static struct itimerval early_output_timer; - -static void log_show_early(struct rev_info *revs, struct commit_list *list) -{ - int i = revs->early_output; - int show_header = 1; - int no_free = revs->diffopt.no_free; - - revs->diffopt.no_free = 0; - sort_in_topological_order(&list, revs->sort_order); - while (list && i) { - struct commit *commit = list->item; - switch (simplify_commit(revs, commit)) { - case commit_show: - if (show_header) { - int n = estimate_commit_count(list); - show_early_header(revs, "incomplete", n); - show_header = 0; - } - log_tree_commit(revs, commit); - i--; - break; - case commit_ignore: - break; - case commit_error: - revs->diffopt.no_free = no_free; - diff_free(&revs->diffopt); - return; - } - list = list->next; - } - - /* Did we already get enough commits for the early output? */ - if (!i) { - revs->diffopt.no_free = 0; - diff_free(&revs->diffopt); - return; - } - - /* - * ..if no, then repeat it twice a second until we - * do. - * - * NOTE! We don't use "it_interval", because if the - * reader isn't listening, we want our output to be - * throttled by the writing, and not have the timer - * trigger every second even if we're blocked on a - * reader! - */ - early_output_timer.it_value.tv_sec = 0; - early_output_timer.it_value.tv_usec = 500000; - setitimer(ITIMER_REAL, &early_output_timer, NULL); -} - -static void early_output(int signal UNUSED) -{ - show_early_output = log_show_early; -} - -static void setup_early_output(void) -{ - struct sigaction sa; - - /* - * Set up the signal handler, minimally intrusively: - * we only set a single volatile integer word (not - * using sigatomic_t - trying to avoid unnecessary - * system dependencies and headers), and using - * SA_RESTART. - */ - memset(&sa, 0, sizeof(sa)); - sa.sa_handler = early_output; - sigemptyset(&sa.sa_mask); - sa.sa_flags = SA_RESTART; - sigaction(SIGALRM, &sa, NULL); - - /* - * If we can get the whole output in less than a - * tenth of a second, don't even bother doing the - * early-output thing.. - * - * This is a one-time-only trigger. - */ - early_output_timer.it_value.tv_sec = 0; - early_output_timer.it_value.tv_usec = 100000; - setitimer(ITIMER_REAL, &early_output_timer, NULL); -} - -static void finish_early_output(struct rev_info *rev) -{ - int n = estimate_commit_count(rev->commits); - signal(SIGALRM, SIG_IGN); - show_early_header(rev, "done", n); -} - static int cmd_log_walk_no_free(struct rev_info *rev) { struct commit *commit; @@ -521,15 +398,9 @@ static int cmd_log_walk_no_free(struct rev_info *rev) int saved_dcctc = 0; int result; - if (rev->early_output) - setup_early_output(); - if (prepare_revision_walk(rev)) die(_("revision walk setup failed")); - if (rev->early_output) - finish_early_output(rev); - /* * For --check and --exit-code, the exit code is based on CHECK_FAILED * and HAS_CHANGES being accumulated in rev->diffopt, so be careful to @@ -659,10 +530,10 @@ int cmd_whatchanged(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.diff = 1; rev.simplify_history = 0; @@ -790,7 +661,7 @@ int cmd_show(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); if (the_repository->gitdir) { prepare_repo_settings(the_repository); @@ -799,7 +670,7 @@ int cmd_show(int argc, memset(&match_all, 0, sizeof(match_all)); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.diff = 1; rev.always_show_header = 1; @@ -907,11 +778,11 @@ int cmd_log_reflog(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); init_reflog_walk(&rev.reflog_info); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.verbose_header = 1; memset(&opt, 0, sizeof(opt)); @@ -952,10 +823,10 @@ int cmd_log(int argc, log_config_init(&cfg); init_diff_ui_defaults(); - git_config(git_log_config, &cfg); + repo_config(the_repository, git_log_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.always_show_header = 1; memset(&opt, 0, sizeof(opt)); @@ -2158,9 +2029,9 @@ int cmd_format_patch(int argc, format_config_init(&cfg); init_diff_ui_defaults(); init_display_notes(&cfg.notes_opt); - git_config(git_format_config, &cfg); + repo_config(the_repository, git_format_config, &cfg); repo_init_revisions(the_repository, &rev, prefix); - git_config(grep_config, &rev.grep_filter); + repo_config(the_repository, grep_config, &rev.grep_filter); rev.show_notes = cfg.show_notes; memcpy(&rev.notes_opt, &cfg.notes_opt, sizeof(cfg.notes_opt)); diff --git a/builtin/ls-files.c b/builtin/ls-files.c index ff975e7be0..b148607f7a 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "config.h" #include "convert.h" +#include "environment.h" #include "quote.h" #include "dir.h" #include "gettext.h" @@ -413,14 +414,21 @@ static void show_files(struct repository *repo, struct dir_struct *dir) if (!(show_cached || show_stage || show_deleted || show_modified)) return; - if (!show_sparse_dirs) - ensure_full_index(repo->index); - for (i = 0; i < repo->index->cache_nr; i++) { const struct cache_entry *ce = repo->index->cache[i]; struct stat st; int stat_err; + if (S_ISSPARSEDIR(ce->ce_mode) && !show_sparse_dirs) { + /* + * This is the first time we've hit a sparse dir, + * so expansion will leave the first 'i' entries + * alone. + */ + ensure_full_index(repo->index); + ce = repo->index->cache[i]; + } + construct_fullname(&fullname, repo, ce); if ((dir->flags & DIR_SHOW_IGNORED) && diff --git a/builtin/ls-tree.c b/builtin/ls-tree.c index 4d616dd528..5d55731ca3 100644 --- a/builtin/ls-tree.c +++ b/builtin/ls-tree.c @@ -7,6 +7,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" @@ -375,7 +376,7 @@ int cmd_ls_tree(int argc, struct object_context obj_context = {0}; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, ls_tree_options, ls_tree_usage, 0); diff --git a/builtin/merge-base.c b/builtin/merge-base.c index 123c81515e..3f82781245 100644 --- a/builtin/merge-base.c +++ b/builtin/merge-base.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "config.h" #include "commit.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "object-name.h" @@ -167,7 +168,7 @@ int cmd_merge_base(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, merge_base_usage, 0); if (cmdmode == 'a') { diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 9464f27562..46775d0c79 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -97,7 +97,7 @@ int cmd_merge_file(int argc, if (startup_info->have_repository) { /* Read the configuration file */ - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); if (0 <= git_xmerge_style) xmp.style = git_xmerge_style; } @@ -155,7 +155,8 @@ int cmd_merge_file(int argc, if (object_id && !to_stdout) { struct object_id oid; if (result.size) { - if (write_object_file(result.ptr, result.size, OBJ_BLOB, &oid) < 0) + if (odb_write_object(the_repository->objects, result.ptr, + result.size, OBJ_BLOB, &oid) < 0) ret = error(_("Could not write object file")); } else { oidcpy(&oid, the_hash_algo->empty_blob); diff --git a/builtin/merge-recursive.c b/builtin/merge-recursive.c index 03b5100cfa..17aa4db37a 100644 --- a/builtin/merge-recursive.c +++ b/builtin/merge-recursive.c @@ -38,7 +38,8 @@ int cmd_merge_recursive(int argc, if (argv[0] && ends_with(argv[0], "-subtree")) o.subtree_shift = ""; - if (argc == 2 && !strcmp(argv[1], "-h")) { + if (argc == 2 && (!strcmp(argv[1], "-h") || + !strcmp(argv[1], "--help-all"))) { struct strbuf msg = STRBUF_INIT; strbuf_addf(&msg, builtin_merge_recursive_usage, argv[0]); show_usage_if_asked(argc, argv, msg.buf); diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index cf8b06cadc..1c063d9a41 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" +#include "environment.h" #include "tree-walk.h" #include "xdiff-interface.h" #include "help.h" @@ -618,32 +619,34 @@ int cmd_merge_tree(int argc, "--merge-base", "--stdin"); line_termination = '\0'; while (strbuf_getline_lf(&buf, stdin) != EOF) { - struct strbuf **split; + struct string_list split = STRING_LIST_INIT_NODUP; const char *input_merge_base = NULL; - split = strbuf_split(&buf, ' '); - if (!split[0] || !split[1]) + string_list_split_in_place_f(&split, buf.buf, " ", -1, + STRING_LIST_SPLIT_TRIM); + + if (split.nr < 2) die(_("malformed input line: '%s'."), buf.buf); - strbuf_rtrim(split[0]); - strbuf_rtrim(split[1]); /* parse the merge-base */ - if (!strcmp(split[1]->buf, "--")) { - input_merge_base = split[0]->buf; + if (!strcmp(split.items[1].string, "--")) { + input_merge_base = split.items[0].string; } - if (input_merge_base && split[2] && split[3] && !split[4]) { - strbuf_rtrim(split[2]); - strbuf_rtrim(split[3]); - real_merge(&o, input_merge_base, split[2]->buf, split[3]->buf, prefix); - } else if (!input_merge_base && !split[2]) { - real_merge(&o, NULL, split[0]->buf, split[1]->buf, prefix); + if (input_merge_base && split.nr == 4) { + real_merge(&o, input_merge_base, + split.items[2].string, split.items[3].string, + prefix); + } else if (!input_merge_base && split.nr == 2) { + real_merge(&o, NULL, + split.items[0].string, split.items[1].string, + prefix); } else { die(_("malformed input line: '%s'."), buf.buf); } maybe_flush_or_die(stdout, "stdout"); - strbuf_list_free(split); + string_list_clear(&split, 0); } strbuf_release(&buf); @@ -683,7 +686,7 @@ int cmd_merge_tree(int argc, if (argc != expected_remaining_argc) usage_with_options(merge_tree_usage, mt_options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); /* Do the relevant type of merge */ if (o.mode == MODE_REAL) diff --git a/builtin/merge.c b/builtin/merge.c index 18b22c0a26..b235af730a 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -264,7 +264,7 @@ static struct option builtin_merge_options[] = { OPT_BOOL(0, "stat", &show_diffstat, N_("show a diffstat at the end of the merge")), OPT_BOOL(0, "summary", &show_diffstat, N_("(synonym to --stat)")), - OPT_CALLBACK_F(0, "compact-summary", &show_diffstat, N_("compact-summary"), + OPT_CALLBACK_F(0, "compact-summary", &show_diffstat, NULL, N_("show a compact-summary at the end of the merge"), PARSE_OPT_NOARG, option_parse_compact_summary), @@ -875,7 +875,7 @@ static void add_strategies(const char *string, unsigned attr) if (string) { struct string_list list = STRING_LIST_INIT_DUP; struct string_list_item *item; - string_list_split(&list, string, ' ', -1); + string_list_split(&list, string, " ", -1); for_each_string_list_item(item, &list) append_strategy(get_strategy(item->string)); string_list_clear(&list, 0); @@ -1374,6 +1374,7 @@ int cmd_merge(int argc, struct commit_list *remoteheads = NULL, *p; void *branch_to_free; int orig_argc = argc; + int merge_log_config = -1; show_usage_with_options_if_asked(argc, argv, builtin_merge_usage, builtin_merge_options); @@ -1392,7 +1393,7 @@ int cmd_merge(int argc, skip_prefix(branch, "refs/heads/", &branch); init_diff_ui_defaults(); - git_config(git_merge_config, NULL); + repo_config(the_repository, git_merge_config, &merge_log_config); if (!branch || is_null_oid(&head_oid)) head_commit = NULL; @@ -1862,7 +1863,7 @@ int cmd_merge(int argc, if (squash) { finish(head_commit, remoteheads, NULL, NULL); - git_test_write_commit_graph_or_die(); + git_test_write_commit_graph_or_die(the_repository->objects->sources); } else write_merge_state(remoteheads); diff --git a/builtin/mktag.c b/builtin/mktag.c index 27e649736c..7cf6e1230a 100644 --- a/builtin/mktag.c +++ b/builtin/mktag.c @@ -98,7 +98,7 @@ int cmd_mktag(int argc, fsck_set_msg_type_from_ids(&fsck_options, FSCK_MSG_EXTRA_HEADER_ENTRY, FSCK_WARN); /* config might set fsck.extraHeaderEntry=* again */ - git_config(git_fsck_config, &fsck_options); + repo_config(the_repository, git_fsck_config, &fsck_options); if (fsck_tag_standalone(NULL, buf.buf, buf.len, &fsck_options, &tagged_oid, &tagged_type)) die(_("tag on stdin did not pass our strict fsck check")); @@ -106,7 +106,7 @@ int cmd_mktag(int argc, if (verify_object_in_tag(&tagged_oid, &tagged_type) < 0) die(_("tag on stdin did not refer to a valid object")); - if (write_object_file(buf.buf, buf.len, OBJ_TAG, &result) < 0) + if (odb_write_object(the_repository->objects, buf.buf, buf.len, OBJ_TAG, &result) < 0) die(_("unable to write tag file")); strbuf_release(&buf); diff --git a/builtin/mktree.c b/builtin/mktree.c index 81df7f6099..12772303f5 100644 --- a/builtin/mktree.c +++ b/builtin/mktree.c @@ -63,7 +63,7 @@ static void write_tree(struct object_id *oid) strbuf_add(&buf, ent->oid.hash, the_hash_algo->rawsz); } - write_object_file(buf.buf, buf.len, OBJ_TREE, oid); + odb_write_object(the_repository->objects, buf.buf, buf.len, OBJ_TREE, oid); strbuf_release(&buf); } diff --git a/builtin/multi-pack-index.c b/builtin/multi-pack-index.c index aa25b06f9d..d3b9e98be3 100644 --- a/builtin/multi-pack-index.c +++ b/builtin/multi-pack-index.c @@ -2,6 +2,7 @@ #include "builtin.h" #include "abspath.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "midx.h" @@ -143,7 +144,7 @@ static int cmd_multi_pack_index_write(int argc, const char **argv, opts.flags |= MIDX_WRITE_BITMAP_HASH_CACHE; - git_config(git_multi_pack_index_write_config, NULL); + repo_config(the_repository, git_multi_pack_index_write_config, NULL); options = add_common_options(builtin_multi_pack_index_write_options); @@ -290,7 +291,7 @@ int cmd_multi_pack_index(int argc, disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (the_repository && the_repository->objects && diff --git a/builtin/mv.c b/builtin/mv.c index 07548fe96a..d43925097b 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -239,7 +239,7 @@ int cmd_mv(int argc, struct strbuf pathbuf = STRBUF_INIT; int ret; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_mv_options, builtin_mv_usage, 0); diff --git a/builtin/name-rev.c b/builtin/name-rev.c index ff199638de..74512e54a3 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -600,7 +600,7 @@ int cmd_name_rev(int argc, mem_pool_init(&string_pool, 0); init_commit_rev_name(&rev_names); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, opts, name_rev_usage, 0); #ifndef WITH_BREAKING_CHANGES diff --git a/builtin/notes.c b/builtin/notes.c index a9529b1696..9af602bdd7 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -229,7 +229,8 @@ static void prepare_note_data(const struct object_id *object, struct note_data * static void write_note_data(struct note_data *d, struct object_id *oid) { - if (write_object_file(d->buf.buf, d->buf.len, OBJ_BLOB, oid)) { + if (odb_write_object(the_repository->objects, d->buf.buf, + d->buf.len, OBJ_BLOB, oid)) { int status = die_message(_("unable to write note object")); if (d->edit_path) @@ -375,18 +376,19 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) while (strbuf_getline_lf(&buf, stdin) != EOF) { struct object_id from_obj, to_obj; - struct strbuf **split; + struct string_list split = STRING_LIST_INIT_NODUP; int err; - split = strbuf_split(&buf, ' '); - if (!split[0] || !split[1]) + string_list_split_in_place_f(&split, buf.buf, " ", -1, + STRING_LIST_SPLIT_TRIM); + if (split.nr < 2) die(_("malformed input line: '%s'."), buf.buf); - strbuf_rtrim(split[0]); - strbuf_rtrim(split[1]); - if (repo_get_oid(the_repository, split[0]->buf, &from_obj)) - die(_("failed to resolve '%s' as a valid ref."), split[0]->buf); - if (repo_get_oid(the_repository, split[1]->buf, &to_obj)) - die(_("failed to resolve '%s' as a valid ref."), split[1]->buf); + if (repo_get_oid(the_repository, split.items[0].string, &from_obj)) + die(_("failed to resolve '%s' as a valid ref."), + split.items[0].string); + if (repo_get_oid(the_repository, split.items[1].string, &to_obj)) + die(_("failed to resolve '%s' as a valid ref."), + split.items[1].string); if (rewrite_cmd) err = copy_note_for_rewrite(c, &from_obj, &to_obj); @@ -396,11 +398,11 @@ static int notes_copy_from_stdin(int force, const char *rewrite_cmd) if (err) { error(_("failed to copy notes from '%s' to '%s'"), - split[0]->buf, split[1]->buf); + split.items[0].string, split.items[1].string); ret = 1; } - strbuf_list_free(split); + string_list_clear(&split, 0); } if (!rewrite_cmd) { @@ -873,7 +875,7 @@ static int git_config_get_notes_strategy(const char *key, { char *value; - if (git_config_get_string(key, &value)) + if (repo_config_get_string(the_repository, key, &value)) return 1; if (parse_notes_merge_strategy(value, strategy)) git_die_config(the_repository, key, _("unknown notes merge strategy %s"), value); @@ -1145,7 +1147,7 @@ int cmd_notes(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_notes_usage, PARSE_OPT_SUBCOMMAND_OPTIONAL); if (!fn) { diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index 067b9e322a..53a2256250 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -1455,7 +1455,7 @@ static void write_pack_file(void) strbuf_setlen(&tmpname, tmpname_len); } - rename_tmp_packfile_idx(&tmpname, &idx_tmp_name); + rename_tmp_packfile_idx(the_repository, &tmpname, &idx_tmp_name); free(idx_tmp_name); strbuf_release(&tmpname); @@ -1706,11 +1706,19 @@ static int want_object_in_pack_mtime(const struct object_id *oid, uint32_t found_mtime) { int want; + struct odb_source *source; struct list_head *pos; - struct multi_pack_index *m; - if (!exclude && local && has_loose_object_nonlocal(oid)) - return 0; + if (!exclude && local) { + /* + * Note that we start iterating at `sources->next` so that we + * skip the local object source. + */ + struct odb_source *source = the_repository->objects->sources->next; + for (; source; source = source->next) + if (has_loose_object(source, oid)) + return 0; + } /* * If we already know the pack object lives in, start checks from that @@ -1727,9 +1735,13 @@ static int want_object_in_pack_mtime(const struct object_id *oid, *found_offset = 0; } - for (m = get_multi_pack_index(the_repository); m; m = m->next) { + odb_prepare_alternates(the_repository->objects); + + for (source = the_repository->objects->sources; source; source = source->next) { + struct multi_pack_index *m = get_multi_pack_index(source); struct pack_entry e; - if (fill_midx_entry(the_repository, oid, &e, m)) { + + if (m && fill_midx_entry(the_repository, oid, &e, m)) { want = want_object_in_pack_one(e.p, oid, exclude, found_pack, found_offset, found_mtime); if (want != -1) return want; @@ -3962,7 +3974,14 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type } else { if (!want_object_in_pack_mtime(oid, 0, &pack, &offset, mtime)) return; - if (!pack && type == OBJ_BLOB && !has_loose_object(oid)) { + if (!pack && type == OBJ_BLOB) { + struct odb_source *source = the_repository->objects->sources; + int found = 0; + + for (; !found && source; source = source->next) + if (has_loose_object(source, oid)) + found = 1; + /* * If a traversed tree has a missing blob then we want * to avoid adding that missing object to our pack. @@ -3976,7 +3995,8 @@ static void add_cruft_object_entry(const struct object_id *oid, enum object_type * limited to "ensure non-tip blobs which don't exist in * packs do exist via loose objects". Confused? */ - return; + if (!found) + return; } entry = create_object_entry(oid, type, pack_name_hash_fn(name), @@ -4364,7 +4384,7 @@ static int add_loose_object(const struct object_id *oid, const char *path, */ static void add_unreachable_loose_objects(struct rev_info *revs) { - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, add_loose_object, NULL, NULL, revs); } @@ -4433,7 +4453,8 @@ static void loosen_unused_packed_objects(void) if (!packlist_find(&to_pack, &oid) && !has_sha1_pack_kept_or_nonlocal(&oid) && !loosened_object_can_be_discarded(&oid, p->mtime)) { - if (force_object_loose(&oid, p->mtime)) + if (force_object_loose(the_repository->objects->sources, + &oid, p->mtime)) die(_("unable to force loose object")); loosened_objects_nr++; } @@ -4981,7 +5002,7 @@ int cmd_pack_objects(int argc, reset_pack_idx_option(&pack_idx_opts); pack_idx_opts.flags |= WRITE_REV; - git_config(git_pack_config, NULL); + repo_config(the_repository, git_pack_config, NULL); if (git_env_bool(GIT_TEST_NO_WRITE_REV_INDEX, 0)) pack_idx_opts.flags &= ~WRITE_REV; diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index e47bae1c80..5e28d0f9e8 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "refs.h" diff --git a/builtin/patch-id.c b/builtin/patch-id.c index 26f04b0335..d26e9d0c1e 100644 --- a/builtin/patch-id.c +++ b/builtin/patch-id.c @@ -3,6 +3,7 @@ #include "builtin.h" #include "config.h" #include "diff.h" +#include "environment.h" #include "gettext.h" #include "hash.h" #include "hex.h" @@ -235,7 +236,7 @@ int cmd_patch_id(int argc, OPT_END() }; - git_config(git_patch_id_config, &config); + repo_config(the_repository, git_patch_id_config, &config); /* verbatim implies stable */ if (config.verbatim) diff --git a/builtin/prune.c b/builtin/prune.c index d1c0ee1419..55635a891f 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -198,7 +198,7 @@ int cmd_prune(int argc, revs.exclude_promisor_objects = 1; } - for_each_loose_file_in_objdir(repo_get_object_directory(repo), + for_each_loose_file_in_source(repo->objects->sources, prune_object, prune_cruft, prune_subdir, &revs); prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0); diff --git a/builtin/pull.c b/builtin/pull.c index c593f324fe..5ebd529620 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "merge.h" @@ -90,7 +91,8 @@ static char *opt_ff; static const char *opt_verify_signatures; static const char *opt_verify; static int opt_autostash = -1; -static int config_autostash; +static int config_rebase_autostash; +static int config_pull_autostash = -1; static int check_trust_level = 1; static struct strvec opt_strategies = STRVEC_INIT; static struct strvec opt_strategy_opts = STRVEC_INIT; @@ -312,7 +314,7 @@ static const char *config_get_ff(void) { const char *value; - if (git_config_get_value("pull.ff", &value)) + if (repo_config_get_value(the_repository, "pull.ff", &value)) return NULL; switch (git_parse_maybe_bool(value)) { @@ -343,7 +345,7 @@ static enum rebase_type config_get_rebase(int *rebase_unspecified) if (curr_branch) { char *key = xstrfmt("branch.%s.rebase", curr_branch->name); - if (!git_config_get_value(key, &value)) { + if (!repo_config_get_value(the_repository, key, &value)) { enum rebase_type ret = parse_config_rebase(key, value, 1); free(key); return ret; @@ -352,7 +354,7 @@ static enum rebase_type config_get_rebase(int *rebase_unspecified) free(key); } - if (!git_config_get_value("pull.rebase", &value)) + if (!repo_config_get_value(the_repository, "pull.rebase", &value)) return parse_config_rebase("pull.rebase", value, 1); *rebase_unspecified = 1; @@ -367,7 +369,18 @@ static int git_pull_config(const char *var, const char *value, const struct config_context *ctx, void *cb) { if (!strcmp(var, "rebase.autostash")) { - config_autostash = git_config_bool(var, value); + /* + * run_rebase() also reads this option. The reason we handle it here is + * that when pull.rebase is true, a fast-forward may occur without + * invoking run_rebase(). We need to ensure that autostash is set even + * in the fast-forward case. + * + * run_merge() handles merge.autostash, so we don't handle it here. + */ + config_rebase_autostash = git_config_bool(var, value); + return 0; + } else if (!strcmp(var, "pull.autostash")) { + config_pull_autostash = git_config_bool(var, value); return 0; } else if (!strcmp(var, "submodule.recurse")) { recurse_submodules = git_config_bool(var, value) ? @@ -999,13 +1012,15 @@ int cmd_pull(int argc, if (!getenv("GIT_REFLOG_ACTION")) set_reflog_message(argc, argv); - git_config(git_pull_config, NULL); + repo_config(the_repository, git_pull_config, NULL); if (the_repository->gitdir) { prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; } argc = parse_options(argc, argv, prefix, pull_options, pull_usage, 0); + if (opt_autostash == -1) + opt_autostash = config_pull_autostash; if (recurse_submodules_cli != RECURSE_SUBMODULES_DEFAULT) recurse_submodules = recurse_submodules_cli; @@ -1052,7 +1067,7 @@ int cmd_pull(int argc, if (opt_rebase) { if (opt_autostash == -1) - opt_autostash = config_autostash; + opt_autostash = config_rebase_autostash; if (is_null_oid(&orig_head) && !is_index_unborn(the_repository->index)) die(_("Updating an unborn branch with changes added to the index.")); diff --git a/builtin/push.c b/builtin/push.c index 92d530e5c4..d0794b7b30 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -598,7 +598,7 @@ int cmd_push(int argc, }; packet_trace_identity("push"); - git_config(git_push_config, &flags); + repo_config(the_repository, git_push_config, &flags); argc = parse_options(argc, argv, prefix, options, push_usage, 0); push_options = (push_options_cmdline.nr ? &push_options_cmdline diff --git a/builtin/range-diff.c b/builtin/range-diff.c index 32ddb6613f..a563abff5f 100644 --- a/builtin/range-diff.c +++ b/builtin/range-diff.c @@ -54,7 +54,7 @@ int cmd_range_diff(int argc, struct object_id oid; const char *three_dots = NULL; - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); repo_diff_setup(the_repository, &diffopt); diff --git a/builtin/read-tree.c b/builtin/read-tree.c index a8f352f7cd..34f7a59f38 100644 --- a/builtin/read-tree.c +++ b/builtin/read-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" @@ -168,7 +169,7 @@ int cmd_read_tree(int argc, opts.src_index = the_repository->index; opts.dst_index = the_repository->index; - git_config(git_read_tree_config, NULL); + repo_config(the_repository, git_read_tree_config, NULL); argc = parse_options(argc, argv, cmd_prefix, read_tree_options, read_tree_usage, 0); diff --git a/builtin/rebase.c b/builtin/rebase.c index e90562a3b8..3c85768d29 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -293,15 +293,6 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) &revisions, &shortrevisions)) goto cleanup; - if (init_basic_state(&replay, - opts->head_name ? opts->head_name : "detached HEAD", - opts->onto, &opts->orig_head->object.oid)) - goto cleanup; - - if (!opts->upstream && opts->squash_onto) - write_file(path_squash_onto(), "%s\n", - oid_to_hex(opts->squash_onto)); - strvec_pushl(&make_script_args, "", revisions, NULL); if (opts->restrict_revision) strvec_pushf(&make_script_args, "^%s", @@ -310,21 +301,30 @@ static int do_interactive_rebase(struct rebase_options *opts, unsigned flags) ret = sequencer_make_script(the_repository, &todo_list.buf, make_script_args.nr, make_script_args.v, flags); - - if (ret) + if (ret) { error(_("could not generate todo list")); - else { - discard_index(the_repository->index); - if (todo_list_parse_insn_buffer(the_repository, &replay, - todo_list.buf.buf, &todo_list)) - BUG("unusable todo list"); - - ret = complete_action(the_repository, &replay, flags, - shortrevisions, opts->onto_name, opts->onto, - &opts->orig_head->object.oid, &opts->exec, - opts->autosquash, opts->update_refs, &todo_list); + goto cleanup; } + if (init_basic_state(&replay, + opts->head_name ? opts->head_name : "detached HEAD", + opts->onto, &opts->orig_head->object.oid)) + goto cleanup; + + if (!opts->upstream && opts->squash_onto) + write_file(path_squash_onto(), "%s\n", + oid_to_hex(opts->squash_onto)); + + discard_index(the_repository->index); + if (todo_list_parse_insn_buffer(the_repository, &replay, + todo_list.buf.buf, &todo_list)) + BUG("unusable todo list"); + + ret = complete_action(the_repository, &replay, flags, + shortrevisions, opts->onto_name, opts->onto, + &opts->orig_head->object.oid, &opts->exec, + opts->autosquash, opts->update_refs, &todo_list); + cleanup: replay_opts_release(&replay); free(revisions); @@ -340,7 +340,7 @@ static int run_sequencer_rebase(struct rebase_options *opts) unsigned flags = 0; int abbreviate_commands = 0, ret = 0; - git_config_get_bool("rebase.abbreviatecommands", &abbreviate_commands); + repo_config_get_bool(the_repository, "rebase.abbreviatecommands", &abbreviate_commands); flags |= opts->keep_empty ? TODO_LIST_KEEP_EMPTY : 0; flags |= abbreviate_commands ? TODO_LIST_ABBREVIATE_CMDS : 0; @@ -1245,7 +1245,7 @@ int cmd_rebase(int argc, prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; - git_config(rebase_config, &options); + repo_config(the_repository, rebase_config, &options); /* options.gpg_sign_opt will be either "-S" or NULL */ gpg_sign = options.gpg_sign_opt ? "" : NULL; FREE_AND_NULL(options.gpg_sign_opt); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 7974d157eb..1113137a6f 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -760,8 +760,8 @@ static void prepare_push_cert_sha1(struct child_process *proc) int bogs /* beginning_of_gpg_sig */; already_done = 1; - if (write_object_file(push_cert.buf, push_cert.len, OBJ_BLOB, - &push_cert_oid)) + if (odb_write_object(the_repository->objects, push_cert.buf, + push_cert.len, OBJ_BLOB, &push_cert_oid)) oidclr(&push_cert_oid, the_repository->hash_algo); memset(&sigcheck, '\0', sizeof(sigcheck)); @@ -2613,7 +2613,7 @@ int cmd_receive_pack(int argc, if (!enter_repo(service_dir, 0)) die("'%s' does not appear to be a git repository", service_dir); - git_config(receive_pack_config, NULL); + repo_config(the_repository, receive_pack_config, NULL); if (cert_nonce_seed) push_cert_nonce = prepare_push_cert_nonce(service_dir, time(NULL)); diff --git a/builtin/reflog.c b/builtin/reflog.c index 3acaf3e32c..c8f6b93d60 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -3,6 +3,8 @@ #include "builtin.h" #include "config.h" #include "gettext.h" +#include "hex.h" +#include "odb.h" #include "revision.h" #include "reachable.h" #include "wildmatch.h" @@ -17,21 +19,24 @@ #define BUILTIN_REFLOG_LIST_USAGE \ N_("git reflog list") -#define BUILTIN_REFLOG_EXPIRE_USAGE \ - N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \ - " [--rewrite] [--updateref] [--stale-fix]\n" \ - " [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]") +#define BUILTIN_REFLOG_EXISTS_USAGE \ + N_("git reflog exists <ref>") + +#define BUILTIN_REFLOG_WRITE_USAGE \ + N_("git reflog write <ref> <old-oid> <new-oid> <message>") #define BUILTIN_REFLOG_DELETE_USAGE \ N_("git reflog delete [--rewrite] [--updateref]\n" \ " [--dry-run | -n] [--verbose] <ref>@{<specifier>}...") -#define BUILTIN_REFLOG_EXISTS_USAGE \ - N_("git reflog exists <ref>") - #define BUILTIN_REFLOG_DROP_USAGE \ N_("git reflog drop [--all [--single-worktree] | <refs>...]") +#define BUILTIN_REFLOG_EXPIRE_USAGE \ + N_("git reflog expire [--expire=<time>] [--expire-unreachable=<time>]\n" \ + " [--rewrite] [--updateref] [--stale-fix]\n" \ + " [--dry-run | -n] [--verbose] [--all [--single-worktree] | <refs>...]") + static const char *const reflog_show_usage[] = { BUILTIN_REFLOG_SHOW_USAGE, NULL, @@ -42,9 +47,14 @@ static const char *const reflog_list_usage[] = { NULL, }; -static const char *const reflog_expire_usage[] = { - BUILTIN_REFLOG_EXPIRE_USAGE, - NULL +static const char *const reflog_exists_usage[] = { + BUILTIN_REFLOG_EXISTS_USAGE, + NULL, +}; + +static const char *const reflog_write_usage[] = { + BUILTIN_REFLOG_WRITE_USAGE, + NULL, }; static const char *const reflog_delete_usage[] = { @@ -52,23 +62,24 @@ static const char *const reflog_delete_usage[] = { NULL }; -static const char *const reflog_exists_usage[] = { - BUILTIN_REFLOG_EXISTS_USAGE, - NULL, -}; - static const char *const reflog_drop_usage[] = { BUILTIN_REFLOG_DROP_USAGE, NULL, }; +static const char *const reflog_expire_usage[] = { + BUILTIN_REFLOG_EXPIRE_USAGE, + NULL +}; + static const char *const reflog_usage[] = { BUILTIN_REFLOG_SHOW_USAGE, BUILTIN_REFLOG_LIST_USAGE, - BUILTIN_REFLOG_EXPIRE_USAGE, + BUILTIN_REFLOG_EXISTS_USAGE, + BUILTIN_REFLOG_WRITE_USAGE, BUILTIN_REFLOG_DELETE_USAGE, BUILTIN_REFLOG_DROP_USAGE, - BUILTIN_REFLOG_EXISTS_USAGE, + BUILTIN_REFLOG_EXPIRE_USAGE, NULL }; @@ -202,7 +213,7 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix, OPT_END() }; - git_config(reflog_expire_config, &opts); + repo_config(the_repository, reflog_expire_config, &opts); save_commit_buffer = 0; do_all = status = 0; @@ -283,6 +294,9 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix, &cb); free(ref); } + + reflog_clear_expire_config(&opts); + return status; } @@ -392,6 +406,59 @@ static int cmd_reflog_drop(int argc, const char **argv, const char *prefix, return ret; } +static int cmd_reflog_write(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + const struct option options[] = { + OPT_END() + }; + struct object_id old_oid, new_oid; + struct strbuf err = STRBUF_INIT; + struct ref_transaction *tx; + const char *ref, *message; + int ret; + + argc = parse_options(argc, argv, prefix, options, reflog_write_usage, 0); + if (argc != 4) + usage_with_options(reflog_write_usage, options); + + ref = argv[0]; + if (!is_root_ref(ref) && check_refname_format(ref, 0)) + die(_("invalid reference name: %s"), ref); + + ret = get_oid_hex_algop(argv[1], &old_oid, repo->hash_algo); + if (ret) + die(_("invalid old object ID: '%s'"), argv[1]); + if (!is_null_oid(&old_oid) && !odb_has_object(repo->objects, &old_oid, 0)) + die(_("old object '%s' does not exist"), argv[1]); + + ret = get_oid_hex_algop(argv[2], &new_oid, repo->hash_algo); + if (ret) + die(_("invalid new object ID: '%s'"), argv[2]); + if (!is_null_oid(&new_oid) && !odb_has_object(repo->objects, &new_oid, 0)) + die(_("new object '%s' does not exist"), argv[2]); + + message = argv[3]; + + tx = ref_store_transaction_begin(get_main_ref_store(repo), 0, &err); + if (!tx) + die(_("cannot start transaction: %s"), err.buf); + + ret = ref_transaction_update_reflog(tx, ref, &new_oid, &old_oid, + git_committer_info(0), + message, 0, &err); + if (ret) + die(_("cannot queue reflog update: %s"), err.buf); + + ret = ref_transaction_commit(tx, &err); + if (ret) + die(_("cannot commit reflog update: %s"), err.buf); + + ref_transaction_free(tx); + strbuf_release(&err); + return 0; +} + /* * main "reflog" */ @@ -404,10 +471,11 @@ int cmd_reflog(int argc, struct option options[] = { OPT_SUBCOMMAND("show", &fn, cmd_reflog_show), OPT_SUBCOMMAND("list", &fn, cmd_reflog_list), - OPT_SUBCOMMAND("expire", &fn, cmd_reflog_expire), - OPT_SUBCOMMAND("delete", &fn, cmd_reflog_delete), OPT_SUBCOMMAND("exists", &fn, cmd_reflog_exists), + OPT_SUBCOMMAND("write", &fn, cmd_reflog_write), + OPT_SUBCOMMAND("delete", &fn, cmd_reflog_delete), OPT_SUBCOMMAND("drop", &fn, cmd_reflog_drop), + OPT_SUBCOMMAND("expire", &fn, cmd_reflog_expire), OPT_END() }; diff --git a/builtin/refs.c b/builtin/refs.c index 998d2a2c1c..76224feba4 100644 --- a/builtin/refs.c +++ b/builtin/refs.c @@ -6,6 +6,7 @@ #include "refs.h" #include "strbuf.h" #include "worktree.h" +#include "for-each-ref.h" #define REFS_MIGRATE_USAGE \ N_("git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]") @@ -88,7 +89,7 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix, if (argc) usage(_("'git refs verify' takes no arguments")); - git_config(git_fsck_config, &fsck_refs_options); + repo_config(the_repository, git_fsck_config, &fsck_refs_options); prepare_repo_settings(the_repository); worktrees = get_worktrees_without_reading_head(); @@ -101,6 +102,17 @@ static int cmd_refs_verify(int argc, const char **argv, const char *prefix, return ret; } +static int cmd_refs_list(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + static char const * const refs_list_usage[] = { + N_("git refs list " COMMON_USAGE_FOR_EACH_REF), + NULL + }; + + return for_each_ref_core(argc, argv, prefix, repo, refs_list_usage); +} + int cmd_refs(int argc, const char **argv, const char *prefix, @@ -109,12 +121,14 @@ int cmd_refs(int argc, const char * const refs_usage[] = { REFS_MIGRATE_USAGE, REFS_VERIFY_USAGE, + "git refs list " COMMON_USAGE_FOR_EACH_REF, NULL, }; parse_opt_subcommand_fn *fn = NULL; struct option opts[] = { OPT_SUBCOMMAND("migrate", &fn, cmd_refs_migrate), OPT_SUBCOMMAND("verify", &fn, cmd_refs_verify), + OPT_SUBCOMMAND("list", &fn, cmd_refs_list), OPT_END(), }; diff --git a/builtin/remote.c b/builtin/remote.c index 5dd6cbbaee..8a7ed4299a 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1,9 +1,11 @@ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "builtin.h" +#include "advice.h" #include "config.h" +#include "date.h" #include "gettext.h" +#include "ident.h" #include "parse-options.h" #include "path.h" #include "transport.h" @@ -132,7 +134,7 @@ static void add_branch(const char *key, const char *branchname, else strbuf_addf(tmp, "refs/heads/%s:refs/remotes/%s/%s", branchname, remotename, branchname); - git_config_set_multivar(key, tmp->buf, "^$", 0); + repo_config_set_multivar(the_repository, key, tmp->buf, "^$", 0); } static const char mirror_advice[] = @@ -182,7 +184,6 @@ static int add(int argc, const char **argv, const char *prefix, struct remote *remote; struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT; const char *name, *url; - int i; int result = 0; struct option options[] = { @@ -226,14 +227,14 @@ static int add(int argc, const char **argv, const char *prefix, for_each_remote(check_remote_collision, (void *)name); strbuf_addf(&buf, "remote.%s.url", name); - git_config_set(buf.buf, url); + repo_config_set(the_repository, buf.buf, url); if (!mirror || mirror & MIRROR_FETCH) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", name); if (track.nr == 0) string_list_append(&track, "*"); - for (i = 0; i < track.nr; i++) { + for (size_t i = 0; i < track.nr; i++) { add_branch(buf.buf, track.items[i].string, name, mirror, &buf2); } @@ -242,14 +243,14 @@ static int add(int argc, const char **argv, const char *prefix, if (mirror & MIRROR_PUSH) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.mirror", name); - git_config_set(buf.buf, "true"); + repo_config_set(the_repository, buf.buf, "true"); } if (fetch_tags != TAGS_DEFAULT) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.tagOpt", name); - git_config_set(buf.buf, - fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); + repo_config_set(the_repository, buf.buf, + fetch_tags == TAGS_SET ? "--tags" : "--no-tags"); } if (fetch && fetch_remote(name)) { @@ -370,7 +371,7 @@ static void read_branches(void) { if (branch_list.nr) return; - git_config(config_read_branches, NULL); + repo_config(the_repository, config_read_branches, NULL); } struct ref_states { @@ -612,54 +613,170 @@ static int add_branch_for_removal(const char *refname, struct rename_info { const char *old_name; const char *new_name; - struct string_list *remote_branches; - uint32_t symrefs_nr; + struct ref_transaction *transaction; + struct progress *progress; + struct strbuf *err; + uint32_t progress_nr; + uint64_t index; }; -static int read_remote_branches(const char *refname, const char *referent UNUSED, - const struct object_id *oid UNUSED, - int flags UNUSED, void *cb_data) +static void compute_renamed_ref(struct rename_info *rename, + const char *refname, + struct strbuf *out) +{ + strbuf_reset(out); + strbuf_addstr(out, refname); + strbuf_splice(out, strlen("refs/remotes/"), strlen(rename->old_name), + rename->new_name, strlen(rename->new_name)); +} + +static int rename_one_reflog_entry(const char *old_refname, + struct object_id *old_oid, + struct object_id *new_oid, + const char *committer, + timestamp_t timestamp, int tz, + const char *msg, void *cb_data) { struct rename_info *rename = cb_data; - struct strbuf buf = STRBUF_INIT; - struct string_list_item *item; - int flag; - const char *symref; - - strbuf_addf(&buf, "refs/remotes/%s/", rename->old_name); - if (starts_with(refname, buf.buf)) { - item = string_list_append(rename->remote_branches, refname); - symref = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), - refname, RESOLVE_REF_READING, - NULL, &flag); - if (symref && (flag & REF_ISSYMREF)) { - item->util = xstrdup(symref); - rename->symrefs_nr++; - } else { - item->util = NULL; - } + struct strbuf new_refname = STRBUF_INIT; + struct strbuf identity = STRBUF_INIT; + struct strbuf name = STRBUF_INIT; + struct strbuf mail = STRBUF_INIT; + struct ident_split ident; + const char *date; + int error; + + compute_renamed_ref(rename, old_refname, &new_refname); + + if (split_ident_line(&ident, committer, strlen(committer)) < 0) { + error = -1; + goto out; } - strbuf_release(&buf); - return 0; + strbuf_add(&name, ident.name_begin, ident.name_end - ident.name_begin); + strbuf_add(&mail, ident.mail_begin, ident.mail_end - ident.mail_begin); + + date = show_date(timestamp, tz, DATE_MODE(NORMAL)); + strbuf_addstr(&identity, fmt_ident(name.buf, mail.buf, + WANT_BLANK_IDENT, date, 0)); + + error = ref_transaction_update_reflog(rename->transaction, new_refname.buf, + new_oid, old_oid, identity.buf, msg, + rename->index++, rename->err); + +out: + strbuf_release(&new_refname); + strbuf_release(&identity); + strbuf_release(&name); + strbuf_release(&mail); + return error; +} + +static int rename_one_reflog(const char *old_refname, + const struct object_id *old_oid, + struct rename_info *rename) +{ + struct strbuf new_refname = STRBUF_INIT; + struct strbuf message = STRBUF_INIT; + int error; + + if (!refs_reflog_exists(get_main_ref_store(the_repository), old_refname)) + return 0; + + error = refs_for_each_reflog_ent(get_main_ref_store(the_repository), + old_refname, rename_one_reflog_entry, rename); + if (error < 0) + goto out; + + compute_renamed_ref(rename, old_refname, &new_refname); + + /* + * Manually write the reflog entry for the now-renamed ref. We cannot + * rely on `rename_one_ref()` to do this for us as that would screw + * over order in which reflog entries are being written. + * + * Furthermore, we only append the entry in case the reference + * resolves. Missing references shouldn't have reflogs anyway. + */ + strbuf_addf(&message, "remote: renamed %s to %s", old_refname, + new_refname.buf); + + error = ref_transaction_update_reflog(rename->transaction, new_refname.buf, + old_oid, old_oid, git_committer_info(0), + message.buf, rename->index++, rename->err); + if (error < 0) + return error; + +out: + strbuf_release(&new_refname); + strbuf_release(&message); + return error; +} + +static int rename_one_ref(const char *old_refname, const char *referent, + const struct object_id *oid, + int flags, void *cb_data) +{ + struct strbuf new_referent = STRBUF_INIT; + struct strbuf new_refname = STRBUF_INIT; + struct rename_info *rename = cb_data; + int error; + + compute_renamed_ref(rename, old_refname, &new_refname); + + if (flags & REF_ISSYMREF) { + /* + * Stupidly enough `referent` is not pointing to the immediate + * target of a symref, but it's the recursively resolved value. + * So symrefs pointing to symrefs would be misresolved, and + * unborn symrefs don't have any value for the `referent` at all. + */ + referent = refs_resolve_ref_unsafe(get_main_ref_store(the_repository), + old_refname, RESOLVE_REF_NO_RECURSE, + NULL, NULL); + compute_renamed_ref(rename, referent, &new_referent); + oid = NULL; + } + + error = ref_transaction_delete(rename->transaction, old_refname, + oid, referent, REF_NO_DEREF, NULL, rename->err); + if (error < 0) + goto out; + + error = ref_transaction_update(rename->transaction, new_refname.buf, oid, null_oid(the_hash_algo), + (flags & REF_ISSYMREF) ? new_referent.buf : NULL, NULL, + REF_SKIP_CREATE_REFLOG | REF_NO_DEREF | REF_SKIP_OID_VERIFICATION, + NULL, rename->err); + if (error < 0) + goto out; + + error = rename_one_reflog(old_refname, oid, rename); + if (error < 0) + goto out; + + display_progress(rename->progress, ++rename->progress_nr); + +out: + strbuf_release(&new_referent); + strbuf_release(&new_refname); + return error; } static int migrate_file(struct remote *remote) { struct strbuf buf = STRBUF_INIT; - int i; strbuf_addf(&buf, "remote.%s.url", remote->name); - for (i = 0; i < remote->url.nr; i++) - git_config_set_multivar(buf.buf, remote->url.v[i], "^$", 0); + for (size_t i = 0; i < remote->url.nr; i++) + repo_config_set_multivar(the_repository, buf.buf, remote->url.v[i], "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.push", remote->name); - for (i = 0; i < remote->push.nr; i++) - git_config_set_multivar(buf.buf, remote->push.items[i].raw, "^$", 0); + for (int i = 0; i < remote->push.nr; i++) + repo_config_set_multivar(the_repository, buf.buf, remote->push.items[i].raw, "^$", 0); strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", remote->name); - for (i = 0; i < remote->fetch.nr; i++) - git_config_set_multivar(buf.buf, remote->fetch.items[i].raw, "^$", 0); + for (int i = 0; i < remote->fetch.nr; i++) + repo_config_set_multivar(the_repository, buf.buf, remote->fetch.items[i].raw, "^$", 0); #ifndef WITH_BREAKING_CHANGES if (remote->origin == REMOTE_REMOTES) unlink_or_warn(repo_git_path_replace(the_repository, &buf, @@ -707,12 +824,12 @@ static void handle_push_default(const char* old_name, const char* new_name) .origin = STRBUF_INIT, .linenr = -1, }; - git_config(config_read_push_default, &push_default); + repo_config(the_repository, config_read_push_default, &push_default); if (push_default.scope >= CONFIG_SCOPE_COMMAND) ; /* pass */ else if (push_default.scope >= CONFIG_SCOPE_LOCAL) { - int result = git_config_set_gently("remote.pushDefault", - new_name); + int result = repo_config_set_gently(the_repository, "remote.pushDefault", + new_name); if (new_name && result && result != CONFIG_NOTHING_SET) die(_("could not set '%s'"), "remote.pushDefault"); else if (!new_name && result && result != CONFIG_NOTHING_SET) @@ -730,6 +847,14 @@ static void handle_push_default(const char* old_name, const char* new_name) strbuf_release(&push_default.origin); } +static const char conflicting_remote_refs_advice[] = N_( + "The remote you are trying to rename has conflicting references in the\n" + "new target refspec. This is most likely caused by you trying to nest\n" + "a remote into itself, e.g. by renaming 'parent' into 'parent/child'\n" + "or by unnesting a remote, e.g. the other way round.\n" + "\n" + "If that is the case, you can address this by first renaming the\n" + "remote to a different name.\n"); static int mv(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) @@ -741,11 +866,11 @@ static int mv(int argc, const char **argv, const char *prefix, }; struct remote *oldremote, *newremote; struct strbuf buf = STRBUF_INIT, buf2 = STRBUF_INIT, buf3 = STRBUF_INIT, - old_remote_context = STRBUF_INIT; - struct string_list remote_branches = STRING_LIST_INIT_DUP; - struct rename_info rename; - int i, refs_renamed_nr = 0, refspec_updated = 0; - struct progress *progress = NULL; + old_remote_context = STRBUF_INIT, err = STRBUF_INIT; + struct rename_info rename = { + .err = &err, + }; + int refspecs_need_update = 0; int result = 0; argc = parse_options(argc, argv, prefix, options, @@ -756,8 +881,6 @@ static int mv(int argc, const char **argv, const char *prefix, rename.old_name = argv[0]; rename.new_name = argv[1]; - rename.remote_branches = &remote_branches; - rename.symrefs_nr = 0; oldremote = remote_get(rename.old_name); if (!remote_is_configured(oldremote, 1)) { @@ -785,19 +908,50 @@ static int mv(int argc, const char **argv, const char *prefix, goto out; } + strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name); + + for (int i = 0; i < oldremote->fetch.nr && !refspecs_need_update; i++) + refspecs_need_update = !!strstr(oldremote->fetch.items[i].raw, + old_remote_context.buf); + + if (refspecs_need_update) { + rename.transaction = ref_store_transaction_begin(get_main_ref_store(the_repository), + 0, &err); + if (!rename.transaction) + goto out; + + if (show_progress) + rename.progress = start_delayed_progress(the_repository, + _("Renaming remote references"), 0); + + strbuf_reset(&buf); + strbuf_addf(&buf, "refs/remotes/%s/", rename.old_name); + + result = refs_for_each_rawref_in(get_main_ref_store(the_repository), buf.buf, + rename_one_ref, &rename); + if (result < 0) + die(_("queueing remote ref renames failed: %s"), rename.err->buf); + + result = ref_transaction_prepare(rename.transaction, &err); + if (result < 0) { + error("renaming remote references failed: %s", err.buf); + if (result == REF_TRANSACTION_ERROR_NAME_CONFLICT) + advise(conflicting_remote_refs_advice); + die(NULL); + } + } + if (oldremote->fetch.nr) { strbuf_reset(&buf); strbuf_addf(&buf, "remote.%s.fetch", rename.new_name); - git_config_set_multivar(buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); - strbuf_addf(&old_remote_context, ":refs/remotes/%s/", rename.old_name); - for (i = 0; i < oldremote->fetch.nr; i++) { + repo_config_set_multivar(the_repository, buf.buf, NULL, NULL, CONFIG_FLAGS_MULTI_REPLACE); + for (int i = 0; i < oldremote->fetch.nr; i++) { char *ptr; strbuf_reset(&buf2); strbuf_addstr(&buf2, oldremote->fetch.items[i].raw); ptr = strstr(buf2.buf, old_remote_context.buf); if (ptr) { - refspec_updated = 1; strbuf_splice(&buf2, ptr-buf2.buf + strlen(":refs/remotes/"), strlen(rename.old_name), rename.new_name, @@ -808,103 +962,43 @@ static int mv(int argc, const char **argv, const char *prefix, "\tPlease update the configuration manually if necessary."), buf2.buf); - git_config_set_multivar(buf.buf, buf2.buf, "^$", 0); + repo_config_set_multivar(the_repository, buf.buf, buf2.buf, "^$", 0); } } read_branches(); - for (i = 0; i < branch_list.nr; i++) { + for (size_t i = 0; i < branch_list.nr; i++) { struct string_list_item *item = branch_list.items + i; struct branch_info *info = item->util; if (info->remote_name && !strcmp(info->remote_name, rename.old_name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.remote", item->string); - git_config_set(buf.buf, rename.new_name); + repo_config_set(the_repository, buf.buf, rename.new_name); } if (info->push_remote_name && !strcmp(info->push_remote_name, rename.old_name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.pushRemote", item->string); - git_config_set(buf.buf, rename.new_name); + repo_config_set(the_repository, buf.buf, rename.new_name); } } - if (!refspec_updated) - goto out; + if (refspecs_need_update) { + result = ref_transaction_commit(rename.transaction, &err); + if (result < 0) + die(_("renaming remote refs failed: %s"), rename.err->buf); - /* - * First remove symrefs, then rename the rest, finally create - * the new symrefs. - */ - refs_for_each_ref(get_main_ref_store(the_repository), - read_remote_branches, &rename); - if (show_progress) { - /* - * Count symrefs twice, since "renaming" them is done by - * deleting and recreating them in two separate passes. - */ - progress = start_progress(the_repository, - _("Renaming remote references"), - rename.remote_branches->nr + rename.symrefs_nr); - } - for (i = 0; i < remote_branches.nr; i++) { - struct string_list_item *item = remote_branches.items + i; - struct strbuf referent = STRBUF_INIT; - - if (refs_read_symbolic_ref(get_main_ref_store(the_repository), item->string, - &referent)) - continue; - if (refs_delete_ref(get_main_ref_store(the_repository), NULL, item->string, NULL, REF_NO_DEREF)) - die(_("deleting '%s' failed"), item->string); + stop_progress(&rename.progress); - strbuf_release(&referent); - display_progress(progress, ++refs_renamed_nr); + handle_push_default(rename.old_name, rename.new_name); } - for (i = 0; i < remote_branches.nr; i++) { - struct string_list_item *item = remote_branches.items + i; - - if (item->util) - continue; - strbuf_reset(&buf); - strbuf_addstr(&buf, item->string); - strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old_name), - rename.new_name, strlen(rename.new_name)); - strbuf_reset(&buf2); - strbuf_addf(&buf2, "remote: renamed %s to %s", - item->string, buf.buf); - if (refs_rename_ref(get_main_ref_store(the_repository), item->string, buf.buf, buf2.buf)) - die(_("renaming '%s' failed"), item->string); - display_progress(progress, ++refs_renamed_nr); - } - for (i = 0; i < remote_branches.nr; i++) { - struct string_list_item *item = remote_branches.items + i; - - if (!item->util) - continue; - strbuf_reset(&buf); - strbuf_addstr(&buf, item->string); - strbuf_splice(&buf, strlen("refs/remotes/"), strlen(rename.old_name), - rename.new_name, strlen(rename.new_name)); - strbuf_reset(&buf2); - strbuf_addstr(&buf2, item->util); - strbuf_splice(&buf2, strlen("refs/remotes/"), strlen(rename.old_name), - rename.new_name, strlen(rename.new_name)); - strbuf_reset(&buf3); - strbuf_addf(&buf3, "remote: renamed %s to %s", - item->string, buf.buf); - if (refs_update_symref(get_main_ref_store(the_repository), buf.buf, buf2.buf, buf3.buf)) - die(_("creating '%s' failed"), buf.buf); - display_progress(progress, ++refs_renamed_nr); - } - stop_progress(&progress); - - handle_push_default(rename.old_name, rename.new_name); out: - string_list_clear(&remote_branches, 1); + ref_transaction_free(rename.transaction); strbuf_release(&old_remote_context); strbuf_release(&buf); strbuf_release(&buf2); strbuf_release(&buf3); + strbuf_release(&err); return result; } @@ -920,7 +1014,7 @@ static int rm(int argc, const char **argv, const char *prefix, struct string_list branches = STRING_LIST_INIT_DUP; struct string_list skipped = STRING_LIST_INIT_DUP; struct branches_for_remote cb_data; - int i, result; + int result; memset(&cb_data, 0, sizeof(cb_data)); cb_data.branches = &branches; @@ -942,7 +1036,7 @@ static int rm(int argc, const char **argv, const char *prefix, for_each_remote(add_known_remote, &known_remotes); read_branches(); - for (i = 0; i < branch_list.nr; i++) { + for (size_t i = 0; i < branch_list.nr; i++) { struct string_list_item *item = branch_list.items + i; struct branch_info *info = item->util; if (info->remote_name && !strcmp(info->remote_name, remote->name)) { @@ -951,7 +1045,7 @@ static int rm(int argc, const char **argv, const char *prefix, strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.%s", item->string, *k); - result = git_config_set_gently(buf.buf, NULL); + result = repo_config_set_gently(the_repository, buf.buf, NULL); if (result && result != CONFIG_NOTHING_SET) die(_("could not unset '%s'"), buf.buf); } @@ -959,7 +1053,7 @@ static int rm(int argc, const char **argv, const char *prefix, if (info->push_remote_name && !strcmp(info->push_remote_name, remote->name)) { strbuf_reset(&buf); strbuf_addf(&buf, "branch.%s.pushremote", item->string); - result = git_config_set_gently(buf.buf, NULL); + result = repo_config_set_gently(the_repository, buf.buf, NULL); if (result && result != CONFIG_NOTHING_SET) die(_("could not unset '%s'"), buf.buf); } @@ -988,7 +1082,7 @@ static int rm(int argc, const char **argv, const char *prefix, "Note: Some branches outside the refs/remotes/ hierarchy were not removed;\n" "to delete them, use:", skipped.nr)); - for (i = 0; i < skipped.nr; i++) + for (size_t i = 0; i < skipped.nr; i++) fprintf(stderr, " git branch -d %s\n", skipped.items[i].string); } @@ -1166,7 +1260,6 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) struct branch_info *branch_info = item->util; struct string_list *merge = &branch_info->merge; int width = show_info->width + 4; - int i; if (branch_info->rebase >= REBASE_TRUE && branch_info->merge.nr > 1) { error(_("invalid branch.%s.merge; cannot rebase onto > 1 branch"), @@ -1192,7 +1285,7 @@ static int show_local_info_item(struct string_list_item *item, void *cb_data) } else { printf_ln(_("merges with remote %s"), merge->items[0].string); } - for (i = 1; i < merge->nr; i++) + for (size_t i = 1; i < merge->nr; i++) printf(_("%-*s and with remote %s\n"), width, "", merge->items[i].string); @@ -1277,7 +1370,6 @@ static int get_one_entry(struct remote *remote, void *priv) struct string_list *list = priv; struct strbuf remote_info_buf = STRBUF_INIT; struct strvec *url; - int i; if (remote->url.nr > 0) { struct strbuf promisor_config = STRBUF_INIT; @@ -1285,7 +1377,7 @@ static int get_one_entry(struct remote *remote, void *priv) strbuf_addf(&promisor_config, "remote.%s.partialclonefilter", remote->name); strbuf_addf(&remote_info_buf, "%s (fetch)", remote->url.v[0]); - if (!git_config_get_string_tmp(promisor_config.buf, &partial_clone_filter)) + if (!repo_config_get_string_tmp(the_repository, promisor_config.buf, &partial_clone_filter)) strbuf_addf(&remote_info_buf, " [%s]", partial_clone_filter); strbuf_release(&promisor_config); @@ -1294,8 +1386,7 @@ static int get_one_entry(struct remote *remote, void *priv) } else string_list_append(list, remote->name)->util = NULL; url = push_url_of_remote(remote); - for (i = 0; i < url->nr; i++) - { + for (size_t i = 0; i < url->nr; i++) { strbuf_addf(&remote_info_buf, "%s (push)", url->v[i]); string_list_append(list, remote->name)->util = strbuf_detach(&remote_info_buf, NULL); @@ -1312,10 +1403,8 @@ static int show_all(void) result = for_each_remote(get_one_entry, &list); if (!result) { - int i; - string_list_sort(&list); - for (i = 0; i < list.nr; i++) { + for (size_t i = 0; i < list.nr; i++) { struct string_list_item *item = list.items + i; if (verbose) printf("%s\t%s\n", item->string, @@ -1352,7 +1441,7 @@ static int show(int argc, const char **argv, const char *prefix, query_flag = (GET_REF_STATES | GET_HEAD_NAMES | GET_PUSH_REF_STATES); for (; argc; argc--, argv++) { - int i; + size_t i; struct strvec *url; get_remote_ref_states(*argv, &info.states, query_flag); @@ -1458,7 +1547,7 @@ static void report_set_head_auto(const char *remote, const char *head_name, static int set_head(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { - int i, opt_a = 0, opt_d = 0, result = 0, was_detached; + int opt_a = 0, opt_d = 0, result = 0, was_detached; struct strbuf b_head = STRBUF_INIT, b_remote_head = STRBUF_INIT, b_local_head = STRBUF_INIT; char *head_name = NULL; @@ -1474,10 +1563,13 @@ static int set_head(int argc, const char **argv, const char *prefix, }; argc = parse_options(argc, argv, prefix, options, builtin_remote_sethead_usage, 0); - if (argc) { - strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); - remote = remote_get(argv[0]); - } + + /* All modes require at least a remote name. */ + if (!argc) + usage_with_options(builtin_remote_sethead_usage, options); + + strbuf_addf(&b_head, "refs/remotes/%s/HEAD", argv[0]); + remote = remote_get(argv[0]); if (!opt_a && !opt_d && argc == 2) { head_name = xstrdup(argv[1]); @@ -1489,7 +1581,7 @@ static int set_head(int argc, const char **argv, const char *prefix, else if (states.heads.nr > 1) { result |= error(_("Multiple remote HEAD branches. " "Please choose one explicitly with:")); - for (i = 0; i < states.heads.nr; i++) + for (size_t i = 0; i < states.heads.nr; i++) fprintf(stderr, " git remote set-head %s %s\n", argv[0], states.heads.items[i].string); } else @@ -1520,7 +1612,7 @@ static int set_head(int argc, const char **argv, const char *prefix, struct strbuf config_name = STRBUF_INIT; strbuf_addf(&config_name, "remote.%s.followremotehead", remote->name); - git_config_set(config_name.buf, "warn"); + repo_config_set(the_repository, config_name.buf, "warn"); strbuf_release(&config_name); } @@ -1637,7 +1729,7 @@ static int update(int argc, const char **argv, const char *prefix, strvec_push(&cmd.args, argv[i]); if (strcmp(cmd.args.v[cmd.args.nr-1], "default") == 0) { - git_config(get_remote_default, &default_defined); + repo_config(the_repository, get_remote_default, &default_defined); if (!default_defined) { strvec_pop(&cmd.args); strvec_push(&cmd.args, "--all"); @@ -1650,8 +1742,8 @@ static int update(int argc, const char **argv, const char *prefix, static int remove_all_fetch_refspecs(const char *key) { - return git_config_set_multivar_gently(key, NULL, NULL, - CONFIG_FLAGS_MULTI_REPLACE); + return repo_config_set_multivar_gently(the_repository, key, NULL, NULL, + CONFIG_FLAGS_MULTI_REPLACE); } static void add_branches(struct remote *remote, const char **branches, @@ -1714,7 +1806,7 @@ static int set_branches(int argc, const char **argv, const char *prefix, static int get_url(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { - int i, push_mode = 0, all_mode = 0; + int push_mode = 0, all_mode = 0; const char *remotename = NULL; struct remote *remote; struct strvec *url; @@ -1742,7 +1834,7 @@ static int get_url(int argc, const char **argv, const char *prefix, url = push_mode ? push_url_of_remote(remote) : &remote->url; if (all_mode) { - for (i = 0; i < url->nr; i++) + for (size_t i = 0; i < url->nr; i++) printf_ln("%s", url->v[i]); } else { printf_ln("%s", url->v[0]); @@ -1754,7 +1846,7 @@ static int get_url(int argc, const char **argv, const char *prefix, static int set_url(int argc, const char **argv, const char *prefix, struct repository *repo UNUSED) { - int i, push_mode = 0, add_mode = 0, delete_mode = 0; + int push_mode = 0, add_mode = 0, delete_mode = 0; int matches = 0, negative_matches = 0; const char *remotename = NULL; const char *newurl = NULL; @@ -1807,10 +1899,10 @@ static int set_url(int argc, const char **argv, const char *prefix, /* Special cases that add new entry. */ if ((!oldurl && !delete_mode) || add_mode) { if (add_mode) - git_config_set_multivar(name_buf.buf, newurl, + repo_config_set_multivar(the_repository, name_buf.buf, newurl, "^$", 0); else - git_config_set(name_buf.buf, newurl); + repo_config_set(the_repository, name_buf.buf, newurl); goto out; } @@ -1818,7 +1910,7 @@ static int set_url(int argc, const char **argv, const char *prefix, if (regcomp(&old_regex, oldurl, REG_EXTENDED)) die(_("Invalid old URL pattern: %s"), oldurl); - for (i = 0; i < urlset->nr; i++) + for (size_t i = 0; i < urlset->nr; i++) if (!regexec(&old_regex, urlset->v[i], 0, NULL, 0)) matches++; else @@ -1831,10 +1923,10 @@ static int set_url(int argc, const char **argv, const char *prefix, regfree(&old_regex); if (!delete_mode) - git_config_set_multivar(name_buf.buf, newurl, oldurl, 0); + repo_config_set_multivar(the_repository, name_buf.buf, newurl, oldurl, 0); else - git_config_set_multivar(name_buf.buf, NULL, oldurl, - CONFIG_FLAGS_MULTI_REPLACE); + repo_config_set_multivar(the_repository, name_buf.buf, NULL, oldurl, + CONFIG_FLAGS_MULTI_REPLACE); out: strbuf_release(&name_buf); return 0; diff --git a/builtin/repack.c b/builtin/repack.c index 75158d7776..a4def39197 100644 --- a/builtin/repack.c +++ b/builtin/repack.c @@ -223,9 +223,9 @@ static void mark_packs_for_deletion(struct existing_packs *existing, static void remove_redundant_pack(const char *dir_name, const char *base_name) { struct strbuf buf = STRBUF_INIT; - struct multi_pack_index *m = get_local_multi_pack_index(the_repository); + struct multi_pack_index *m = get_multi_pack_index(the_repository->objects->sources); strbuf_addf(&buf, "%s.pack", base_name); - if (m && midx_contains_pack(m, buf.buf)) + if (m && m->local && midx_contains_pack(m, buf.buf)) clear_midx_file(the_repository); strbuf_insertf(&buf, 0, "%s/", dir_name); unlink_pack_path(buf.buf, 1); @@ -1340,7 +1340,7 @@ int cmd_repack(int argc, list_objects_filter_init(&po_args.filter_options); - git_config(repack_config, &cruft_po_args); + repo_config(the_repository, repack_config, &cruft_po_args); argc = parse_options(argc, argv, prefix, builtin_repack_options, git_repack_usage, 0); @@ -1531,7 +1531,7 @@ int cmd_repack(int argc, * midx_has_unknown_packs() will make the decision for * us. */ - if (!get_local_multi_pack_index(the_repository)) + if (!get_multi_pack_index(the_repository->objects->sources)) midx_must_contain_cruft = 1; } @@ -1614,9 +1614,9 @@ int cmd_repack(int argc, string_list_sort(&names); - if (get_local_multi_pack_index(the_repository)) { + if (get_multi_pack_index(the_repository->objects->sources)) { struct multi_pack_index *m = - get_local_multi_pack_index(the_repository); + get_multi_pack_index(the_repository->objects->sources); ALLOC_ARRAY(midx_pack_names, m->num_packs + m->num_packs_in_base); diff --git a/builtin/replace.c b/builtin/replace.c index 5ff2ab723c..900b560a77 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -11,6 +11,7 @@ #include "builtin.h" #include "config.h" #include "editor.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs.h" @@ -488,7 +489,8 @@ static int create_graft(int argc, const char **argv, int force, int gentle) return -1; } - if (write_object_file(buf.buf, buf.len, OBJ_COMMIT, &new_oid)) { + if (odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_COMMIT, &new_oid)) { strbuf_release(&buf); return error(_("could not write replacement commit for: '%s'"), old_ref); @@ -574,7 +576,7 @@ int cmd_replace(int argc, }; disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0); diff --git a/builtin/repo.c b/builtin/repo.c new file mode 100644 index 0000000000..8c6e7f42ab --- /dev/null +++ b/builtin/repo.c @@ -0,0 +1,150 @@ +#define USE_THE_REPOSITORY_VARIABLE + +#include "builtin.h" +#include "environment.h" +#include "parse-options.h" +#include "quote.h" +#include "refs.h" +#include "strbuf.h" +#include "shallow.h" + +static const char *const repo_usage[] = { + "git repo info [--format=(keyvalue|nul)] [<key>...]", + NULL +}; + +typedef int get_value_fn(struct repository *repo, struct strbuf *buf); + +enum output_format { + FORMAT_KEYVALUE, + FORMAT_NUL_TERMINATED, +}; + +struct field { + const char *key; + get_value_fn *get_value; +}; + +static int get_layout_bare(struct repository *repo UNUSED, struct strbuf *buf) +{ + strbuf_addstr(buf, is_bare_repository() ? "true" : "false"); + return 0; +} + +static int get_layout_shallow(struct repository *repo, struct strbuf *buf) +{ + strbuf_addstr(buf, + is_repository_shallow(repo) ? "true" : "false"); + return 0; +} + +static int get_references_format(struct repository *repo, struct strbuf *buf) +{ + strbuf_addstr(buf, + ref_storage_format_to_name(repo->ref_storage_format)); + return 0; +} + +/* repo_info_fields keys must be in lexicographical order */ +static const struct field repo_info_fields[] = { + { "layout.bare", get_layout_bare }, + { "layout.shallow", get_layout_shallow }, + { "references.format", get_references_format }, +}; + +static int repo_info_fields_cmp(const void *va, const void *vb) +{ + const struct field *a = va; + const struct field *b = vb; + + return strcmp(a->key, b->key); +} + +static get_value_fn *get_value_fn_for_key(const char *key) +{ + const struct field search_key = { key, NULL }; + const struct field *found = bsearch(&search_key, repo_info_fields, + ARRAY_SIZE(repo_info_fields), + sizeof(*found), + repo_info_fields_cmp); + return found ? found->get_value : NULL; +} + +static int print_fields(int argc, const char **argv, + struct repository *repo, + enum output_format format) +{ + int ret = 0; + struct strbuf valbuf = STRBUF_INIT; + struct strbuf quotbuf = STRBUF_INIT; + + for (int i = 0; i < argc; i++) { + get_value_fn *get_value; + const char *key = argv[i]; + + get_value = get_value_fn_for_key(key); + + if (!get_value) { + ret = error(_("key '%s' not found"), key); + continue; + } + + strbuf_reset(&valbuf); + strbuf_reset("buf); + + get_value(repo, &valbuf); + + switch (format) { + case FORMAT_KEYVALUE: + quote_c_style(valbuf.buf, "buf, NULL, 0); + printf("%s=%s\n", key, quotbuf.buf); + break; + case FORMAT_NUL_TERMINATED: + printf("%s\n%s%c", key, valbuf.buf, '\0'); + break; + default: + BUG("not a valid output format: %d", format); + } + } + + strbuf_release(&valbuf); + strbuf_release("buf); + return ret; +} + +static int repo_info(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + const char *format_str = "keyvalue"; + enum output_format format; + struct option options[] = { + OPT_STRING(0, "format", &format_str, N_("format"), + N_("output format")), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, repo_usage, 0); + + if (!strcmp(format_str, "keyvalue")) + format = FORMAT_KEYVALUE; + else if (!strcmp(format_str, "nul")) + format = FORMAT_NUL_TERMINATED; + else + die(_("invalid format '%s'"), format_str); + + return print_fields(argc, argv, repo, format); +} + +int cmd_repo(int argc, const char **argv, const char *prefix, + struct repository *repo) +{ + parse_opt_subcommand_fn *fn = NULL; + struct option options[] = { + OPT_SUBCOMMAND("info", &fn, repo_info), + OPT_END() + }; + + argc = parse_options(argc, argv, prefix, options, repo_usage, 0); + + return fn(argc, argv, prefix, repo); +} diff --git a/builtin/rerere.c b/builtin/rerere.c index 1312e79d89..a056cb791b 100644 --- a/builtin/rerere.c +++ b/builtin/rerere.c @@ -66,7 +66,7 @@ int cmd_rerere(int argc, argc = parse_options(argc, argv, prefix, options, rerere_usage, 0); - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); if (autoupdate == 1) flags = RERERE_AUTOUPDATE; diff --git a/builtin/reset.c b/builtin/reset.c index dc50ffc1ac..ed35802af1 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -346,6 +346,7 @@ int cmd_reset(int argc, struct object_id oid; struct pathspec pathspec; int intent_to_add = 0; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; const struct option options[] = { OPT__QUIET(&quiet, N_("be quiet, only report errors")), OPT_BOOL(0, "no-refresh", &no_refresh, @@ -370,6 +371,8 @@ int cmd_reset(int argc, PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater), OPT_BOOL('p', "patch", &patch_mode, N_("select hunks interactively")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that removed paths will be added later")), OPT_PATHSPEC_FROM_FILE(&pathspec_from_file), @@ -377,7 +380,7 @@ int cmd_reset(int argc, OPT_END() }; - git_config(git_reset_config, NULL); + repo_config(the_repository, git_reset_config, NULL); argc = parse_options(argc, argv, prefix, options, git_reset_usage, PARSE_OPT_KEEP_DASHDASH); @@ -420,6 +423,11 @@ int cmd_reset(int argc, oidcpy(&oid, &tree->object.oid); } + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; @@ -427,9 +435,14 @@ int cmd_reset(int argc, if (reset_type != NONE) die(_("options '%s' and '%s' cannot be used together"), "--patch", "--{hard,mixed,soft}"); trace2_cmd_mode("patch-interactive"); - update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, rev, - &pathspec); + update_ref_status = !!run_add_p(the_repository, ADD_P_RESET, + &add_p_opt, rev, &pathspec); goto cleanup; + } else { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); } /* git reset tree [--] paths... can be used to diff --git a/builtin/rev-list.c b/builtin/rev-list.c index 4d0c460f18..99f876ba85 100644 --- a/builtin/rev-list.c +++ b/builtin/rev-list.c @@ -28,6 +28,14 @@ #include "quote.h" #include "strbuf.h" +struct rev_list_info { + struct rev_info *revs; + int flags; + int show_timestamp; + int hdr_termination; + const char *header_prefix; +}; + static const char rev_list_usage[] = "git rev-list [<options>] <commit>... [--] [<path>...]\n" "\n" @@ -636,7 +644,7 @@ int cmd_rev_list(int argc, show_usage_if_asked(argc, argv, rev_list_usage); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); repo_init_revisions(the_repository, &revs, prefix); revs.abbrev = DEFAULT_ABBREV; revs.commit_format = CMIT_FMT_UNSPECIFIED; @@ -652,17 +660,21 @@ int cmd_rev_list(int argc, * * Let "--missing" to conditionally set fetch_if_missing. */ + /* - * NEEDSWORK: These loops that attempt to find presence of - * options without understanding that the options they are - * skipping are broken (e.g., it would not know "--grep + * NEEDSWORK: The next loop is utterly broken. It tries to + * notice an option is used, but without understanding if each + * option takes an argument, which fundamentally would not + * work. It would not know "--grep * --exclude-promisor-objects" is not triggering - * "--exclude-promisor-objects" option). We really need - * setup_revisions() to have a mechanism to allow and disallow - * some sets of options for different commands (like rev-list, - * replay, etc). Such a mechanism should do an early parsing - * of options and be able to manage the `--missing=...` and - * `--exclude-promisor-objects` options below. + * "--exclude-promisor-objects" option, for example. + * + * We really need setup_revisions() to have a mechanism to + * allow and disallow some sets of options for different + * commands (like rev-list, replay, etc). Such a mechanism + * should do an early parsing of options and be able to manage + * the `--missing=...` and `--exclude-promisor-objects` + * options below. */ for (i = 1; i < argc; i++) { const char *arg = argv[i]; diff --git a/builtin/rev-parse.c b/builtin/rev-parse.c index 490da33bec..44ff1b8342 100644 --- a/builtin/rev-parse.c +++ b/builtin/rev-parse.c @@ -734,7 +734,7 @@ int cmd_rev_parse(int argc, /* No options; just report on whether we're in a git repo or not. */ if (argc == 1) { setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); return 0; } @@ -769,7 +769,7 @@ int cmd_rev_parse(int argc, /* The rest of the options require a git repository. */ if (!did_repo_setup) { prefix = setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); did_repo_setup = 1; prepare_repo_settings(the_repository); diff --git a/builtin/revert.c b/builtin/revert.c index e07c2217fe..c3f92b585d 100644 --- a/builtin/revert.c +++ b/builtin/revert.c @@ -111,7 +111,7 @@ static int run_sequencer(int argc, const char **argv, const char *prefix, const char * const * usage_str = revert_or_cherry_pick_usage(opts); const char *me = action_name(opts); const char *cleanup_arg = NULL; - const char sentinel_value; + const char sentinel_value = 0; /* value not important */ const char *strategy = &sentinel_value; const char *gpg_sign = &sentinel_value; enum empty_action empty_opt = EMPTY_COMMIT_UNSPECIFIED; diff --git a/builtin/rm.c b/builtin/rm.c index a6565a69cf..05d89e98c3 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -9,6 +9,7 @@ #include "builtin.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "lockfile.h" #include "dir.h" #include "gettext.h" @@ -271,7 +272,7 @@ int cmd_rm(int argc, struct pathspec pathspec; char *seen; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, builtin_rm_options, builtin_rm_usage, 0); diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 28b69d26b4..8b81c8a848 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "hex.h" #include "pkt-line.h" #include "run-command.h" diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 60adc5e7a5..b91acf45c8 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -421,7 +421,7 @@ int cmd_shortlog(int argc, if (nongit && !the_hash_algo) repo_set_hash_algo(the_repository, GIT_HASH_DEFAULT); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); shortlog_init(&log); repo_init_revisions(the_repository, &rev, prefix); parse_options_start(&ctx, argc, argv, prefix, options, diff --git a/builtin/show-branch.c b/builtin/show-branch.c index 525b231d87..1ab7db9d2c 100644 --- a/builtin/show-branch.c +++ b/builtin/show-branch.c @@ -710,7 +710,7 @@ int cmd_show_branch(int ac, init_commit_name_slab(&name_slab); - git_config(git_show_branch_config, NULL); + repo_config(the_repository, git_show_branch_config, NULL); /* If nothing is specified, try the default first */ if (ac == 1 && default_args.nr) { diff --git a/builtin/show-ref.c b/builtin/show-ref.c index 117709cb07..0b6f9edf86 100644 --- a/builtin/show-ref.c +++ b/builtin/show-ref.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "refs/refs-internal.h" @@ -324,7 +325,7 @@ struct repository *repo UNUSED) OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, show_ref_options, show_ref_usage, 0); diff --git a/builtin/sparse-checkout.c b/builtin/sparse-checkout.c index 1bf01591b2..8c333b3e2e 100644 --- a/builtin/sparse-checkout.c +++ b/builtin/sparse-checkout.c @@ -1082,7 +1082,7 @@ int cmd_sparse_checkout(int argc, builtin_sparse_checkout_options, builtin_sparse_checkout_usage, 0); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); prepare_repo_settings(the_repository); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/stash.c b/builtin/stash.c index e2f95cc2eb..f5ddee5c7f 100644 --- a/builtin/stash.c +++ b/builtin/stash.c @@ -738,7 +738,8 @@ cleanup: return ret; } -static int reject_reflog_ent(struct object_id *ooid UNUSED, +static int reject_reflog_ent(const char *refname UNUSED, + struct object_id *ooid UNUSED, struct object_id *noid UNUSED, const char *email UNUSED, timestamp_t timestamp UNUSED, @@ -979,7 +980,7 @@ static int show_stash(int argc, const char **argv, const char *prefix, int do_usage = 0; init_diff_ui_defaults(); - git_config(git_diff_ui_config, NULL); + repo_config(the_repository, git_diff_ui_config, NULL); repo_init_revisions(the_repository, &rev, prefix); argc = parse_options(argc, argv, prefix, options, git_stash_show_usage, @@ -1301,7 +1302,8 @@ done: } static int stash_patch(struct stash_info *info, const struct pathspec *ps, - struct strbuf *out_patch, int quiet) + struct strbuf *out_patch, int quiet, + struct add_p_opt *add_p_opt) { int ret = 0; struct child_process cp_read_tree = CHILD_PROCESS_INIT; @@ -1326,7 +1328,7 @@ static int stash_patch(struct stash_info *info, const struct pathspec *ps, old_index_env = xstrdup_or_null(getenv(INDEX_ENVIRONMENT)); setenv(INDEX_ENVIRONMENT, the_repository->index_file, 1); - ret = !!run_add_p(the_repository, ADD_P_STASH, NULL, ps); + ret = !!run_add_p(the_repository, ADD_P_STASH, add_p_opt, NULL, ps); the_repository->index_file = old_repo_index_file; if (old_index_env && *old_index_env) @@ -1421,8 +1423,8 @@ done: } static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_buf, - int include_untracked, int patch_mode, int only_staged, - struct stash_info *info, struct strbuf *patch, + int include_untracked, int patch_mode, struct add_p_opt *add_p_opt, + int only_staged, struct stash_info *info, struct strbuf *patch, int quiet) { int ret = 0; @@ -1503,7 +1505,7 @@ static int do_create_stash(const struct pathspec *ps, struct strbuf *stash_msg_b untracked_commit_option = 1; } if (patch_mode) { - ret = stash_patch(info, ps, patch, quiet); + ret = stash_patch(info, ps, patch, quiet, add_p_opt); if (ret < 0) { if (!quiet) fprintf_ln(stderr, _("Cannot save the current " @@ -1578,7 +1580,7 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, if (!check_changes_tracked_files(&ps)) return 0; - ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, 0, &info, + ret = do_create_stash(&ps, &stash_msg_buf, 0, 0, NULL, 0, &info, NULL, 0); if (!ret) printf_ln("%s", oid_to_hex(&info.w_commit)); @@ -1589,7 +1591,8 @@ static int create_stash(int argc, const char **argv, const char *prefix UNUSED, } static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int quiet, - int keep_index, int patch_mode, int include_untracked, int only_staged) + int keep_index, int patch_mode, struct add_p_opt *add_p_opt, + int include_untracked, int only_staged) { int ret = 0; struct stash_info info = STASH_INFO_INIT; @@ -1659,8 +1662,8 @@ static int do_push_stash(const struct pathspec *ps, const char *stash_msg, int q if (stash_msg) strbuf_addstr(&stash_msg_buf, stash_msg); - if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, only_staged, - &info, &patch, quiet)) { + if (do_create_stash(ps, &stash_msg_buf, include_untracked, patch_mode, + add_p_opt, only_staged, &info, &patch, quiet)) { ret = -1; goto done; } @@ -1833,6 +1836,7 @@ static int push_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; char *pathspec_from_file = NULL; struct pathspec ps; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1840,6 +1844,8 @@ static int push_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1895,8 +1901,20 @@ static int push_stash(int argc, const char **argv, const char *prefix, die(_("the option '%s' requires '%s'"), "--pathspec-file-nul", "--pathspec-from-file"); } + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, patch_mode, - include_untracked, only_staged); + &add_p_opt, include_untracked, only_staged); clear_pathspec(&ps); free(pathspec_from_file); @@ -1921,6 +1939,7 @@ static int save_stash(int argc, const char **argv, const char *prefix, const char *stash_msg = NULL; struct pathspec ps; struct strbuf stash_msg_buf = STRBUF_INIT; + struct add_p_opt add_p_opt = ADD_P_OPT_INIT; struct option options[] = { OPT_BOOL('k', "keep-index", &keep_index, N_("keep index")), @@ -1928,6 +1947,8 @@ static int save_stash(int argc, const char **argv, const char *prefix, N_("stash staged changes only")), OPT_BOOL('p', "patch", &patch_mode, N_("stash in patch mode")), + OPT_DIFF_UNIFIED(&add_p_opt.context), + OPT_DIFF_INTERHUNK_CONTEXT(&add_p_opt.interhunkcontext), OPT__QUIET(&quiet, N_("quiet mode")), OPT_BOOL('u', "include-untracked", &include_untracked, N_("include untracked files in stash")), @@ -1946,8 +1967,22 @@ static int save_stash(int argc, const char **argv, const char *prefix, stash_msg = strbuf_join_argv(&stash_msg_buf, argc, argv, ' '); memset(&ps, 0, sizeof(ps)); + + if (add_p_opt.context < -1) + die(_("'%s' cannot be negative"), "--unified"); + if (add_p_opt.interhunkcontext < -1) + die(_("'%s' cannot be negative"), "--inter-hunk-context"); + + if (!patch_mode) { + if (add_p_opt.context != -1) + die(_("the option '%s' requires '%s'"), "--unified", "--patch"); + if (add_p_opt.interhunkcontext != -1) + die(_("the option '%s' requires '%s'"), "--inter-hunk-context", "--patch"); + } + ret = do_push_stash(&ps, stash_msg, quiet, keep_index, - patch_mode, include_untracked, only_staged); + patch_mode, &add_p_opt, include_untracked, + only_staged); strbuf_release(&stash_msg_buf); return ret; @@ -2173,7 +2208,8 @@ struct stash_entry_data { size_t count; }; -static int collect_stash_entries(struct object_id *old_oid UNUSED, +static int collect_stash_entries(const char *refname UNUSED, + struct object_id *old_oid UNUSED, struct object_id *new_oid, const char *committer UNUSED, timestamp_t timestamp UNUSED, @@ -2358,7 +2394,7 @@ int cmd_stash(int argc, const char **args_copy; int ret; - git_config(git_stash_config, NULL); + repo_config(the_repository, git_stash_config, NULL); argc = parse_options(argc, argv, prefix, options, git_stash_usage, PARSE_OPT_SUBCOMMAND_OPTIONAL | diff --git a/builtin/stripspace.c b/builtin/stripspace.c index e147f3ff92..4a566cbc5d 100644 --- a/builtin/stripspace.c +++ b/builtin/stripspace.c @@ -55,7 +55,7 @@ int cmd_stripspace(int argc, if (mode == STRIP_COMMENTS || mode == COMMENT_LINES) { setup_git_directory_gently(&nongit); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); } if (strbuf_read(&buf, 0, 1024) < 0) diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index d8a6fa47e5..07a1935cbe 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -32,6 +32,8 @@ #include "advice.h" #include "branch.h" #include "list-objects-filter-options.h" +#include "wildmatch.h" +#include "strbuf.h" #define OPT_QUIET (1 << 0) #define OPT_CACHED (1 << 1) @@ -53,7 +55,7 @@ static char *resolve_relative_url(const char *rel_url, const char *up_path, int struct strbuf remotesb = STRBUF_INIT; strbuf_addf(&remotesb, "remote.%s.url", remote); - if (git_config_get_string(remotesb.buf, &remoteurl)) { + if (repo_config_get_string(the_repository, remotesb.buf, &remoteurl)) { if (!quiet) warning(_("could not look up configuration '%s'. " "Assuming this repository is its own " @@ -458,7 +460,7 @@ static void init_submodule(const char *path, const char *prefix, */ if (!is_submodule_active(the_repository, path)) { strbuf_addf(&sb, "submodule.%s.active", sub->name); - git_config_set_gently(sb.buf, "true"); + repo_config_set_gently(the_repository, sb.buf, "true"); strbuf_reset(&sb); } @@ -468,7 +470,7 @@ static void init_submodule(const char *path, const char *prefix, * .gitmodules, so look it up directly. */ strbuf_addf(&sb, "submodule.%s.url", sub->name); - if (git_config_get_string(sb.buf, &url)) { + if (repo_config_get_string(the_repository, sb.buf, &url)) { if (!sub->url) die(_("No url found for submodule path '%s' in .gitmodules"), displaypath); @@ -484,7 +486,7 @@ static void init_submodule(const char *path, const char *prefix, free(oldurl); } - if (git_config_set_gently(sb.buf, url)) + if (repo_config_set_gently(the_repository, sb.buf, url)) die(_("Failed to register url for submodule path '%s'"), displaypath); if (!(flags & OPT_QUIET)) @@ -496,7 +498,7 @@ static void init_submodule(const char *path, const char *prefix, /* Copy "update" setting when it is not set yet */ strbuf_addf(&sb, "submodule.%s.update", sub->name); - if (git_config_get_string_tmp(sb.buf, &upd) && + if (repo_config_get_string_tmp(the_repository, sb.buf, &upd) && sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) { if (sub->update_strategy.type == SM_UPDATE_COMMAND) { fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"), @@ -506,7 +508,7 @@ static void init_submodule(const char *path, const char *prefix, upd = submodule_update_type_to_string(sub->update_strategy.type); } - if (git_config_set_gently(sb.buf, upd)) + if (repo_config_set_gently(the_repository, sb.buf, upd)) die(_("Failed to register update mode for submodule path '%s'"), displaypath); } strbuf_release(&sb); @@ -549,7 +551,7 @@ static int module_init(int argc, const char **argv, const char *prefix, * If there are no path args and submodule.active is set then, * by default, only initialize 'active' modules. */ - if (!argc && !git_config_get("submodule.active")) + if (!argc && !repo_config_get(the_repository, "submodule.active")) module_list_active(&list); info.prefix = prefix; @@ -649,7 +651,7 @@ static void status_submodule(const char *path, const struct object_id *ce_oid, "--ignore-submodules=dirty", "--quiet", "--", path, NULL); - git_config(git_diff_basic_config, NULL); + repo_config(the_repository, git_diff_basic_config, NULL); repo_init_revisions(the_repository, &rev, NULL); rev.abbrev = 0; @@ -1034,7 +1036,7 @@ static void prepare_submodule_summary(struct summary_cb *info, config_key = xstrfmt("submodule.%s.ignore", sub->name); - if (!git_config_get_string_tmp(config_key, &value)) + if (!repo_config_get_string_tmp(the_repository, config_key, &value)) ignore_all = !strcmp(value, "all"); else if (sub->ignore) ignore_all = !strcmp(sub->ignore, "all"); @@ -1108,7 +1110,7 @@ static int compute_summary_module_list(struct object_id *head_oid, if (info->argc) strvec_pushv(&diff_args, info->argv); - git_config(git_diff_basic_config, NULL); + repo_config(the_repository, git_diff_basic_config, NULL); repo_init_revisions(the_repository, &rev, info->prefix); rev.abbrev = 0; precompose_argv_prefix(diff_args.nr, diff_args.v, NULL); @@ -1262,7 +1264,7 @@ static void sync_submodule(const char *path, const char *prefix, strbuf_reset(&sb); strbuf_addf(&sb, "submodule.%s.url", sub->name); - if (git_config_set_gently(sb.buf, super_config_url)) + if (repo_config_set_gently(the_repository, sb.buf, super_config_url)) die(_("failed to register url for submodule path '%s'"), displaypath); @@ -1280,7 +1282,7 @@ static void sync_submodule(const char *path, const char *prefix, submodule_to_gitdir(the_repository, &sb, path); strbuf_addstr(&sb, "/config"); - if (git_config_set_in_file_gently(sb.buf, remote_key, NULL, sub_origin_url)) + if (repo_config_set_in_file_gently(the_repository, sb.buf, remote_key, NULL, sub_origin_url)) die(_("failed to update remote for submodule '%s'"), path); @@ -1623,11 +1625,11 @@ static void prepare_possible_alternates(const char *sm_name, char *sm_alternate = NULL, *error_strategy = NULL; struct submodule_alternate_setup sas = SUBMODULE_ALTERNATE_SETUP_INIT; - git_config_get_string("submodule.alternateLocation", &sm_alternate); + repo_config_get_string(the_repository, "submodule.alternateLocation", &sm_alternate); if (!sm_alternate) return; - git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); + repo_config_get_string(the_repository, "submodule.alternateErrorStrategy", &error_strategy); if (!error_strategy) error_strategy = xstrdup("die"); @@ -1808,14 +1810,14 @@ static int clone_submodule(const struct module_clone_data *clone_data, die(_("could not get submodule directory for '%s'"), clone_data_path); /* setup alternateLocation and alternateErrorStrategy in the cloned submodule if needed */ - git_config_get_string("submodule.alternateLocation", &sm_alternate); + repo_config_get_string(the_repository, "submodule.alternateLocation", &sm_alternate); if (sm_alternate) - git_config_set_in_file(p, "submodule.alternateLocation", - sm_alternate); - git_config_get_string("submodule.alternateErrorStrategy", &error_strategy); + repo_config_set_in_file(the_repository, p, "submodule.alternateLocation", + sm_alternate); + repo_config_get_string(the_repository, "submodule.alternateErrorStrategy", &error_strategy); if (error_strategy) - git_config_set_in_file(p, "submodule.alternateErrorStrategy", - error_strategy); + repo_config_set_in_file(the_repository, p, "submodule.alternateErrorStrategy", + error_strategy); free(sm_alternate); free(error_strategy); @@ -2522,7 +2524,7 @@ static int ensure_core_worktree(const char *path) abs_path = absolute_pathdup(path); rel_path = relative_path(abs_path, subrepo.gitdir, &sb); - git_config_set_in_file(cfg_file, "core.worktree", rel_path); + repo_config_set_in_file(the_repository, cfg_file, "core.worktree", rel_path); free(cfg_file); free(abs_path); @@ -2830,7 +2832,7 @@ static int module_update(int argc, const char **argv, const char *prefix, }; update_clone_config_from_gitmodules(&opt.max_jobs); - git_config(git_update_clone_config, &opt.max_jobs); + repo_config(the_repository, git_update_clone_config, &opt.max_jobs); argc = parse_options(argc, argv, prefix, module_update_options, git_submodule_helper_usage, 0); @@ -2878,7 +2880,7 @@ static int module_update(int argc, const char **argv, const char *prefix, * If there are no path args and submodule.active is set then, * by default, only initialize 'active' modules. */ - if (!argc && !git_config_get("submodule.active")) + if (!argc && !repo_config_get(the_repository, "submodule.active")) module_list_active(&list); info.prefix = opt.prefix; @@ -3128,7 +3130,7 @@ static int module_create_branch(int argc, const char **argv, const char *prefix, NULL }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); track = git_branch_track; argc = parse_options(argc, argv, prefix, options, usage, 0); @@ -3307,9 +3309,11 @@ static void configure_added_submodule(struct add_data *add_data) char *key; struct child_process add_submod = CHILD_PROCESS_INIT; struct child_process add_gitmodules = CHILD_PROCESS_INIT; + const struct string_list *values; + int matched = 0; key = xstrfmt("submodule.%s.url", add_data->sm_name); - git_config_set_gently(key, add_data->realrepo); + repo_config_set_gently(the_repository, key, add_data->realrepo); free(key); add_submod.git_cmd = 1; @@ -3349,20 +3353,28 @@ static void configure_added_submodule(struct add_data *add_data) * is_submodule_active(), since that function needs to find * out the value of "submodule.active" again anyway. */ - if (!git_config_get("submodule.active")) { + if (repo_config_get(the_repository, "submodule.active") || /* key absent */ + repo_config_get_string_multi(the_repository, "submodule.active", &values)) { /* * If the submodule being added isn't already covered by the * current configured pathspec, set the submodule's active flag */ - if (!is_submodule_active(the_repository, add_data->sm_path)) { + key = xstrfmt("submodule.%s.active", add_data->sm_name); + repo_config_set_gently(the_repository, key, "true"); + free(key); + } else { + for (size_t i = 0; i < values->nr; i++) { + const char *pat = values->items[i].string; + if (!wildmatch(pat, add_data->sm_path, 0)) { /* match found */ + matched = 1; + break; + } + } + if (!matched) { /* no pattern matched -> force-enable */ key = xstrfmt("submodule.%s.active", add_data->sm_name); - git_config_set_gently(key, "true"); + repo_config_set_gently(the_repository, key, "true"); free(key); } - } else { - key = xstrfmt("submodule.%s.active", add_data->sm_name); - git_config_set_gently(key, "true"); - free(key); } } @@ -3423,6 +3435,9 @@ static int module_add(int argc, const char **argv, const char *prefix, struct add_data add_data = ADD_DATA_INIT; const char *ref_storage_format = NULL; char *to_free = NULL; + const struct submodule *existing; + struct strbuf buf = STRBUF_INIT; + char *sm_name_to_free = NULL; struct option options[] = { OPT_STRING('b', "branch", &add_data.branch, N_("branch"), N_("branch of repository to add as submodule")), @@ -3525,6 +3540,28 @@ static int module_add(int argc, const char **argv, const char *prefix, if(!add_data.sm_name) add_data.sm_name = add_data.sm_path; + existing = submodule_from_name(the_repository, + null_oid(the_hash_algo), + add_data.sm_name); + + if (existing && strcmp(existing->path, add_data.sm_path)) { + if (!force) { + die(_("submodule name '%s' already used for path '%s'"), + add_data.sm_name, existing->path); + } + /* --force: build <name><n> until unique */ + for (int i = 1; ; i++) { + strbuf_reset(&buf); + strbuf_addf(&buf, "%s%d", add_data.sm_name, i); + if (!submodule_from_name(the_repository, + null_oid(the_hash_algo), + buf.buf)) { + break; + } + } + add_data.sm_name = sm_name_to_free = strbuf_detach(&buf, NULL); + } + if (check_submodule_name(add_data.sm_name)) die(_("'%s' is not a valid submodule name"), add_data.sm_name); @@ -3540,6 +3577,7 @@ static int module_add(int argc, const char **argv, const char *prefix, ret = 0; cleanup: + free(sm_name_to_free); free(add_data.sm_path); free(to_free); strbuf_release(&sb); diff --git a/builtin/symbolic-ref.c b/builtin/symbolic-ref.c index 299d23d76a..231e41e715 100644 --- a/builtin/symbolic-ref.c +++ b/builtin/symbolic-ref.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "refs.h" #include "parse-options.h" @@ -59,7 +60,7 @@ int cmd_symbolic_ref(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_symbolic_ref_usage, 0); if (msg && !*msg) diff --git a/builtin/tag.c b/builtin/tag.c index 46cbf892e3..f0665af3ac 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -271,8 +271,8 @@ static int build_tag_object(struct strbuf *buf, int sign, struct object_id *resu struct object_id *compat_oid = NULL, compat_oid_buf; if (sign && do_sign(buf, &compat_oid, &compat_oid_buf) < 0) return error(_("unable to sign the tag")); - if (write_object_file_flags(buf->buf, buf->len, OBJ_TAG, result, - compat_oid, 0) < 0) + if (odb_write_object_ext(the_repository->objects, buf->buf, + buf->len, OBJ_TAG, result, compat_oid, 0) < 0) return error(_("unable to write tag file")); return 0; } @@ -546,7 +546,7 @@ int cmd_tag(int argc, * Try to set sort keys from config. If config does not set any, * fall back on default (refname) sorting. */ - git_config(git_tag_config, &sorting_options); + repo_config(the_repository, git_tag_config, &sorting_options); if (!sorting_options.nr) string_list_append(&sorting_options, "refname"); diff --git a/builtin/unpack-file.c b/builtin/unpack-file.c index 4360872ae0..87877a9fab 100644 --- a/builtin/unpack-file.c +++ b/builtin/unpack-file.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "hex.h" #include "object-file.h" #include "object-name.h" @@ -43,7 +44,7 @@ int cmd_unpack_file(int argc, if (repo_get_oid(the_repository, argv[1], &oid)) die("Not a valid object name %s", argv[1]); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); puts(create_temp_file(&oid)); return 0; diff --git a/builtin/unpack-objects.c b/builtin/unpack-objects.c index a69d59eb50..7ae7c82b6c 100644 --- a/builtin/unpack-objects.c +++ b/builtin/unpack-objects.c @@ -204,8 +204,8 @@ static void write_cached_object(struct object *obj, struct obj_buffer *obj_buf) { struct object_id oid; - if (write_object_file(obj_buf->buffer, obj_buf->size, - obj->type, &oid) < 0) + if (odb_write_object(the_repository->objects, obj_buf->buffer, obj_buf->size, + obj->type, &oid) < 0) die("failed to write object %s", oid_to_hex(&obj->oid)); obj->flags |= FLAG_WRITTEN; } @@ -272,16 +272,16 @@ static void write_object(unsigned nr, enum object_type type, void *buf, unsigned long size) { if (!strict) { - if (write_object_file(buf, size, type, - &obj_list[nr].oid) < 0) + if (odb_write_object(the_repository->objects, buf, size, type, + &obj_list[nr].oid) < 0) die("failed to write object"); added_object(nr, type, buf, size); free(buf); obj_list[nr].obj = NULL; } else if (type == OBJ_BLOB) { struct blob *blob; - if (write_object_file(buf, size, type, - &obj_list[nr].oid) < 0) + if (odb_write_object(the_repository->objects, buf, size, type, + &obj_list[nr].oid) < 0) die("failed to write object"); added_object(nr, type, buf, size); free(buf); @@ -403,7 +403,8 @@ static void stream_blob(unsigned long size, unsigned nr) data.zstream = &zstream; git_inflate_init(&zstream); - if (stream_loose_object(&in_stream, size, &info->oid)) + if (stream_loose_object(the_repository->objects->sources, + &in_stream, size, &info->oid)) die(_("failed to write object in stream")); if (data.status != Z_STREAM_END) @@ -621,7 +622,7 @@ int cmd_unpack_objects(int argc, disable_replace_refs(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); quiet = !isatty(2); diff --git a/builtin/update-index.c b/builtin/update-index.c index 0c1d4ed55b..2380f3ccd6 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -1103,7 +1103,7 @@ int cmd_update_index(int argc, show_usage_with_options_if_asked(argc, argv, update_index_usage, options); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); prepare_repo_settings(r); the_repository->settings.command_requires_full_index = 0; diff --git a/builtin/update-ref.c b/builtin/update-ref.c index 1e6131e04a..195437e7c6 100644 --- a/builtin/update-ref.c +++ b/builtin/update-ref.c @@ -3,6 +3,7 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hash.h" #include "hex.h" @@ -769,7 +770,7 @@ int cmd_update_ref(int argc, OPT_END(), }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_update_ref_usage, 0); if (msg && !*msg) diff --git a/builtin/update-server-info.c b/builtin/update-server-info.c index ba702d30ef..4c12968a83 100644 --- a/builtin/update-server-info.c +++ b/builtin/update-server-info.c @@ -1,5 +1,6 @@ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "server-info.h" diff --git a/builtin/var.c b/builtin/var.c index ada642a9fe..cc3a43cde2 100644 --- a/builtin/var.c +++ b/builtin/var.c @@ -11,6 +11,7 @@ #include "attr.h" #include "config.h" #include "editor.h" +#include "environment.h" #include "ident.h" #include "pager.h" #include "refs.h" @@ -181,7 +182,7 @@ static void list_vars(void) if (ptr->multivalued && *val) { struct string_list list = STRING_LIST_INIT_DUP; - string_list_split(&list, val, '\n', -1); + string_list_split(&list, val, "\n", -1); for (size_t i = 0; i < list.nr; i++) printf("%s=%s\n", ptr->name, list.items[i].string); string_list_clear(&list, 0); @@ -226,11 +227,11 @@ int cmd_var(int argc, usage(var_usage); if (strcmp(argv[1], "-l") == 0) { - git_config(show_config, NULL); + repo_config(the_repository, show_config, NULL); list_vars(); return 0; } - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); git_var = get_git_var(argv[1]); if (!git_var) diff --git a/builtin/verify-commit.c b/builtin/verify-commit.c index 5f749a30da..62398acd72 100644 --- a/builtin/verify-commit.c +++ b/builtin/verify-commit.c @@ -7,6 +7,7 @@ */ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "object-name.h" #include "commit.h" diff --git a/builtin/verify-pack.c b/builtin/verify-pack.c index 34e4ed715f..65fd6629a0 100644 --- a/builtin/verify-pack.c +++ b/builtin/verify-pack.c @@ -1,6 +1,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "run-command.h" #include "parse-options.h" @@ -81,7 +82,7 @@ int cmd_verify_pack(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, prefix, verify_pack_options, verify_pack_usage, 0); if (argc < 1) diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index ed1c40338f..cd6bc11095 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -7,6 +7,7 @@ */ #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "tag.h" #include "object-name.h" diff --git a/builtin/worktree.c b/builtin/worktree.c index 2dceeeed8b..812774a5ca 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -379,13 +379,13 @@ static void copy_filtered_worktree_config(const char *worktree_git_dir) if (!git_configset_get_bool(&cs, "core.bare", &bare) && bare && - git_config_set_multivar_in_file_gently( + repo_config_set_multivar_in_file_gently(the_repository, to_file, "core.bare", NULL, "true", NULL, 0)) error(_("failed to unset '%s' in '%s'"), "core.bare", to_file); if (!git_configset_get(&cs, "core.worktree") && - git_config_set_in_file_gently(to_file, - "core.worktree", NULL, NULL)) + repo_config_set_in_file_gently(the_repository, to_file, + "core.worktree", NULL, NULL)) error(_("failed to unset '%s' in '%s'"), "core.worktree", to_file); @@ -1448,7 +1448,7 @@ int cmd_worktree(int ac, OPT_END() }; - git_config(git_worktree_config, NULL); + repo_config(the_repository, git_worktree_config, NULL); if (!prefix) prefix = ""; diff --git a/builtin/write-tree.c b/builtin/write-tree.c index cfec044710..e3bd1a40db 100644 --- a/builtin/write-tree.c +++ b/builtin/write-tree.c @@ -6,6 +6,7 @@ #define USE_THE_REPOSITORY_VARIABLE #include "builtin.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "tree.h" @@ -43,7 +44,7 @@ int cmd_write_tree(int argc, OPT_END() }; - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); argc = parse_options(argc, argv, cmd_prefix, write_tree_options, write_tree_usage, 0); diff --git a/bulk-checkin.c b/bulk-checkin.c index 16df86c0ba..b2809ab039 100644 --- a/bulk-checkin.c +++ b/bulk-checkin.c @@ -46,7 +46,7 @@ static void finish_tmp_packfile(struct strbuf *basename, stage_tmp_packfiles(the_repository, basename, pack_tmp_name, written_list, nr_written, NULL, pack_idx_opts, hash, &idx_tmp_name); - rename_tmp_packfile_idx(basename, &idx_tmp_name); + rename_tmp_packfile_idx(the_repository, basename, &idx_tmp_name); free(idx_tmp_name); } diff --git a/cache-tree.c b/cache-tree.c index a4bc14ad15..66ef2becbe 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -456,9 +456,8 @@ static int update_one(struct cache_tree *it, } else if (dryrun) { hash_object_file(the_hash_algo, buffer.buf, buffer.len, OBJ_TREE, &it->oid); - } else if (write_object_file_flags(buffer.buf, buffer.len, OBJ_TREE, - &it->oid, NULL, flags & WRITE_TREE_SILENT - ? WRITE_OBJECT_FILE_SILENT : 0)) { + } else if (odb_write_object_ext(the_repository->objects, buffer.buf, buffer.len, OBJ_TREE, + &it->oid, NULL, flags & WRITE_TREE_SILENT ? WRITE_OBJECT_SILENT : 0)) { strbuf_release(&buffer); return -1; } diff --git a/checkout.c b/checkout.c index 0b1cf8b40b..1588b116ee 100644 --- a/checkout.c +++ b/checkout.c @@ -52,7 +52,7 @@ char *unique_tracking_name(const char *name, struct object_id *oid, { struct tracking_name_data cb_data = TRACKING_NAME_DATA_INIT; const char *default_remote = NULL; - if (!git_config_get_string_tmp("checkout.defaultremote", &default_remote)) + if (!repo_config_get_string_tmp(the_repository, "checkout.defaultremote", &default_remote)) cb_data.default_remote = default_remote; cb_data.src_ref = xstrfmt("refs/heads/%s", name); cb_data.dst_oid = oid; diff --git a/ci/print-test-failures.sh b/ci/print-test-failures.sh index dc910e5160..5545e77c13 100755 --- a/ci/print-test-failures.sh +++ b/ci/print-test-failures.sh @@ -41,7 +41,7 @@ do case "$CI_TYPE" in github-actions) mkdir -p failed-test-artifacts - echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:t}/failed-test-artifacts" >>$GITHUB_ENV + echo "FAILED_TEST_ARTIFACTS=${TEST_OUTPUT_DIRECTORY:-t}/failed-test-artifacts" >>$GITHUB_ENV cp "${TEST_EXIT%.exit}.out" failed-test-artifacts/ tar czf failed-test-artifacts/"$test_name".trash.tar.gz "$trash_dir" continue diff --git a/combine-diff.c b/combine-diff.c index 4ea2dc93c4..3878faabe7 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1315,7 +1315,7 @@ static struct diff_filepair *combined_pair(struct combine_diff_path *p, struct diff_filepair *pair; struct diff_filespec *pool; - pair = xmalloc(sizeof(*pair)); + CALLOC_ARRAY(pair, 1); CALLOC_ARRAY(pool, st_add(num_parent, 1)); pair->one = pool + 1; pair->two = pool; diff --git a/command-list.txt b/command-list.txt index b715777b24..accd3d0c4b 100644 --- a/command-list.txt +++ b/command-list.txt @@ -165,6 +165,7 @@ git-remote ancillarymanipulators complete git-repack ancillarymanipulators complete git-replace ancillarymanipulators complete git-replay plumbingmanipulators +git-repo plumbinginterrogators git-request-pull foreignscminterface complete git-rerere ancillaryinterrogators git-reset mainporcelain history diff --git a/commit-graph.c b/commit-graph.c index dc1f29dd2f..2f20f66cfd 100644 --- a/commit-graph.c +++ b/commit-graph.c @@ -1,9 +1,9 @@ -#define USE_THE_REPOSITORY_VARIABLE #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "config.h" #include "csum-file.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" @@ -28,7 +28,7 @@ #include "tree.h" #include "chunk-format.h" -void git_test_write_commit_graph_or_die(void) +void git_test_write_commit_graph_or_die(struct odb_source *source) { int flags = 0; if (!git_env_bool(GIT_TEST_COMMIT_GRAPH, 0)) @@ -37,8 +37,7 @@ void git_test_write_commit_graph_or_die(void) if (git_env_bool(GIT_TEST_COMMIT_GRAPH_CHANGED_PATHS, 0)) flags = COMMIT_GRAPH_WRITE_BLOOM_FILTERS; - if (write_commit_graph_reachable(the_repository->objects->sources, - flags, NULL)) + if (write_commit_graph_reachable(source, flags, NULL)) die("failed to write commit-graph under GIT_TEST_COMMIT_GRAPH"); } @@ -53,8 +52,6 @@ void git_test_write_commit_graph_or_die(void) #define GRAPH_CHUNKID_BLOOMDATA 0x42444154 /* "BDAT" */ #define GRAPH_CHUNKID_BASE 0x42415345 /* "BASE" */ -#define GRAPH_DATA_WIDTH (the_hash_algo->rawsz + 16) - #define GRAPH_VERSION_1 0x1 #define GRAPH_VERSION GRAPH_VERSION_1 @@ -66,8 +63,6 @@ void git_test_write_commit_graph_or_die(void) #define GRAPH_HEADER_SIZE 8 #define GRAPH_FANOUT_SIZE (4 * 256) -#define GRAPH_MIN_SIZE (GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE \ - + GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) #define CORRECTED_COMMIT_DATE_OFFSET_OVERFLOW (1ULL << 31) @@ -80,6 +75,16 @@ define_commit_slab(topo_level_slab, uint32_t); define_commit_slab(commit_pos, int); static struct commit_pos commit_pos = COMMIT_SLAB_INIT(1, commit_pos); +static size_t graph_data_width(const struct git_hash_algo *algop) +{ + return algop->rawsz + 16; +} + +static size_t graph_min_size(const struct git_hash_algo *algop) +{ + return GRAPH_HEADER_SIZE + 4 * CHUNK_TOC_ENTRY_SIZE + GRAPH_FANOUT_SIZE + algop->rawsz; +} + static void set_commit_pos(struct repository *r, const struct object_id *oid) { static int32_t max_pos; @@ -248,9 +253,8 @@ int open_commit_graph(const char *graph_file, int *fd, struct stat *st) return 1; } -struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, - int fd, struct stat *st, - struct odb_source *source) +struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source, + int fd, struct stat *st) { void *graph_map; size_t graph_size; @@ -258,16 +262,15 @@ struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, graph_size = xsize_t(st->st_size); - if (graph_size < GRAPH_MIN_SIZE) { + if (graph_size < graph_min_size(source->odb->repo->hash_algo)) { close(fd); error(_("commit-graph file is too small")); return NULL; } graph_map = xmmap(NULL, graph_size, PROT_READ, MAP_PRIVATE, fd, 0); close(fd); - prepare_repo_settings(r); - ret = parse_commit_graph(&r->settings, graph_map, graph_size); + ret = parse_commit_graph(source->odb->repo, graph_map, graph_size); if (ret) ret->odb_source = source; else @@ -305,7 +308,7 @@ static int graph_read_oid_lookup(const unsigned char *chunk_start, { struct commit_graph *g = data; g->chunk_oid_lookup = chunk_start; - if (chunk_size / g->hash_len != g->num_commits) + if (chunk_size / g->hash_algo->rawsz != g->num_commits) return error(_("commit-graph OID lookup chunk is the wrong size")); return 0; } @@ -314,7 +317,7 @@ static int graph_read_commit_data(const unsigned char *chunk_start, size_t chunk_size, void *data) { struct commit_graph *g = data; - if (chunk_size / GRAPH_DATA_WIDTH != g->num_commits) + if (chunk_size / graph_data_width(g->hash_algo) != g->num_commits) return error(_("commit-graph commit data chunk is wrong size")); g->chunk_commit_data = chunk_start; return 0; @@ -367,7 +370,7 @@ static int graph_read_bloom_data(const unsigned char *chunk_start, return 0; } -struct commit_graph *parse_commit_graph(struct repo_settings *s, +struct commit_graph *parse_commit_graph(struct repository *r, void *graph_map, size_t graph_size) { const unsigned char *data; @@ -379,7 +382,7 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, if (!graph_map) return NULL; - if (graph_size < GRAPH_MIN_SIZE) + if (graph_size < graph_min_size(r->hash_algo)) return NULL; data = (const unsigned char *)graph_map; @@ -399,22 +402,22 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, } hash_version = *(unsigned char*)(data + 5); - if (hash_version != oid_version(the_hash_algo)) { + if (hash_version != oid_version(r->hash_algo)) { error(_("commit-graph hash version %X does not match version %X"), - hash_version, oid_version(the_hash_algo)); + hash_version, oid_version(r->hash_algo)); return NULL; } graph = alloc_commit_graph(); - graph->hash_len = the_hash_algo->rawsz; + graph->hash_algo = r->hash_algo; graph->num_chunks = *(unsigned char*)(data + 6); graph->data = graph_map; graph->data_len = graph_size; if (graph_size < GRAPH_HEADER_SIZE + (graph->num_chunks + 1) * CHUNK_TOC_ENTRY_SIZE + - GRAPH_FANOUT_SIZE + the_hash_algo->rawsz) { + GRAPH_FANOUT_SIZE + r->hash_algo->rawsz) { error(_("commit-graph file is too small to hold %u chunks"), graph->num_chunks); free(graph); @@ -445,7 +448,9 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, pair_chunk(cf, GRAPH_CHUNKID_BASE, &graph->chunk_base_graphs, &graph->chunk_base_graphs_size); - if (s->commit_graph_generation_version >= 2) { + prepare_repo_settings(r); + + if (r->settings.commit_graph_generation_version >= 2) { read_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA, graph_read_generation_data, graph); pair_chunk(cf, GRAPH_CHUNKID_GENERATION_DATA_OVERFLOW, @@ -456,7 +461,7 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, graph->read_generation_data = 1; } - if (s->commit_graph_changed_paths_version) { + if (r->settings.commit_graph_changed_paths_version) { read_chunk(cf, GRAPH_CHUNKID_BLOOMINDEXES, graph_read_bloom_index, graph); read_chunk(cf, GRAPH_CHUNKID_BLOOMDATA, @@ -472,8 +477,8 @@ struct commit_graph *parse_commit_graph(struct repo_settings *s, FREE_AND_NULL(graph->bloom_filter_settings); } - oidread(&graph->oid, graph->data + graph->data_len - graph->hash_len, - the_repository->hash_algo); + oidread(&graph->oid, graph->data + graph->data_len - graph->hash_algo->rawsz, + r->hash_algo); free_chunkfile(cf); return graph; @@ -485,11 +490,9 @@ free_and_return: return NULL; } -static struct commit_graph *load_commit_graph_one(struct repository *r, - const char *graph_file, - struct odb_source *source) +static struct commit_graph *load_commit_graph_one(struct odb_source *source, + const char *graph_file) { - struct stat st; int fd; struct commit_graph *g; @@ -498,19 +501,17 @@ static struct commit_graph *load_commit_graph_one(struct repository *r, if (!open_ok) return NULL; - g = load_commit_graph_one_fd_st(r, fd, &st, source); - + g = load_commit_graph_one_fd_st(source, fd, &st); if (g) g->filename = xstrdup(graph_file); return g; } -static struct commit_graph *load_commit_graph_v1(struct repository *r, - struct odb_source *source) +static struct commit_graph *load_commit_graph_v1(struct odb_source *source) { char *graph_name = get_commit_graph_filename(source); - struct commit_graph *g = load_commit_graph_one(r, graph_name, source); + struct commit_graph *g = load_commit_graph_one(source, graph_name); free(graph_name); return g; @@ -578,7 +579,7 @@ static int add_graph_to_chain(struct commit_graph *g, return 0; } - if (g->chunk_base_graphs_size / g->hash_len < n) { + if (g->chunk_base_graphs_size / g->hash_algo->rawsz < n) { warning(_("commit-graph base graphs chunk is too small")); return 0; } @@ -588,8 +589,8 @@ static int add_graph_to_chain(struct commit_graph *g, if (!cur_g || !oideq(&oids[n], &cur_g->oid) || - !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_len, n), - the_repository->hash_algo)) { + !hasheq(oids[n].hash, g->chunk_base_graphs + st_mult(g->hash_algo->rawsz, n), + g->hash_algo)) { warning(_("commit-graph chain does not match")); return 0; } @@ -613,7 +614,8 @@ static int add_graph_to_chain(struct commit_graph *g, } int open_commit_graph_chain(const char *chain_file, - int *fd, struct stat *st) + int *fd, struct stat *st, + const struct git_hash_algo *hash_algo) { *fd = git_open(chain_file); if (*fd < 0) @@ -622,7 +624,7 @@ int open_commit_graph_chain(const char *chain_file, close(*fd); return 0; } - if (st->st_size < the_hash_algo->hexsz) { + if (st->st_size < hash_algo->hexsz) { close(*fd); if (!st->st_size) { /* treat empty files the same as missing */ @@ -636,7 +638,7 @@ int open_commit_graph_chain(const char *chain_file, return 1; } -struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, +struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb, int fd, struct stat *st, int *incomplete_chain) { @@ -646,10 +648,10 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, int i = 0, valid = 1, count; FILE *fp = xfdopen(fd, "r"); - count = st->st_size / (the_hash_algo->hexsz + 1); + count = st->st_size / (odb->repo->hash_algo->hexsz + 1); CALLOC_ARRAY(oids, count); - odb_prepare_alternates(r->objects); + odb_prepare_alternates(odb); for (i = 0; i < count; i++) { struct odb_source *source; @@ -657,7 +659,7 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, if (strbuf_getline_lf(&line, fp) == EOF) break; - if (get_oid_hex(line.buf, &oids[i])) { + if (get_oid_hex_algop(line.buf, &oids[i], odb->repo->hash_algo)) { warning(_("invalid commit-graph chain: line '%s' not a hash"), line.buf); valid = 0; @@ -665,9 +667,9 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, } valid = 0; - for (source = r->objects->sources; source; source = source->next) { + for (source = odb->sources; source; source = source->next) { char *graph_name = get_split_graph_filename(source, line.buf); - struct commit_graph *g = load_commit_graph_one(r, graph_name, source); + struct commit_graph *g = load_commit_graph_one(source, graph_name); free(graph_name); @@ -700,50 +702,38 @@ struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, return graph_chain; } -static struct commit_graph *load_commit_graph_chain(struct repository *r, - struct odb_source *source) +static struct commit_graph *load_commit_graph_chain(struct odb_source *source) { char *chain_file = get_commit_graph_chain_filename(source); struct stat st; int fd; struct commit_graph *g = NULL; - if (open_commit_graph_chain(chain_file, &fd, &st)) { + if (open_commit_graph_chain(chain_file, &fd, &st, source->odb->repo->hash_algo)) { int incomplete; /* ownership of fd is taken over by load function */ - g = load_commit_graph_chain_fd_st(r, fd, &st, &incomplete); + g = load_commit_graph_chain_fd_st(source->odb, fd, &st, &incomplete); } free(chain_file); return g; } -struct commit_graph *read_commit_graph_one(struct repository *r, - struct odb_source *source) +struct commit_graph *read_commit_graph_one(struct odb_source *source) { - struct commit_graph *g = load_commit_graph_v1(r, source); + struct commit_graph *g = load_commit_graph_v1(source); if (!g) - g = load_commit_graph_chain(r, source); + g = load_commit_graph_chain(source); return g; } -static void prepare_commit_graph_one(struct repository *r, - struct odb_source *source) -{ - - if (r->objects->commit_graph) - return; - - r->objects->commit_graph = read_commit_graph_one(r, source); -} - /* * Return 1 if commit_graph is non-NULL, and 0 otherwise. * * On the first invocation, this function attempts to load the commit - * graph if the_repository is configured to have one. + * graph if the repository is configured to have one. */ static int prepare_commit_graph(struct repository *r) { @@ -779,10 +769,12 @@ static int prepare_commit_graph(struct repository *r) return 0; odb_prepare_alternates(r->objects); - for (source = r->objects->sources; - !r->objects->commit_graph && source; - source = source->next) - prepare_commit_graph_one(r, source); + for (source = r->objects->sources; source; source = source->next) { + r->objects->commit_graph = read_commit_graph_one(source); + if (r->objects->commit_graph) + break; + } + return !!r->objects->commit_graph; } @@ -799,7 +791,7 @@ int generation_numbers_enabled(struct repository *r) return 0; first_generation = get_be32(g->chunk_commit_data + - g->hash_len + 8) >> 2; + g->hash_algo->rawsz + 8) >> 2; return !!first_generation; } @@ -848,7 +840,7 @@ void close_commit_graph(struct object_database *o) static int bsearch_graph(struct commit_graph *g, const struct object_id *oid, uint32_t *pos) { return bsearch_hash(oid->hash, g->chunk_oid_fanout, - g->chunk_oid_lookup, g->hash_len, pos); + g->chunk_oid_lookup, g->hash_algo->rawsz, pos); } static void load_oid_from_graph(struct commit_graph *g, @@ -868,12 +860,11 @@ static void load_oid_from_graph(struct commit_graph *g, lex_index = pos - g->num_commits_in_base; - oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_len, lex_index), - the_repository->hash_algo); + oidread(oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, lex_index), + g->hash_algo); } -static struct commit_list **insert_parent_or_die(struct repository *r, - struct commit_graph *g, +static struct commit_list **insert_parent_or_die(struct commit_graph *g, uint32_t pos, struct commit_list **pptr) { @@ -884,7 +875,7 @@ static struct commit_list **insert_parent_or_die(struct repository *r, die("invalid parent position %"PRIu32, pos); load_oid_from_graph(g, pos, &oid); - c = lookup_commit(r, &oid); + c = lookup_commit(g->odb_source->odb->repo, &oid); if (!c) die(_("could not find commit %s"), oid_to_hex(&oid)); commit_graph_data_at(c)->graph_pos = pos; @@ -905,13 +896,13 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, die(_("invalid commit position. commit-graph is likely corrupt")); lex_index = pos - g->num_commits_in_base; - commit_data = g->chunk_commit_data + st_mult(GRAPH_DATA_WIDTH, lex_index); + commit_data = g->chunk_commit_data + st_mult(graph_data_width(g->hash_algo), lex_index); graph_data = commit_graph_data_at(item); graph_data->graph_pos = pos; - date_high = get_be32(commit_data + g->hash_len + 8) & 0x3; - date_low = get_be32(commit_data + g->hash_len + 12); + date_high = get_be32(commit_data + g->hash_algo->rawsz + 8) & 0x3; + date_low = get_be32(commit_data + g->hash_algo->rawsz + 12); item->date = (timestamp_t)((date_high << 32) | date_low); if (g->read_generation_data) { @@ -929,10 +920,10 @@ static void fill_commit_graph_info(struct commit *item, struct commit_graph *g, } else graph_data->generation = item->date + offset; } else - graph_data->generation = get_be32(commit_data + g->hash_len + 8) >> 2; + graph_data->generation = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2; if (g->topo_levels) - *topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_len + 8) >> 2; + *topo_level_slab_at(g->topo_levels, item) = get_be32(commit_data + g->hash_algo->rawsz + 8) >> 2; } static inline void set_commit_tree(struct commit *c, struct tree *t) @@ -940,8 +931,7 @@ static inline void set_commit_tree(struct commit *c, struct tree *t) c->maybe_tree = t; } -static int fill_commit_in_graph(struct repository *r, - struct commit *item, +static int fill_commit_in_graph(struct commit *item, struct commit_graph *g, uint32_t pos) { uint32_t edge_value; @@ -956,7 +946,7 @@ static int fill_commit_in_graph(struct repository *r, fill_commit_graph_info(item, g, pos); lex_index = pos - g->num_commits_in_base; - commit_data = g->chunk_commit_data + st_mult(g->hash_len + 16, lex_index); + commit_data = g->chunk_commit_data + st_mult(g->hash_algo->rawsz + 16, lex_index); item->object.parsed = 1; @@ -964,16 +954,16 @@ static int fill_commit_in_graph(struct repository *r, pptr = &item->parents; - edge_value = get_be32(commit_data + g->hash_len); + edge_value = get_be32(commit_data + g->hash_algo->rawsz); if (edge_value == GRAPH_PARENT_NONE) return 1; - pptr = insert_parent_or_die(r, g, edge_value, pptr); + pptr = insert_parent_or_die(g, edge_value, pptr); - edge_value = get_be32(commit_data + g->hash_len + 4); + edge_value = get_be32(commit_data + g->hash_algo->rawsz + 4); if (edge_value == GRAPH_PARENT_NONE) return 1; if (!(edge_value & GRAPH_EXTRA_EDGES_NEEDED)) { - pptr = insert_parent_or_die(r, g, edge_value, pptr); + pptr = insert_parent_or_die(g, edge_value, pptr); return 1; } @@ -988,7 +978,7 @@ static int fill_commit_in_graph(struct repository *r, } edge_value = get_be32(g->chunk_extra_edges + sizeof(uint32_t) * parent_data_pos); - pptr = insert_parent_or_die(r, g, + pptr = insert_parent_or_die(g, edge_value & GRAPH_EDGE_LAST_MASK, pptr); parent_data_pos++; @@ -1054,14 +1044,13 @@ struct commit *lookup_commit_in_graph(struct repository *repo, const struct obje if (commit->object.parsed) return commit; - if (!fill_commit_in_graph(repo, commit, repo->objects->commit_graph, pos)) + if (!fill_commit_in_graph(commit, repo->objects->commit_graph, pos)) return NULL; return commit; } -static int parse_commit_in_graph_one(struct repository *r, - struct commit_graph *g, +static int parse_commit_in_graph_one(struct commit_graph *g, struct commit *item) { uint32_t pos; @@ -1070,7 +1059,7 @@ static int parse_commit_in_graph_one(struct repository *r, return 1; if (find_commit_pos_in_graph(item, g, &pos)) - return fill_commit_in_graph(r, item, g, pos); + return fill_commit_in_graph(item, g, pos); return 0; } @@ -1087,7 +1076,7 @@ int parse_commit_in_graph(struct repository *r, struct commit *item) if (!prepare_commit_graph(r)) return 0; - return parse_commit_in_graph_one(r, r->objects->commit_graph, item); + return parse_commit_in_graph_one(r->objects->commit_graph, item); } void load_commit_graph_info(struct repository *r, struct commit *item) @@ -1097,8 +1086,7 @@ void load_commit_graph_info(struct repository *r, struct commit *item) fill_commit_graph_info(item, r->objects->commit_graph, pos); } -static struct tree *load_tree_for_commit(struct repository *r, - struct commit_graph *g, +static struct tree *load_tree_for_commit(struct commit_graph *g, struct commit *c) { struct object_id oid; @@ -1109,16 +1097,16 @@ static struct tree *load_tree_for_commit(struct repository *r, g = g->base_graph; commit_data = g->chunk_commit_data + - st_mult(GRAPH_DATA_WIDTH, graph_pos - g->num_commits_in_base); + st_mult(graph_data_width(g->hash_algo), + graph_pos - g->num_commits_in_base); - oidread(&oid, commit_data, the_repository->hash_algo); - set_commit_tree(c, lookup_tree(r, &oid)); + oidread(&oid, commit_data, g->hash_algo); + set_commit_tree(c, lookup_tree(g->odb_source->odb->repo, &oid)); return c->maybe_tree; } -static struct tree *get_commit_tree_in_graph_one(struct repository *r, - struct commit_graph *g, +static struct tree *get_commit_tree_in_graph_one(struct commit_graph *g, const struct commit *c) { if (c->maybe_tree) @@ -1126,12 +1114,12 @@ static struct tree *get_commit_tree_in_graph_one(struct repository *r, if (commit_graph_position(c) == COMMIT_NOT_FROM_GRAPH) BUG("get_commit_tree_in_graph_one called from non-commit-graph commit"); - return load_tree_for_commit(r, g, (struct commit *)c); + return load_tree_for_commit(g, (struct commit *)c); } struct tree *get_commit_tree_in_graph(struct repository *r, const struct commit *c) { - return get_commit_tree_in_graph_one(r, r->objects->commit_graph, c); + return get_commit_tree_in_graph_one(r->objects->commit_graph, c); } struct packed_commit_list { @@ -1217,7 +1205,7 @@ static int write_graph_chunk_oids(struct hashfile *f, int count; for (count = 0; count < ctx->commits.nr; count++, list++) { display_progress(ctx->progress, ++ctx->progress_cnt); - hashwrite(f, (*list)->object.oid.hash, the_hash_algo->rawsz); + hashwrite(f, (*list)->object.oid.hash, f->algop->rawsz); } return 0; @@ -1248,7 +1236,7 @@ static int write_graph_chunk_data(struct hashfile *f, die(_("unable to parse commit %s"), oid_to_hex(&(*list)->object.oid)); tree = get_commit_tree_oid(*list); - hashwrite(f, tree->hash, the_hash_algo->rawsz); + hashwrite(f, tree->hash, ctx->r->hash_algo->rawsz); parent = (*list)->parents; @@ -1538,7 +1526,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Loading known commits in commit graph"), ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { @@ -1556,7 +1544,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) */ if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Expanding reachable commits in commit graph"), 0); for (i = 0; i < ctx->oids.nr; i++) { @@ -1577,7 +1565,7 @@ static void close_reachable(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Clearing commit marks in commit graph"), ctx->oids.nr); for (i = 0; i < ctx->oids.nr; i++) { @@ -1695,7 +1683,7 @@ static void compute_topological_levels(struct write_commit_graph_context *ctx) if (ctx->report_progress) info.progress = ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Computing commit graph topological levels"), ctx->commits.nr); @@ -1730,7 +1718,7 @@ static void compute_generation_numbers(struct write_commit_graph_context *ctx) if (ctx->report_progress) info.progress = ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Computing commit graph generation numbers"), ctx->commits.nr); @@ -1807,7 +1795,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx) if (ctx->report_progress) progress = start_delayed_progress( - the_repository, + ctx->r, _("Computing commit changed paths Bloom filters"), ctx->commits.nr); @@ -1853,6 +1841,7 @@ static void compute_bloom_filters(struct write_commit_graph_context *ctx) } struct refs_cb_data { + struct repository *repo; struct oidset *commits; struct progress *progress; }; @@ -1865,9 +1854,9 @@ static int add_ref_to_set(const char *refname UNUSED, struct object_id peeled; struct refs_cb_data *data = (struct refs_cb_data *)cb_data; - if (!peel_iterated_oid(the_repository, oid, &peeled)) + if (!peel_iterated_oid(data->repo, oid, &peeled)) oid = &peeled; - if (odb_read_object_info(the_repository->objects, oid, NULL) == OBJ_COMMIT) + if (odb_read_object_info(data->repo->objects, oid, NULL) == OBJ_COMMIT) oidset_insert(data->commits, oid); display_progress(data->progress, oidset_size(data->commits)); @@ -1884,13 +1873,15 @@ int write_commit_graph_reachable(struct odb_source *source, int result; memset(&data, 0, sizeof(data)); + data.repo = source->odb->repo; data.commits = &commits; + if (flags & COMMIT_GRAPH_WRITE_PROGRESS) data.progress = start_delayed_progress( - the_repository, + source->odb->repo, _("Collecting referenced commits"), 0); - refs_for_each_ref(get_main_ref_store(the_repository), add_ref_to_set, + refs_for_each_ref(get_main_ref_store(source->odb->repo), add_ref_to_set, &data); stop_progress(&data.progress); @@ -1919,7 +1910,7 @@ static int fill_oids_from_packs(struct write_commit_graph_context *ctx, "Finding commits for commit graph in %"PRIuMAX" packs", pack_indexes->nr), (uintmax_t)pack_indexes->nr); - ctx->progress = start_delayed_progress(the_repository, + ctx->progress = start_delayed_progress(ctx->r, progress_title.buf, 0); ctx->progress_done = 0; } @@ -1973,7 +1964,7 @@ static void fill_oids_from_all_packs(struct write_commit_graph_context *ctx) { if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Finding commits for commit graph among packed objects"), ctx->approx_nr_objects); for_each_packed_object(ctx->r, add_packed_commits, ctx, @@ -1992,7 +1983,7 @@ static void copy_oids_to_commits(struct write_commit_graph_context *ctx) ctx->num_extra_edges = 0; if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Finding extra edges in commit graph"), ctx->oids.nr); oid_array_sort(&ctx->oids); @@ -2031,7 +2022,7 @@ static int write_graph_chunk_base_1(struct hashfile *f, return 0; num = write_graph_chunk_base_1(f, g->base_graph); - hashwrite(f, g->oid.hash, the_hash_algo->rawsz); + hashwrite(f, g->oid.hash, g->hash_algo->rawsz); return num + 1; } @@ -2055,7 +2046,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) struct hashfile *f; struct tempfile *graph_layer; /* when ctx->split is non-zero */ struct lock_file lk = LOCK_INIT; - const unsigned hashsz = the_hash_algo->rawsz; + const unsigned hashsz = ctx->r->hash_algo->rawsz; struct strbuf progress_title = STRBUF_INIT; struct chunkfile *cf; unsigned char file_hash[GIT_MAX_RAWSZ]; @@ -2071,7 +2062,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) ctx->graph_name = get_commit_graph_filename(ctx->odb_source); } - if (safe_create_leading_directories(the_repository, ctx->graph_name)) { + if (safe_create_leading_directories(ctx->r, ctx->graph_name)) { error(_("unable to create leading directories of %s"), ctx->graph_name); return -1; @@ -2090,18 +2081,18 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) return -1; } - if (adjust_shared_perm(the_repository, get_tempfile_path(graph_layer))) { + if (adjust_shared_perm(ctx->r, get_tempfile_path(graph_layer))) { error(_("unable to adjust shared permissions for '%s'"), get_tempfile_path(graph_layer)); return -1; } - f = hashfd(the_repository->hash_algo, + f = hashfd(ctx->r->hash_algo, get_tempfile_fd(graph_layer), get_tempfile_path(graph_layer)); } else { hold_lock_file_for_update_mode(&lk, ctx->graph_name, LOCK_DIE_ON_ERROR, 0444); - f = hashfd(the_repository->hash_algo, + f = hashfd(ctx->r->hash_algo, get_lock_file_fd(&lk), get_lock_file_path(&lk)); } @@ -2143,7 +2134,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(the_hash_algo)); + hashwrite_u8(f, oid_version(ctx->r->hash_algo)); hashwrite_u8(f, get_num_chunks(cf)); hashwrite_u8(f, ctx->num_commit_graphs_after - 1); @@ -2154,7 +2145,7 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) get_num_chunks(cf)), get_num_chunks(cf)); ctx->progress = start_delayed_progress( - the_repository, + ctx->r, progress_title.buf, st_mult(get_num_chunks(cf), ctx->commits.nr)); } @@ -2212,7 +2203,8 @@ static int write_commit_graph_file(struct write_commit_graph_context *ctx) } free(ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]); - ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = xstrdup(hash_to_hex(file_hash)); + ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1] = + xstrdup(hash_to_hex_algop(file_hash, ctx->r->hash_algo)); final_graph_name = get_split_graph_filename(ctx->odb_source, ctx->commit_graph_hash_after[ctx->num_commit_graphs_after - 1]); free(ctx->commit_graph_filenames_after[ctx->num_commit_graphs_after - 1]); @@ -2367,7 +2359,7 @@ static void sort_and_scan_merged_commits(struct write_commit_graph_context *ctx) if (ctx->report_progress) ctx->progress = start_delayed_progress( - the_repository, + ctx->r, _("Scanning merged commits"), ctx->commits.nr); @@ -2412,7 +2404,7 @@ static void merge_commit_graphs(struct write_commit_graph_context *ctx) current_graph_number--; if (ctx->report_progress) - ctx->progress = start_delayed_progress(the_repository, + ctx->progress = start_delayed_progress(ctx->r, _("Merging commit-graph"), 0); merge_commit_graph(ctx, g); @@ -2515,7 +2507,7 @@ int write_commit_graph(struct odb_source *source, enum commit_graph_write_flags flags, const struct commit_graph_opts *opts) { - struct repository *r = the_repository; + struct repository *r = source->odb->repo; struct write_commit_graph_context ctx = { .r = r, .odb_source = source, @@ -2615,14 +2607,14 @@ int write_commit_graph(struct odb_source *source, replace = ctx.opts->split_flags & COMMIT_GRAPH_SPLIT_REPLACE; } - ctx.approx_nr_objects = repo_approximate_object_count(the_repository); + ctx.approx_nr_objects = repo_approximate_object_count(r); if (ctx.append && ctx.r->objects->commit_graph) { struct commit_graph *g = ctx.r->objects->commit_graph; for (i = 0; i < g->num_commits; i++) { struct object_id oid; - oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_len, i), - the_repository->hash_algo); + oidread(&oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i), + r->hash_algo); oid_array_append(&ctx.oids, &oid); } } @@ -2730,15 +2722,15 @@ static void graph_report(const char *fmt, ...) static int commit_graph_checksum_valid(struct commit_graph *g) { - return hashfile_checksum_valid(the_repository->hash_algo, + return hashfile_checksum_valid(g->hash_algo, g->data, g->data_len); } -static int verify_one_commit_graph(struct repository *r, - struct commit_graph *g, +static int verify_one_commit_graph(struct commit_graph *g, struct progress *progress, uint64_t *seen) { + struct repository *r = g->odb_source->odb->repo; uint32_t i, cur_fanout_pos = 0; struct object_id prev_oid, cur_oid; struct commit *seen_gen_zero = NULL; @@ -2752,8 +2744,8 @@ static int verify_one_commit_graph(struct repository *r, for (i = 0; i < g->num_commits; i++) { struct commit *graph_commit; - oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i), - the_repository->hash_algo); + oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i), + g->hash_algo); if (i && oidcmp(&prev_oid, &cur_oid) >= 0) graph_report(_("commit-graph has incorrect OID order: %s then %s"), @@ -2772,7 +2764,7 @@ static int verify_one_commit_graph(struct repository *r, } graph_commit = lookup_commit(r, &cur_oid); - if (!parse_commit_in_graph_one(r, g, graph_commit)) + if (!parse_commit_in_graph_one(g, graph_commit)) graph_report(_("failed to parse commit %s from commit-graph"), oid_to_hex(&cur_oid)); } @@ -2797,8 +2789,8 @@ static int verify_one_commit_graph(struct repository *r, timestamp_t generation; display_progress(progress, ++(*seen)); - oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_len, i), - the_repository->hash_algo); + oidread(&cur_oid, g->chunk_oid_lookup + st_mult(g->hash_algo->rawsz, i), + g->hash_algo); graph_commit = lookup_commit(r, &cur_oid); odb_commit = (struct commit *)create_object(r, &cur_oid, alloc_commit_node(r)); @@ -2808,7 +2800,7 @@ static int verify_one_commit_graph(struct repository *r, continue; } - if (!oideq(&get_commit_tree_in_graph_one(r, g, graph_commit)->object.oid, + if (!oideq(&get_commit_tree_in_graph_one(g, graph_commit)->object.oid, get_commit_tree_oid(odb_commit))) graph_report(_("root tree OID for commit %s in commit-graph is %s != %s"), oid_to_hex(&cur_oid), @@ -2826,7 +2818,7 @@ static int verify_one_commit_graph(struct repository *r, } /* parse parent in case it is in a base graph */ - parse_commit_in_graph_one(r, g, graph_parents->item); + parse_commit_in_graph_one(g, graph_parents->item); if (!oideq(&graph_parents->item->object.oid, &odb_parents->item->object.oid)) graph_report(_("commit-graph parent for %s is %s != %s"), @@ -2886,7 +2878,7 @@ static int verify_one_commit_graph(struct repository *r, return verify_commit_graph_error; } -int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) +int verify_commit_graph(struct commit_graph *g, int flags) { struct progress *progress = NULL; int local_error = 0; @@ -2902,13 +2894,13 @@ int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags) if (!(flags & COMMIT_GRAPH_VERIFY_SHALLOW)) total += g->num_commits_in_base; - progress = start_progress(the_repository, + progress = start_progress(g->odb_source->odb->repo, _("Verifying commits in commit graph"), total); } for (; g; g = g->base_graph) { - local_error |= verify_one_commit_graph(r, g, progress, &seen); + local_error |= verify_one_commit_graph(g, progress, &seen); if (flags & COMMIT_GRAPH_VERIFY_SHALLOW) break; } diff --git a/commit-graph.h b/commit-graph.h index 78ab7b875b..4899b54ef8 100644 --- a/commit-graph.h +++ b/commit-graph.h @@ -21,7 +21,7 @@ * call this method oustide of a builtin, and only if you know what * you are doing! */ -void git_test_write_commit_graph_or_die(void); +void git_test_write_commit_graph_or_die(struct odb_source *source); struct commit; struct bloom_filter_settings; @@ -32,7 +32,8 @@ struct string_list; char *get_commit_graph_filename(struct odb_source *source); char *get_commit_graph_chain_filename(struct odb_source *source); int open_commit_graph(const char *graph_file, int *fd, struct stat *st); -int open_commit_graph_chain(const char *chain_file, int *fd, struct stat *st); +int open_commit_graph_chain(const char *chain_file, int *fd, struct stat *st, + const struct git_hash_algo *hash_algo); /* * Given a commit struct, try to fill the commit struct info, including: @@ -84,7 +85,7 @@ struct commit_graph { const unsigned char *data; size_t data_len; - unsigned char hash_len; + const struct git_hash_algo *hash_algo; unsigned char num_chunks; uint32_t num_commits; struct object_id oid; @@ -113,14 +114,12 @@ struct commit_graph { struct bloom_filter_settings *bloom_filter_settings; }; -struct commit_graph *load_commit_graph_one_fd_st(struct repository *r, - int fd, struct stat *st, - struct odb_source *source); -struct commit_graph *load_commit_graph_chain_fd_st(struct repository *r, +struct commit_graph *load_commit_graph_one_fd_st(struct odb_source *source, + int fd, struct stat *st); +struct commit_graph *load_commit_graph_chain_fd_st(struct object_database *odb, int fd, struct stat *st, int *incomplete_chain); -struct commit_graph *read_commit_graph_one(struct repository *r, - struct odb_source *source); +struct commit_graph *read_commit_graph_one(struct odb_source *source); struct repo_settings; @@ -128,7 +127,7 @@ struct repo_settings; * Callers should initialize the repo_settings with prepare_repo_settings() * prior to calling parse_commit_graph(). */ -struct commit_graph *parse_commit_graph(struct repo_settings *s, +struct commit_graph *parse_commit_graph(struct repository *r, void *graph_map, size_t graph_size); /* @@ -184,7 +183,7 @@ int write_commit_graph(struct odb_source *source, #define COMMIT_GRAPH_VERIFY_SHALLOW (1 << 0) -int verify_commit_graph(struct repository *r, struct commit_graph *g, int flags); +int verify_commit_graph(struct commit_graph *g, int flags); void close_commit_graph(struct object_database *); void free_commit_graph(struct commit_graph *); @@ -1039,7 +1039,8 @@ static void add_one_commit(struct object_id *oid, struct rev_collect *revs) commit->object.flags |= TMP_MARK; } -static int collect_one_reflog_ent(struct object_id *ooid, struct object_id *noid, +static int collect_one_reflog_ent(const char *refname UNUSED, + struct object_id *ooid, struct object_id *noid, const char *ident UNUSED, timestamp_t timestamp UNUSED, int tz UNUSED, const char *message UNUSED, void *cbdata) @@ -1805,8 +1806,8 @@ int commit_tree_extended(const char *msg, size_t msg_len, compat_oid = &compat_oid_buf; } - result = write_object_file_flags(buffer.buf, buffer.len, OBJ_COMMIT, - ret, compat_oid, 0); + result = odb_write_object_ext(the_repository->objects, buffer.buf, buffer.len, + OBJ_COMMIT, ret, compat_oid, 0); out: free(parent_buf); strbuf_release(&buffer); @@ -2,6 +2,7 @@ #define COMMIT_H #include "object.h" +#include "add-interactive.h" struct signature_check; struct strbuf; @@ -257,7 +258,7 @@ int for_each_commit_graft(each_commit_graft_fn, void *); int interactive_add(struct repository *repo, const char **argv, const char *prefix, - int patch); + int patch, struct add_p_opt *add_p_opt); struct commit_extra_header { struct commit_extra_header *next; diff --git a/compat/mingw.c b/compat/mingw.c index 5d69ae32f4..8538e3d172 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -244,7 +244,6 @@ enum hide_dotfiles_type { HIDE_DOTFILES_DOTGITONLY }; -static int core_restrict_inherited_handles = -1; static enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; static char *unset_environment_variables; @@ -268,15 +267,6 @@ int mingw_core_config(const char *var, const char *value, return 0; } - if (!strcmp(var, "core.restrictinheritedhandles")) { - if (value && !strcasecmp(value, "auto")) - core_restrict_inherited_handles = -1; - else - core_restrict_inherited_handles = - git_config_bool(var, value); - return 0; - } - return 0; } @@ -588,13 +578,24 @@ static int mingw_open_existing(const wchar_t *filename, int oflags, ...) &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (handle == INVALID_HANDLE_VALUE) { DWORD err = GetLastError(); + if (err == ERROR_ACCESS_DENIED) { + DWORD attrs = GetFileAttributesW(filename); + if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) + handle = CreateFileW(filename, access, + FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, + &security_attributes, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL| FILE_FLAG_BACKUP_SEMANTICS, NULL); + } - /* See `mingw_open_append()` for why we have this conversion. */ - if (err == ERROR_INVALID_PARAMETER) - err = ERROR_PATH_NOT_FOUND; + if (handle == INVALID_HANDLE_VALUE) { + err = GetLastError(); - errno = err_win_to_posix(err); - return -1; + /* See `mingw_open_append()` for why we have this conversion. */ + if (err == ERROR_INVALID_PARAMETER) + err = ERROR_PATH_NOT_FOUND; + + errno = err_win_to_posix(err); + return -1; + } } fd = _open_osfhandle((intptr_t)handle, oflags | O_BINARY); @@ -1656,7 +1657,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen const char *dir, int prepend_cmd, int fhin, int fhout, int fherr) { - static int restrict_handle_inheritance = -1; STARTUPINFOEXW si; PROCESS_INFORMATION pi; LPPROC_THREAD_ATTRIBUTE_LIST attr_list = NULL; @@ -1676,16 +1676,6 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen /* Make sure to override previous errors, if any */ errno = 0; - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = core_restrict_inherited_handles; - /* - * The following code to restrict which handles are inherited seems - * to work properly only on Windows 7 and later, so let's disable it - * on Windows Vista and 2008. - */ - if (restrict_handle_inheritance < 0) - restrict_handle_inheritance = GetVersion() >> 16 >= 7601; - do_unset_environment_variables(); /* Determine whether or not we are associated to a console */ @@ -1787,7 +1777,7 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen wenvblk = make_environment_block(deltaenv); memset(&pi, 0, sizeof(pi)); - if (restrict_handle_inheritance && stdhandles_count && + if (stdhandles_count && (InitializeProcThreadAttributeList(NULL, 1, 0, &size) || GetLastError() == ERROR_INSUFFICIENT_BUFFER) && (attr_list = (LPPROC_THREAD_ATTRIBUTE_LIST) @@ -1808,52 +1798,13 @@ static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **deltaen &si.StartupInfo, &pi); /* - * On Windows 2008 R2, it seems that specifying certain types of handles - * (such as FILE_TYPE_CHAR or FILE_TYPE_PIPE) will always produce an - * error. Rather than playing finicky and fragile games, let's just try - * to detect this situation and simply try again without restricting any - * handle inheritance. This is still better than failing to create - * processes. + * On the off-chance that something with the file handle restriction + * went wrong, silently fall back to trying without it. */ - if (!ret && restrict_handle_inheritance && stdhandles_count) { + if (!ret && stdhandles_count) { DWORD err = GetLastError(); struct strbuf buf = STRBUF_INIT; - if (err != ERROR_NO_SYSTEM_RESOURCES && - /* - * On Windows 7 and earlier, handles on pipes and character - * devices are inherited automatically, and cannot be - * specified in the thread handle list. Rather than trying - * to catch each and every corner case (and running the - * chance of *still* forgetting a few), let's just fall - * back to creating the process without trying to limit the - * handle inheritance. - */ - !(err == ERROR_INVALID_PARAMETER && - GetVersion() >> 16 < 9200) && - !getenv("SUPPRESS_HANDLE_INHERITANCE_WARNING")) { - DWORD fl = 0; - int i; - - setenv("SUPPRESS_HANDLE_INHERITANCE_WARNING", "1", 1); - - for (i = 0; i < stdhandles_count; i++) { - HANDLE h = stdhandles[i]; - strbuf_addf(&buf, "handle #%d: %p (type %lx, " - "handle info (%d) %lx\n", i, h, - GetFileType(h), - GetHandleInformation(h, &fl), - fl); - } - strbuf_addstr(&buf, "\nThis is a bug; please report it " - "at\nhttps://github.com/git-for-windows/" - "git/issues/new\n\n" - "To suppress this warning, please set " - "the environment variable\n\n" - "\tSUPPRESS_HANDLE_INHERITANCE_WARNING=1" - "\n"); - } - restrict_handle_inheritance = 0; flags &= ~EXTENDED_STARTUPINFO_PRESENT; ret = CreateProcessW(*wcmd ? wcmd : NULL, wargs, NULL, NULL, TRUE, flags, wenvblk, dir ? wdir : NULL, @@ -2326,7 +2277,9 @@ repeat: * current system doesn't support FileRenameInfoEx. Keep us * from using it in future calls and retry. */ - if (gle == ERROR_INVALID_PARAMETER) { + if (gle == ERROR_INVALID_PARAMETER || + gle == ERROR_NOT_SUPPORTED || + gle == ERROR_INVALID_FUNCTION) { supports_file_rename_info_ex = 0; goto repeat; } diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 12e38e0ea3..43b3be0114 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -56,8 +56,8 @@ void probe_utf8_pathname_composition(void) close(output_fd); repo_git_path_replace(the_repository, &path, "%s", auml_nfd); precomposed_unicode = access(path.buf, R_OK) ? 0 : 1; - git_config_set("core.precomposeunicode", - precomposed_unicode ? "true" : "false"); + repo_config_set(the_repository, "core.precomposeunicode", + precomposed_unicode ? "true" : "false"); repo_git_path_replace(the_repository, &path, "%s", auml_nfc); if (unlink(path.buf)) die_errno(_("failed to unlink '%s'"), path.buf); @@ -75,7 +75,7 @@ const char *precompose_string_if_needed(const char *in) iconv_t ic_prec; char *out; if (precomposed_unicode < 0) - git_config_get_bool("core.precomposeunicode", &precomposed_unicode); + repo_config_get_bool(the_repository, "core.precomposeunicode", &precomposed_unicode); if (precomposed_unicode != 1) return in; ic_prec = iconv_open(repo_encoding, path_encoding); @@ -6,12 +6,8 @@ * */ -#define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS - #include "git-compat-util.h" #include "abspath.h" -#include "advice.h" #include "date.h" #include "branch.h" #include "config.h" @@ -20,11 +16,8 @@ #include "environment.h" #include "gettext.h" #include "git-zlib.h" -#include "ident.h" #include "repository.h" #include "lockfile.h" -#include "mailmap.h" -#include "attr.h" #include "exec-cmd.h" #include "strbuf.h" #include "quote.h" @@ -32,7 +25,6 @@ #include "string-list.h" #include "object-name.h" #include "odb.h" -#include "pager.h" #include "path.h" #include "utf8.h" #include "color.h" @@ -41,7 +33,6 @@ #include "strvec.h" #include "trace2.h" #include "wildmatch.h" -#include "ws.h" #include "write-or-die.h" struct config_source { @@ -70,9 +61,6 @@ struct config_source { }; #define CONFIG_SOURCE_INIT { 0 } -static int pack_compression_seen; -static int zlib_compression_seen; - /* * Config that comes from trusted scopes, namely: * - CONFIG_SCOPE_SYSTEM (e.g. /etc/gitconfig) @@ -207,11 +195,12 @@ static void add_trailing_starstar_for_dir(struct strbuf *pat) } static int prepare_include_condition_pattern(const struct key_value_info *kvi, - struct strbuf *pat) + struct strbuf *pat, + size_t *out) { struct strbuf path = STRBUF_INIT; char *expanded; - int prefix = 0; + size_t prefix = 0; expanded = interpolate_path(pat->buf, 1); if (expanded) { @@ -238,8 +227,10 @@ static int prepare_include_condition_pattern(const struct key_value_info *kvi, add_trailing_starstar_for_dir(pat); + *out = prefix; + strbuf_release(&path); - return prefix; + return 0; } static int include_by_gitdir(const struct key_value_info *kvi, @@ -248,7 +239,8 @@ static int include_by_gitdir(const struct key_value_info *kvi, { struct strbuf text = STRBUF_INIT; struct strbuf pattern = STRBUF_INIT; - int ret = 0, prefix; + size_t prefix; + int ret = 0; const char *git_dir; int already_tried_absolute = 0; @@ -259,12 +251,11 @@ static int include_by_gitdir(const struct key_value_info *kvi, strbuf_realpath(&text, git_dir, 1); strbuf_add(&pattern, cond, cond_len); - prefix = prepare_include_condition_pattern(kvi, &pattern); - -again: - if (prefix < 0) + ret = prepare_include_condition_pattern(kvi, &pattern, &prefix); + if (ret < 0) goto done; +again: if (prefix > 0) { /* * perform literal matching on the prefix part so that @@ -638,31 +629,28 @@ int git_config_parse_parameter(const char *text, config_fn_t fn, void *data) { const char *value; - struct strbuf **pair; + struct string_list pair = STRING_LIST_INIT_DUP; int ret; struct key_value_info kvi = KVI_INIT; kvi_from_param(&kvi); - pair = strbuf_split_str(text, '=', 2); - if (!pair[0]) + string_list_split(&pair, text, "=", 1); + if (!pair.nr) return error(_("bogus config parameter: %s"), text); - if (pair[0]->len && pair[0]->buf[pair[0]->len - 1] == '=') { - strbuf_setlen(pair[0], pair[0]->len - 1); - value = pair[1] ? pair[1]->buf : ""; - } else { + if (pair.nr == 1) value = NULL; - } + else + value = pair.items[1].string; - strbuf_trim(pair[0]); - if (!pair[0]->len) { - strbuf_list_free(pair); + if (!*pair.items[0].string) { + string_list_clear(&pair, 0); return error(_("bogus config parameter: %s"), text); } - ret = config_parse_pair(pair[0]->buf, value, &kvi, fn, data); - strbuf_list_free(pair); + ret = config_parse_pair(pair.items[0].string, value, &kvi, fn, data); + string_list_clear(&pair, 0); return ret; } @@ -732,7 +720,6 @@ int git_config_from_parameters(config_fn_t fn, void *data) if (env) { unsigned long count; char *endp; - int i; count = strtoul(env, &endp, 10); if (*endp) { @@ -744,10 +731,10 @@ int git_config_from_parameters(config_fn_t fn, void *data) goto out; } - for (i = 0; i < count; i++) { + for (unsigned long i = 0; i < count; i++) { const char *key, *value; - strbuf_addf(&envvar, "GIT_CONFIG_KEY_%d", i); + strbuf_addf(&envvar, "GIT_CONFIG_KEY_%lu", i); key = getenv_safe(&to_free, envvar.buf); if (!key) { ret = error(_("missing config key %s"), envvar.buf); @@ -755,7 +742,7 @@ int git_config_from_parameters(config_fn_t fn, void *data) } strbuf_reset(&envvar); - strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%d", i); + strbuf_addf(&envvar, "GIT_CONFIG_VALUE_%lu", i); value = getenv_safe(&to_free, envvar.buf); if (!value) { ret = error(_("missing config value %s"), envvar.buf); @@ -1259,80 +1246,6 @@ double git_config_double(const char *name, const char *value, return ret; } -static const struct fsync_component_name { - const char *name; - enum fsync_component component_bits; -} fsync_component_names[] = { - { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT }, - { "pack", FSYNC_COMPONENT_PACK }, - { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA }, - { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH }, - { "index", FSYNC_COMPONENT_INDEX }, - { "objects", FSYNC_COMPONENTS_OBJECTS }, - { "reference", FSYNC_COMPONENT_REFERENCE }, - { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA }, - { "committed", FSYNC_COMPONENTS_COMMITTED }, - { "added", FSYNC_COMPONENTS_ADDED }, - { "all", FSYNC_COMPONENTS_ALL }, -}; - -static enum fsync_component parse_fsync_components(const char *var, const char *string) -{ - enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT; - enum fsync_component positive = 0, negative = 0; - - while (string) { - int i; - size_t len; - const char *ep; - int negated = 0; - int found = 0; - - string = string + strspn(string, ", \t\n\r"); - ep = strchrnul(string, ','); - len = ep - string; - if (!strcmp(string, "none")) { - current = FSYNC_COMPONENT_NONE; - goto next_name; - } - - if (*string == '-') { - negated = 1; - string++; - len--; - if (!len) - warning(_("invalid value for variable %s"), var); - } - - if (!len) - break; - - for (i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) { - const struct fsync_component_name *n = &fsync_component_names[i]; - - if (strncmp(n->name, string, len)) - continue; - - found = 1; - if (negated) - negative |= n->component_bits; - else - positive |= n->component_bits; - } - - if (!found) { - char *component = xstrndup(string, len); - warning(_("ignoring unknown core.fsync component '%s'"), component); - free(component); - } - -next_name: - string = ep; - } - - return (current & ~negative) | positive; -} - int git_config_bool_or_int(const char *name, const char *value, const struct key_value_info *kvi, int *is_bool) { @@ -1390,435 +1303,6 @@ int git_config_color(char *dest, const char *var, const char *value) return 0; } -static int git_default_core_config(const char *var, const char *value, - const struct config_context *ctx, void *cb) -{ - /* This needs a better name */ - if (!strcmp(var, "core.filemode")) { - trust_executable_bit = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.trustctime")) { - trust_ctime = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "core.checkstat")) { - if (!value) - return config_error_nonbool(var); - if (!strcasecmp(value, "default")) - check_stat = 1; - else if (!strcasecmp(value, "minimal")) - check_stat = 0; - else - return error(_("invalid value for '%s': '%s'"), - var, value); - } - - if (!strcmp(var, "core.quotepath")) { - quote_path_fully = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.symlinks")) { - has_symlinks = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.ignorecase")) { - ignore_case = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.attributesfile")) { - FREE_AND_NULL(git_attributes_file); - return git_config_pathname(&git_attributes_file, var, value); - } - - if (!strcmp(var, "core.bare")) { - is_bare_repository_cfg = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.ignorestat")) { - assume_unchanged = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.abbrev")) { - if (!value) - return config_error_nonbool(var); - if (!strcasecmp(value, "auto")) - default_abbrev = -1; - else if (!git_parse_maybe_bool_text(value)) - default_abbrev = GIT_MAX_HEXSZ; - else { - int abbrev = git_config_int(var, value, ctx->kvi); - if (abbrev < minimum_abbrev) - return error(_("abbrev length out of range: %d"), abbrev); - default_abbrev = abbrev; - } - return 0; - } - - if (!strcmp(var, "core.disambiguate")) - return set_disambiguate_hint_config(var, value); - - if (!strcmp(var, "core.loosecompression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad zlib compression level %d"), level); - zlib_compression_level = level; - zlib_compression_seen = 1; - return 0; - } - - if (!strcmp(var, "core.compression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad zlib compression level %d"), level); - if (!zlib_compression_seen) - zlib_compression_level = level; - if (!pack_compression_seen) - pack_compression_level = level; - return 0; - } - - if (!strcmp(var, "core.autocrlf")) { - if (value && !strcasecmp(value, "input")) { - auto_crlf = AUTO_CRLF_INPUT; - return 0; - } - auto_crlf = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.safecrlf")) { - int eol_rndtrp_die; - if (value && !strcasecmp(value, "warn")) { - global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; - return 0; - } - eol_rndtrp_die = git_config_bool(var, value); - global_conv_flags_eol = eol_rndtrp_die ? - CONV_EOL_RNDTRP_DIE : 0; - return 0; - } - - if (!strcmp(var, "core.eol")) { - if (value && !strcasecmp(value, "lf")) - core_eol = EOL_LF; - else if (value && !strcasecmp(value, "crlf")) - core_eol = EOL_CRLF; - else if (value && !strcasecmp(value, "native")) - core_eol = EOL_NATIVE; - else - core_eol = EOL_UNSET; - return 0; - } - - if (!strcmp(var, "core.checkroundtripencoding")) { - FREE_AND_NULL(check_roundtrip_encoding); - return git_config_string(&check_roundtrip_encoding, var, value); - } - - if (!strcmp(var, "core.editor")) { - FREE_AND_NULL(editor_program); - return git_config_string(&editor_program, var, value); - } - - if (!strcmp(var, "core.commentchar") || - !strcmp(var, "core.commentstring")) { - if (!value) - return config_error_nonbool(var); - else if (!strcasecmp(value, "auto")) { - auto_comment_line_char = 1; - FREE_AND_NULL(comment_line_str_to_free); - comment_line_str = "#"; - } else if (value[0]) { - if (strchr(value, '\n')) - return error(_("%s cannot contain newline"), var); - comment_line_str = value; - FREE_AND_NULL(comment_line_str_to_free); - auto_comment_line_char = 0; - } else - return error(_("%s must have at least one character"), var); - return 0; - } - - if (!strcmp(var, "core.askpass")) { - FREE_AND_NULL(askpass_program); - return git_config_string(&askpass_program, var, value); - } - - if (!strcmp(var, "core.excludesfile")) { - FREE_AND_NULL(excludes_file); - return git_config_pathname(&excludes_file, var, value); - } - - if (!strcmp(var, "core.whitespace")) { - if (!value) - return config_error_nonbool(var); - whitespace_rule_cfg = parse_whitespace_rule(value); - return 0; - } - - if (!strcmp(var, "core.fsync")) { - if (!value) - return config_error_nonbool(var); - fsync_components = parse_fsync_components(var, value); - return 0; - } - - if (!strcmp(var, "core.fsyncmethod")) { - if (!value) - return config_error_nonbool(var); - if (!strcmp(value, "fsync")) - 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); - - } - - if (!strcmp(var, "core.fsyncobjectfiles")) { - if (fsync_object_files < 0) - warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead")); - fsync_object_files = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.createobject")) { - if (!value) - return config_error_nonbool(var); - if (!strcmp(value, "rename")) - object_creation_mode = OBJECT_CREATION_USES_RENAMES; - else if (!strcmp(value, "link")) - object_creation_mode = OBJECT_CREATION_USES_HARDLINKS; - else - die(_("invalid mode for object creation: %s"), value); - return 0; - } - - if (!strcmp(var, "core.sparsecheckout")) { - core_apply_sparse_checkout = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.sparsecheckoutcone")) { - core_sparse_checkout_cone = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.precomposeunicode")) { - precomposed_unicode = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.protecthfs")) { - protect_hfs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.protectntfs")) { - protect_ntfs = git_config_bool(var, value); - return 0; - } - - if (!strcmp(var, "core.maxtreedepth")) { - max_allowed_tree_depth = git_config_int(var, value, ctx->kvi); - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return platform_core_config(var, value, ctx, cb); -} - -static int git_default_sparse_config(const char *var, const char *value) -{ - if (!strcmp(var, "sparse.expectfilesoutsideofpatterns")) { - sparse_expect_files_outside_of_patterns = git_config_bool(var, value); - return 0; - } - - /* Add other config variables here and to Documentation/config/sparse.adoc. */ - return 0; -} - -static int git_default_i18n_config(const char *var, const char *value) -{ - if (!strcmp(var, "i18n.commitencoding")) { - FREE_AND_NULL(git_commit_encoding); - return git_config_string(&git_commit_encoding, var, value); - } - - if (!strcmp(var, "i18n.logoutputencoding")) { - FREE_AND_NULL(git_log_output_encoding); - return git_config_string(&git_log_output_encoding, var, value); - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_branch_config(const char *var, const char *value) -{ - if (!strcmp(var, "branch.autosetupmerge")) { - if (value && !strcmp(value, "always")) { - git_branch_track = BRANCH_TRACK_ALWAYS; - return 0; - } else if (value && !strcmp(value, "inherit")) { - git_branch_track = BRANCH_TRACK_INHERIT; - return 0; - } else if (value && !strcmp(value, "simple")) { - git_branch_track = BRANCH_TRACK_SIMPLE; - return 0; - } - git_branch_track = git_config_bool(var, value); - return 0; - } - if (!strcmp(var, "branch.autosetuprebase")) { - if (!value) - return config_error_nonbool(var); - else if (!strcmp(value, "never")) - autorebase = AUTOREBASE_NEVER; - else if (!strcmp(value, "local")) - autorebase = AUTOREBASE_LOCAL; - else if (!strcmp(value, "remote")) - autorebase = AUTOREBASE_REMOTE; - else if (!strcmp(value, "always")) - autorebase = AUTOREBASE_ALWAYS; - else - return error(_("malformed value for %s"), var); - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_push_config(const char *var, const char *value) -{ - if (!strcmp(var, "push.default")) { - if (!value) - return config_error_nonbool(var); - else if (!strcmp(value, "nothing")) - push_default = PUSH_DEFAULT_NOTHING; - else if (!strcmp(value, "matching")) - push_default = PUSH_DEFAULT_MATCHING; - else if (!strcmp(value, "simple")) - push_default = PUSH_DEFAULT_SIMPLE; - else if (!strcmp(value, "upstream")) - push_default = PUSH_DEFAULT_UPSTREAM; - else if (!strcmp(value, "tracking")) /* deprecated */ - push_default = PUSH_DEFAULT_UPSTREAM; - else if (!strcmp(value, "current")) - push_default = PUSH_DEFAULT_CURRENT; - else { - error(_("malformed value for %s: %s"), var, value); - return error(_("must be one of nothing, matching, simple, " - "upstream or current")); - } - return 0; - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_mailmap_config(const char *var, const char *value) -{ - if (!strcmp(var, "mailmap.file")) { - FREE_AND_NULL(git_mailmap_file); - return git_config_pathname(&git_mailmap_file, var, value); - } - - if (!strcmp(var, "mailmap.blob")) { - FREE_AND_NULL(git_mailmap_blob); - return git_config_string(&git_mailmap_blob, var, value); - } - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - -static int git_default_attr_config(const char *var, const char *value) -{ - if (!strcmp(var, "attr.tree")) { - FREE_AND_NULL(git_attr_tree); - return git_config_string(&git_attr_tree, var, value); - } - - /* - * Add other attribute related config variables here and to - * Documentation/config/attr.adoc. - */ - return 0; -} - -int git_default_config(const char *var, const char *value, - const struct config_context *ctx, void *cb) -{ - if (starts_with(var, "core.")) - return git_default_core_config(var, value, ctx, cb); - - if (starts_with(var, "user.") || - starts_with(var, "author.") || - starts_with(var, "committer.")) - return git_ident_config(var, value, ctx, cb); - - if (starts_with(var, "i18n.")) - return git_default_i18n_config(var, value); - - if (starts_with(var, "branch.")) - return git_default_branch_config(var, value); - - if (starts_with(var, "push.")) - return git_default_push_config(var, value); - - if (starts_with(var, "mailmap.")) - return git_default_mailmap_config(var, value); - - if (starts_with(var, "attr.")) - return git_default_attr_config(var, value); - - if (starts_with(var, "advice.") || starts_with(var, "color.advice")) - return git_default_advice_config(var, value); - - if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { - pager_use_color = git_config_bool(var,value); - return 0; - } - - if (!strcmp(var, "pack.packsizelimit")) { - pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi); - return 0; - } - - if (!strcmp(var, "pack.compression")) { - int level = git_config_int(var, value, ctx->kvi); - if (level == -1) - level = Z_DEFAULT_COMPRESSION; - else if (level < 0 || level > Z_BEST_COMPRESSION) - die(_("bad pack compression level %d"), level); - pack_compression_level = level; - pack_compression_seen = 1; - return 0; - } - - if (starts_with(var, "sparse.")) - return git_default_sparse_config(var, value); - - /* Add other config variables here and to Documentation/config.adoc. */ - return 0; -} - /* * All source specific fields in the union, die_on_error, name and the callbacks * fgetc, ungetc, ftell of top need to be initialized before calling @@ -2125,13 +1609,13 @@ int config_with_options(config_fn_t fn, void *data, static void configset_iter(struct config_set *set, config_fn_t fn, void *data) { - int i, value_index; + int value_index; struct string_list *values; struct config_set_element *entry; struct configset_list *list = &set->list; struct config_context ctx = CONFIG_CONTEXT_INIT; - for (i = 0; i < list->nr; i++) { + for (size_t i = 0; i < list->nr; i++) { entry = list->items[i].e; value_index = list->items[i].value_index; values = &entry->value_list; @@ -2748,7 +2232,7 @@ void git_die_config(struct repository *r, const char *key, const char *err, ...) } /* - * Find all the stuff for git_config_set() below. + * Find all the stuff for repo_config_set() below. */ struct config_store_data { @@ -2981,10 +2465,11 @@ static ssize_t write_pair(int fd, const char *key, const char *value, */ static void maybe_remove_section(struct config_store_data *store, size_t *begin_offset, size_t *end_offset, - int *seen_ptr) + unsigned *seen_ptr) { size_t begin; - int i, seen, section_seen = 0; + int section_seen = 0; + unsigned int i, seen; /* * First, ensure that this is the first key, and that there are no @@ -3227,7 +2712,8 @@ int repo_config_set_multivar_in_file_gently(struct repository *r, } else { struct stat st; size_t copy_begin, copy_end; - int i, new_line = 0; + unsigned i; + int new_line = 0; struct config_options opts; if (!value_pattern) @@ -163,9 +163,6 @@ struct config_context { typedef int (*config_fn_t)(const char *, const char *, const struct config_context *, void *); -int git_default_config(const char *, const char *, - const struct config_context *, void *); - /** * Read a specific file in git-config format. * This function takes the same callback and data parameters as `repo_config`. @@ -716,140 +713,4 @@ NORETURN void git_die_config_linenr(const char *key, const char *filename, int l lookup_config(mapping, ARRAY_SIZE(mapping), var) int lookup_config(const char **mapping, int nr_mapping, const char *var); -# ifdef USE_THE_REPOSITORY_VARIABLE -static inline void git_config(config_fn_t fn, void *data) -{ - repo_config(the_repository, fn, data); -} - -static inline void git_config_clear(void) -{ - repo_config_clear(the_repository); -} - -static inline int git_config_get(const char *key) -{ - return repo_config_get(the_repository, key); -} - -static inline int git_config_get_value(const char *key, const char **value) -{ - return repo_config_get_value(the_repository, key, value); -} - -static inline int git_config_get_value_multi(const char *key, const struct string_list **dest) -{ - return repo_config_get_value_multi(the_repository, key, dest); -} - -static inline int git_config_get_string_multi(const char *key, - const struct string_list **dest) -{ - return repo_config_get_string_multi(the_repository, key, dest); -} - -static inline int git_config_get_string(const char *key, char **dest) -{ - return repo_config_get_string(the_repository, key, dest); -} - -static inline int git_config_get_string_tmp(const char *key, const char **dest) -{ - return repo_config_get_string_tmp(the_repository, key, dest); -} - -static inline int git_config_get_int(const char *key, int *dest) -{ - return repo_config_get_int(the_repository, key, dest); -} - -static inline int git_config_get_ulong(const char *key, unsigned long *dest) -{ - return repo_config_get_ulong(the_repository, key, dest); -} - -static inline int git_config_get_bool(const char *key, int *dest) -{ - return repo_config_get_bool(the_repository, key, dest); -} - -static inline int git_config_get_bool_or_int(const char *key, int *is_bool, int *dest) -{ - return repo_config_get_bool_or_int(the_repository, key, is_bool, dest); -} - -static inline int git_config_get_maybe_bool(const char *key, int *dest) -{ - return repo_config_get_maybe_bool(the_repository, key, dest); -} - -static inline int git_config_get_pathname(const char *key, char **dest) -{ - return repo_config_get_pathname(the_repository, key, dest); -} - -static inline void git_config_set_in_file(const char *config_filename, - const char *key, const char *value) -{ - repo_config_set_in_file(the_repository, config_filename, key, value); -} - -static inline int git_config_set_gently(const char *key, const char *value) -{ - return repo_config_set_gently(the_repository, key, value); -} - -static inline void git_config_set(const char *key, const char *value) -{ - repo_config_set(the_repository, key, value); -} - -static inline int git_config_set_in_file_gently( - const char *config_filename, - const char *key, - const char *comment, - const char *value) -{ - return repo_config_set_in_file_gently(the_repository, config_filename, - key, comment, value); -} - -static inline int git_config_set_multivar_in_file_gently( - const char *config_filename, - const char *key, const char *value, - const char *value_pattern, - const char *comment, - unsigned flags) -{ - return repo_config_set_multivar_in_file_gently(the_repository, config_filename, - key, value, value_pattern, - comment, flags); -} - -static inline void git_config_set_multivar_in_file( - const char *config_filename, - const char *key, - const char *value, - const char *value_pattern, - unsigned flags) -{ - repo_config_set_multivar_in_file(the_repository, config_filename, - key, value, value_pattern, flags); -} - -static inline int git_config_set_multivar_gently(const char *key, const char *value, - const char *value_pattern, unsigned flags) -{ - return repo_config_set_multivar_gently(the_repository, key, value, - value_pattern, flags); -} - -static inline void git_config_set_multivar(const char *key, const char *value, - const char *value_pattern, unsigned flags) -{ - repo_config_set_multivar(the_repository, key, value, - value_pattern, flags); -} -# endif /* USE_THE_REPOSITORY_VARIABLE */ - #endif /* CONFIG_H */ @@ -407,7 +407,7 @@ static int process_ref_v2(struct packet_reader *reader, struct ref ***list, * name. Subsequent fields (symref-target and peeled) are optional and * don't have a particular order. */ - if (string_list_split(&line_sections, line, ' ', -1) < 2) { + if (string_list_split(&line_sections, line, " ", -1) < 2) { ret = 0; goto out; } @@ -1028,7 +1028,7 @@ static int git_proxy_command_options(const char *var, const char *value, static int git_use_proxy(const char *host) { git_proxy_command = getenv("GIT_PROXY_COMMAND"); - git_config(git_proxy_command_options, (void*)host); + repo_config(the_repository, git_proxy_command_options, (void*)host); return (git_proxy_command && *git_proxy_command); } @@ -1154,7 +1154,7 @@ static const char *get_ssh_command(void) if ((ssh = getenv("GIT_SSH_COMMAND"))) return ssh; - if (!git_config_get_string_tmp("core.sshcommand", &ssh)) + if (!repo_config_get_string_tmp(the_repository, "core.sshcommand", &ssh)) return ssh; return NULL; @@ -1173,7 +1173,7 @@ static void override_ssh_variant(enum ssh_variant *ssh_variant) { const char *variant = getenv("GIT_SSH_VARIANT"); - if (!variant && git_config_get_string_tmp("ssh.variant", &variant)) + if (!variant && repo_config_get_string_tmp(the_repository, "ssh.variant", &variant)) return; if (!strcmp(variant, "auto")) diff --git a/contrib/buildsystems/CMakeLists.txt b/contrib/buildsystems/CMakeLists.txt index 25b495fa73..edb0fc04ad 100644 --- a/contrib/buildsystems/CMakeLists.txt +++ b/contrib/buildsystems/CMakeLists.txt @@ -1005,7 +1005,9 @@ parse_makefile_for_sources(clar-test_SOURCES ${CMAKE_SOURCE_DIR}/Makefile "CLAR_ list(TRANSFORM clar-test_SOURCES REPLACE "\\$\\(UNIT_TEST_DIR\\)/" "${CMAKE_SOURCE_DIR}/t/unit-tests/") add_library(clar-test-lib STATIC ${clar-test_SOURCES}) -parse_makefile_for_scripts(unit_test_PROGRAMS "UNIT_TEST_PROGRAMS" "") +file(GLOB unit_test_PROGRAMS "${CMAKE_SOURCE_DIR}/t/unit-tests/t-*.c") +list(TRANSFORM unit_test_PROGRAMS REPLACE "${CMAKE_SOURCE_DIR}/" "") +list(TRANSFORM unit_test_PROGRAMS REPLACE ".c" "") foreach(unit_test ${unit_test_PROGRAMS}) add_executable("${unit_test}" "${CMAKE_SOURCE_DIR}/t/unit-tests/${unit_test}.c") target_link_libraries("${unit_test}" unit-test-lib clar-test-lib common-main) diff --git a/contrib/coccinelle/config_fn_ctx.pending.cocci b/contrib/coccinelle/config_fn_ctx.pending.cocci index 6d3d1000a9..54f09fcbcd 100644 --- a/contrib/coccinelle/config_fn_ctx.pending.cocci +++ b/contrib/coccinelle/config_fn_ctx.pending.cocci @@ -83,7 +83,7 @@ int fn(const char *C1, const char *C2, // The previous rules don't catch all callbacks, especially if they're defined -// in a separate file from the git_config() call. Fix these manually. +// in a separate file from the repo_config() call. Fix these manually. @@ identifier C1, C2, D; attribute name UNUSED; diff --git a/contrib/git-jump/git-jump b/contrib/git-jump/git-jump index 3f69675961..8d1d5d79a6 100755 --- a/contrib/git-jump/git-jump +++ b/contrib/git-jump/git-jump @@ -44,7 +44,7 @@ open_editor() { mode_diff() { git diff --no-prefix --relative "$@" | perl -ne ' - if (m{^\+\+\+ (.*)}) { $file = $1 eq "/dev/null" ? undef : $1; next } + if (m{^\+\+\+ (.*?)\t?$}) { $file = $1 eq "/dev/null" ? undef : $1; next } defined($file) or next; if (m/^@@ .*?\+(\d+)/) { $line = $1; next } defined($line) or next; @@ -1326,7 +1326,7 @@ void convert_attrs(struct index_state *istate, "eol", "text", "working-tree-encoding", NULL); user_convert_tail = &user_convert; - git_config(read_convert_config, NULL); + repo_config(the_repository, read_convert_config, NULL); } git_check_attr(istate, path, check); @@ -402,7 +402,7 @@ static int run_service(const char *dir, struct daemon_service *service, if (service->overridable) { strbuf_addf(&var, "daemon.%s", service->config_name); - git_config_get_bool(var.buf, &enabled); + repo_config_get_bool(the_repository, var.buf, &enabled); strbuf_release(&var); } if (!enabled) { diff --git a/diff-lib.c b/diff-lib.c index 244468dd1a..b8f8f3bc31 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -115,6 +115,9 @@ void run_diff_files(struct rev_info *revs, unsigned int option) uint64_t start = getnanotime(); struct index_state *istate = revs->diffopt.repo->index; + if (revs->diffopt.max_depth_valid) + die(_("max-depth is not supported for worktree diffs")); + diff_set_mnemonic_prefix(&revs->diffopt, "i/", "w/"); refresh_fsmonitor(istate); @@ -560,6 +563,8 @@ static int diff_cache(struct rev_info *revs, opts.dst_index = NULL; opts.pathspec = &revs->diffopt.pathspec; opts.pathspec->recursive = 1; + if (revs->diffopt.max_depth_valid) + die(_("max-depth is not supported for index diffs")); init_tree_desc(&t, &tree->object.oid, tree->buffer, tree->size); return unpack_trees(1, &t, &opts); @@ -327,29 +327,23 @@ static unsigned parse_color_moved_ws(const char *arg) struct string_list l = STRING_LIST_INIT_DUP; struct string_list_item *i; - string_list_split(&l, arg, ',', -1); + string_list_split_f(&l, arg, ",", -1, STRING_LIST_SPLIT_TRIM); for_each_string_list_item(i, &l) { - struct strbuf sb = STRBUF_INIT; - strbuf_addstr(&sb, i->string); - strbuf_trim(&sb); - - if (!strcmp(sb.buf, "no")) + if (!strcmp(i->string, "no")) ret = 0; - else if (!strcmp(sb.buf, "ignore-space-change")) + else if (!strcmp(i->string, "ignore-space-change")) ret |= XDF_IGNORE_WHITESPACE_CHANGE; - else if (!strcmp(sb.buf, "ignore-space-at-eol")) + else if (!strcmp(i->string, "ignore-space-at-eol")) ret |= XDF_IGNORE_WHITESPACE_AT_EOL; - else if (!strcmp(sb.buf, "ignore-all-space")) + else if (!strcmp(i->string, "ignore-all-space")) ret |= XDF_IGNORE_WHITESPACE; - else if (!strcmp(sb.buf, "allow-indentation-change")) + else if (!strcmp(i->string, "allow-indentation-change")) ret |= COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE; else { ret |= COLOR_MOVED_WS_ERROR; - error(_("unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', 'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'"), sb.buf); + error(_("unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', 'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'"), i->string); } - - strbuf_release(&sb); } if ((ret & COLOR_MOVED_WS_ALLOW_INDENTATION_CHANGE) && @@ -2444,6 +2438,15 @@ static int fn_out_consume(void *priv, char *line, unsigned long len) return 0; } +static int quick_consume(void *priv, char *line UNUSED, unsigned long len UNUSED) +{ + struct emit_callback *ecbdata = priv; + struct diff_options *o = ecbdata->opt; + + o->found_changes = 1; + return 1; +} + static void pprint_rename(struct strbuf *name, const char *a, const char *b) { const char *old_name = a; @@ -3759,8 +3762,21 @@ static void builtin_diff(const char *name_a, if (o->word_diff) init_diff_words_data(&ecbdata, o, one, two); - if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume, - &ecbdata, &xpp, &xecfg)) + if (o->dry_run) { + /* + * Unlike the !dry_run case, we need to ignore the + * return value from xdi_diff_outf() here, because + * xdi_diff_outf() takes non-zero return from its + * callback function as a sign of error and returns + * early (which is why we return non-zero from our + * callback, quick_consume()). Unfortunately, + * xdi_diff_outf() signals an error by returning + * non-zero. + */ + xdi_diff_outf(&mf1, &mf2, NULL, quick_consume, + &ecbdata, &xpp, &xecfg); + } else if (xdi_diff_outf(&mf1, &mf2, NULL, fn_out_consume, + &ecbdata, &xpp, &xecfg)) die("unable to generate diff for %s", one->path); if (o->word_diff) free_diff_words_data(&ecbdata); @@ -4988,6 +5004,9 @@ void diff_setup_done(struct diff_options *options) options->filter = ~filter_bit[DIFF_STATUS_FILTER_AON]; options->filter &= ~options->filter_not; } + + if (options->pathspec.has_wildcard && options->max_depth_valid) + die("max-depth cannot be used with wildcard pathspecs"); } int parse_long_opt(const char *opt, const char **argv, @@ -5622,6 +5641,23 @@ static int diff_opt_rotate_to(const struct option *opt, const char *arg, int uns return 0; } +static int diff_opt_max_depth(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_NEG(unset); + + if (!git_parse_int(arg, &options->max_depth)) + return error(_("invalid value for '%s': '%s'"), + "--max-depth", arg); + + options->flags.recursive = 1; + options->max_depth_valid = options->max_depth >= 0; + + return 0; +} + /* * Consider adding new flags to __git_diff_common_options * in contrib/completion/git-completion.bash @@ -5894,6 +5930,10 @@ struct option *add_diff_options(const struct option *opts, OPT_CALLBACK_F(0, "diff-filter", options, N_("[(A|C|D|M|R|T|U|X|B)...[*]]"), N_("select files by diff type"), PARSE_OPT_NONEG, diff_opt_diff_filter), + OPT_CALLBACK_F(0, "max-depth", options, N_("<depth>"), + N_("maximum tree depth to recurse"), + PARSE_OPT_NONEG, diff_opt_max_depth), + { .type = OPTION_CALLBACK, .long_name = "output", @@ -6150,6 +6190,22 @@ static void diff_flush_patch(struct diff_filepair *p, struct diff_options *o) run_diff(p, o); } +/* return 1 if any change is found; otherwise, return 0 */ +static int diff_flush_patch_quietly(struct diff_filepair *p, struct diff_options *o) +{ + int saved_dry_run = o->dry_run; + int saved_found_changes = o->found_changes; + int ret; + + o->dry_run = 1; + o->found_changes = 0; + diff_flush_patch(p, o); + ret = o->found_changes; + o->dry_run = saved_dry_run; + o->found_changes |= saved_found_changes; + return ret; +} + static void diff_flush_stat(struct diff_filepair *p, struct diff_options *o, struct diffstat_t *diffstat) { @@ -6778,8 +6834,15 @@ void diff_flush(struct diff_options *options) DIFF_FORMAT_CHECKDIFF)) { for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; - if (check_pair_status(p)) - flush_one_pair(p, options); + + if (!check_pair_status(p)) + continue; + + if (options->flags.diff_from_contents && + !diff_flush_patch_quietly(p, options)) + continue; + + flush_one_pair(p, options); } separator++; } @@ -6831,19 +6894,10 @@ void diff_flush(struct diff_options *options) if (output_format & DIFF_FORMAT_NO_OUTPUT && options->flags.exit_with_status && options->flags.diff_from_contents) { - /* - * run diff_flush_patch for the exit status. setting - * options->file to /dev/null should be safe, because we - * aren't supposed to produce any output anyway. - */ - diff_free_file(options); - options->file = xfopen("/dev/null", "w"); - options->close_file = 1; - options->color_moved = 0; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; if (check_pair_status(p)) - diff_flush_patch(p, options); + diff_flush_patch_quietly(p, options); if (options->found_changes) break; } @@ -400,10 +400,20 @@ struct diff_options { #define COLOR_MOVED_WS_ERROR (1<<0) unsigned color_moved_ws_handling; + bool dry_run; + struct repository *repo; struct strmap *additional_path_headers; int no_free; + + /* + * The value '0' is a valid max-depth (for no recursion), and value '-1' + * also (for unlimited recursion), so the extra "valid" flag is used to + * determined whether the user specified option --max-depth. + */ + int max_depth; + int max_depth_valid; }; unsigned diff_filter_bit(char status); @@ -277,7 +277,7 @@ int within_depth(const char *name, int namelen, if (depth > max_depth) return 0; } - return 1; + return depth <= max_depth; } /* @@ -4091,8 +4091,8 @@ void connect_work_tree_and_git_dir(const char *work_tree_, write_file(gitfile_sb.buf, "gitdir: %s", relative_path(git_dir, work_tree, &rel_path)); /* Update core.worktree setting */ - git_config_set_in_file(cfg_sb.buf, "core.worktree", - relative_path(work_tree, git_dir, &rel_path)); + repo_config_set_in_file(the_repository, cfg_sb.buf, "core.worktree", + relative_path(work_tree, git_dir, &rel_path)); strbuf_release(&gitfile_sb); strbuf_release(&cfg_sb); @@ -50,7 +50,7 @@ const char *git_sequence_editor(void) const char *editor = getenv("GIT_SEQUENCE_EDITOR"); if (!editor) - git_config_get_string_tmp("sequence.editor", &editor); + repo_config_get_string_tmp(the_repository, "sequence.editor", &editor); if (!editor) editor = git_editor(); diff --git a/environment.c b/environment.c index 7c2480b22e..0e72fdac85 100644 --- a/environment.c +++ b/environment.c @@ -12,22 +12,34 @@ #include "git-compat-util.h" #include "abspath.h" +#include "advice.h" +#include "attr.h" #include "branch.h" +#include "color.h" #include "convert.h" #include "environment.h" #include "gettext.h" #include "git-zlib.h" +#include "ident.h" +#include "mailmap.h" +#include "object-name.h" #include "repository.h" #include "config.h" #include "refs.h" #include "fmt-merge-msg.h" #include "commit.h" #include "strvec.h" +#include "pager.h" #include "path.h" +#include "quote.h" #include "chdir-notify.h" #include "setup.h" +#include "ws.h" #include "write-or-die.h" +static int pack_compression_seen; +static int zlib_compression_seen; + int trust_executable_bit = 1; int trust_ctime = 1; int check_stat = 1; @@ -66,7 +78,6 @@ int grafts_keep_true_parents; int core_apply_sparse_checkout; int core_sparse_checkout_cone; int sparse_expect_files_outside_of_patterns; -int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; int max_allowed_tree_depth = @@ -163,10 +174,10 @@ int have_git_dir(void) const char *get_git_namespace(void) { static const char *namespace; - struct strbuf buf = STRBUF_INIT; - struct strbuf **components, **c; const char *raw_namespace; + struct string_list components = STRING_LIST_INIT_DUP; + struct string_list_item *item; if (namespace) return namespace; @@ -178,12 +189,17 @@ const char *get_git_namespace(void) } strbuf_addstr(&buf, raw_namespace); - components = strbuf_split(&buf, '/'); + + string_list_split(&components, buf.buf, "/", -1); strbuf_reset(&buf); - for (c = components; *c; c++) - if (strcmp((*c)->buf, "/") != 0) - strbuf_addf(&buf, "refs/namespaces/%s", (*c)->buf); - strbuf_list_free(components); + + for_each_string_list_item(item, &components) { + if (item->string[0]) + strbuf_addf(&buf, "refs/namespaces/%s/", item->string); + } + string_list_clear(&components, 0); + + strbuf_trim_trailing_dir_sep(&buf); if (check_refname_format(buf.buf, 0)) die(_("bad git namespace path \"%s\""), raw_namespace); strbuf_addch(&buf, '/'); @@ -231,3 +247,503 @@ int print_sha1_ellipsis(void) } return cached_result; } + +static const struct fsync_component_name { + const char *name; + enum fsync_component component_bits; +} fsync_component_names[] = { + { "loose-object", FSYNC_COMPONENT_LOOSE_OBJECT }, + { "pack", FSYNC_COMPONENT_PACK }, + { "pack-metadata", FSYNC_COMPONENT_PACK_METADATA }, + { "commit-graph", FSYNC_COMPONENT_COMMIT_GRAPH }, + { "index", FSYNC_COMPONENT_INDEX }, + { "objects", FSYNC_COMPONENTS_OBJECTS }, + { "reference", FSYNC_COMPONENT_REFERENCE }, + { "derived-metadata", FSYNC_COMPONENTS_DERIVED_METADATA }, + { "committed", FSYNC_COMPONENTS_COMMITTED }, + { "added", FSYNC_COMPONENTS_ADDED }, + { "all", FSYNC_COMPONENTS_ALL }, +}; + +static enum fsync_component parse_fsync_components(const char *var, const char *string) +{ + enum fsync_component current = FSYNC_COMPONENTS_PLATFORM_DEFAULT; + enum fsync_component positive = 0, negative = 0; + + while (string) { + size_t len; + const char *ep; + int negated = 0; + int found = 0; + + string = string + strspn(string, ", \t\n\r"); + ep = strchrnul(string, ','); + len = ep - string; + if (!strcmp(string, "none")) { + current = FSYNC_COMPONENT_NONE; + goto next_name; + } + + if (*string == '-') { + negated = 1; + string++; + len--; + if (!len) + warning(_("invalid value for variable %s"), var); + } + + if (!len) + break; + + for (size_t i = 0; i < ARRAY_SIZE(fsync_component_names); ++i) { + const struct fsync_component_name *n = &fsync_component_names[i]; + + if (strncmp(n->name, string, len)) + continue; + + found = 1; + if (negated) + negative |= n->component_bits; + else + positive |= n->component_bits; + } + + if (!found) { + char *component = xstrndup(string, len); + warning(_("ignoring unknown core.fsync component '%s'"), component); + free(component); + } + +next_name: + string = ep; + } + + return (current & ~negative) | positive; +} + +static int git_default_core_config(const char *var, const char *value, + const struct config_context *ctx, void *cb) +{ + /* This needs a better name */ + if (!strcmp(var, "core.filemode")) { + trust_executable_bit = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.trustctime")) { + trust_ctime = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "core.checkstat")) { + if (!value) + return config_error_nonbool(var); + if (!strcasecmp(value, "default")) + check_stat = 1; + else if (!strcasecmp(value, "minimal")) + check_stat = 0; + else + return error(_("invalid value for '%s': '%s'"), + var, value); + } + + if (!strcmp(var, "core.quotepath")) { + quote_path_fully = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.symlinks")) { + has_symlinks = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.ignorecase")) { + ignore_case = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.attributesfile")) { + FREE_AND_NULL(git_attributes_file); + return git_config_pathname(&git_attributes_file, var, value); + } + + if (!strcmp(var, "core.bare")) { + is_bare_repository_cfg = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.ignorestat")) { + assume_unchanged = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.abbrev")) { + if (!value) + return config_error_nonbool(var); + if (!strcasecmp(value, "auto")) + default_abbrev = -1; + else if (!git_parse_maybe_bool_text(value)) + default_abbrev = GIT_MAX_HEXSZ; + else { + int abbrev = git_config_int(var, value, ctx->kvi); + if (abbrev < minimum_abbrev) + return error(_("abbrev length out of range: %d"), abbrev); + default_abbrev = abbrev; + } + return 0; + } + + if (!strcmp(var, "core.disambiguate")) + return set_disambiguate_hint_config(var, value); + + if (!strcmp(var, "core.loosecompression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad zlib compression level %d"), level); + zlib_compression_level = level; + zlib_compression_seen = 1; + return 0; + } + + if (!strcmp(var, "core.compression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad zlib compression level %d"), level); + if (!zlib_compression_seen) + zlib_compression_level = level; + if (!pack_compression_seen) + pack_compression_level = level; + return 0; + } + + if (!strcmp(var, "core.autocrlf")) { + if (value && !strcasecmp(value, "input")) { + auto_crlf = AUTO_CRLF_INPUT; + return 0; + } + auto_crlf = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.safecrlf")) { + int eol_rndtrp_die; + if (value && !strcasecmp(value, "warn")) { + global_conv_flags_eol = CONV_EOL_RNDTRP_WARN; + return 0; + } + eol_rndtrp_die = git_config_bool(var, value); + global_conv_flags_eol = eol_rndtrp_die ? + CONV_EOL_RNDTRP_DIE : 0; + return 0; + } + + if (!strcmp(var, "core.eol")) { + if (value && !strcasecmp(value, "lf")) + core_eol = EOL_LF; + else if (value && !strcasecmp(value, "crlf")) + core_eol = EOL_CRLF; + else if (value && !strcasecmp(value, "native")) + core_eol = EOL_NATIVE; + else + core_eol = EOL_UNSET; + return 0; + } + + if (!strcmp(var, "core.checkroundtripencoding")) { + FREE_AND_NULL(check_roundtrip_encoding); + return git_config_string(&check_roundtrip_encoding, var, value); + } + + if (!strcmp(var, "core.editor")) { + FREE_AND_NULL(editor_program); + return git_config_string(&editor_program, var, value); + } + + if (!strcmp(var, "core.commentchar") || + !strcmp(var, "core.commentstring")) { + if (!value) + return config_error_nonbool(var); + else if (!strcasecmp(value, "auto")) + auto_comment_line_char = 1; + else if (value[0]) { + if (strchr(value, '\n')) + return error(_("%s cannot contain newline"), var); + comment_line_str = value; + FREE_AND_NULL(comment_line_str_to_free); + auto_comment_line_char = 0; + } else + return error(_("%s must have at least one character"), var); + return 0; + } + + if (!strcmp(var, "core.askpass")) { + FREE_AND_NULL(askpass_program); + return git_config_string(&askpass_program, var, value); + } + + if (!strcmp(var, "core.excludesfile")) { + FREE_AND_NULL(excludes_file); + return git_config_pathname(&excludes_file, var, value); + } + + if (!strcmp(var, "core.whitespace")) { + if (!value) + return config_error_nonbool(var); + whitespace_rule_cfg = parse_whitespace_rule(value); + return 0; + } + + if (!strcmp(var, "core.fsync")) { + if (!value) + return config_error_nonbool(var); + fsync_components = parse_fsync_components(var, value); + return 0; + } + + if (!strcmp(var, "core.fsyncmethod")) { + if (!value) + return config_error_nonbool(var); + if (!strcmp(value, "fsync")) + 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); + + } + + if (!strcmp(var, "core.fsyncobjectfiles")) { + if (fsync_object_files < 0) + warning(_("core.fsyncObjectFiles is deprecated; use core.fsync instead")); + fsync_object_files = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.createobject")) { + if (!value) + return config_error_nonbool(var); + if (!strcmp(value, "rename")) + object_creation_mode = OBJECT_CREATION_USES_RENAMES; + else if (!strcmp(value, "link")) + object_creation_mode = OBJECT_CREATION_USES_HARDLINKS; + else + die(_("invalid mode for object creation: %s"), value); + return 0; + } + + if (!strcmp(var, "core.sparsecheckout")) { + core_apply_sparse_checkout = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.sparsecheckoutcone")) { + core_sparse_checkout_cone = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.precomposeunicode")) { + precomposed_unicode = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.protecthfs")) { + protect_hfs = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.protectntfs")) { + protect_ntfs = git_config_bool(var, value); + return 0; + } + + if (!strcmp(var, "core.maxtreedepth")) { + max_allowed_tree_depth = git_config_int(var, value, ctx->kvi); + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return platform_core_config(var, value, ctx, cb); +} + +static int git_default_sparse_config(const char *var, const char *value) +{ + if (!strcmp(var, "sparse.expectfilesoutsideofpatterns")) { + sparse_expect_files_outside_of_patterns = git_config_bool(var, value); + return 0; + } + + /* Add other config variables here and to Documentation/config/sparse.adoc. */ + return 0; +} + +static int git_default_i18n_config(const char *var, const char *value) +{ + if (!strcmp(var, "i18n.commitencoding")) { + FREE_AND_NULL(git_commit_encoding); + return git_config_string(&git_commit_encoding, var, value); + } + + if (!strcmp(var, "i18n.logoutputencoding")) { + FREE_AND_NULL(git_log_output_encoding); + return git_config_string(&git_log_output_encoding, var, value); + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_branch_config(const char *var, const char *value) +{ + if (!strcmp(var, "branch.autosetupmerge")) { + if (value && !strcmp(value, "always")) { + git_branch_track = BRANCH_TRACK_ALWAYS; + return 0; + } else if (value && !strcmp(value, "inherit")) { + git_branch_track = BRANCH_TRACK_INHERIT; + return 0; + } else if (value && !strcmp(value, "simple")) { + git_branch_track = BRANCH_TRACK_SIMPLE; + return 0; + } + git_branch_track = git_config_bool(var, value); + return 0; + } + if (!strcmp(var, "branch.autosetuprebase")) { + if (!value) + return config_error_nonbool(var); + else if (!strcmp(value, "never")) + autorebase = AUTOREBASE_NEVER; + else if (!strcmp(value, "local")) + autorebase = AUTOREBASE_LOCAL; + else if (!strcmp(value, "remote")) + autorebase = AUTOREBASE_REMOTE; + else if (!strcmp(value, "always")) + autorebase = AUTOREBASE_ALWAYS; + else + return error(_("malformed value for %s"), var); + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_push_config(const char *var, const char *value) +{ + if (!strcmp(var, "push.default")) { + if (!value) + return config_error_nonbool(var); + else if (!strcmp(value, "nothing")) + push_default = PUSH_DEFAULT_NOTHING; + else if (!strcmp(value, "matching")) + push_default = PUSH_DEFAULT_MATCHING; + else if (!strcmp(value, "simple")) + push_default = PUSH_DEFAULT_SIMPLE; + else if (!strcmp(value, "upstream")) + push_default = PUSH_DEFAULT_UPSTREAM; + else if (!strcmp(value, "tracking")) /* deprecated */ + push_default = PUSH_DEFAULT_UPSTREAM; + else if (!strcmp(value, "current")) + push_default = PUSH_DEFAULT_CURRENT; + else { + error(_("malformed value for %s: %s"), var, value); + return error(_("must be one of nothing, matching, simple, " + "upstream or current")); + } + return 0; + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_mailmap_config(const char *var, const char *value) +{ + if (!strcmp(var, "mailmap.file")) { + FREE_AND_NULL(git_mailmap_file); + return git_config_pathname(&git_mailmap_file, var, value); + } + + if (!strcmp(var, "mailmap.blob")) { + FREE_AND_NULL(git_mailmap_blob); + return git_config_string(&git_mailmap_blob, var, value); + } + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} + +static int git_default_attr_config(const char *var, const char *value) +{ + if (!strcmp(var, "attr.tree")) { + FREE_AND_NULL(git_attr_tree); + return git_config_string(&git_attr_tree, var, value); + } + + /* + * Add other attribute related config variables here and to + * Documentation/config/attr.adoc. + */ + return 0; +} + +int git_default_config(const char *var, const char *value, + const struct config_context *ctx, void *cb) +{ + if (starts_with(var, "core.")) + return git_default_core_config(var, value, ctx, cb); + + if (starts_with(var, "user.") || + starts_with(var, "author.") || + starts_with(var, "committer.")) + return git_ident_config(var, value, ctx, cb); + + if (starts_with(var, "i18n.")) + return git_default_i18n_config(var, value); + + if (starts_with(var, "branch.")) + return git_default_branch_config(var, value); + + if (starts_with(var, "push.")) + return git_default_push_config(var, value); + + if (starts_with(var, "mailmap.")) + return git_default_mailmap_config(var, value); + + if (starts_with(var, "attr.")) + return git_default_attr_config(var, value); + + if (starts_with(var, "advice.") || starts_with(var, "color.advice")) + return git_default_advice_config(var, value); + + if (!strcmp(var, "pager.color") || !strcmp(var, "color.pager")) { + pager_use_color = git_config_bool(var,value); + return 0; + } + + if (!strcmp(var, "pack.packsizelimit")) { + pack_size_limit_cfg = git_config_ulong(var, value, ctx->kvi); + return 0; + } + + if (!strcmp(var, "pack.compression")) { + int level = git_config_int(var, value, ctx->kvi); + if (level == -1) + level = Z_DEFAULT_COMPRESSION; + else if (level < 0 || level > Z_BEST_COMPRESSION) + die(_("bad pack compression level %d"), level); + pack_compression_level = level; + pack_compression_seen = 1; + return 0; + } + + if (starts_with(var, "sparse.")) + return git_default_sparse_config(var, value); + + /* Add other config variables here and to Documentation/config.adoc. */ + return 0; +} diff --git a/environment.h b/environment.h index 3d806ced6e..8cfce41015 100644 --- a/environment.h +++ b/environment.h @@ -104,6 +104,9 @@ int use_optional_locks(void); const char *get_git_namespace(void); const char *strip_namespace(const char *namespaced_ref); +int git_default_config(const char *, const char *, + const struct config_context *, void *); + /* * TODO: All the below state either explicitly or implicitly relies on * `the_repository`. We should eventually get rid of these and make the diff --git a/fetch-pack.c b/fetch-pack.c index c1be9b76eb..6ed5662951 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -143,7 +143,8 @@ static struct commit *deref_without_lazy_fetch(const struct object_id *oid, commit = lookup_commit_in_graph(the_repository, oid); if (commit) { if (mark_tags_complete_and_check_obj_db) { - if (!odb_has_object(the_repository->objects, oid, 0)) + if (!odb_has_object(the_repository->objects, oid, + HAS_OBJECT_RECHECK_PACKED)) die_in_commit_graph_only(oid); } return commit; @@ -1904,22 +1905,22 @@ static int fetch_pack_config_cb(const char *var, const char *value, static void fetch_pack_config(void) { - git_config_get_int("fetch.unpacklimit", &fetch_unpack_limit); - git_config_get_int("transfer.unpacklimit", &transfer_unpack_limit); - git_config_get_bool("repack.usedeltabaseoffset", &prefer_ofs_delta); - git_config_get_bool("fetch.fsckobjects", &fetch_fsck_objects); - git_config_get_bool("transfer.fsckobjects", &transfer_fsck_objects); - git_config_get_bool("transfer.advertisesid", &advertise_sid); + repo_config_get_int(the_repository, "fetch.unpacklimit", &fetch_unpack_limit); + repo_config_get_int(the_repository, "transfer.unpacklimit", &transfer_unpack_limit); + repo_config_get_bool(the_repository, "repack.usedeltabaseoffset", &prefer_ofs_delta); + repo_config_get_bool(the_repository, "fetch.fsckobjects", &fetch_fsck_objects); + repo_config_get_bool(the_repository, "transfer.fsckobjects", &transfer_fsck_objects); + repo_config_get_bool(the_repository, "transfer.advertisesid", &advertise_sid); if (!uri_protocols.nr) { char *str; - if (!git_config_get_string("fetch.uriprotocols", &str) && str) { - string_list_split(&uri_protocols, str, ',', -1); + if (!repo_config_get_string(the_repository, "fetch.uriprotocols", &str) && str) { + string_list_split(&uri_protocols, str, ",", -1); free(str); } } - git_config(fetch_pack_config_cb, NULL); + repo_config(the_repository, fetch_pack_config_cb, NULL); } static void fetch_pack_setup(void) diff --git a/fmt-merge-msg.c b/fmt-merge-msg.c index 40174efa3d..c9085edc40 100644 --- a/fmt-merge-msg.c +++ b/fmt-merge-msg.c @@ -26,13 +26,15 @@ static struct string_list suppress_dest_patterns = STRING_LIST_INIT_DUP; int fmt_merge_msg_config(const char *key, const char *value, const struct config_context *ctx, void *cb) { + int *merge_log_config = cb; + if (!strcmp(key, "merge.log") || !strcmp(key, "merge.summary")) { int is_bool; - merge_log_config = git_config_bool_or_int(key, value, ctx->kvi, &is_bool); - if (!is_bool && merge_log_config < 0) + *merge_log_config = git_config_bool_or_int(key, value, ctx->kvi, &is_bool); + if (!is_bool && *merge_log_config < 0) return error("%s: negative length %s", key, value); - if (is_bool && merge_log_config) - merge_log_config = DEFAULT_MERGE_LOG_LEN; + if (is_bool && *merge_log_config) + *merge_log_config = DEFAULT_MERGE_LOG_LEN; } else if (!strcmp(key, "merge.branchdesc")) { use_branch_desc = git_config_bool(key, value); } else if (!strcmp(key, "merge.suppressdest")) { diff --git a/fmt-merge-msg.h b/fmt-merge-msg.h index 73ca3e4465..c066d83761 100644 --- a/fmt-merge-msg.h +++ b/fmt-merge-msg.h @@ -12,7 +12,6 @@ struct fmt_merge_msg_opts { const char *into_name; }; -extern int merge_log_config; int fmt_merge_msg_config(const char *key, const char *value, const struct config_context *ctx, void *cb); int fmt_merge_msg(struct strbuf *in, struct strbuf *out, diff --git a/for-each-ref.h b/for-each-ref.h new file mode 100644 index 0000000000..c8d0219179 --- /dev/null +++ b/for-each-ref.h @@ -0,0 +1,26 @@ +#ifndef FOR_EACH_REF_H +#define FOR_EACH_REF_H + +struct repository; + +/* + * Shared usage string for options common to git-for-each-ref(1) + * and git-refs-list(1). The command-specific part (e.g., "git refs list ") + * must be prepended by the caller. + */ +#define COMMON_USAGE_FOR_EACH_REF \ + "[--count=<count>] [--shell|--perl|--python|--tcl]\n" \ + " [(--sort=<key>)...] [--format=<format>]\n" \ + " [--include-root-refs] [--points-at=<object>]\n" \ + " [--merged[=<object>]] [--no-merged[=<object>]]\n" \ + " [--contains[=<object>]] [--no-contains[=<object>]]\n" \ + " [(--exclude=<pattern>)...] [--start-after=<marker>]\n" \ + " [ --stdin | (<pattern>...)]" + +/* + * The core logic for for-each-ref and its clones. + */ +int for_each_ref_core(int argc, const char **argv, const char *prefix, + struct repository *repo, const char *const *usage); + +#endif /* FOR_EACH_REF_H */ @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "date.h" #include "dir.h" +#include "environment.h" #include "hex.h" #include "odb.h" #include "path.h" @@ -287,7 +287,7 @@ const char *fsck_describe_object(struct fsck_options *options, struct key_value_info; /* - * git_config() callback for use by fsck-y tools that want to support + * repo_config() callback for use by fsck-y tools that want to support * fsck.<msg> fsck.skipList etc. */ int git_fsck_config(const char *var, const char *value, diff --git a/fsmonitor.c b/fsmonitor.c index 98b2b476f0..d07dc18967 100644 --- a/fsmonitor.c +++ b/fsmonitor.c @@ -43,7 +43,7 @@ static int fsmonitor_hook_version(void) { int hook_version; - if (git_config_get_int("core.fsmonitorhookversion", &hook_version)) + if (repo_config_get_int(the_repository, "core.fsmonitorhookversion", &hook_version)) return -1; if (hook_version == HOOK_INTERFACE_VERSION1 || diff --git a/git-gui/.gitignore b/git-gui/.gitignore index ff6e0be4b4..5130b4f018 100644 --- a/git-gui/.gitignore +++ b/git-gui/.gitignore @@ -1,8 +1,8 @@ .DS_Store config.mak -Git Gui.app* git-gui.tcl GIT-GUI-BUILD-OPTIONS GIT-VERSION-FILE git-gui +git-gui--askpass lib/tclIndex diff --git a/git-gui/GIT-GUI-BUILD-OPTIONS.in b/git-gui/GIT-GUI-BUILD-OPTIONS.in index 5fd885c2bf..3c112af578 100644 --- a/git-gui/GIT-GUI-BUILD-OPTIONS.in +++ b/git-gui/GIT-GUI-BUILD-OPTIONS.in @@ -4,4 +4,3 @@ GITGUI_RELATIVE=@GITGUI_RELATIVE@ SHELL_PATH=@SHELL_PATH@ TCLTK_PATH=@TCLTK_PATH@ TCL_PATH=@TCL_PATH@ -TKEXECUTABLE=@TKEXECUTABLE@ diff --git a/git-gui/Makefile b/git-gui/Makefile index 8672dd2d6b..27bbe051de 100644 --- a/git-gui/Makefile +++ b/git-gui/Makefile @@ -12,7 +12,6 @@ GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN . $@ uname_S := $(shell sh -c 'uname -s 2>/dev/null || echo not') -uname_O := $(shell sh -c 'uname -o 2>/dev/null || echo not') uname_R := $(shell sh -c 'uname -r 2>/dev/null || echo not') SCRIPT_SH = git-gui.sh @@ -54,8 +53,6 @@ INSTALL_R0 = $(INSTALL) -m 644 # space is required here INSTALL_R1 = INSTALL_X0 = $(INSTALL) -m 755 # space is required here INSTALL_X1 = -INSTALL_A0 = find # space is required here -INSTALL_A1 = | cpio -pud INSTALL_L0 = rm -f # space is required here INSTALL_L1 = && ln # space is required here INSTALL_L2 = @@ -80,8 +77,6 @@ ifndef V INSTALL_R1 = && echo ' ' INSTALL 644 `basename $$src` && $(INSTALL) -m 644 $$src INSTALL_X0 = src= INSTALL_X1 = && echo ' ' INSTALL 755 `basename $$src` && $(INSTALL) -m 755 $$src - INSTALL_A0 = src= - INSTALL_A1 = && echo ' ' INSTALL ' ' `basename "$$src"` && find "$$src" | cpio -pud INSTALL_L0 = dst= INSTALL_L1 = && src= @@ -102,18 +97,6 @@ else TCL_PATH ?= $(dir $(TCLTK_PATH))$(notdir $(subst wish,tclsh,$(TCLTK_PATH))) endif -ifeq ($(uname_S),Darwin) - TKFRAMEWORK = /Library/Frameworks/Tk.framework/Resources/Wish.app - ifeq ($(shell echo "$(uname_R)" | awk -F. '{if ($$1 >= 9) print "y"}')_$(shell test -d $(TKFRAMEWORK) || echo n),y_n) - TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish.app - ifeq ($(shell test -d $(TKFRAMEWORK) || echo n),n) - TKFRAMEWORK = /System/Library/Frameworks/Tk.framework/Resources/Wish\ Shell.app - endif - endif - TKEXECUTABLE = $(TKFRAMEWORK)/Contents/MacOS/$(shell basename "$(TKFRAMEWORK)" .app) - TKEXECUTABLE_SQ = $(subst ','\'',$(TKEXECUTABLE)) -endif - ifeq ($(findstring $(firstword -$(MAKEFLAGS)),s),s) QUIET_GEN = endif @@ -131,16 +114,10 @@ libdir_SQ = $(subst ','\'',$(gg_libdir)) exedir = $(dir $(gitexecdir))share/git-gui/lib GITGUI_RELATIVE := -GITGUI_MACOSXAPP := ifeq ($(exedir),$(gg_libdir)) GITGUI_RELATIVE := 1 endif -ifeq ($(uname_S),Darwin) - ifeq ($(shell test -d $(TKFRAMEWORK) && echo y),y) - GITGUI_MACOSXAPP := YesPlease - endif -endif ifneq (,$(findstring MINGW,$(uname_S))) ifeq ($(shell expr "$(uname_R)" : '1\.'),2) NO_MSGFMT=1 @@ -149,20 +126,6 @@ endif GITGUI_RELATIVE := 1 endif -ifdef GITGUI_MACOSXAPP -GITGUI_MAIN := git-gui.tcl - -git-gui: generate-macos-wrapper.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS - $(QUIET_GEN)$(SHELL_PATH) generate-macos-wrapper.sh "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE - -Git\ Gui.app: GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS \ - macosx/Info.plist \ - macosx/git-gui.icns \ - macosx/AppMain.tcl \ - $(TKEXECUTABLE) - $(QUIET_GEN)$(SHELL_PATH) generate-macos-app.sh . "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE -endif - ifdef GITGUI_WINDOWS_WRAPPER GITGUI_MAIN := git-gui.tcl @@ -170,7 +133,7 @@ git-gui: windows/git-gui.sh cp $< $@ endif -$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS +$(GITGUI_MAIN): git-gui.sh GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS generate-git-gui.sh $(QUIET_GEN)$(SHELL_PATH) generate-git-gui.sh "$<" "$@" ./GIT-GUI-BUILD-OPTIONS ./GIT-VERSION-FILE XGETTEXT ?= xgettext @@ -207,18 +170,17 @@ GIT-GUI-BUILD-OPTIONS: FORCE -e 's|@SHELL_PATH@|$(SHELL_PATH_SQ)|' \ -e 's|@TCLTK_PATH@|$(TCLTK_PATH_SQ)|' \ -e 's|@TCL_PATH@|$(TCL_PATH_SQ)|' \ - -e 's|@TKEXECUTABLE@|$(TKEXECUTABLE_SQ)|' \ $@.in >$@+ @if grep -q '^[A-Z][A-Z_]*=@.*@$$' $@+; then echo "Unsubstituted build options in $@" >&2 && exit 1; fi @if cmp $@+ $@ >/dev/null 2>&1; then $(RM) $@+; else mv $@+ $@; fi -ifdef GITGUI_MACOSXAPP -all:: git-gui Git\ Gui.app -endif +git-gui--askpass: git-gui--askpass.sh GIT-GUI-BUILD-OPTIONS generate-script.sh + $(QUIET_GEN)$(SHELL_PATH) generate-script.sh $@ $< ./GIT-GUI-BUILD-OPTIONS + ifdef GITGUI_WINDOWS_WRAPPER all:: git-gui endif -all:: $(GITGUI_MAIN) lib/tclIndex $(ALL_MSGFILES) +all:: $(GITGUI_MAIN) git-gui--askpass lib/tclIndex $(ALL_MSGFILES) install: all $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(gitexecdir_SQ)' $(INSTALL_D1) @@ -230,10 +192,6 @@ ifdef GITGUI_WINDOWS_WRAPPER endif $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(libdir_SQ)' $(INSTALL_D1) $(QUIET)$(INSTALL_R0)lib/tclIndex $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' -ifdef GITGUI_MACOSXAPP - $(QUIET)$(INSTALL_A0)'Git Gui.app' $(INSTALL_A1) '$(DESTDIR_SQ)$(libdir_SQ)' - $(QUIET)$(INSTALL_X0)git-gui.tcl $(INSTALL_X1) '$(DESTDIR_SQ)$(libdir_SQ)' -endif $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(libdir_SQ)' &&) true $(QUIET)$(INSTALL_D0)'$(DESTDIR_SQ)$(msgsdir_SQ)' $(INSTALL_D1) $(QUIET)$(foreach p,$(ALL_MSGFILES), $(INSTALL_R0)$p $(INSTALL_R1) '$(DESTDIR_SQ)$(msgsdir_SQ)' &&) true @@ -248,10 +206,6 @@ ifdef GITGUI_WINDOWS_WRAPPER endif $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(libdir_SQ)' $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/tclIndex $(REMOVE_F1) -ifdef GITGUI_MACOSXAPP - $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)/Git Gui.app' $(REMOVE_F1) - $(QUIET)$(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/git-gui.tcl $(REMOVE_F1) -endif $(QUIET)$(foreach p,$(ALL_LIBFILES) $(NONTCL_LIBFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(libdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true $(QUIET)$(CLEAN_DST) '$(DESTDIR_SQ)$(msgsdir_SQ)' $(QUIET)$(foreach p,$(ALL_MSGFILES), $(REMOVE_F0)'$(DESTDIR_SQ)$(msgsdir_SQ)'/$(notdir $p) $(REMOVE_F1) &&) true @@ -265,11 +219,8 @@ dist-version: GIT-VERSION-FILE @sed 's|^GITGUI_VERSION=||' <GIT-VERSION-FILE >$(TARDIR)/version clean:: - $(RM_RF) $(GITGUI_MAIN) lib/tclIndex po/*.msg $(PO_TEMPLATE) + $(RM_RF) $(GITGUI_MAIN) git-gui--askpass lib/tclIndex po/*.msg $(PO_TEMPLATE) $(RM_RF) GIT-VERSION-FILE GIT-GUI-BUILD-OPTIONS -ifdef GITGUI_MACOSXAPP - $(RM_RF) 'Git Gui.app'* git-gui -endif ifdef GITGUI_WINDOWS_WRAPPER $(RM_RF) git-gui endif diff --git a/git-gui/generate-macos-app.sh b/git-gui/generate-macos-app.sh deleted file mode 100755 index 71b9fa67a4..0000000000 --- a/git-gui/generate-macos-app.sh +++ /dev/null @@ -1,30 +0,0 @@ -#!/bin/sh - -set -e - -SOURCE_DIR="$1" -OUTPUT="$2" -BUILD_OPTIONS="$3" -VERSION_FILE="$4" - -. "$BUILD_OPTIONS" -. "$VERSION_FILE" - -rm -rf "$OUTPUT" "$OUTPUT+" - -mkdir -p "$OUTPUT+/Contents/MacOS" -mkdir -p "$OUTPUT+/Contents/Resources/Scripts" - -cp "$TKEXECUTABLE" "$OUTPUT+/Contents/MacOS" -cp "$SOURCE_DIR/macosx/git-gui.icns" "$OUTPUT+/Contents/Resources" -sed \ - -e "s/@@GITGUI_VERSION@@/$GITGUI_VERSION/g" \ - -e "s/@@GITGUI_TKEXECUTABLE@@/$(basename "$TKEXECUTABLE")/g" \ - "$SOURCE_DIR/macosx/Info.plist" \ - >"$OUTPUT+/Contents/Info.plist" -sed \ - -e "s|@@gitexecdir@@|$GITGUI_GITEXECDIR|" \ - -e "s|@@GITGUI_LIBDIR@@|$GITGUI_LIBDIR|" \ - "$SOURCE_DIR/macosx/AppMain.tcl" \ - >"$OUTPUT+/Contents/Resources/Scripts/AppMain.tcl" -mv "$OUTPUT+" "$OUTPUT" diff --git a/git-gui/generate-macos-wrapper.sh b/git-gui/generate-macos-wrapper.sh deleted file mode 100755 index 0304937f41..0000000000 --- a/git-gui/generate-macos-wrapper.sh +++ /dev/null @@ -1,35 +0,0 @@ -#!/bin/sh - -set -e - -if test "$#" -ne 3 -then - echo >&2 "usage: $0 <OUTPUT> <BUILD_OPTIONS> <VERSION_FILE>" - exit 1 -fi - -OUTPUT="$1" -BUILD_OPTIONS="$2" -VERSION_FILE="$3" - -. "$BUILD_OPTIONS" - -rm -f "$OUTPUT" "$OUTPUT+" - -( - echo "#!$SHELL_PATH" - cat "$BUILD_OPTIONS" "$VERSION_FILE" - cat <<-'EOF' - if test "z$*" = zversion || - test "z$*" = z--version - then - echo "git-gui version $GITGUI_VERSION" - else - libdir="${GIT_GUI_LIB_DIR:-$GITGUI_LIBDIR}" - exec "$libdir/Git Gui.app/Contents/MacOS/$(basename "$TKEXECUTABLE")" "$0" "$@" - fi - EOF -) >"$OUTPUT+" - -chmod +x "$OUTPUT+" -mv "$OUTPUT+" "$OUTPUT" diff --git a/git-gui/generate-script.sh b/git-gui/generate-script.sh new file mode 100755 index 0000000000..0dd2da92e3 --- /dev/null +++ b/git-gui/generate-script.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +set -e + +if test $# -ne 3 +then + echo >&2 "USAGE: $0 <OUTPUT> <INPUT> <GIT-GUI-BUILD-OPTIONS>" + exit 1 +fi + +OUTPUT="$1" +INPUT="$2" +BUILD_OPTIONS="$3" + +. "$BUILD_OPTIONS" + +sed \ + -e "1s|#!.*/sh|#!$SHELL_PATH|" \ + -e "1,3s|^exec wish|exec '$TCLTK_PATH'|" \ + "$INPUT" >"$OUTPUT" + +chmod a+x "$OUTPUT" diff --git a/git-gui/git-gui--askpass b/git-gui/git-gui--askpass.sh index 71a536d232..71a536d232 100755 --- a/git-gui/git-gui--askpass +++ b/git-gui/git-gui--askpass.sh diff --git a/git-gui/git-gui.sh b/git-gui/git-gui.sh index 8bb121db4f..a931d7f7c9 100755 --- a/git-gui/git-gui.sh +++ b/git-gui/git-gui.sh @@ -30,7 +30,7 @@ along with this program; if not, see <https://www.gnu.org/licenses/>.}] ## ## Tcl/Tk sanity check -if {[catch {package require Tcl 8.6-8.8} err]} { +if {[catch {package require Tcl 8.6-} err]} { catch {wm withdraw .} tk_messageBox \ -icon error \ @@ -74,6 +74,26 @@ proc is_Cygwin {} { } ###################################################################### +## Enable Tcl8 profile in Tcl9, allowing consumption of data that has +## bytes not conforming to the assumed encoding profile. + +if {[package vcompare $::tcl_version 9.0] >= 0} { + rename open _strict_open + proc open args { + set f [_strict_open {*}$args] + chan configure $f -profile tcl8 + return $f + } + proc convertfrom args { + return [encoding convertfrom -profile tcl8 {*}$args] + } +} else { + proc convertfrom args { + return [encoding convertfrom {*}$args] + } +} + +###################################################################### ## ## PATH lookup. Sanitize $PATH, assure exec/open use only that @@ -83,12 +103,6 @@ if {[is_Windows]} { set _path_sep {:} } -if {[is_Windows]} { - set gitguidir [file dirname [info script]] - regsub -all ";" $gitguidir "\\;" gitguidir - set env(PATH) "$gitguidir;$env(PATH)" -} - set _search_path {} set _path_seen [dict create] foreach p [split $env(PATH) $_path_sep] { @@ -183,7 +197,9 @@ if {[is_Windows]} { set command_line [string trim [string range $arg0 1 end]] lset args 0 "| [sanitize_command_line $command_line 0]" } - uplevel 1 real_open $args + set fd [real_open {*}$args] + fconfigure $fd -eofchar {} + return $fd } } else { @@ -575,8 +591,6 @@ proc _lappend_nice {cmd_var} { set _nice [_which nice] if {[catch {safe_exec [list $_nice git version]}]} { set _nice {} - } elseif {[is_Windows] && [file dirname $_nice] ne [file dirname $::_git]} { - set _nice {} } } if {$_nice ne {}} { @@ -590,7 +604,7 @@ proc git {args} { proc git_redir {cmd redir} { set fd [git_read $cmd $redir] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 set result [string trimright [read $fd] "\n"] close $fd if {$::_trace} { @@ -607,7 +621,6 @@ proc safe_open_command {cmd {redir {}}} { } err]} { error $err } - fconfigure $fd -eofchar {} return $fd } @@ -1003,7 +1016,7 @@ proc _parse_config {arr_name args} { [concat config \ $args \ --null --list]] - fconfigure $fd_rc -translation binary -encoding utf-8 + fconfigure $fd_rc -encoding utf-8 set buf [read $fd_rc] close $fd_rc } @@ -1113,9 +1126,11 @@ citool { ## execution environment # Suggest our implementation of askpass, if none is set +set argv0dir [file dirname [file normalize $::argv0]] if {![info exists env(SSH_ASKPASS)]} { - set env(SSH_ASKPASS) [file join [git --exec-path] git-gui--askpass] + set env(SSH_ASKPASS) [file join $argv0dir git-gui--askpass] } +unset argv0dir ###################################################################### ## @@ -1405,15 +1420,15 @@ proc rescan_stage2 {fd after} { set fd_di [git_read [list diff-index --cached --ignore-submodules=dirty -z [PARENT]]] set fd_df [git_read [list diff-files -z]] - fconfigure $fd_di -blocking 0 -translation binary -encoding binary - fconfigure $fd_df -blocking 0 -translation binary -encoding binary + fconfigure $fd_di -blocking 0 -translation binary + fconfigure $fd_df -blocking 0 -translation binary fileevent $fd_di readable [list read_diff_index $fd_di $after] fileevent $fd_df readable [list read_diff_files $fd_df $after] if {[is_config_true gui.displayuntracked]} { set fd_lo [git_read [concat ls-files --others -z $ls_others]] - fconfigure $fd_lo -blocking 0 -translation binary -encoding binary + fconfigure $fd_lo -blocking 0 -translation binary fileevent $fd_lo readable [list read_ls_others $fd_lo $after] incr rescan_active } @@ -1427,7 +1442,6 @@ proc load_message {file {encoding {}}} { if {[catch {set fd [safe_open_file $f r]}]} { return 0 } - fconfigure $fd -eofchar {} if {$encoding ne {}} { fconfigure $fd -encoding $encoding } @@ -1484,7 +1498,7 @@ proc run_prepare_commit_msg_hook {} { ui_status [mc "Calling prepare-commit-msg hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list prepare_commit_msg_hook_wait $fd_ph] @@ -1530,7 +1544,7 @@ proc read_diff_index {fd after} { set i [split [string range $buf_rdi $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdi $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom utf-8 $p] \ + [convertfrom utf-8 $p] \ [lindex $i 4]? \ [list [lindex $i 0] [lindex $i 2]] \ [list] @@ -1563,7 +1577,7 @@ proc read_diff_files {fd after} { set i [split [string range $buf_rdf $c [expr {$z1 - 2}]] { }] set p [string range $buf_rdf $z1 [expr {$z2 - 1}]] merge_state \ - [encoding convertfrom utf-8 $p] \ + [convertfrom utf-8 $p] \ ?[lindex $i 4] \ [list] \ [list [lindex $i 0] [lindex $i 2]] @@ -1586,7 +1600,7 @@ proc read_ls_others {fd after} { set pck [split $buf_rlo "\0"] set buf_rlo [lindex $pck end] foreach p [lrange $pck 0 end-1] { - set p [encoding convertfrom utf-8 $p] + set p [convertfrom utf-8 $p] if {[string index $p end] eq {/}} { set p [string range $p 0 end-1] } diff --git a/git-gui/lib/blame.tcl b/git-gui/lib/blame.tcl index 9d4d1ac872..4477b84eae 100644 --- a/git-gui/lib/blame.tcl +++ b/git-gui/lib/blame.tcl @@ -483,7 +483,6 @@ method _load {jump} { } else { set fd [safe_open_file $path r] } - fconfigure $fd -eofchar {} } else { if {$do_textconv ne 0} { set fd [git_read [list cat-file --textconv "$commit:$path"]] @@ -493,7 +492,6 @@ method _load {jump} { } fconfigure $fd \ -blocking 0 \ - -translation lf \ -encoding [get_path_encoding $path] fileevent $fd readable [cb _read_file $fd $jump] set current_fd $fd @@ -620,7 +618,7 @@ method _exec_blame {cur_w cur_d options cur_s} { lappend options -- $path set fd [git_read_nice [concat blame $options]] - fconfigure $fd -blocking 0 -translation lf -encoding utf-8 + fconfigure $fd -blocking 0 -encoding utf-8 fileevent $fd readable [cb _read_blame $fd $cur_w $cur_d] set current_fd $fd set blame_lines 0 @@ -986,7 +984,7 @@ method _showcommit {cur_w lno} { set msg {} catch { set fd [git_read [list cat-file commit $cmit]] - fconfigure $fd -encoding binary -translation lf + fconfigure $fd -encoding iso8859-1 # By default commits are assumed to be in utf-8 set enc utf-8 while {[gets $fd line] > 0} { @@ -999,7 +997,7 @@ method _showcommit {cur_w lno} { set enc [tcl_encoding $enc] if {$enc ne {}} { - set msg [encoding convertfrom $enc $msg] + set msg [convertfrom $enc $msg] } set msg [string trim $msg] } @@ -1143,7 +1141,6 @@ method _blameparent {} { fconfigure $fd \ -blocking 0 \ - -encoding binary \ -translation binary fileevent $fd readable [cb _read_diff_load_commit \ $fd $cparent $new_path $r_orig_line] diff --git a/git-gui/lib/branch.tcl b/git-gui/lib/branch.tcl index 39e0f2dc98..97c9ec1c00 100644 --- a/git-gui/lib/branch.tcl +++ b/git-gui/lib/branch.tcl @@ -8,7 +8,7 @@ proc load_all_heads {} { set rh_len [expr {[string length $rh] + 1}] set all_heads [list] set fd [git_read [list for-each-ref --format=%(refname) $rh]] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { if {!$some_heads_tracking || ![is_tracking_branch $line]} { lappend all_heads [string range $line $rh_len end] @@ -25,7 +25,7 @@ proc load_all_tags {} { --sort=-taggerdate \ --format=%(refname) \ refs/tags]] - fconfigure $fd -translation binary -encoding utf-8 + fconfigure $fd -encoding utf-8 while {[gets $fd line] > 0} { if {![regsub ^refs/tags/ $line {} name]} continue lappend all_tags $name diff --git a/git-gui/lib/browser.tcl b/git-gui/lib/browser.tcl index f53eb952cf..fe72de025e 100644 --- a/git-gui/lib/browser.tcl +++ b/git-gui/lib/browser.tcl @@ -195,7 +195,7 @@ method _ls {tree_id {name {}}} { $w conf -state disabled set fd [git_read [list ls-tree -z $tree_id]] - fconfigure $fd -blocking 0 -translation binary -encoding utf-8 + fconfigure $fd -blocking 0 -encoding utf-8 fileevent $fd readable [cb _read $fd] } diff --git a/git-gui/lib/checkout_op.tcl b/git-gui/lib/checkout_op.tcl index 987486a4b6..449e89e2bc 100644 --- a/git-gui/lib/checkout_op.tcl +++ b/git-gui/lib/checkout_op.tcl @@ -462,7 +462,7 @@ If you wanted to be on a branch, create one now starting from 'This Detached Che if {$fd_ph ne {}} { global pch_error set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable [cb _postcheckout_wait $fd_ph] } else { _update_repo_state $this diff --git a/git-gui/lib/choose_rev.tcl b/git-gui/lib/choose_rev.tcl index 7a9e3c83bb..cd355cc92a 100644 --- a/git-gui/lib/choose_rev.tcl +++ b/git-gui/lib/choose_rev.tcl @@ -147,7 +147,7 @@ constructor _new {path unmerged_only title} { refs/remotes \ refs/tags \ ]] - fconfigure $fr_fd -translation lf -encoding utf-8 + fconfigure $fr_fd -encoding utf-8 while {[gets $fr_fd line] > 0} { set line [eval $line] if {[lindex $line 1 0] eq {tag}} { @@ -570,7 +570,7 @@ method _reflog_last {name} { set last {} if {[catch {set last [file mtime [gitdir $name]]}] && ![catch {set g [safe_open_file [gitdir logs $name] r]}]} { - fconfigure $g -translation binary + fconfigure $g -encoding iso8859-1 while {[gets $g line] >= 0} { if {[regexp {> ([1-9][0-9]*) } $line line when]} { set last $when diff --git a/git-gui/lib/commit.tcl b/git-gui/lib/commit.tcl index 2fd57a51fb..89eb8c7b73 100644 --- a/git-gui/lib/commit.tcl +++ b/git-gui/lib/commit.tcl @@ -28,7 +28,7 @@ You are currently in the middle of a merge that has not been fully completed. Y set name "" set email "" set fd [git_read [list cat-file commit $curHEAD]] - fconfigure $fd -encoding binary -translation lf + fconfigure $fd -encoding iso8859-1 # By default commits are assumed to be in utf-8 set enc utf-8 while {[gets $fd line] > 0} { @@ -43,9 +43,9 @@ You are currently in the middle of a merge that has not been fully completed. Y set enc [tcl_encoding $enc] if {$enc ne {}} { - set msg [encoding convertfrom $enc $msg] - set name [encoding convertfrom $enc $name] - set email [encoding convertfrom $enc $email] + set msg [convertfrom $enc $msg] + set name [convertfrom $enc $name] + set email [convertfrom $enc $email] } if {$name ne {} && $email ne {}} { set commit_author [list name $name email $email date $time] @@ -208,28 +208,6 @@ You must stage at least 1 file before you can commit. # -- A message is required. # set msg [$ui_comm get 1.0 end] - # Strip trailing whitespace - regsub -all -line {[ \t\r]+$} $msg {} msg - # Strip comment lines - global comment_string - set cmt_rx [strcat {(^|\n)} [regsub -all {\W} $comment_string {\\&}] {[^\n]*}] - regsub -all $cmt_rx $msg {\1} msg - # Strip leading and trailing empty lines (puts adds one \n) - set msg [string trim $msg \n] - # Compress consecutive empty lines - regsub -all {\n{3,}} $msg "\n\n" msg - if {$msg eq {}} { - error_popup [mc "Please supply a commit message. - -A good commit message has the following format: - -- First line: Describe in one sentence what you did. -- Second line: Blank -- Remaining lines: Describe why this change is good. -"] - unlock_index - return - } # -- Build the message file. # @@ -252,7 +230,7 @@ A good commit message has the following format: ui_status [mc "Calling pre-commit hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_prehook_wait $fd_ph $curHEAD $msg_p] } @@ -307,7 +285,7 @@ Do you really want to proceed with your Commit?"] ui_status [mc "Calling commit-msg hook..."] set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_commitmsg_wait $fd_ph $curHEAD $msg_p] } @@ -332,7 +310,52 @@ proc commit_commitmsg_wait {fd_ph curHEAD msg_p} { fconfigure $fd_ph -blocking 0 } +proc wash_commit_message {msg} { + # Strip trailing whitespace + regsub -all -line {[ \t\r]+$} $msg {} msg + # Strip comment lines + global comment_string + set cmt_rx [strcat {(^|\n)} [regsub -all {\W} $comment_string {\\&}] {[^\n]*}] + regsub -all $cmt_rx $msg {\1} msg + # Strip leading and trailing empty lines (puts adds one \n) + set msg [string trim $msg \n] + # Compress consecutive empty lines + regsub -all {\n{3,}} $msg \n\n msg + + return $msg +} + proc commit_writetree {curHEAD msg_p} { + # -- Process the commit message after hooks have run. + # + set msg_fd [safe_open_file $msg_p r] + setup_commit_encoding $msg_fd 1 + set msg [read $msg_fd] + close $msg_fd + + # Process the message (strip whitespace, comments, etc.) + set msg [wash_commit_message $msg] + + if {$msg eq {}} { + error_popup [mc "Please supply a commit message. + +A good commit message has the following format: + +- First line: Describe in one sentence what you did. +- Second line: Blank +- Remaining lines: Describe why this change is good. +"] + unlock_index + return + } + + # Write the processed message back to the file + set msg_wt [safe_open_file $msg_p w] + fconfigure $msg_wt -translation lf + setup_commit_encoding $msg_wt + puts $msg_wt $msg + close $msg_wt + ui_status [mc "Committing changes..."] set fd_wt [git_read [list write-tree]] fileevent $fd_wt readable \ @@ -361,7 +384,7 @@ proc commit_committree {fd_wt curHEAD msg_p} { # if {$commit_type eq {normal}} { set fd_ot [git_read [list cat-file commit $PARENT]] - fconfigure $fd_ot -encoding binary -translation lf + fconfigure $fd_ot -encoding iso8859-1 set old_tree [gets $fd_ot] close $fd_ot @@ -460,7 +483,7 @@ A rescan will be automatically started now. if {$fd_ph ne {}} { global pch_error set pch_error {} - fconfigure $fd_ph -blocking 0 -translation binary -eofchar {} + fconfigure $fd_ph -blocking 0 -translation binary fileevent $fd_ph readable \ [list commit_postcommit_wait $fd_ph $cmt_id] } diff --git a/git-gui/lib/diff.tcl b/git-gui/lib/diff.tcl index 1acd37bdb4..442737ba4f 100644 --- a/git-gui/lib/diff.tcl +++ b/git-gui/lib/diff.tcl @@ -191,7 +191,6 @@ proc show_other_diff {path w m cont_info} { file { set fd [safe_open_file $path r] fconfigure $fd \ - -eofchar {} \ -encoding [get_path_encoding $path] set content [read $fd $max_sz] close $fd @@ -325,6 +324,8 @@ proc start_show_diff {cont_info {add_opts {}}} { # '++' lines which is not bijective. Thus, we need to maintain a state # across lines. set ::conflict_in_pre_image 0 + + # git-diff has eol==\n, \r if present is part of the text fconfigure $fd \ -blocking 0 \ -encoding [get_path_encoding $path] \ diff --git a/git-gui/lib/index.tcl b/git-gui/lib/index.tcl index 377547034b..7aa09c7728 100644 --- a/git-gui/lib/index.tcl +++ b/git-gui/lib/index.tcl @@ -78,7 +78,6 @@ proc update_indexinfo {msg path_list after} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_update_indexinfo \ @@ -147,7 +146,6 @@ proc update_index {msg path_list after} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_update_index \ @@ -227,7 +225,6 @@ proc checkout_index {msg path_list after capture_error} { -blocking 0 \ -buffering full \ -buffersize 512 \ - -encoding binary \ -translation binary fileevent $fd writable [list \ write_checkout_index \ diff --git a/git-gui/lib/mergetool.tcl b/git-gui/lib/mergetool.tcl index 2c9bb3af40..44be4ed3ff 100644 --- a/git-gui/lib/mergetool.tcl +++ b/git-gui/lib/mergetool.tcl @@ -90,7 +90,7 @@ proc merge_load_stages {path cont} { set merge_stages_fd [git_read [list ls-files -u -z -- $path]] - fconfigure $merge_stages_fd -blocking 0 -translation binary -encoding binary + fconfigure $merge_stages_fd -blocking 0 -translation binary fileevent $merge_stages_fd readable [list read_merge_stages $merge_stages_fd $cont] } @@ -370,7 +370,7 @@ proc merge_tool_start {cmdline target backup stages} { ui_status [mc "Running merge tool..."] - fconfigure $mtool_fd -blocking 0 -translation binary -encoding binary + fconfigure $mtool_fd -blocking 0 -translation binary fileevent $mtool_fd readable [list read_mtool_output $mtool_fd] } diff --git a/git-gui/lib/remote_branch_delete.tcl b/git-gui/lib/remote_branch_delete.tcl index 349d31edf3..f0814efdd7 100644 --- a/git-gui/lib/remote_branch_delete.tcl +++ b/git-gui/lib/remote_branch_delete.tcl @@ -307,7 +307,6 @@ method _load {cache uri} { set active_ls [git_read [list ls-remote $uri]] fconfigure $active_ls \ -blocking 0 \ - -translation lf \ -encoding utf-8 fileevent $active_ls readable [cb _read $cache $active_ls] } else { diff --git a/git-gui/lib/shortcut.tcl b/git-gui/lib/shortcut.tcl index 1d01d9cbfa..431665059e 100644 --- a/git-gui/lib/shortcut.tcl +++ b/git-gui/lib/shortcut.tcl @@ -3,27 +3,41 @@ proc do_windows_shortcut {} { global _gitworktree - set fn [tk_getSaveFile \ - -parent . \ - -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \ - -initialfile "Git [reponame].lnk"] - if {$fn != {}} { - if {[file extension $fn] ne {.lnk}} { - set fn ${fn}.lnk - } - # Use git-gui.exe if available (ie: git-for-windows) - set cmdLine [list [_which git-gui]] - if {$cmdLine eq {}} { - set cmdLine [list [info nameofexecutable] \ - [file normalize $::argv0]] - } - if {[catch { - win32_create_lnk $fn $cmdLine \ - [file normalize $_gitworktree] - } err]} { - error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] + + set desktop [safe_exec [list cygpath -mD]] + set link_file "Git [reponame].lnk" + set link_path [file normalize [file join $desktop $link_file]] + + # on Windows, tk_getSaveFile dereferences .lnk files, so no simple + # filename chooser is available. Use the default or quit. + if {[file exists $link_path]} { + set answer [tk_messageBox \ + -type yesno \ + -title [mc "%s (%s): Create Desktop Icon" [appname] [reponame]] \ + -default yes \ + -message [mc "Replace existing shortcut: %s?" $link_file]] + if {$answer == no} { + return } } + + # Use git-gui.exe if found, fall back to wish + launcher + set link_arguments {} + set link_target [safe_exec [list cygpath -m /cmd/git-gui.exe]] + if {![file executable $link_target]} { + set link_target [_which git-gui] + } + if {![file executable $link_target]} { + set link_target [file normalize [info nameofexecutable]] + set link_arguments [file normalize $::argv0] + } + set cmdLine [list $link_target $link_arguments] + if {[catch { + win32_create_lnk $link_path $cmdLine \ + [file normalize $_gitworktree] + } err]} { + error_popup [strcat [mc "Cannot write shortcut:"] "\n\n$err"] + } } proc do_cygwin_shortcut {} { diff --git a/git-gui/lib/spellcheck.tcl b/git-gui/lib/spellcheck.tcl index 538d61c792..634656820d 100644 --- a/git-gui/lib/spellcheck.tcl +++ b/git-gui/lib/spellcheck.tcl @@ -33,7 +33,6 @@ constructor init {pipe_fd ui_text ui_menu} { method _connect {pipe_fd} { fconfigure $pipe_fd \ -encoding utf-8 \ - -eofchar {} \ -translation lf if {[gets $pipe_fd s_version] <= 0} { diff --git a/git-gui/lib/themed.tcl b/git-gui/lib/themed.tcl index 8c4a0c2ee7..c18e201d85 100644 --- a/git-gui/lib/themed.tcl +++ b/git-gui/lib/themed.tcl @@ -21,10 +21,10 @@ namespace eval color { set inactive_select_bg [convert_rgb_to_gray $select_bg] set inactive_select_fg $select_fg - set color::select_bg $select_bg - set color::select_fg $select_fg - set color::inactive_select_bg $inactive_select_bg - set color::inactive_select_fg $inactive_select_fg + set ::color::select_bg $select_bg + set ::color::select_fg $select_fg + set ::color::inactive_select_bg $inactive_select_bg + set ::color::inactive_select_fg $inactive_select_fg proc add_option {key val} { option add $key $val widgetDefault diff --git a/git-gui/macosx/AppMain.tcl b/git-gui/macosx/AppMain.tcl deleted file mode 100644 index b6c6dc3500..0000000000 --- a/git-gui/macosx/AppMain.tcl +++ /dev/null @@ -1,29 +0,0 @@ -set gitexecdir {@@gitexecdir@@} -if { [info exists ::env(GIT_GUI_LIB_DIR) ] } { - set gitguilib $::env(GIT_GUI_LIB_DIR) -} else { - set gitguilib {@@GITGUI_LIBDIR@@} -} - -set env(PATH) "$gitexecdir:$env(PATH)" - -if {[string first -psn [lindex $argv 0]] == 0} { - lset argv 0 [file join $gitexecdir git-gui] -} - -if {[file tail [lindex $argv 0]] eq {gitk}} { - set argv0 [lindex $argv 0] - set AppMain_source $argv0 -} else { - set argv0 [file join $gitexecdir [file tail [lindex $argv 0]]] - set AppMain_source [file join $gitguilib git-gui.tcl] - if {[info exists env(PWD)]} { - cd $env(PWD) - } elseif {[pwd] eq {/}} { - cd $env(HOME) - } -} - -unset gitexecdir gitguilib -set argv [lrange $argv 1 end] -source $AppMain_source diff --git a/git-gui/macosx/Info.plist b/git-gui/macosx/Info.plist deleted file mode 100644 index 1ade121c4c..0000000000 --- a/git-gui/macosx/Info.plist +++ /dev/null @@ -1,30 +0,0 @@ -<?xml version="1.0" encoding="UTF-8"?> -<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> -<plist version="1.0"> -<dict> - <key>CFBundleDevelopmentRegion</key> - <string>English</string> - <key>CFBundleExecutable</key> - <string>@@GITGUI_TKEXECUTABLE@@</string> - <key>CFBundleGetInfoString</key> - <string>Git Gui @@GITGUI_VERSION@@ © 2006-2007 Shawn Pearce, et. al.</string> - <key>CFBundleIconFile</key> - <string>git-gui.icns</string> - <key>CFBundleIdentifier</key> - <string>cz.or.repo.git-gui</string> - <key>CFBundleInfoDictionaryVersion</key> - <string>6.0</string> - <key>CFBundleName</key> - <string>Git Gui</string> - <key>CFBundlePackageType</key> - <string>APPL</string> - <key>CFBundleShortVersionString</key> - <string>@@GITGUI_VERSION@@</string> - <key>CFBundleSignature</key> - <string>GITg</string> - <key>CFBundleVersion</key> - <string>@@GITGUI_VERSION@@</string> - <key>NSHighResolutionCapable</key> - <true/> -</dict> -</plist> diff --git a/git-gui/macosx/git-gui.icns b/git-gui/macosx/git-gui.icns Binary files differdeleted file mode 100644 index 77d88a77a7..0000000000 --- a/git-gui/macosx/git-gui.icns +++ /dev/null diff --git a/git-gui/meson.build b/git-gui/meson.build index cdae85e4b9..320ba09ecf 100644 --- a/git-gui/meson.build +++ b/git-gui/meson.build @@ -19,17 +19,6 @@ build_options_config.set_quoted('GITGUI_LIBDIR', get_option('prefix') / get_opti build_options_config.set_quoted('SHELL_PATH', fs.as_posix(shell.full_path())) build_options_config.set_quoted('TCLTK_PATH', fs.as_posix(wish.full_path())) build_options_config.set_quoted('TCL_PATH', fs.as_posix(tclsh.full_path())) -if target_machine.system() == 'darwin' - tkexecutables = [ - '/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', - '/System/Library/Frameworks/Tk.framework/Resources/Wish.app/Contents/MacOS/Wish', - '/System/Library/Frameworks/Tk.framework/Resources/Wish Shell.app/Contents/MacOS/Wish Shell', - ] - tkexecutable = find_program(tkexecutables) - build_options_config.set_quoted('TKEXECUTABLE', tkexecutable.full_path()) -else - build_options_config.set('TKEXECUTABLE', '') -endif build_options = configure_file( input: 'GIT-GUI-BUILD-OPTIONS.in', @@ -49,14 +38,6 @@ version_file = custom_target( build_always_stale: true, ) -configure_file( - input: 'git-gui--askpass', - output: 'git-gui--askpass', - copy: true, - install: true, - install_dir: get_option('libexecdir') / 'git-core', -) - gitgui_main = 'git-gui' gitgui_main_install_dir = get_option('libexecdir') / 'git-core' @@ -70,55 +51,23 @@ if target_machine.system() == 'windows' install: true, install_dir: get_option('libexecdir') / 'git-core', ) -elif target_machine.system() == 'darwin' - gitgui_main = 'git-gui.tcl' - gitgui_main_install_dir = get_option('datadir') / 'git-gui/lib' - - custom_target( - output: 'git-gui', - command: [ - shell, - meson.current_source_dir() / 'generate-macos-wrapper.sh', - '@OUTPUT@', - meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', - meson.current_build_dir() / 'GIT-VERSION-FILE', - ], - depends: [ - version_file, - ], - depend_files: [ - build_options, - ], - install: true, - install_dir: get_option('libexecdir') / 'git-core', - ) - - custom_target( - output: 'Git Gui.app', - command: [ - shell, - meson.current_source_dir() / 'generate-macos-app.sh', - meson.current_source_dir(), - meson.current_build_dir() / 'Git Gui.app', - meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', - meson.current_build_dir() / 'GIT-VERSION-FILE', - ], - depends: [ - version_file, - ], - depend_files: [ - build_options, - 'macosx/AppMain.tcl', - 'macosx/Info.plist', - 'macosx/git-gui.icns', - ], - build_by_default: true, - install: true, - install_dir: get_option('datadir') / 'git-gui/lib', - ) endif custom_target( + output: 'git-gui--askpass', + input: 'git-gui--askpass.sh', + command: [ + shell, + meson.current_source_dir() / 'generate-script.sh', + '@OUTPUT@', + '@INPUT@', + meson.current_build_dir() / 'GIT-GUI-BUILD-OPTIONS', + ], + install: true, + install_dir: get_option('libexecdir') / 'git-core', +) + +custom_target( input: 'git-gui.sh', output: gitgui_main, command: [ diff --git a/git-gui/po/bg.po b/git-gui/po/bg.po index 70ab2b438a..21f5bd54e9 100644 --- a/git-gui/po/bg.po +++ b/git-gui/po/bg.po @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: git-gui master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2025-04-20 09:27+0200\n" -"PO-Revision-Date: 2025-05-29 13:37+0200\n" +"POT-Creation-Date: 2025-07-22 17:37+0200\n" +"PO-Revision-Date: 2025-07-28 11:56+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -18,88 +18,58 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: git-gui.sh:861 #, tcl-format msgid "Invalid font specified in %s:" msgstr "Указан е неправилен шрифт в „%s“:" -#: git-gui.sh:924 msgid "Main Font" msgstr "ОÑновен шрифт" -#: git-gui.sh:925 msgid "Diff/Console Font" msgstr "Шрифт за разликите/конзолата" -#: git-gui.sh:940 git-gui.sh:954 git-gui.sh:967 git-gui.sh:1057 git-gui.sh:1076 -#: git-gui.sh:3217 msgid "git-gui: fatal error" msgstr "git-gui: фатална грешка" -#: git-gui.sh:941 msgid "Cannot find git in PATH." msgstr "Командата git липÑва в Ð¿ÑŠÑ‚Ñ (PATH)." -#: git-gui.sh:968 msgid "Cannot parse Git version string:" msgstr "Ðизът Ñ Ð²ÐµÑ€ÑиÑта на Git не може да Ñе анализира:" -#: git-gui.sh:993 -#, tcl-format -msgid "" -"Git version cannot be determined.\n" -"\n" -"%s claims it is version '%s'.\n" -"\n" -"%s requires at least Git 1.5.0 or later.\n" -"\n" -"Assume '%s' is version 1.5.0?\n" -msgstr "" -"ВерÑиÑта на Git не може да Ñе определи.\n" -"\n" -"ВерÑиÑта на „%s“ изглежда, че е „%s“.\n" -"\n" -"„%s“ изиÑква Git, верÑÐ¸Ñ Ð¿Ð¾Ð½Ðµ 1.5.0.\n" -"\n" -"Да Ñе приеме ли, че „%s“ е верÑÐ¸Ñ â€ž1.5.0“?\n" +msgid "Insufficient git version, require: " +msgstr "Прекалено ниÑка верÑÐ¸Ñ Ð½Ð° git, необходима е поне: " + +msgid "git returned:" +msgstr "git върна:" -#: git-gui.sh:1287 msgid "Git directory not found:" msgstr "ДиректориÑта на Git не е открита:" -#: git-gui.sh:1317 msgid "Cannot move to top of working directory:" msgstr "Ðе може да Ñе премине към родителÑката директориÑ." -#: git-gui.sh:1325 msgid "Cannot use bare repository:" msgstr "Голо хранилище не може да Ñе използва:" -#: git-gui.sh:1333 msgid "No working directory" msgstr "Работната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð»Ð¸Ð¿Ñва" -#: git-gui.sh:1507 lib/checkout_op.tcl:306 msgid "Refreshing file status..." msgstr "ОбновÑване на ÑÑŠÑтоÑнието на файла…" -#: git-gui.sh:1551 msgid "Scanning for modified files ..." msgstr "Проверка за променени файлове…" -#: git-gui.sh:1635 msgid "Calling prepare-commit-msg hook..." msgstr "Куката „prepare-commit-msg“ Ñе изпълнÑва в момента…" -#: git-gui.sh:1652 msgid "Commit declined by prepare-commit-msg hook." msgstr "Подаването е отхвърлено от куката „prepare-commit-msg“." -#: git-gui.sh:1810 lib/browser.tcl:252 msgid "Ready." msgstr "Готово." -#: git-gui.sh:1974 #, tcl-format msgid "" "Display limit (gui.maxfilesdisplayed = %s) reached, not showing all %s files." @@ -108,721 +78,539 @@ msgstr "" "извеждане(gui.maxfilesdisplayed = %s), Ñъответно не Ñа показани вÑички %s " "файла." -#: git-gui.sh:2097 msgid "Unmodified" msgstr "Ðепроменен" -#: git-gui.sh:2099 msgid "Modified, not staged" msgstr "Променен, но не е в индекÑа" -#: git-gui.sh:2100 git-gui.sh:2112 msgid "Staged for commit" msgstr "Ð’ индекÑа за подаване" -#: git-gui.sh:2101 git-gui.sh:2113 msgid "Portions staged for commit" msgstr "ЧаÑти Ñа в индекÑа за подаване" -#: git-gui.sh:2102 git-gui.sh:2114 msgid "Staged for commit, missing" msgstr "Ð’ индекÑа за подаване, но липÑва" -#: git-gui.sh:2104 msgid "File type changed, not staged" msgstr "Видът на файла е Ñменен, но не е в индекÑа" -#: git-gui.sh:2105 git-gui.sh:2106 msgid "File type changed, old type staged for commit" msgstr "Видът на файла е Ñменен, но новиÑÑ‚ вид не е в индекÑа" -#: git-gui.sh:2107 msgid "File type changed, staged" msgstr "Видът на файла е Ñменен и е в индекÑа" -#: git-gui.sh:2108 msgid "File type change staged, modification not staged" msgstr "Видът на файла е Ñменен в индекÑа, но не и Ñъдържанието" -#: git-gui.sh:2109 msgid "File type change staged, file missing" msgstr "Видът на файла е Ñменен в индекÑа, но файлът липÑва" -#: git-gui.sh:2111 msgid "Untracked, not staged" msgstr "ÐеÑледен" -#: git-gui.sh:2116 msgid "Missing" msgstr "ЛипÑващ" -#: git-gui.sh:2117 msgid "Staged for removal" msgstr "Ð’ индекÑа за изтриване" -#: git-gui.sh:2118 msgid "Staged for removal, still present" msgstr "Ð’ индекÑа за изтриване, но още го има" -#: git-gui.sh:2120 git-gui.sh:2121 git-gui.sh:2122 git-gui.sh:2123 -#: git-gui.sh:2124 git-gui.sh:2125 msgid "Requires merge resolution" msgstr "ИзиÑква коригиране при Ñливане" -#: git-gui.sh:2170 msgid "Couldn't find gitk in PATH" msgstr "Командата „gitk“ липÑва в пътищата, определени от променливата PATH." -#: git-gui.sh:2217 git-gui.sh:2253 #, tcl-format msgid "Starting %s... please wait..." msgstr "Стартиране на „%s“…, изчакайте…" -#: git-gui.sh:2232 msgid "Couldn't find git gui in PATH" msgstr "" "Командата „git gui“ липÑва в пътищата, определени от променливата PATH." -#: git-gui.sh:2735 lib/choose_repository.tcl:53 msgid "Repository" msgstr "Хранилище" -#: git-gui.sh:2736 msgid "Edit" msgstr "Редактиране" -#: git-gui.sh:2738 lib/choose_rev.tcl:567 msgid "Branch" msgstr "Клон" -#: git-gui.sh:2741 lib/choose_rev.tcl:554 msgid "Commit@@noun" msgstr "Подаване" -#: git-gui.sh:2744 lib/merge.tcl:127 lib/merge.tcl:174 msgid "Merge" msgstr "Сливане" -#: git-gui.sh:2745 lib/choose_rev.tcl:563 msgid "Remote" msgstr "Отдалечено хранилище" -#: git-gui.sh:2748 msgid "Tools" msgstr "Команди" -#: git-gui.sh:2757 msgid "Explore Working Copy" msgstr "Разглеждане на работното копие" -#: git-gui.sh:2772 msgid "Git Bash" msgstr "Bash за Git" -#: git-gui.sh:2781 msgid "Browse Current Branch's Files" msgstr "Разглеждане на файловете в Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: git-gui.sh:2785 msgid "Browse Branch Files..." msgstr "Разглеждане на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½â€¦" -#: git-gui.sh:2790 msgid "Visualize Current Branch's History" msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° иÑториÑта на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: git-gui.sh:2794 msgid "Visualize All Branch History" msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° иÑториÑта на вÑички клонове" -#: git-gui.sh:2801 #, tcl-format msgid "Browse %s's Files" msgstr "Разглеждане на файловете в „%s“" -#: git-gui.sh:2803 #, tcl-format msgid "Visualize %s's History" msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° иÑториÑта на „%s“" -#: git-gui.sh:2808 lib/database.tcl:40 msgid "Database Statistics" msgstr "СтатиÑтика на базата от данни" -#: git-gui.sh:2811 lib/database.tcl:33 msgid "Compress Database" msgstr "КомпреÑиране на базата от данни" -#: git-gui.sh:2814 msgid "Verify Database" msgstr "Проверка на базата от данни" -#: git-gui.sh:2821 git-gui.sh:2825 git-gui.sh:2829 msgid "Create Desktop Icon" msgstr "ДобавÑне на икона на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚" -#: git-gui.sh:2837 lib/choose_repository.tcl:206 lib/choose_repository.tcl:214 msgid "Quit" msgstr "Спиране на програмата" -#: git-gui.sh:2845 msgid "Undo" msgstr "ОтмÑна" -#: git-gui.sh:2848 msgid "Redo" msgstr "Повторение" -#: git-gui.sh:2852 git-gui.sh:3477 msgid "Cut" msgstr "ОтрÑзване" -#: git-gui.sh:2855 git-gui.sh:3480 git-gui.sh:3556 git-gui.sh:3651 -#: lib/console.tcl:69 msgid "Copy" msgstr "Копиране" -#: git-gui.sh:2858 git-gui.sh:3483 msgid "Paste" msgstr "ПоÑтавÑне" -#: git-gui.sh:2861 git-gui.sh:3486 lib/branch_delete.tcl:28 -#: lib/remote_branch_delete.tcl:39 msgid "Delete" msgstr "Изтриване" -#: git-gui.sh:2865 git-gui.sh:3490 git-gui.sh:3655 lib/console.tcl:71 msgid "Select All" msgstr "Избиране на вÑичко" -#: git-gui.sh:2874 msgid "Create..." msgstr "Създаване…" -#: git-gui.sh:2880 msgid "Checkout..." msgstr "ИзтеглÑне…" -#: git-gui.sh:2886 msgid "Rename..." msgstr "Преименуване…" -#: git-gui.sh:2891 msgid "Delete..." msgstr "Изтриване…" -#: git-gui.sh:2896 msgid "Reset..." msgstr "ОтмÑна на промените…" -#: git-gui.sh:2906 msgid "Done" msgstr "Готово" -#: git-gui.sh:2908 msgid "Commit@@verb" msgstr "Подаване" -#: git-gui.sh:2917 git-gui.sh:3416 msgid "Amend Last Commit" msgstr "ПоправÑне на поÑледното подаване" -#: git-gui.sh:2927 git-gui.sh:3377 lib/remote_branch_delete.tcl:101 msgid "Rescan" msgstr "ОбновÑване" -#: git-gui.sh:2933 msgid "Stage To Commit" msgstr "Към индекÑа за подаване" -#: git-gui.sh:2939 msgid "Stage Changed Files To Commit" msgstr "Ð’Ñички променени файлове към индекÑа за подаване" -#: git-gui.sh:2945 msgid "Unstage From Commit" msgstr "Изваждане от индекÑа за подаване" -#: git-gui.sh:2951 lib/index.tcl:521 msgid "Revert Changes" msgstr "Връщане на оригинала" -#: git-gui.sh:2959 git-gui.sh:3718 git-gui.sh:3749 msgid "Show Less Context" msgstr "По-малко контекÑÑ‚" -#: git-gui.sh:2963 git-gui.sh:3722 git-gui.sh:3753 msgid "Show More Context" msgstr "Повече контекÑÑ‚" -#: git-gui.sh:2970 git-gui.sh:3390 git-gui.sh:3501 msgid "Sign Off" msgstr "ПодпиÑване" -#: git-gui.sh:2986 msgid "Local Merge..." msgstr "Локално Ñливане…" -#: git-gui.sh:2991 msgid "Abort Merge..." msgstr "ПреуÑтановÑване на Ñливане…" -#: git-gui.sh:3003 git-gui.sh:3031 msgid "Add..." msgstr "ДобавÑне…" -#: git-gui.sh:3007 msgid "Push..." msgstr "ИзтлаÑкване…" -#: git-gui.sh:3011 msgid "Delete Branch..." msgstr "Изтриване на клон…" -#: git-gui.sh:3021 git-gui.sh:3684 msgid "Options..." msgstr "Опции…" -#: git-gui.sh:3032 msgid "Remove..." msgstr "Премахване…" -#: git-gui.sh:3041 lib/choose_repository.tcl:67 msgid "Help" msgstr "Помощ" -#: git-gui.sh:3045 git-gui.sh:3049 lib/about.tcl:14 -#: lib/choose_repository.tcl:61 lib/choose_repository.tcl:70 #, tcl-format msgid "About %s" msgstr "ОтноÑно „%s“" -#: git-gui.sh:3069 msgid "Online Documentation" msgstr "Ð”Ð¾ÐºÑƒÐ¼ÐµÐ½Ñ‚Ð°Ñ†Ð¸Ñ Ð² Интернет" -#: git-gui.sh:3072 lib/choose_repository.tcl:64 lib/choose_repository.tcl:73 msgid "Show SSH Key" msgstr "Показване на ключа за SSH" -#: git-gui.sh:3102 git-gui.sh:3234 msgid "usage:" msgstr "употреба:" -#: git-gui.sh:3106 git-gui.sh:3238 msgid "Usage" msgstr "Употреба" -#: git-gui.sh:3187 lib/blame.tcl:576 msgid "Error" msgstr "Грешка" -#: git-gui.sh:3218 #, tcl-format msgid "fatal: cannot stat path %s: No such file or directory" msgstr "ФÐТÐЛÐРГРЕШКÐ: пътÑÑ‚ „%s“ липÑва: такъв файл или Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ð½Ñма" -#: git-gui.sh:3251 msgid "Current Branch:" msgstr "Текущ клон:" -#: git-gui.sh:3276 msgid "Unstaged Changes" msgstr "Промени извън индекÑа" -#: git-gui.sh:3298 msgid "Staged Changes (Will Commit)" msgstr "Промени в индекÑа (за подаване)" -#: git-gui.sh:3383 msgid "Stage Changed" msgstr "ИндекÑÑŠÑ‚ е променен" -#: git-gui.sh:3402 lib/transport.tcl:137 msgid "Push" msgstr "ИзтлаÑкване" -#: git-gui.sh:3429 msgid "Initial Commit Message:" msgstr "Първоначално Ñъобщение при подаване:" -#: git-gui.sh:3430 msgid "Amended Commit Message:" msgstr "Поправено Ñъобщение при подаване:" -#: git-gui.sh:3431 msgid "Amended Initial Commit Message:" msgstr "Поправено първоначално Ñъобщение при подаване:" -#: git-gui.sh:3432 msgid "Amended Merge Commit Message:" msgstr "Поправено Ñъобщение при подаване ÑÑŠÑ Ñливане:" -#: git-gui.sh:3433 msgid "Merge Commit Message:" msgstr "Съобщение при подаване ÑÑŠÑ Ñливане:" -#: git-gui.sh:3434 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: git-gui.sh:3493 git-gui.sh:3659 lib/console.tcl:73 msgid "Copy All" msgstr "Копиране на вÑичко" -#: git-gui.sh:3517 lib/blame.tcl:106 msgid "File:" msgstr "Файл:" -#: git-gui.sh:3565 lib/choose_repository.tcl:1054 msgid "Open" msgstr "ОтварÑне" -#: git-gui.sh:3647 msgid "Refresh" msgstr "ОбновÑване" -#: git-gui.sh:3668 msgid "Decrease Font Size" msgstr "По-дребен шрифт" -#: git-gui.sh:3672 msgid "Increase Font Size" msgstr "По-едър шрифт" -#: git-gui.sh:3680 lib/blame.tcl:296 msgid "Encoding" msgstr "Кодиране" -#: git-gui.sh:3691 msgid "Apply/Reverse Hunk" msgstr "Прилагане/връщане на парче" -#: git-gui.sh:3696 msgid "Apply/Reverse Line" msgstr "Прилагане/връщане на ред" -#: git-gui.sh:3702 git-gui.sh:3812 git-gui.sh:3823 msgid "Revert Hunk" msgstr "Връщане на парче" -#: git-gui.sh:3707 git-gui.sh:3819 git-gui.sh:3830 msgid "Revert Line" msgstr "Връщане на ред" -#: git-gui.sh:3712 git-gui.sh:3809 msgid "Undo Last Revert" msgstr "ОтмÑна на поÑледното връщане" -#: git-gui.sh:3731 msgid "Run Merge Tool" msgstr "Изпълнение на програмата за Ñливане" -#: git-gui.sh:3736 msgid "Use Remote Version" msgstr "ВерÑÐ¸Ñ Ð¾Ñ‚ отдалеченото хранилище" -#: git-gui.sh:3740 msgid "Use Local Version" msgstr "Локална верÑиÑ" -#: git-gui.sh:3744 msgid "Revert To Base" msgstr "Връщане към родителÑката верÑиÑ" -#: git-gui.sh:3762 msgid "Visualize These Changes In The Submodule" msgstr "Визуализиране на промените в подмодула" -#: git-gui.sh:3766 msgid "Visualize Current Branch History In The Submodule" msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° иÑториÑта на Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ ÐºÐ»Ð¾Ð½ в иÑториÑта за подмодула" -#: git-gui.sh:3770 msgid "Visualize All Branch History In The Submodule" msgstr "Ð’Ð¸Ð·ÑƒÐ°Ð»Ð¸Ð·Ð°Ñ†Ð¸Ñ Ð½Ð° иÑториÑта на вÑички клони в иÑториÑта за подмодула" -#: git-gui.sh:3775 msgid "Start git gui In The Submodule" msgstr "Стартиране на „git gui“ за подмодула" -#: git-gui.sh:3811 msgid "Unstage Hunk From Commit" msgstr "Изваждане на парчето от подаването" -#: git-gui.sh:3815 msgid "Unstage Lines From Commit" msgstr "Изваждане на редовете от подаването" -#: git-gui.sh:3816 git-gui.sh:3827 msgid "Revert Lines" msgstr "Връщане на редовете" -#: git-gui.sh:3818 msgid "Unstage Line From Commit" msgstr "Изваждане на реда от подаването" -#: git-gui.sh:3822 msgid "Stage Hunk For Commit" msgstr "ДобавÑне на парчето за подаване" -#: git-gui.sh:3826 msgid "Stage Lines For Commit" msgstr "ДобавÑне на редовете за подаване" -#: git-gui.sh:3829 msgid "Stage Line For Commit" msgstr "ДобавÑне на реда за подаване" -#: git-gui.sh:3879 msgid "Initializing..." msgstr "Инициализиране…" -#: lib/about.tcl:26 msgid "git-gui - a graphical user interface for Git." msgstr "git-gui — графичен Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð·Ð° Git." -#: lib/blame.tcl:74 #, tcl-format msgid "%s (%s): File Viewer" msgstr "%s (%s): Преглед на файлове" -#: lib/blame.tcl:80 msgid "Commit:" msgstr "Подаване:" -#: lib/blame.tcl:282 msgid "Copy Commit" msgstr "Копиране на подаване" -#: lib/blame.tcl:286 msgid "Find Text..." msgstr "ТърÑене на текÑт…" -#: lib/blame.tcl:290 msgid "Goto Line..." msgstr "Към ред…" -#: lib/blame.tcl:299 msgid "Do Full Copy Detection" msgstr "Пълно търÑене на копиране" -#: lib/blame.tcl:303 msgid "Show History Context" msgstr "Показване на контекÑта от иÑториÑта" -#: lib/blame.tcl:306 msgid "Blame Parent Commit" msgstr "Ðнотиране на родителÑкото подаване" -#: lib/blame.tcl:469 #, tcl-format msgid "Reading %s..." msgstr "Чете Ñе „%s“…" -#: lib/blame.tcl:597 msgid "Loading copy/move tracking annotations..." msgstr "Зареждане на анотациите за проÑледÑване на копирането/премеÑтването…" -#: lib/blame.tcl:614 msgid "lines annotated" msgstr "реда анотирани" -#: lib/blame.tcl:816 msgid "Loading original location annotations..." msgstr "Зареждане на анотациите за първоначалното меÑтоположение…" -#: lib/blame.tcl:819 msgid "Annotation complete." msgstr "Ðнотирането завърши." -#: lib/blame.tcl:850 msgid "Busy" msgstr "ОперациÑта не е завършила" -#: lib/blame.tcl:851 msgid "Annotation process is already running." msgstr "Ð’ момента тече Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° анотиране." -#: lib/blame.tcl:890 msgid "Running thorough copy detection..." msgstr "ИзпълнÑва Ñе цÑлоÑтен Ð¿Ñ€Ð¾Ñ†ÐµÑ Ð½Ð° откриване на копиране…" -#: lib/blame.tcl:958 msgid "Loading annotation..." msgstr "Зареждане на анотации…" -#: lib/blame.tcl:1011 msgid "Author:" msgstr "Ðвтор:" -#: lib/blame.tcl:1015 msgid "Committer:" msgstr "Подал:" -#: lib/blame.tcl:1020 msgid "Original File:" msgstr "Първоначален файл:" -#: lib/blame.tcl:1068 msgid "Cannot find HEAD commit:" msgstr "Подаването за връх „HEAD“ не може да Ñе открие:" -#: lib/blame.tcl:1123 msgid "Cannot find parent commit:" msgstr "РодителÑкото подаване не може да Ñе открие" -#: lib/blame.tcl:1138 msgid "Unable to display parent" msgstr "РодителÑÑ‚ не може да Ñе покаже" -#: lib/blame.tcl:1139 lib/diff.tcl:334 msgid "Error loading diff:" msgstr "Грешка при зареждане на разлика:" -#: lib/blame.tcl:1280 msgid "Originally By:" msgstr "Първоначално от:" -#: lib/blame.tcl:1286 msgid "In File:" msgstr "Във файл:" -#: lib/blame.tcl:1291 msgid "Copied Or Moved Here By:" msgstr "Копирано или премеÑтено тук от:" -#: lib/branch_checkout.tcl:16 #, tcl-format msgid "%s (%s): Checkout Branch" msgstr "%s (%s): Клон за изтеглÑне" -#: lib/branch_checkout.tcl:21 msgid "Checkout Branch" msgstr "Клон за изтеглÑне" -#: lib/branch_checkout.tcl:26 msgid "Checkout" msgstr "ИзтеглÑне" -#: lib/branch_checkout.tcl:30 lib/branch_create.tcl:37 lib/branch_delete.tcl:34 -#: lib/branch_rename.tcl:32 lib/browser.tcl:292 lib/checkout_op.tcl:580 -#: lib/choose_font.tcl:45 lib/merge.tcl:178 lib/option.tcl:127 -#: lib/remote_add.tcl:34 lib/remote_branch_delete.tcl:43 lib/tools_dlg.tcl:41 -#: lib/tools_dlg.tcl:202 lib/tools_dlg.tcl:345 lib/transport.tcl:141 msgid "Cancel" msgstr "Отказване" -#: lib/branch_checkout.tcl:35 lib/browser.tcl:297 lib/tools_dlg.tcl:321 msgid "Revision" msgstr "ВерÑиÑ" -#: lib/branch_checkout.tcl:39 lib/branch_create.tcl:69 lib/option.tcl:310 msgid "Options" msgstr "Опции" -#: lib/branch_checkout.tcl:42 lib/branch_create.tcl:92 msgid "Fetch Tracking Branch" msgstr "ИзтеглÑне на промените от ÑÐ»ÐµÐ´ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/branch_checkout.tcl:47 msgid "Detach From Local Branch" msgstr "Изтриване от Ð»Ð¾ÐºÐ°Ð»Ð½Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/branch_create.tcl:23 #, tcl-format msgid "%s (%s): Create Branch" msgstr "%s (%s): Създаване на клон" -#: lib/branch_create.tcl:28 msgid "Create New Branch" msgstr "Създаване на нов клон" -#: lib/branch_create.tcl:33 lib/choose_repository.tcl:386 msgid "Create" msgstr "Създаване" -#: lib/branch_create.tcl:42 msgid "Branch Name" msgstr "Име на клона" -#: lib/branch_create.tcl:44 lib/remote_add.tcl:41 lib/tools_dlg.tcl:51 msgid "Name:" msgstr "Име:" -#: lib/branch_create.tcl:57 msgid "Match Tracking Branch Name" msgstr "Съвпадане по името на ÑÐ»ÐµÐ´ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/branch_create.tcl:66 msgid "Starting Revision" msgstr "Ðачална верÑиÑ" -#: lib/branch_create.tcl:72 msgid "Update Existing Branch:" msgstr "ОбновÑване на ÑъщеÑтвуващ клон:" -#: lib/branch_create.tcl:75 msgid "No" msgstr "Ðе" -#: lib/branch_create.tcl:80 msgid "Fast Forward Only" msgstr "Само тривиално превъртащо Ñливане" -#: lib/branch_create.tcl:85 lib/checkout_op.tcl:572 msgid "Reset" msgstr "Отначало" -#: lib/branch_create.tcl:97 msgid "Checkout After Creation" msgstr "Преминаване към клона Ñлед Ñъздаването му" -#: lib/branch_create.tcl:132 msgid "Please select a tracking branch." msgstr "Изберете клон за Ñледени." -#: lib/branch_create.tcl:141 #, tcl-format msgid "Tracking branch %s is not a branch in the remote repository." msgstr "СледÑщиÑÑ‚ клон — „%s“, не ÑъщеÑтвува в отдалеченото хранилище." -#: lib/branch_create.tcl:154 lib/branch_rename.tcl:92 msgid "Please supply a branch name." msgstr "Дайте име на клона." -#: lib/branch_create.tcl:165 lib/branch_rename.tcl:112 #, tcl-format msgid "'%s' is not an acceptable branch name." msgstr "„%s“ не може да Ñе използва за име на клон." -#: lib/branch_delete.tcl:16 #, tcl-format msgid "%s (%s): Delete Branch" msgstr "%s (%s): Изтриване на клон" -#: lib/branch_delete.tcl:21 msgid "Delete Local Branch" msgstr "Изтриване на локален клон" -#: lib/branch_delete.tcl:39 msgid "Local Branches" msgstr "Локални клони" -#: lib/branch_delete.tcl:51 msgid "Delete Only If Merged Into" msgstr "Изтриване, Ñамо ако промените Ñа Ñлети и другаде" -#: lib/branch_delete.tcl:53 lib/remote_branch_delete.tcl:120 msgid "Always (Do not perform merge checks)" msgstr "Винаги (без проверка за Ñливане)" -#: lib/branch_delete.tcl:103 #, tcl-format msgid "The following branches are not completely merged into %s:" msgstr "Ðе вÑички промени в клоните Ñа Ñлети в „%s“:" -#: lib/branch_delete.tcl:115 lib/remote_branch_delete.tcl:218 msgid "" "Recovering deleted branches is difficult.\n" "\n" @@ -832,12 +620,10 @@ msgstr "" "\n" "Сигурни ли Ñте, че иÑкате да триете?" -#: lib/branch_delete.tcl:131 #, tcl-format msgid " - %s:" msgstr " — „%s:“" -#: lib/branch_delete.tcl:141 #, tcl-format msgid "" "Failed to delete branches:\n" @@ -846,100 +632,76 @@ msgstr "" "ÐеуÑпешно триене на клони:\n" "%s" -#: lib/branch_rename.tcl:15 #, tcl-format msgid "%s (%s): Rename Branch" msgstr "%s (%s): Преименуване на клон" -#: lib/branch_rename.tcl:23 msgid "Rename Branch" msgstr "Преименуване на клон" -#: lib/branch_rename.tcl:28 msgid "Rename" msgstr "Преименуване" -#: lib/branch_rename.tcl:38 msgid "Branch:" msgstr "Клон:" -#: lib/branch_rename.tcl:46 msgid "New Name:" msgstr "Ðово име:" -#: lib/branch_rename.tcl:81 msgid "Please select a branch to rename." msgstr "Изберете клон за преименуване." -#: lib/branch_rename.tcl:102 lib/checkout_op.tcl:202 #, tcl-format msgid "Branch '%s' already exists." msgstr "Клонът „%s“ вече ÑъщеÑтвува." -#: lib/branch_rename.tcl:123 #, tcl-format msgid "Failed to rename '%s'." msgstr "ÐеуÑпешно преименуване на „%s“." -#: lib/browser.tcl:17 msgid "Starting..." msgstr "Стартиране…" -#: lib/browser.tcl:27 #, tcl-format msgid "%s (%s): File Browser" msgstr "%s (%s): Файлов браузър" -#: lib/browser.tcl:132 lib/browser.tcl:149 #, tcl-format msgid "Loading %s..." msgstr "Зареждане на „%s“…" -#: lib/browser.tcl:193 msgid "[Up To Parent]" msgstr "[Към родителÑ]" -#: lib/browser.tcl:275 #, tcl-format msgid "%s (%s): Browse Branch Files" msgstr "%s (%s): Разглеждане на файловете в клона" -#: lib/browser.tcl:282 msgid "Browse Branch Files" msgstr "Разглеждане на файловете в клона" -#: lib/browser.tcl:288 lib/choose_repository.tcl:401 -#: lib/choose_repository.tcl:488 lib/choose_repository.tcl:497 -#: lib/choose_repository.tcl:1069 msgid "Browse" msgstr "Разглеждане" -#: lib/checkout_op.tcl:85 #, tcl-format msgid "Fetching %s from %s" msgstr "ДоÑтавÑне на „%s“ от „%s“" -#: lib/checkout_op.tcl:133 #, tcl-format msgid "fatal: Cannot resolve %s" msgstr "фатална грешка: „%s“ не може да Ñе открие" -#: lib/checkout_op.tcl:146 lib/console.tcl:81 lib/database.tcl:30 -#: lib/sshkey.tcl:58 msgid "Close" msgstr "ЗатварÑне" -#: lib/checkout_op.tcl:175 #, tcl-format msgid "Branch '%s' does not exist." msgstr "Клонът „%s“ не ÑъщеÑтвува." -#: lib/checkout_op.tcl:194 #, tcl-format msgid "Failed to configure simplified git-pull for '%s'." msgstr "ÐеуÑпешно наÑтройване на опроÑтен git-pull за „%s“." -#: lib/checkout_op.tcl:229 #, tcl-format msgid "" "Branch '%s' already exists.\n" @@ -952,21 +714,17 @@ msgstr "" "Той не може да Ñе Ñлее тривиално до „%s“.\n" "Ðеобходимо е Ñливане." -#: lib/checkout_op.tcl:243 #, tcl-format msgid "Merge strategy '%s' not supported." msgstr "Ð¡Ñ‚Ñ€Ð°Ñ‚ÐµÐ³Ð¸Ñ Ð·Ð° Ñливане „%s“ не Ñе поддържа." -#: lib/checkout_op.tcl:262 #, tcl-format msgid "Failed to update '%s'." msgstr "ÐеуÑпешно обновÑване на „%s“." -#: lib/checkout_op.tcl:274 msgid "Staging area (index) is already locked." msgstr "ИндекÑÑŠÑ‚ вече е заключен." -#: lib/checkout_op.tcl:289 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -983,31 +741,25 @@ msgstr "" "\n" "Ðвтоматично ще започне нова проверка.\n" -#: lib/checkout_op.tcl:345 #, tcl-format msgid "Updating working directory to '%s'..." msgstr "Работната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ Ñе привежда към „%s“…" -#: lib/checkout_op.tcl:346 msgid "files checked out" msgstr "файла Ñа изтеглени" -#: lib/checkout_op.tcl:377 #, tcl-format msgid "Aborted checkout of '%s' (file level merging is required)." msgstr "" "ПреуÑтановÑване на изтеглÑнето на „%s“ (необходимо е пофайлово Ñливане)." -#: lib/checkout_op.tcl:378 msgid "File level merge required." msgstr "Ðеобходимо е пофайлово Ñливане." -#: lib/checkout_op.tcl:382 #, tcl-format msgid "Staying on branch '%s'." msgstr "ОÑтаване върху клона „%s“." -#: lib/checkout_op.tcl:453 msgid "" "You are no longer on a local branch.\n" "\n" @@ -1018,31 +770,25 @@ msgstr "" "\n" "Ðко иÑкате да Ñте на клон, Ñъздайте базиран на „Това неÑвързано изтеглÑне“." -#: lib/checkout_op.tcl:504 lib/checkout_op.tcl:508 #, tcl-format msgid "Checked out '%s'." msgstr "„%s“ е изтеглен." -#: lib/checkout_op.tcl:536 #, tcl-format msgid "Resetting '%s' to '%s' will lose the following commits:" msgstr "" "ЗанулÑването на „%s“ към „%s“ ще доведе до загубването на Ñледните подаваниÑ:" -#: lib/checkout_op.tcl:558 msgid "Recovering lost commits may not be easy." msgstr "ВъзÑтановÑването на загубените Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð¼Ð¾Ð¶Ðµ да е трудно." -#: lib/checkout_op.tcl:563 #, tcl-format msgid "Reset '%s'?" msgstr "ЗанулÑване на „%s“?" -#: lib/checkout_op.tcl:568 lib/merge.tcl:170 lib/tools_dlg.tcl:336 msgid "Visualize" msgstr "ВизуализациÑ" -#: lib/checkout_op.tcl:636 #, tcl-format msgid "" "Failed to set current branch.\n" @@ -1060,23 +806,18 @@ msgstr "" "Това ÑÑŠÑтоÑние е аварийно и не трÑбва да Ñе Ñлучва. Програмата „%s“ ще " "преуÑтанови работа." -#: lib/choose_font.tcl:41 msgid "Select" msgstr "Избор" -#: lib/choose_font.tcl:55 msgid "Font Family" msgstr "Шрифт" -#: lib/choose_font.tcl:76 msgid "Font Size" msgstr "Размер" -#: lib/choose_font.tcl:93 msgid "Font Example" msgstr "МоÑтра" -#: lib/choose_font.tcl:105 msgid "" "This is example text.\n" "If you like this text, it can be your font." @@ -1084,289 +825,137 @@ msgstr "" "Това е примерен текÑÑ‚.\n" "Ðко ви хареÑва как изглежда, изберете шрифта." -#: lib/choose_repository.tcl:45 msgid "Git Gui" msgstr "ГПИ на Git" -#: lib/choose_repository.tcl:104 lib/choose_repository.tcl:391 msgid "Create New Repository" msgstr "Създаване на ново хранилище" -#: lib/choose_repository.tcl:110 msgid "New..." msgstr "Ðово…" -#: lib/choose_repository.tcl:117 lib/choose_repository.tcl:475 msgid "Clone Existing Repository" msgstr "Клониране на ÑъщеÑтвуващо хранилище" -#: lib/choose_repository.tcl:128 msgid "Clone..." msgstr "Клониране…" -#: lib/choose_repository.tcl:135 lib/choose_repository.tcl:1059 msgid "Open Existing Repository" msgstr "ОтварÑне на ÑъщеÑтвуващо хранилище" -#: lib/choose_repository.tcl:141 msgid "Open..." msgstr "ОтварÑне…" -#: lib/choose_repository.tcl:154 msgid "Recent Repositories" msgstr "Скоро ползвани" -#: lib/choose_repository.tcl:164 msgid "Open Recent Repository:" msgstr "ОтварÑне на хранилище ползвано наÑкоро:" -#: lib/choose_repository.tcl:328 lib/choose_repository.tcl:335 -#: lib/choose_repository.tcl:342 #, tcl-format msgid "Failed to create repository %s:" msgstr "ÐеуÑпешно Ñъздаване на хранилището „%s“:" -#: lib/choose_repository.tcl:396 msgid "Directory:" msgstr "ДиректориÑ:" -#: lib/choose_repository.tcl:426 lib/choose_repository.tcl:552 -#: lib/choose_repository.tcl:1093 msgid "Git Repository" msgstr "Хранилище на Git" -#: lib/choose_repository.tcl:451 #, tcl-format msgid "Directory %s already exists." msgstr "Вече ÑъщеÑтвува Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ â€ž%s“." -#: lib/choose_repository.tcl:455 #, tcl-format msgid "File %s already exists." msgstr "Вече ÑъщеÑтвува файл „%s“." -#: lib/choose_repository.tcl:470 msgid "Clone" msgstr "Клониране" -#: lib/choose_repository.tcl:483 msgid "Source Location:" msgstr "ÐÐ´Ñ€ÐµÑ Ð½Ð° източника:" -#: lib/choose_repository.tcl:492 msgid "Target Directory:" msgstr "Целева директориÑ:" -#: lib/choose_repository.tcl:502 msgid "Clone Type:" msgstr "Вид клониране:" -#: lib/choose_repository.tcl:507 msgid "Standard (Fast, Semi-Redundant, Hardlinks)" msgstr "Стандартно (бързо, чаÑтично ÑподелÑне на файлове, твърди връзки)" -#: lib/choose_repository.tcl:512 msgid "Full Copy (Slower, Redundant Backup)" msgstr "Пълно (бавно, пълноценно резервно копие)" -#: lib/choose_repository.tcl:517 msgid "Shared (Fastest, Not Recommended, No Backup)" msgstr "Споделено (най-бързо, не Ñе препоръчва, не прави резервно копие)" -#: lib/choose_repository.tcl:524 msgid "Recursively clone submodules too" msgstr "РекурÑивно клониране и на подмодулите" -#: lib/choose_repository.tcl:558 lib/choose_repository.tcl:605 -#: lib/choose_repository.tcl:744 lib/choose_repository.tcl:818 -#: lib/choose_repository.tcl:1099 lib/choose_repository.tcl:1107 #, tcl-format msgid "Not a Git repository: %s" msgstr "Това не е хранилище на Git: %s" -#: lib/choose_repository.tcl:594 +msgid "Hardlinks are unavailable. Falling back to copying." +msgstr "Ðе Ñе поддържат твърди връзки. Преминава Ñе към копиране." + msgid "Standard only available for local repository." msgstr "Само локални хранилища може да Ñе клонират Ñтандартно" -#: lib/choose_repository.tcl:598 msgid "Shared only available for local repository." msgstr "Само локални хранилища може да Ñе клонират Ñподелено" -#: lib/choose_repository.tcl:613 #, tcl-format msgid "Location %s already exists." msgstr "МеÑтоположението „%s“ вече ÑъщеÑтвува." -#: lib/choose_repository.tcl:624 -msgid "Failed to configure origin" -msgstr "ÐеуÑпешно наÑтройване на хранилището-източник" - -#: lib/choose_repository.tcl:636 -msgid "Counting objects" -msgstr "ПреброÑване на обекти" - -#: lib/choose_repository.tcl:637 -msgid "buckets" -msgstr "клетки" - -#: lib/choose_repository.tcl:657 -#, tcl-format -msgid "Unable to copy objects/info/alternates: %s" -msgstr "Обектите/ИнформациÑта/Синонимите не може да Ñе копират: %s" - -#: lib/choose_repository.tcl:694 -#, tcl-format -msgid "Nothing to clone from %s." -msgstr "ÐÑма какво да Ñе клонира от „%s“." - -#: lib/choose_repository.tcl:696 lib/choose_repository.tcl:916 -#: lib/choose_repository.tcl:928 -msgid "The 'master' branch has not been initialized." -msgstr "ОÑновниÑÑ‚ клон — „master“ не е инициализиран." - -#: lib/choose_repository.tcl:709 -msgid "Hardlinks are unavailable. Falling back to copying." -msgstr "Ðе Ñе поддържат твърди връзки. Преминава Ñе към копиране." - -#: lib/choose_repository.tcl:723 #, tcl-format msgid "Cloning from %s" msgstr "Клониране на „%s“" -#: lib/choose_repository.tcl:754 -msgid "Copying objects" -msgstr "Копиране на обекти" - -#: lib/choose_repository.tcl:755 -msgid "KiB" -msgstr "KiB" - -#: lib/choose_repository.tcl:779 -#, tcl-format -msgid "Unable to copy object: %s" -msgstr "ÐеуÑпешно копиране на обект: %s" - -#: lib/choose_repository.tcl:791 -msgid "Linking objects" -msgstr "Създаване на връзки към обектите" - -#: lib/choose_repository.tcl:792 -msgid "objects" -msgstr "обекти" - -#: lib/choose_repository.tcl:800 -#, tcl-format -msgid "Unable to hardlink object: %s" -msgstr "ÐеуÑпешно Ñъздаване на твърда връзка към обект: %s" - -#: lib/choose_repository.tcl:857 -msgid "Cannot fetch branches and objects. See console output for details." -msgstr "" -"Клоните и обектите не може да Ñе изтеглÑÑ‚. За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð³Ð»ÐµÐ´Ð½ÐµÑ‚Ðµ " -"изхода на конзолата." - -#: lib/choose_repository.tcl:868 -msgid "Cannot fetch tags. See console output for details." -msgstr "" -"Етикетите не може да Ñе изтеглÑÑ‚. За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð³Ð»ÐµÐ´Ð½ÐµÑ‚Ðµ изхода на " -"конзолата." - -#: lib/choose_repository.tcl:892 -msgid "Cannot determine HEAD. See console output for details." -msgstr "" -"Върхът „HEAD“ не може да Ñе определи. За повече Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð¿Ð¾Ð³Ð»ÐµÐ´Ð½ÐµÑ‚Ðµ изхода " -"на конзолата." - -#: lib/choose_repository.tcl:901 -#, tcl-format -msgid "Unable to cleanup %s" -msgstr "„%s“ не може да Ñе изчиÑти" - -#: lib/choose_repository.tcl:907 msgid "Clone failed." msgstr "ÐеуÑпешно клониране." -#: lib/choose_repository.tcl:914 -msgid "No default branch obtained." -msgstr "Ðе е получен клон по подразбиране." - -#: lib/choose_repository.tcl:925 -#, tcl-format -msgid "Cannot resolve %s as a commit." -msgstr "ÐÑма подаване отговарÑщо на „%s“." - -#: lib/choose_repository.tcl:952 -msgid "Creating working directory" -msgstr "Създаване на работната директориÑ" - -#: lib/choose_repository.tcl:953 lib/index.tcl:77 lib/index.tcl:146 -#: lib/index.tcl:220 lib/index.tcl:589 -msgid "files" -msgstr "файлове" - -#: lib/choose_repository.tcl:982 -msgid "Initial file checkout failed." -msgstr "ÐеуÑпешно първоначално изтеглÑне." - -#: lib/choose_repository.tcl:1026 -msgid "Cloning submodules" -msgstr "Клониране на подмодули" - -#: lib/choose_repository.tcl:1041 -msgid "Cannot clone submodules." -msgstr "Подмодулите не може да Ñе клонират." - -#: lib/choose_repository.tcl:1064 msgid "Repository:" msgstr "Хранилище:" -#: lib/choose_repository.tcl:1113 #, tcl-format msgid "Failed to open repository %s:" msgstr "ÐеуÑпешно отварÑне на хранилището „%s“:" -#: lib/choose_rev.tcl:52 msgid "This Detached Checkout" msgstr "Това неÑвързано изтеглÑне" -#: lib/choose_rev.tcl:60 msgid "Revision Expression:" msgstr "Израз за верÑиÑ:" -#: lib/choose_rev.tcl:72 msgid "Local Branch" msgstr "Локален клон" -#: lib/choose_rev.tcl:77 msgid "Tracking Branch" msgstr "СледÑщ клон" -#: lib/choose_rev.tcl:82 lib/choose_rev.tcl:544 msgid "Tag" msgstr "Етикет" -#: lib/choose_rev.tcl:321 #, tcl-format msgid "Invalid revision: %s" msgstr "Ðеправилна верÑиÑ: %s" -#: lib/choose_rev.tcl:342 msgid "No revision selected." msgstr "Ðе е избрана верÑиÑ." -#: lib/choose_rev.tcl:350 msgid "Revision expression is empty." msgstr "Изразът за верÑÐ¸Ñ Ðµ празен." -#: lib/choose_rev.tcl:537 msgid "Updated" msgstr "Обновен" -#: lib/choose_rev.tcl:565 msgid "URL" msgstr "ÐдреÑ" -#: lib/commit.tcl:9 msgid "" "There is nothing to amend.\n" "\n" @@ -1378,7 +967,6 @@ msgstr "" "Ще Ñъздадете първоначалното подаване. Преди него нÑма други подаваниÑ, които " "да поправите.\n" -#: lib/commit.tcl:18 msgid "" "Cannot amend while merging.\n" "\n" @@ -1391,24 +979,19 @@ msgstr "" "Ð’ момента вÑе още не Ñте завършили Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¿Ð¾ Ñливане. Ðе може да поправите " "предишното подаване, оÑвен ако първо не преуÑтановите текущото Ñливане.\n" -#: lib/commit.tcl:56 msgid "Error loading commit data for amend:" msgstr "Грешка при зареждане на данните от подаване, които да Ñе поправÑÑ‚:" -#: lib/commit.tcl:83 msgid "Unable to obtain your identity:" msgstr "ИдентификациÑта ви не може да Ñе определи:" -#: lib/commit.tcl:88 msgid "Invalid GIT_COMMITTER_IDENT:" msgstr "Ðеправилно поле „GIT_COMMITTER_IDENT“:" -#: lib/commit.tcl:138 #, tcl-format msgid "warning: Tcl does not support encoding '%s'." msgstr "предупреждение: Tcl не поддържа кодирането „%s“." -#: lib/commit.tcl:158 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1425,7 +1008,6 @@ msgstr "" "\n" "Ðвтоматично ще започне нова проверка.\n" -#: lib/commit.tcl:182 #, tcl-format msgid "" "Unmerged files cannot be committed.\n" @@ -1438,7 +1020,6 @@ msgstr "" "Във файла „%s“ има конфликти при Ñливане. За да го подадете, трÑбва първо да " "коригирате конфликтите и да добавите файла към индекÑа за подаване.\n" -#: lib/commit.tcl:190 #, tcl-format msgid "" "Unknown file state %s detected.\n" @@ -1449,7 +1030,6 @@ msgstr "" "\n" "Файлът „%s“ не може да Ñе подаде чрез текущата програма.\n" -#: lib/commit.tcl:198 msgid "" "No changes to commit.\n" "\n" @@ -1459,7 +1039,6 @@ msgstr "" "\n" "ТрÑбва да добавите поне един файл към индекÑа, за да подадете.\n" -#: lib/commit.tcl:224 msgid "" "Please supply a commit message.\n" "\n" @@ -1477,15 +1056,12 @@ msgstr "" "◠Втори ред: празен.\n" "◠ОÑтаналите редове: опишете защо Ñе налага тази промÑна.\n" -#: lib/commit.tcl:255 msgid "Calling pre-commit hook..." msgstr "ИзпълнÑване на куката преди подаване…" -#: lib/commit.tcl:270 msgid "Commit declined by pre-commit hook." msgstr "Подаването е отхвърлено от куката преди подаване." -#: lib/commit.tcl:289 msgid "" "You are about to commit on a detached head. This is a potentially dangerous " "thing to do because if you switch to another branch you will lose your " @@ -1501,32 +1077,25 @@ msgstr "" " \n" "Сигурни ли Ñте, че иÑкате да извършите текущото подаване?" -#: lib/commit.tcl:310 msgid "Calling commit-msg hook..." msgstr "ИзпълнÑване на куката за Ñъобщението при подаване…" -#: lib/commit.tcl:325 msgid "Commit declined by commit-msg hook." msgstr "Подаването е отхвърлено от куката за Ñъобщението при подаване." -#: lib/commit.tcl:338 msgid "Committing changes..." msgstr "Подаване на промените…" -#: lib/commit.tcl:355 msgid "write-tree failed:" msgstr "неуÑпешно запазване на дървото (write-tree):" -#: lib/commit.tcl:356 lib/commit.tcl:406 lib/commit.tcl:433 msgid "Commit failed." msgstr "ÐеуÑпешно подаване." -#: lib/commit.tcl:373 #, tcl-format msgid "Commit %s appears to be corrupt" msgstr "Подаването „%s“ изглежда повредено" -#: lib/commit.tcl:378 msgid "" "No changes to commit.\n" "\n" @@ -1541,83 +1110,63 @@ msgstr "" "\n" "Ðвтоматично ще започне нова проверка.\n" -#: lib/commit.tcl:385 msgid "No changes to commit." msgstr "ÐÑма промени за подаване." -#: lib/commit.tcl:405 msgid "commit-tree failed:" msgstr "неуÑпешно подаване на дървото (commit-tree):" -#: lib/commit.tcl:432 msgid "update-ref failed:" msgstr "неуÑпешно обновÑване на указателите (update-ref):" -#: lib/commit.tcl:526 #, tcl-format msgid "Created commit %s: %s" msgstr "УÑпешно подаване %s: %s" -#: lib/console.tcl:59 msgid "Working... please wait..." msgstr "Ð’ момента Ñе извършва дейÑтвие, изчакайте…" -#: lib/console.tcl:186 msgid "Success" msgstr "УÑпех" -#: lib/console.tcl:200 msgid "Error: Command Failed" msgstr "Грешка: неуÑпешно изпълнение на команда" -#: lib/database.tcl:42 msgid "Number of loose objects" msgstr "Брой непакетирани обекти" -#: lib/database.tcl:43 msgid "Disk space used by loose objects" msgstr "ДиÑково проÑтранÑтво заето от непакетирани обекти" -#: lib/database.tcl:44 msgid "Number of packed objects" msgstr "Брой пакетирани обекти" -#: lib/database.tcl:45 msgid "Number of packs" msgstr "Брой пакети" -#: lib/database.tcl:46 msgid "Disk space used by packed objects" msgstr "ДиÑково проÑтранÑтво заето от пакетирани обекти" -#: lib/database.tcl:47 msgid "Packed objects waiting for pruning" msgstr "Пакетирани обекти за окаÑтрÑне" -#: lib/database.tcl:48 msgid "Garbage files" msgstr "Файлове за боклука" -#: lib/database.tcl:57 lib/option.tcl:182 lib/option.tcl:197 lib/option.tcl:220 -#: lib/option.tcl:282 #, tcl-format msgid "%s:" msgstr "%s:" -#: lib/database.tcl:66 #, tcl-format msgid "%s (%s): Database Statistics" msgstr "%s (%s): СтатиÑтика на базата от данни" -#: lib/database.tcl:72 msgid "Compressing the object database" msgstr "КомпреÑиране на базата Ñ Ð´Ð°Ð½Ð½Ð¸ за обектите" -#: lib/database.tcl:83 msgid "Verifying the object database with fsck-objects" msgstr "Проверка на базата Ñ Ð´Ð°Ð½Ð½Ð¸ за обектите Ñ Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð°Ñ‚Ð° „fsck-objects“" -#: lib/database.tcl:107 #, tcl-format msgid "" "This repository currently has approximately %i loose objects.\n" @@ -1634,12 +1183,10 @@ msgstr "" "\n" "Да Ñе започне ли компреÑирането?" -#: lib/date.tcl:25 #, tcl-format msgid "Invalid date from Git: %s" msgstr "Ðеправилни данни от Git: %s" -#: lib/diff.tcl:74 msgid "" "* No differences detected; stage the file to de-list it from Unstaged " "Changes.\n" @@ -1647,16 +1194,13 @@ msgstr "" "â— ÐÑма разлики. Добавете файла към индекÑа, за да Ñе извади от промените " "извън индекÑа.\n" -#: lib/diff.tcl:75 msgid "* Click to find other files that may have the same state.\n" msgstr "â— ÐатиÑнете, за да потърÑите други файлове в това ÑÑŠÑтоÑние.\n" -#: lib/diff.tcl:106 #, tcl-format msgid "Loading diff of %s..." msgstr "Зареждане на разликите в „%s“…" -#: lib/diff.tcl:132 msgid "" "LOCAL: deleted\n" "REMOTE:\n" @@ -1664,7 +1208,6 @@ msgstr "" "ЛОКÐЛÐО: изтрит\n" "ОТДÐЛЕЧЕÐО:\n" -#: lib/diff.tcl:137 msgid "" "REMOTE: deleted\n" "LOCAL:\n" @@ -1672,32 +1215,25 @@ msgstr "" "ОТДÐЛЕЧЕÐО: изтрит\n" "ЛОКÐЛÐО:\n" -#: lib/diff.tcl:144 msgid "LOCAL:\n" msgstr "ЛОКÐЛÐО:\n" -#: lib/diff.tcl:147 msgid "REMOTE:\n" msgstr "ОТДÐЛЕЧЕÐО:\n" -#: lib/diff.tcl:209 lib/diff.tcl:333 #, tcl-format msgid "Unable to display %s" msgstr "Файлът „%s“ не може да Ñе покаже" -#: lib/diff.tcl:210 msgid "Error loading file:" msgstr "Грешка при зареждане на файл:" -#: lib/diff.tcl:216 msgid "Git Repository (subproject)" msgstr "Хранилище на Git (подмодул)" -#: lib/diff.tcl:228 msgid "* Binary file (not showing content)." msgstr "◠Двоичен файл (Ñъдържанието не Ñе показва)." -#: lib/diff.tcl:233 #, tcl-format msgid "" "* Untracked file is %d bytes.\n" @@ -1706,7 +1242,6 @@ msgstr "" "â— ÐеÑледениÑÑ‚ файл е %d байта.\n" "◠Показват Ñе Ñамо първите %d байта.\n" -#: lib/diff.tcl:239 #, tcl-format msgid "" "\n" @@ -1717,80 +1252,62 @@ msgstr "" "â— ÐеÑледениÑÑ‚ файл е отрÑзан дотук от програмата „%s“.\n" "◠Използвайте външен редактор, за да видите Ñ†ÐµÐ»Ð¸Ñ Ñ„Ð°Ð¹Ð».\n" -#: lib/diff.tcl:569 msgid "Failed to unstage selected hunk." msgstr "Избраното парче не може да Ñе извади от индекÑа." -#: lib/diff.tcl:577 msgid "Failed to revert selected hunk." msgstr "Избраното парче не може да Ñе върне." -#: lib/diff.tcl:580 msgid "Failed to stage selected hunk." msgstr "Избраното парче не може да Ñе добави към индекÑа." -#: lib/diff.tcl:673 msgid "Failed to unstage selected line." msgstr "ИзбраниÑÑ‚ ред не може да Ñе извади от индекÑа." -#: lib/diff.tcl:682 msgid "Failed to revert selected line." msgstr "ИзбраниÑÑ‚ ред не може да Ñе върне." -#: lib/diff.tcl:686 msgid "Failed to stage selected line." msgstr "ИзбраниÑÑ‚ ред не може да Ñе добави към индекÑа." -#: lib/diff.tcl:875 msgid "Failed to undo last revert." msgstr "ÐеуÑпешна отмÑна на поÑледното връщане." -#: lib/encoding.tcl:443 msgid "Default" msgstr "Стандартното" -#: lib/encoding.tcl:448 #, tcl-format msgid "System (%s)" msgstr "СиÑтемното (%s)" -#: lib/encoding.tcl:459 lib/encoding.tcl:465 msgid "Other" msgstr "Друго" -#: lib/error.tcl:20 #, tcl-format msgid "%s: error" msgstr "%s: грешка" -#: lib/error.tcl:36 #, tcl-format msgid "%s: warning" msgstr "%s: предупреждение" -#: lib/error.tcl:80 #, tcl-format msgid "%s hook failed:" msgstr "%s: грешка от куката" -#: lib/error.tcl:96 msgid "You must correct the above errors before committing." msgstr "Преди да можете да подадете, коригирайте горните грешки." -#: lib/error.tcl:116 #, tcl-format msgid "%s (%s): error" msgstr "%s (%s): грешка" -#: lib/index.tcl:6 msgid "Unable to unlock the index." msgstr "ИндекÑÑŠÑ‚ не може да Ñе отключи." -#: lib/index.tcl:30 msgid "Index Error" msgstr "Грешка в индекÑа" -#: lib/index.tcl:32 msgid "" "Updating the Git index failed. A rescan will be automatically started to " "resynchronize git-gui." @@ -1798,119 +1315,96 @@ msgstr "" "ÐеуÑпешно обновÑване на индекÑа на Git. Ðвтоматично ще започне нова проверка " "за Ñинхронизирането на git-gui." -#: lib/index.tcl:43 msgid "Continue" msgstr "Продължаване" -#: lib/index.tcl:46 msgid "Unlock Index" msgstr "Отключване на индекÑа" -#: lib/index.tcl:326 +msgid "files" +msgstr "файлове" + msgid "Unstaging selected files from commit" msgstr "Изваждане на избраните файлове от подаването" -#: lib/index.tcl:330 #, tcl-format msgid "Unstaging %s from commit" msgstr "Изваждане на „%s“ от подаването" -#: lib/index.tcl:369 msgid "Ready to commit." msgstr "ГотовноÑÑ‚ за подаване." -#: lib/index.tcl:378 msgid "Adding selected files" msgstr "ДобавÑне на избраните файлове" -#: lib/index.tcl:382 #, tcl-format msgid "Adding %s" msgstr "ДобавÑне на „%s“" -#: lib/index.tcl:412 #, tcl-format msgid "Stage %d untracked files?" msgstr "Да Ñе добавÑÑ‚ ли %d неÑледени файла към индекÑа?" -#: lib/index.tcl:420 msgid "Adding all changed files" msgstr "ДобавÑне на вÑички променени файлове" -#: lib/index.tcl:503 #, tcl-format msgid "Revert changes in file %s?" msgstr "Да Ñе махнат ли промените във файла „%s“?" -#: lib/index.tcl:508 #, tcl-format msgid "Revert changes in these %i files?" msgstr "Да Ñе махнат ли промените в тези %i файла?" -#: lib/index.tcl:517 msgid "Any unstaged changes will be permanently lost by the revert." msgstr "" "Ð’Ñички промени, които не Ñа били добавени в индекÑа, ще Ñе загубÑÑ‚ " "безвъзвратно." -#: lib/index.tcl:520 lib/index.tcl:564 msgid "Do Nothing" msgstr "Ðищо да не Ñе прави" -#: lib/index.tcl:546 #, tcl-format msgid "Delete untracked file %s?" msgstr "Да Ñе изтрие ли неÑледениÑÑ‚ файл „%s“?" -#: lib/index.tcl:551 #, tcl-format msgid "Delete these %i untracked files?" msgstr "Да Ñе изтриÑÑ‚ ли тези %d неÑледени файла?" -#: lib/index.tcl:561 msgid "Files will be permanently deleted." msgstr "Файловете ще Ñе изтриÑÑ‚ окончателно." -#: lib/index.tcl:565 msgid "Delete Files" msgstr "Изтриване на файлове" -#: lib/index.tcl:588 msgid "Deleting" msgstr "Изтриване" -#: lib/index.tcl:667 msgid "Encountered errors deleting files:\n" msgstr "Грешки при изтриване на файловете:\n" -#: lib/index.tcl:676 #, tcl-format msgid "None of the %d selected files could be deleted." msgstr "Ðикой от избраните %d файла не бе изтрит." -#: lib/index.tcl:681 #, tcl-format msgid "%d of the %d selected files could not be deleted." msgstr "%d от избраните %d файла не бÑха изтрити." -#: lib/index.tcl:728 msgid "Reverting selected files" msgstr "Махане на промените в избраните файлове" -#: lib/index.tcl:732 #, tcl-format msgid "Reverting %s" msgstr "Махане на промените в „%s“" -#: lib/line.tcl:17 msgid "Goto Line:" msgstr "Към ред:" -#: lib/line.tcl:23 msgid "Go" msgstr "Към" -#: lib/merge.tcl:13 msgid "" "Cannot merge while amending.\n" "\n" @@ -1921,7 +1415,6 @@ msgstr "" "ТрÑбва да завършите поправÑнето на текущото подаване, преди да започнете " "Ñливане.\n" -#: lib/merge.tcl:27 msgid "" "Last scanned state does not match repository state.\n" "\n" @@ -1938,7 +1431,6 @@ msgstr "" "Ðвтоматично ще започне нова проверка.\n" "\n" -#: lib/merge.tcl:45 #, tcl-format msgid "" "You are in the middle of a conflicted merge.\n" @@ -1956,7 +1448,6 @@ msgstr "" "завършите текущото Ñливане чрез подаване. Чак тогава може да започнете ново " "Ñливане.\n" -#: lib/merge.tcl:55 #, tcl-format msgid "" "You are in the middle of a change.\n" @@ -1973,39 +1464,31 @@ msgstr "" "ТрÑбва да завършите текущото подаване, преди да започнете Ñливане. Така ще " "можете леÑно да преуÑтановите Ñливането, ако възникне нужда.\n" -#: lib/merge.tcl:108 #, tcl-format msgid "%s of %s" msgstr "%s от общо %s" -#: lib/merge.tcl:126 #, tcl-format msgid "Merging %s and %s..." msgstr "Сливане на „%s“ и „%s“…" -#: lib/merge.tcl:137 msgid "Merge completed successfully." msgstr "Сливането завърши уÑпешно." -#: lib/merge.tcl:139 msgid "Merge failed. Conflict resolution is required." msgstr "ÐеуÑпешно Ñливане — има конфликти за коригиране." -#: lib/merge.tcl:156 #, tcl-format msgid "%s (%s): Merge" msgstr "%s (%s): Сливане" -#: lib/merge.tcl:164 #, tcl-format msgid "Merge Into %s" msgstr "Сливане в „%s“" -#: lib/merge.tcl:183 msgid "Revision To Merge" msgstr "ВерÑÐ¸Ñ Ð·Ð° Ñливане" -#: lib/merge.tcl:218 msgid "" "Cannot abort while amending.\n" "\n" @@ -2015,7 +1498,6 @@ msgstr "" "\n" "ТрÑбва да завършите поправката на това подаване.\n" -#: lib/merge.tcl:228 msgid "" "Abort merge?\n" "\n" @@ -2029,7 +1511,6 @@ msgstr "" "\n" "ÐаиÑтина ли да Ñе преуÑтанови Ñливането?" -#: lib/merge.tcl:234 msgid "" "Reset changes?\n" "\n" @@ -2043,35 +1524,27 @@ msgstr "" "\n" "ÐаиÑтина ли да Ñе занулÑÑ‚ промените?" -#: lib/merge.tcl:246 msgid "Aborting" msgstr "ПреуÑтановÑване" -#: lib/merge.tcl:247 msgid "files reset" msgstr "файла ÑÑŠÑ Ð·Ð°Ð½ÑƒÐ»ÐµÐ½Ð¸ промени" -#: lib/merge.tcl:277 msgid "Abort failed." msgstr "ÐеуÑпешно преуÑтановÑване." -#: lib/merge.tcl:279 msgid "Abort completed. Ready." msgstr "УÑпешно преуÑтановÑване. ГотовноÑÑ‚ за Ñледващо дейÑтвие." -#: lib/mergetool.tcl:8 msgid "Force resolution to the base version?" msgstr "Да Ñе използва базовата верÑиÑ" -#: lib/mergetool.tcl:9 msgid "Force resolution to this branch?" msgstr "Да Ñе използва верÑиÑта от този клон" -#: lib/mergetool.tcl:10 msgid "Force resolution to the other branch?" msgstr "Да Ñе използва верÑиÑта от Ð´Ñ€ÑƒÐ³Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/mergetool.tcl:14 #, tcl-format msgid "" "Note that the diff shows only conflicting changes.\n" @@ -2086,34 +1559,28 @@ msgstr "" "\n" "Тази Ð¾Ð¿ÐµÑ€Ð°Ñ†Ð¸Ñ Ð¼Ð¾Ð¶Ðµ да Ñе отмени Ñамо чрез започване на Ñливането наново." -#: lib/mergetool.tcl:45 #, tcl-format msgid "File %s seems to have unresolved conflicts, still stage?" msgstr "" "Изглежда, че вÑе още има некоригирани конфликти във файла „%s“. Да Ñе добави " "ли файлът към индекÑа?" -#: lib/mergetool.tcl:60 #, tcl-format msgid "Adding resolution for %s" msgstr "ДобавÑне на ÐºÐ¾Ñ€ÐµÐºÑ†Ð¸Ñ Ð½Ð° конфликтите в „%s“" -#: lib/mergetool.tcl:141 msgid "Cannot resolve deletion or link conflicts using a tool" msgstr "" "Конфликтите при Ñимволни връзки или изтриване не може да Ñе коригират Ñ " "външна програма." -#: lib/mergetool.tcl:146 msgid "Conflict file does not exist" msgstr "Файлът, в който е конфликтът, не ÑъщеÑтвува" -#: lib/mergetool.tcl:246 #, tcl-format msgid "Not a GUI merge tool: '%s'" msgstr "Това не е графична програма за Ñливане: „%s“" -#: lib/mergetool.tcl:278 #, tcl-format msgid "" "Unable to process square brackets in \"mergetool.%s.cmd\" configuration " @@ -2125,7 +1592,6 @@ msgstr "" "\n" "Махнете ги." -#: lib/mergetool.tcl:289 #, tcl-format msgid "" "Unsupported merge tool '%s'.\n" @@ -2138,11 +1604,9 @@ msgstr "" "За да Ñ Ð¸Ð·Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ‚Ðµ, наÑтройте „mergetool.%s.cmd“ както както е обÑÑнено в " "Ñтраницата на ръководÑтвото за „git-config“." -#: lib/mergetool.tcl:327 msgid "Merge tool is already running, terminate it?" msgstr "Програмата за Ñливане вече е Ñтартирана. Да Ñе изключи ли?" -#: lib/mergetool.tcl:347 #, tcl-format msgid "" "Error retrieving versions:\n" @@ -2151,7 +1615,6 @@ msgstr "" "Грешка при изтеглÑнето на верÑии:\n" "%s" -#: lib/mergetool.tcl:367 #, tcl-format msgid "" "Could not start the merge tool:\n" @@ -2162,277 +1625,211 @@ msgstr "" "\n" "%s" -#: lib/mergetool.tcl:371 msgid "Running merge tool..." msgstr "Стартиране на програмата за Ñливане…" -#: lib/mergetool.tcl:399 lib/mergetool.tcl:407 msgid "Merge tool failed." msgstr "Грешка в програмата за Ñливане." -#: lib/option.tcl:11 #, tcl-format msgid "Invalid global encoding '%s'" msgstr "Ðеправилно глобално кодиране „%s“" -#: lib/option.tcl:19 #, tcl-format msgid "Invalid repo encoding '%s'" msgstr "Ðеправилно кодиране „%s“ на хранилището" -#: lib/option.tcl:119 msgid "Restore Defaults" msgstr "Стандартни наÑтройки" -#: lib/option.tcl:123 msgid "Save" msgstr "Запазване" -#: lib/option.tcl:133 #, tcl-format msgid "%s Repository" msgstr "Хранилище „%s“" -#: lib/option.tcl:134 msgid "Global (All Repositories)" msgstr "Глобално (за вÑички хранилища)" -#: lib/option.tcl:140 msgid "User Name" msgstr "ПотребителÑко име" -#: lib/option.tcl:141 msgid "Email Address" msgstr "ÐÐ´Ñ€ÐµÑ Ð½Ð° е-поща" -#: lib/option.tcl:143 msgid "Summarize Merge Commits" msgstr "Обобщаване на подаваниÑта при Ñливане" -#: lib/option.tcl:144 msgid "Merge Verbosity" msgstr "ПодробноÑти при ÑливаниÑта" -#: lib/option.tcl:145 msgid "Show Diffstat After Merge" msgstr "Извеждане на ÑтатиÑтика Ñлед ÑливаниÑта" -#: lib/option.tcl:146 msgid "Use Merge Tool" msgstr "Използване на програма за Ñливане" -#: lib/option.tcl:148 msgid "Trust File Modification Timestamps" msgstr "Доверие във времето на промÑна на файловете" -#: lib/option.tcl:149 msgid "Prune Tracking Branches During Fetch" msgstr "ОкаÑтрÑне на ÑледÑщите клонове при доÑтавÑне" -#: lib/option.tcl:150 msgid "Match Tracking Branches" msgstr "ÐапаÑване на ÑледÑщите клонове" -#: lib/option.tcl:151 msgid "Use Textconv For Diffs and Blames" msgstr "Използване на „textconv“ за разликите и анотирането" -#: lib/option.tcl:152 msgid "Blame Copy Only On Changed Files" msgstr "Ðнотиране на копието Ñамо по променените файлове" -#: lib/option.tcl:153 msgid "Maximum Length of Recent Repositories List" msgstr "МакÑимален брой на ÑпиÑъка „Скоро ползвани“ хранилища" -#: lib/option.tcl:154 msgid "Minimum Letters To Blame Copy On" msgstr "Минимален брой знаци за анотиране на копието" -#: lib/option.tcl:155 msgid "Blame History Context Radius (days)" msgstr "ИÑторичеÑки обхват за анотиране в дни" -#: lib/option.tcl:156 msgid "Number of Diff Context Lines" msgstr "Брой редове за контекÑта на разликите" -#: lib/option.tcl:157 msgid "Additional Diff Parameters" msgstr "Ðргументи към командата за разликите" -#: lib/option.tcl:158 msgid "Commit Message Text Width" msgstr "Широчина на текÑта на Ñъобщението при подаване" -#: lib/option.tcl:159 msgid "New Branch Name Template" msgstr "Шаблон за името на новите клони" -#: lib/option.tcl:160 msgid "Default File Contents Encoding" msgstr "Кодиране на файловете" -#: lib/option.tcl:161 msgid "Warn before committing to a detached head" msgstr "Предупреждаване при подаване към неÑвързан указател" -#: lib/option.tcl:162 msgid "Staging of untracked files" msgstr "ДобавÑне на неÑледените файлове към индекÑа" -#: lib/option.tcl:163 msgid "Show untracked files" msgstr "Показване на неÑледените файлове" -#: lib/option.tcl:164 msgid "Tab spacing" msgstr "Ширина на табулациÑта" -#: lib/option.tcl:210 msgid "Change" msgstr "СмÑна" -#: lib/option.tcl:254 msgid "Spelling Dictionary:" msgstr "ПравопиÑен речник:" -#: lib/option.tcl:284 msgid "Change Font" msgstr "СмÑна на шрифта" -#: lib/option.tcl:288 #, tcl-format msgid "Choose %s" msgstr "Избор на „%s“" -#: lib/option.tcl:294 msgid "pt." msgstr "тчк." -#: lib/option.tcl:308 msgid "Preferences" msgstr "ÐаÑтройки" -#: lib/option.tcl:345 msgid "Failed to completely save options:" msgstr "ÐеуÑпешно запазване на наÑтройките:" -#: lib/remote_add.tcl:20 #, tcl-format msgid "%s (%s): Add Remote" msgstr "%s (%s): ДобавÑне на отдалечено хранилище" -#: lib/remote_add.tcl:25 msgid "Add New Remote" msgstr "ДобавÑне на отдалечено хранилище" -#: lib/remote_add.tcl:30 lib/tools_dlg.tcl:37 msgid "Add" msgstr "ДобавÑне" -#: lib/remote_add.tcl:39 msgid "Remote Details" msgstr "Данни за отдалеченото хранилище" -#: lib/remote_add.tcl:50 msgid "Location:" msgstr "МеÑтоположение:" -#: lib/remote_add.tcl:60 msgid "Further Action" msgstr "Следващо дейÑтвие" -#: lib/remote_add.tcl:63 msgid "Fetch Immediately" msgstr "Ðезабавно доÑтавÑне" -#: lib/remote_add.tcl:69 msgid "Initialize Remote Repository and Push" msgstr "Инициализиране на отдалеченото хранилище и изтлаÑкване на промените" -#: lib/remote_add.tcl:75 msgid "Do Nothing Else Now" msgstr "Да не Ñе прави нищо" -#: lib/remote_add.tcl:100 msgid "Please supply a remote name." msgstr "Задайте име за отдалеченото хранилище." -#: lib/remote_add.tcl:113 #, tcl-format msgid "'%s' is not an acceptable remote name." msgstr "Отдалечено хранилище не може да Ñе казва „%s“." -#: lib/remote_add.tcl:124 #, tcl-format msgid "Failed to add remote '%s' of location '%s'." msgstr "ÐеуÑпешно добавÑне на отдалеченото хранилище „%s“ от Ð°Ð´Ñ€ÐµÑ â€ž%s“." -#: lib/remote_add.tcl:132 lib/transport.tcl:6 #, tcl-format msgid "fetch %s" msgstr "доÑтавÑне на „%s“" -#: lib/remote_add.tcl:133 #, tcl-format msgid "Fetching the %s" msgstr "ДоÑтавÑне на „%s“" -#: lib/remote_add.tcl:156 #, tcl-format msgid "Do not know how to initialize repository at location '%s'." msgstr "Хранилището Ñ Ð¼ÐµÑтоположение „%s“ не може да Ñе инициализира." -#: lib/remote_add.tcl:162 lib/transport.tcl:54 lib/transport.tcl:92 -#: lib/transport.tcl:110 #, tcl-format msgid "push %s" msgstr "изтлаÑкване на „%s“" -#: lib/remote_add.tcl:163 #, tcl-format msgid "Setting up the %s (at %s)" msgstr "ДобавÑне на хранилище „%s“ (Ñ Ð°Ð´Ñ€ÐµÑ â€ž%s“)" -#: lib/remote_branch_delete.tcl:29 #, tcl-format msgid "%s (%s): Delete Branch Remotely" msgstr "%s (%s): Изтриване на Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/remote_branch_delete.tcl:34 msgid "Delete Branch Remotely" msgstr "Изтриване на Ð¾Ñ‚Ð´Ð°Ð»ÐµÑ‡ÐµÐ½Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: lib/remote_branch_delete.tcl:48 msgid "From Repository" msgstr "От хранилище" -#: lib/remote_branch_delete.tcl:51 lib/transport.tcl:165 msgid "Remote:" msgstr "Отдалечено хранилище:" -#: lib/remote_branch_delete.tcl:72 lib/transport.tcl:187 msgid "Arbitrary Location:" msgstr "Произволно меÑтоположение:" -#: lib/remote_branch_delete.tcl:88 msgid "Branches" msgstr "Клони" -#: lib/remote_branch_delete.tcl:110 msgid "Delete Only If" msgstr "Изтриване, Ñамо ако" -#: lib/remote_branch_delete.tcl:112 msgid "Merged Into:" msgstr "СлÑÑ‚ в:" -#: lib/remote_branch_delete.tcl:153 msgid "A branch is required for 'Merged Into'." msgstr "За данните „СлÑÑ‚ в“ е необходимо да зададете клон." -#: lib/remote_branch_delete.tcl:185 #, tcl-format msgid "" "The following branches are not completely merged into %s:\n" @@ -2443,7 +1840,6 @@ msgstr "" "\n" " â— %s" -#: lib/remote_branch_delete.tcl:190 #, tcl-format msgid "" "One or more of the merge tests failed because you have not fetched the " @@ -2452,140 +1848,107 @@ msgstr "" "Поне една от пробите за Ñливане е неуÑпешна, защото не Ñте доÑтавили вÑички " "необходими подаваниÑ. Пробвайте първо да доÑтавите подаваниÑта от „%s“." -#: lib/remote_branch_delete.tcl:208 msgid "Please select one or more branches to delete." msgstr "Изберете поне един клон за изтриване." -#: lib/remote_branch_delete.tcl:227 #, tcl-format msgid "Deleting branches from %s" msgstr "Изтриване на клони от „%s“" -#: lib/remote_branch_delete.tcl:300 msgid "No repository selected." msgstr "Ðе е избрано хранилище." -#: lib/remote_branch_delete.tcl:305 #, tcl-format msgid "Scanning %s..." msgstr "ПретърÑване на „%s“…" -#: lib/remote.tcl:200 msgid "Push to" msgstr "ИзтлаÑкване към" -#: lib/remote.tcl:218 msgid "Remove Remote" msgstr "Премахване на отдалечено хранилище" -#: lib/remote.tcl:223 msgid "Prune from" msgstr "ОкаÑтрÑне от" -#: lib/remote.tcl:228 msgid "Fetch from" msgstr "ДоÑтавÑне от" -#: lib/remote.tcl:249 lib/remote.tcl:253 lib/remote.tcl:258 lib/remote.tcl:264 msgid "All" msgstr "Ð’Ñички" -#: lib/search.tcl:48 msgid "Find:" msgstr "ТърÑене:" -#: lib/search.tcl:50 msgid "Next" msgstr "Следваща поÑва" -#: lib/search.tcl:51 msgid "Prev" msgstr "Предишна поÑва" -#: lib/search.tcl:52 msgid "RegExp" msgstr "РегИзр" -#: lib/search.tcl:54 msgid "Case" msgstr "Главни/Малки" -#: lib/shortcut.tcl:8 lib/shortcut.tcl:40 lib/shortcut.tcl:72 #, tcl-format msgid "%s (%s): Create Desktop Icon" msgstr "%s (%s): ДобавÑне на икона на Ñ€Ð°Ð±Ð¾Ñ‚Ð½Ð¸Ñ Ð¿Ð»Ð¾Ñ‚" -#: lib/shortcut.tcl:24 lib/shortcut.tcl:62 msgid "Cannot write shortcut:" msgstr "Клавишната ÐºÐ¾Ð¼Ð±Ð¸Ð½Ð°Ñ†Ð¸Ñ Ð½Ðµ може да Ñе запази:" -#: lib/shortcut.tcl:137 msgid "Cannot write icon:" msgstr "Иконата не може да Ñе запази:" -#: lib/spellcheck.tcl:57 msgid "Unsupported spell checker" msgstr "Тази програма за проверка на правопиÑа не Ñе поддържа" -#: lib/spellcheck.tcl:65 msgid "Spell checking is unavailable" msgstr "ЛипÑва програма за проверка на правопиÑа" -#: lib/spellcheck.tcl:68 msgid "Invalid spell checking configuration" msgstr "Ðеправилни наÑтройки на проверката на правопиÑа" -#: lib/spellcheck.tcl:70 #, tcl-format msgid "Reverting dictionary to %s." msgstr "Ползване на речник за език „%s“." -#: lib/spellcheck.tcl:73 msgid "Spell checker silently failed on startup" msgstr "Програмата за Ð¿Ñ€Ð°Ð²Ð¾Ð¿Ð¸Ñ Ð´Ð°Ð¶Ðµ не Ñтартира уÑпешно." -#: lib/spellcheck.tcl:80 msgid "Unrecognized spell checker" msgstr "Ðепозната програма за проверка на правопиÑа" -#: lib/spellcheck.tcl:186 msgid "No Suggestions" msgstr "ÐÑма предложениÑ" -#: lib/spellcheck.tcl:388 msgid "Unexpected EOF from spell checker" msgstr "Ðеочакван край на файл от програмата за проверка на правопиÑа" -#: lib/spellcheck.tcl:392 msgid "Spell Checker Failed" msgstr "Грешка в програмата за проверка на правопиÑа" -#: lib/sshkey.tcl:34 msgid "No keys found." msgstr "Ðе Ñа открити ключове." -#: lib/sshkey.tcl:37 #, tcl-format msgid "Found a public key in: %s" msgstr "Открит е публичен ключ в „%s“" -#: lib/sshkey.tcl:43 msgid "Generate Key" msgstr "Генериране на ключ" -#: lib/sshkey.tcl:61 msgid "Copy To Clipboard" msgstr "Копиране към ÑиÑÑ‚ÐµÐ¼Ð½Ð¸Ñ Ð±ÑƒÑ„ÐµÑ€" -#: lib/sshkey.tcl:75 msgid "Your OpenSSH Public Key" msgstr "ПубличниÑÑ‚ ви ключ за OpenSSH" -#: lib/sshkey.tcl:83 msgid "Generating..." msgstr "Генериране…" -#: lib/sshkey.tcl:89 #, tcl-format msgid "" "Could not start ssh-keygen:\n" @@ -2596,81 +1959,63 @@ msgstr "" "\n" "%s" -#: lib/sshkey.tcl:116 msgid "Generation failed." msgstr "ÐеуÑпешно генериране." -#: lib/sshkey.tcl:123 msgid "Generation succeeded, but no keys found." msgstr "Генерирането завърши уÑпешно, а не Ñа намерени ключове." -#: lib/sshkey.tcl:126 #, tcl-format msgid "Your key is in: %s" msgstr "Ключът ви е в „%s“" -#: lib/status_bar.tcl:263 #, tcl-format msgid "%s ... %*i of %*i %s (%3i%%)" msgstr "%s… %*i от общо %*i %s (%3i%%)" -#: lib/tools_dlg.tcl:22 #, tcl-format msgid "%s (%s): Add Tool" msgstr "%s (%s): ДобавÑне на команда" -#: lib/tools_dlg.tcl:28 msgid "Add New Tool Command" msgstr "ДобавÑне на команда" -#: lib/tools_dlg.tcl:34 msgid "Add globally" msgstr "Глобално добавÑне" -#: lib/tools_dlg.tcl:46 msgid "Tool Details" msgstr "ПодробноÑти за командата" -#: lib/tools_dlg.tcl:49 msgid "Use '/' separators to create a submenu tree:" msgstr "За Ñъздаване на подменюта използвайте знака „/“ за разделител:" -#: lib/tools_dlg.tcl:60 msgid "Command:" msgstr "Команда:" -#: lib/tools_dlg.tcl:71 msgid "Show a dialog before running" msgstr "Преди изпълнение да Ñе извежда диалогов прозорец" -#: lib/tools_dlg.tcl:77 msgid "Ask the user to select a revision (sets $REVISION)" msgstr "ПотребителÑÑ‚ да укаже верÑÐ¸Ñ (задаване на променливата $REVISION)" -#: lib/tools_dlg.tcl:82 msgid "Ask the user for additional arguments (sets $ARGS)" msgstr "" "ПотребителÑÑ‚ да укаже допълнителни аргументи (задаване на променливата $ARGS)" -#: lib/tools_dlg.tcl:89 msgid "Don't show the command output window" msgstr "Без показване на прозорец Ñ Ð¸Ð·Ñ…Ð¾Ð´Ð° от командата" -#: lib/tools_dlg.tcl:94 msgid "Run only if a diff is selected ($FILENAME not empty)" msgstr "" "Стартиране Ñамо Ñлед избор на разлика (променливата $FILENAME не е празна)" -#: lib/tools_dlg.tcl:118 msgid "Please supply a name for the tool." msgstr "Задайте име за командата." -#: lib/tools_dlg.tcl:126 #, tcl-format msgid "Tool '%s' already exists." msgstr "Командата „%s“ вече ÑъщеÑтвува." -#: lib/tools_dlg.tcl:148 #, tcl-format msgid "" "Could not add tool:\n" @@ -2679,154 +2024,121 @@ msgstr "" "Командата не може да Ñе добави:\n" "%s" -#: lib/tools_dlg.tcl:187 #, tcl-format msgid "%s (%s): Remove Tool" msgstr "%s (%s): Премахване на команда" -#: lib/tools_dlg.tcl:193 msgid "Remove Tool Commands" msgstr "Премахване на команди" -#: lib/tools_dlg.tcl:198 msgid "Remove" msgstr "Премахване" -#: lib/tools_dlg.tcl:231 msgid "(Blue denotes repository-local tools)" msgstr "(командите към локалното хранилище Ñа обозначени в Ñиньо)" -#: lib/tools_dlg.tcl:283 #, tcl-format msgid "%s (%s):" msgstr "%s (%s):" -#: lib/tools_dlg.tcl:292 #, tcl-format msgid "Run Command: %s" msgstr "Изпълнение на командата „%s“" -#: lib/tools_dlg.tcl:306 msgid "Arguments" msgstr "Ðргументи" -#: lib/tools_dlg.tcl:341 msgid "OK" msgstr "Добре" -#: lib/tools.tcl:76 #, tcl-format msgid "Running %s requires a selected file." msgstr "За изпълнението на „%s“ трÑбва да изберете файл." -#: lib/tools.tcl:92 #, tcl-format msgid "Are you sure you want to run %1$s on file \"%2$s\"?" msgstr "Сигурни ли Ñте, че иÑкате да изпълните „%1$s“ върху файла „%2$s“?" -#: lib/tools.tcl:96 #, tcl-format msgid "Are you sure you want to run %s?" msgstr "Сигурни ли Ñте, че иÑкате да изпълните „%s“?" -#: lib/tools.tcl:118 #, tcl-format msgid "Tool: %s" msgstr "Команда: %s" -#: lib/tools.tcl:119 #, tcl-format msgid "Running: %s" msgstr "Изпълнение: %s" -#: lib/tools.tcl:158 #, tcl-format msgid "Tool completed successfully: %s" msgstr "Командата завърши уÑпешно: %s" -#: lib/tools.tcl:160 #, tcl-format msgid "Tool failed: %s" msgstr "Командата върна грешка: %s" -#: lib/transport.tcl:7 #, tcl-format msgid "Fetching new changes from %s" msgstr "ДоÑтавÑне на промените от „%s“" -#: lib/transport.tcl:18 #, tcl-format msgid "remote prune %s" msgstr "окаÑтрÑне на ÑледÑщите клони към „%s“" -#: lib/transport.tcl:19 #, tcl-format msgid "Pruning tracking branches deleted from %s" msgstr "ОкаÑтрÑне на ÑледÑщите клони на изтритите клони от „%s“" -#: lib/transport.tcl:25 msgid "fetch all remotes" msgstr "доÑтавÑне от вÑички отдалечени" -#: lib/transport.tcl:26 msgid "Fetching new changes from all remotes" msgstr "ДоÑтавÑне на промените от вÑички отдалечени хранилища" -#: lib/transport.tcl:40 msgid "remote prune all remotes" msgstr "окаÑтрÑне на ÑледÑщите изтрити" -#: lib/transport.tcl:41 msgid "Pruning tracking branches deleted from all remotes" msgstr "" "ОкаÑтрÑне на ÑледÑщите клони на изтритите клони от вÑички отдалечени " "хранилища" -#: lib/transport.tcl:55 #, tcl-format msgid "Pushing changes to %s" msgstr "ИзтлаÑкване на промените към „%s“" -#: lib/transport.tcl:93 #, tcl-format msgid "Mirroring to %s" msgstr "ИзтлаÑкване на вÑичко към „%s“" -#: lib/transport.tcl:111 #, tcl-format msgid "Pushing %s %s to %s" msgstr "ИзтлаÑкване на %s „%s“ към „%s“" -#: lib/transport.tcl:132 msgid "Push Branches" msgstr "Клони за изтлаÑкване" -#: lib/transport.tcl:147 msgid "Source Branches" msgstr "Клони-източници" -#: lib/transport.tcl:162 msgid "Destination Repository" msgstr "Целево хранилище" -#: lib/transport.tcl:205 msgid "Transfer Options" msgstr "ÐаÑтройки при пренаÑÑнето" -#: lib/transport.tcl:207 msgid "Force overwrite existing branch (may discard changes)" msgstr "" "Изрично презапиÑване на ÑъщеÑтвуващ клон (нÑкои промени може да Ñе загубÑÑ‚)" -#: lib/transport.tcl:211 msgid "Use thin pack (for slow network connections)" msgstr "МакÑимална компреÑÐ¸Ñ (за бавни мрежови връзки)" -#: lib/transport.tcl:215 msgid "Include tags" msgstr "Включване на етикетите" -#: lib/transport.tcl:229 #, tcl-format msgid "%s (%s): Push" msgstr "%s (%s): ИзтлаÑкване" diff --git a/git-gui/windows/git-gui.sh b/git-gui/windows/git-gui.sh index b1845c5055..38debe376c 100755 --- a/git-gui/windows/git-gui.sh +++ b/git-gui/windows/git-gui.sh @@ -13,13 +13,5 @@ if { $argc >=2 && [lindex $argv 0] == "--working-dir" } { incr argc -2 } -set basedir [file dirname \ - [file dirname \ - [file dirname [info script]]]] -set bindir [file join $basedir bin] -set bindir "$bindir;[file join $basedir mingw bin]" -regsub -all ";" $bindir "\\;" bindir -set env(PATH) "$bindir;$env(PATH)" -unset bindir - -source [file join [file dirname [info script]] git-gui.tcl] +set thisdir [file normalize [file dirname [info script]]] +source [file join $thisdir git-gui.tcl] @@ -371,7 +371,7 @@ static int handle_alias(struct strvec *args) alias_command = args->v[0]; alias_string = alias_lookup(alias_command); if (alias_string) { - if (args->nr > 1 && !strcmp(args->v[1], "-h")) + if (args->nr == 2 && !strcmp(args->v[1], "-h")) fprintf_ln(stderr, _("'%s' is aliased to '%s'"), alias_command, alias_string); if (alias_string[0] == '!') { @@ -445,7 +445,7 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv, struct const char *prefix; int run_setup = (p->option & (RUN_SETUP | RUN_SETUP_GENTLY)); - help = argc == 2 && !strcmp(argv[1], "-h"); + help = argc == 2 && (!strcmp(argv[1], "-h") || !strcmp(argv[1], "--help-all")); if (help && (run_setup & RUN_SETUP)) /* demote to GENTLY to allow 'git cmd -h' outside repo */ run_setup = RUN_SETUP_GENTLY; @@ -612,6 +612,7 @@ static struct cmd_struct commands[] = { { "repack", cmd_repack, RUN_SETUP }, { "replace", cmd_replace, RUN_SETUP }, { "replay", cmd_replay, RUN_SETUP }, + { "repo", cmd_repo, RUN_SETUP }, { "rerere", cmd_rerere, RUN_SETUP }, { "reset", cmd_reset, RUN_SETUP }, { "restore", cmd_restore, RUN_SETUP | NEED_WORK_TREE }, diff --git a/gitk-git/gitk b/gitk-git/gitk index 427a8a96c9..3b6acfc592 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -7,7 +7,7 @@ exec wish "$0" -- "$@" # and distributed under the terms of the GNU General Public Licence, # either version 2, or (at your option) any later version. -if {[catch {package require Tcl 8.6-8.8} err]} { +if {[catch {package require Tcl 8.6-} err]} { catch {wm withdraw .} tk_messageBox \ -icon error \ @@ -34,6 +34,26 @@ The version of git found is $git_version." } ###################################################################### +## Enable Tcl8 profile in Tcl9, allowing consumption of data that has +## bytes not conforming to the assumed encoding profile. + +if {[package vcompare $::tcl_version 9.0] >= 0} { + rename open _strict_open + proc open args { + set f [_strict_open {*}$args] + chan configure $f -profile tcl8 + return $f + } + proc convertfrom args { + return [encoding convertfrom -profile tcl8 {*}$args] + } +} else { + proc convertfrom args { + return [encoding convertfrom {*}$args] + } +} + +###################################################################### ## ## Enabling platform-specific code paths @@ -2033,8 +2053,10 @@ proc readrefs {} { set tagids($name) $id lappend idtags($id) $name } else { - set otherrefids($name) $id - lappend idotherrefs($id) $name + if [is_other_ref_visible $name] { + set otherrefids($name) $id + lappend idotherrefs($id) $name + } } } catch {close $refd} @@ -2288,6 +2310,16 @@ proc bind_mousewheel {} { bind $cflist <MouseWheel> {$cflist yview scroll [scrollval %D 2] units} bind $cflist <Shift-MouseWheel> break bind $canv <Shift-MouseWheel> {$canv xview scroll [scrollval %D] units} + + if {[package vcompare $::tcl_version 8.7] >= 0} { + bindall <Alt-MouseWheel> {allcanvs yview scroll [scrollval 5*%D] units} + bindall <Alt-Shift-MouseWheel> break + bind $ctext <Alt-MouseWheel> {$ctext yview scroll [scrollval 5*%D 2] units} + bind $ctext <Alt-Shift-MouseWheel> {$ctext xview scroll [scrollval 5*%D 2] units} + bind $cflist <Alt-MouseWheel> {$cflist yview scroll [scrollval 5*%D 2] units} + bind $cflist <Alt-Shift-MouseWheel> break + bind $canv <Alt-Shift-MouseWheel> {$canv xview scroll [scrollval 5*%D] units} + } } proc bind_mousewheel_buttons {} { @@ -2747,7 +2779,7 @@ proc makewindow {} { bindall <1> {selcanvline %W %x %y} #Mouse / touchpad scrolling - if {[tk windowingsystem] == "win32"} { + if {[tk windowingsystem] == "win32" || [package vcompare $::tcl_version 8.7] >= 0} { set scroll_D0 120 bind_mousewheel } elseif {[tk windowingsystem] == "x11"} { @@ -7794,7 +7826,7 @@ proc gettree {id} { set treepending $id set treefilelist($id) {} set treeidlist($id) {} - fconfigure $gtf -blocking 0 -encoding binary + fconfigure $gtf -blocking 0 -translation binary filerun $gtf [list gettreeline $gtf $id] } } else { @@ -7821,7 +7853,7 @@ proc gettreeline {gtf id} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] lappend treefilelist($id) $fname } if {![eof $gtf]} { @@ -8055,7 +8087,7 @@ proc gettreediffs {ids} { set treepending $ids set treediff {} - fconfigure $gdtf -blocking 0 -encoding binary + fconfigure $gdtf -blocking 0 -translation binary filerun $gdtf [list gettreediffline $gdtf $ids] } @@ -8081,7 +8113,7 @@ proc gettreediffline {gdtf ids} { if {[string index $file 0] eq "\""} { set file [lindex $file 0] } - set file [encoding convertfrom utf-8 $file] + set file [convertfrom utf-8 $file] if {$file ne [lindex $treediff end]} { lappend treediff $file lappend sublist $file @@ -8166,7 +8198,7 @@ proc getblobdiffs {ids} { error_popup [mc "Error getting diffs: %s" $err] return } - fconfigure $bdf -blocking 0 -encoding binary -eofchar {} + fconfigure $bdf -blocking 0 -translation binary set blobdifffd($ids) $bdf initblobdiffvars filerun $bdf [list getblobdiffline $bdf $diffids] @@ -8217,7 +8249,7 @@ proc makediffhdr {fname ids} { global ctext curdiffstart treediffs diffencoding global ctext_file_names jump_to_here targetline diffline - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] set diffencoding [get_path_encoding $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { @@ -8279,7 +8311,7 @@ proc parseblobdiffline {ids line} { if {![string compare -length 5 "diff " $line]} { if {![regexp {^diff (--cc|--git) } $line m type]} { - set line [encoding convertfrom utf-8 $line] + set line [convertfrom utf-8 $line] $ctext insert end "$line\n" hunksep continue } @@ -8328,7 +8360,7 @@ proc parseblobdiffline {ids line} { makediffhdr $fname $ids } elseif {![string compare -length 16 "* Unmerged path " $line]} { - set fname [encoding convertfrom utf-8 [string range $line 16 end]] + set fname [convertfrom utf-8 [string range $line 16 end]] $ctext insert end "\n" set curdiffstart [$ctext index "end - 1c"] lappend ctext_file_names $fname @@ -8341,7 +8373,7 @@ proc parseblobdiffline {ids line} { } elseif {![string compare -length 2 "@@" $line]} { regexp {^@@+} $line ats - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" hunksep if {[regexp { \+(\d+),\d+ @@} $line m nl]} { set diffline $nl @@ -8370,10 +8402,10 @@ proc parseblobdiffline {ids line} { $ctext insert end "$line\n" filesep } } elseif {$currdiffsubmod != "" && ![string compare -length 3 " >" $line]} { - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" dresult } elseif {$currdiffsubmod != "" && ![string compare -length 3 " <" $line]} { - set line [encoding convertfrom $diffencoding $line] + set line [convertfrom $diffencoding $line] $ctext insert end "$line\n" d0 } elseif {$diffinhdr} { if {![string compare -length 12 "rename from " $line]} { @@ -8381,7 +8413,7 @@ proc parseblobdiffline {ids line} { if {[string index $fname 0] eq "\""} { set fname [lindex $fname 0] } - set fname [encoding convertfrom utf-8 $fname] + set fname [convertfrom utf-8 $fname] set i [lsearch -exact $treediffs($ids) $fname] if {$i >= 0} { setinlist difffilestart $i $curdiffstart @@ -8400,12 +8432,12 @@ proc parseblobdiffline {ids line} { set diffinhdr 0 return } - set line [encoding convertfrom utf-8 $line] + set line [convertfrom utf-8 $line] $ctext insert end "$line\n" filesep } else { set line [string map {\x1A ^Z} \ - [encoding convertfrom $diffencoding $line]] + [convertfrom $diffencoding $line]] # parse the prefix - one ' ', '-' or '+' for each parent set prefix [string range $line 0 [expr {$diffnparents - 1}]] set tag [expr {$diffnparents > 1? "m": "d"}] @@ -10238,7 +10270,7 @@ proc refill_reflist {} { if {![string match "remotes/*" $n] && [string match $reflistfilter $n]} { if {[commitinview $headids($n) $curview]} { lappend localrefs [list $n H] - if {[info exists upstreamofref($n)]} { + if {[info exists upstreamofref($n)] && [commitinview $headids($upstreamofref($n)) $curview]} { lappend trackedremoterefs [list $upstreamofref($n) R] } } else { @@ -10246,7 +10278,7 @@ proc refill_reflist {} { } } } - set trackedremoterefs [lsort -index 0 $trackedremoterefs] + set trackedremoterefs [lsort -index 0 -unique $trackedremoterefs] set localrefs [lsort -index 0 $localrefs] foreach n [array names headids] { @@ -11649,6 +11681,13 @@ proc prefspage_general {notebook} { -variable hideremotes grid x $page.hideremotes -sticky w + ttk::entry $page.refstohide -textvariable refstohide + ttk::frame $page.refstohidef + ttk::label $page.refstohidef.l -text [mc "Refs to hide (space-separated globs)" ] + pack $page.refstohidef.l -side left + pack configure $page.refstohidef.l -padx 10 + grid x $page.refstohidef $page.refstohide -sticky ew + ttk::checkbutton $page.autocopy -text [mc "Copy commit ID to clipboard"] \ -variable autocopy grid x $page.autocopy -sticky w @@ -11720,57 +11759,63 @@ proc prefspage_colors {notebook} { grid $page.cdisp - -sticky w -pady 10 label $page.ui -padx 40 -relief sunk -background $uicolor ttk::button $page.uibut -text [mc "Interface"] \ - -command [list choosecolor uicolor {} $page.ui [mc "interface"] setui] + -command [list choosecolor uicolor {} $page [mc "interface"]] grid x $page.uibut $page.ui -sticky w label $page.bg -padx 40 -relief sunk -background $bgcolor ttk::button $page.bgbut -text [mc "Background"] \ - -command [list choosecolor bgcolor {} $page.bg [mc "background"] setbg] + -command [list choosecolor bgcolor {} $page [mc "background"]] grid x $page.bgbut $page.bg -sticky w label $page.fg -padx 40 -relief sunk -background $fgcolor ttk::button $page.fgbut -text [mc "Foreground"] \ - -command [list choosecolor fgcolor {} $page.fg [mc "foreground"] setfg] + -command [list choosecolor fgcolor {} $page [mc "foreground"]] grid x $page.fgbut $page.fg -sticky w label $page.diffold -padx 40 -relief sunk -background [lindex $diffcolors 0] ttk::button $page.diffoldbut -text [mc "Diff: old lines"] \ - -command [list choosecolor diffcolors 0 $page.diffold [mc "diff old lines"] \ - [list $ctext tag conf d0 -foreground]] + -command [list choosecolor diffcolors 0 $page [mc "diff old lines"]] grid x $page.diffoldbut $page.diffold -sticky w label $page.diffoldbg -padx 40 -relief sunk -background [lindex $diffbgcolors 0] ttk::button $page.diffoldbgbut -text [mc "Diff: old lines bg"] \ - -command [list choosecolor diffbgcolors 0 $page.diffoldbg \ - [mc "diff old lines bg"] \ - [list $ctext tag conf d0 -background]] + -command [list choosecolor diffbgcolors 0 $page [mc "diff old lines bg"]] grid x $page.diffoldbgbut $page.diffoldbg -sticky w label $page.diffnew -padx 40 -relief sunk -background [lindex $diffcolors 1] ttk::button $page.diffnewbut -text [mc "Diff: new lines"] \ - -command [list choosecolor diffcolors 1 $page.diffnew [mc "diff new lines"] \ - [list $ctext tag conf dresult -foreground]] + -command [list choosecolor diffcolors 1 $page [mc "diff new lines"]] grid x $page.diffnewbut $page.diffnew -sticky w label $page.diffnewbg -padx 40 -relief sunk -background [lindex $diffbgcolors 1] ttk::button $page.diffnewbgbut -text [mc "Diff: new lines bg"] \ - -command [list choosecolor diffbgcolors 1 $page.diffnewbg \ - [mc "diff new lines bg"] \ - [list $ctext tag conf dresult -background]] + -command [list choosecolor diffbgcolors 1 $page [mc "diff new lines bg"]] grid x $page.diffnewbgbut $page.diffnewbg -sticky w label $page.hunksep -padx 40 -relief sunk -background [lindex $diffcolors 2] ttk::button $page.hunksepbut -text [mc "Diff: hunk header"] \ - -command [list choosecolor diffcolors 2 $page.hunksep \ - [mc "diff hunk header"] \ - [list $ctext tag conf hunksep -foreground]] + -command [list choosecolor diffcolors 2 $page [mc "diff hunk header"]] grid x $page.hunksepbut $page.hunksep -sticky w label $page.markbgsep -padx 40 -relief sunk -background $markbgcolor ttk::button $page.markbgbut -text [mc "Marked line bg"] \ - -command [list choosecolor markbgcolor {} $page.markbgsep \ - [mc "marked line background"] \ - [list $ctext tag conf omark -background]] + -command [list choosecolor markbgcolor {} $page [mc "marked line background"]] grid x $page.markbgbut $page.markbgsep -sticky w label $page.selbgsep -padx 40 -relief sunk -background $selectbgcolor ttk::button $page.selbgbut -text [mc "Select bg"] \ - -command [list choosecolor selectbgcolor {} $page.selbgsep [mc "background"] setselbg] + -command [list choosecolor selectbgcolor {} $page [mc "background"]] grid x $page.selbgbut $page.selbgsep -sticky w return $page } +proc prefspage_set_colorswatches {page} { + global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor + global diffbgcolors + + $page.ui configure -background $uicolor + $page.bg configure -background $bgcolor + $page.fg configure -background $fgcolor + $page.diffold configure -background [lindex $diffcolors 0] + $page.diffoldbg configure -background [lindex $diffbgcolors 0] + $page.diffnew configure -background [lindex $diffcolors 1] + $page.diffnewbg configure -background [lindex $diffbgcolors 1] + $page.hunksep configure -background [lindex $diffcolors 2] + $page.markbgsep configure -background $markbgcolor + $page.selbgsep configure -background $selectbgcolor +} + proc prefspage_fonts {notebook} { set page [create_prefs_page $notebook.fonts] ttk::label $page.cfont -text [mc "Fonts: press to choose"] -font mainfontbold @@ -11838,15 +11883,15 @@ proc choose_extdiff {} { } } -proc choosecolor {v vi w x cmd} { +proc choosecolor {v vi prefspage x} { global $v set c [tk_chooseColor -initialcolor [lindex [set $v] $vi] \ -title [mc "Gitk: choose color for %s" $x]] if {$c eq {}} return - $w conf -background $c lset $v $vi $c - eval $cmd $c + set_gui_colors + prefspage_set_colorswatches $prefspage } proc setselbg {c} { @@ -11899,6 +11944,22 @@ proc setfg {c} { $canv itemconf markid -outline $c } +proc set_gui_colors {} { + global uicolor bgcolor fgcolor ctext diffcolors selectbgcolor markbgcolor + global diffbgcolors + + setui $uicolor + setbg $bgcolor + setfg $fgcolor + $ctext tag conf d0 -foreground [lindex $diffcolors 0] + $ctext tag conf d0 -background [lindex $diffbgcolors 0] + $ctext tag conf dresult -foreground [lindex $diffcolors 1] + $ctext tag conf dresult -background [lindex $diffbgcolors 1] + $ctext tag conf hunksep -foreground [lindex $diffcolors 2] + $ctext tag conf omark -background $markbgcolor + setselbg $selectbgcolor +} + proc prefscan {} { global oldprefs prefstop global {*}$::config_variables @@ -11909,6 +11970,7 @@ proc prefscan {} { catch {destroy $prefstop} unset prefstop fontcan + set_gui_colors } proc prefsok {} { @@ -11960,7 +12022,7 @@ proc prefsok {} { $limitdiffs != $oldprefs(limitdiffs)} { reselectline } - if {$hideremotes != $oldprefs(hideremotes)} { + if {$hideremotes != $oldprefs(hideremotes) || $refstohide != $oldprefs(refstohide)} { rereadrefs } if {$wrapcomment != $oldprefs(wrapcomment)} { @@ -12316,7 +12378,7 @@ proc cache_gitattr {attr pathlist} { foreach row [split $rlist "\n"] { if {[regexp "(.*): $attr: (.*)" $row m path value]} { if {[string index $path 0] eq "\""} { - set path [encoding convertfrom utf-8 [lindex $path 0]] + set path [convertfrom utf-8 [lindex $path 0]] } set path_attr_cache($attr,$path) $value } @@ -12337,6 +12399,23 @@ proc get_path_encoding {path} { return $tcl_enc } +proc is_other_ref_visible {ref} { + global refstohide + + if {$refstohide eq {}} { + return 1 + } + + foreach pat [split $refstohide " "] { + if {$pat eq {}} continue + if {[string match $pat $ref]} { + return 0 + } + } + + return 1 +} + ## For msgcat loading, first locate the installation location. if { [info exists ::env(GITK_MSGSDIR)] } { ## Msgsdir was manually set in the environment. @@ -12444,6 +12523,7 @@ set wrapcomment "none" set wrapdefault "none" set showneartags 1 set hideremotes 0 +set refstohide "" set sortrefsbytype 1 set maxrefs 20 set visiblerefs {"master"} @@ -12531,14 +12611,14 @@ catch { set config_file_tmp [file join $env(XDG_CONFIG_HOME) git gitk-tmp] } else { # default XDG_CONFIG_HOME - set config_file "~/.config/git/gitk" - set config_file_tmp "~/.config/git/gitk-tmp" + set config_file "$env(HOME)/.config/git/gitk" + set config_file_tmp "$env(HOME)/.config/git/gitk-tmp" } if {![file exists $config_file]} { # for backward compatibility use the old config file if it exists - if {[file exists "~/.gitk"]} { - set config_file "~/.gitk" - set config_file_tmp "~/.gitk-tmp" + if {[file exists "$env(HOME)/.gitk"]} { + set config_file "$env(HOME)/.gitk" + set config_file_tmp "$env(HOME)/.gitk-tmp" } elseif {![file exists [file dirname $config_file]]} { file mkdir [file dirname $config_file] } @@ -12587,6 +12667,7 @@ set config_variables { mergecolors perfile_attrs reflinecolor + refstohide remotebgcolor selectbgcolor showlocalchanges @@ -12624,8 +12705,6 @@ eval font create textfontbold [fontflags textfont 1] parsefont uifont $uifont eval font create uifont [fontflags uifont] -setui $uicolor - setoptions # check that we can find a .git directory somewhere... @@ -12814,6 +12893,8 @@ if {[tk windowingsystem] eq "win32"} { focus -force . } +set_gui_colors + getcommits {} # Local variables: diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po index 773a049831..d1e7d92425 100644 --- a/gitk-git/po/bg.po +++ b/gitk-git/po/bg.po @@ -1,15 +1,15 @@ # Bulgarian translation of gitk po-file. -# Copyright (C) 2014, 2015, 2019, 2020, 2024 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2014, 2015, 2019, 2020, 2024, 2025 Alexander Shopov <ash@kambanaria.org>. # This file is distributed under the same license as the git package. -# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2019, 2020, 2024. +# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2019, 2020, 2024, 2025. # # msgid "" msgstr "" "Project-Id-Version: gitk master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2024-12-24 11:01+0100\n" -"PO-Revision-Date: 2024-12-24 11:05+0100\n" +"POT-Creation-Date: 2025-07-22 18:34+0200\n" +"PO-Revision-Date: 2025-07-28 13:38+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -18,32 +18,25 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: gitk:139 msgid "Couldn't get list of unmerged files:" msgstr "СпиÑъкът Ñ Ð½ÐµÑлети файлове не може да Ñе получи:" -#: gitk:211 gitk:2430 msgid "Color words" msgstr "ОцветÑване на думите" -#: gitk:216 gitk:2430 gitk:8335 gitk:8368 msgid "Markup words" msgstr "ОтбелÑзване на думите" -#: gitk:323 msgid "Error parsing revisions:" msgstr "Грешка при анализ на верÑиите:" -#: gitk:389 msgid "Error executing --argscmd command:" msgstr "Грешка при изпълнение на командата Ñ â€ž--argscmd“." -#: gitk:402 msgid "No files selected: --merge specified but no files are unmerged." msgstr "" "Ðе Ñа избрани файлове — указана е опциÑта „--merge“, но нÑма неÑлети файлове." -#: gitk:405 msgid "" "No files selected: --merge specified but no unmerged files are within file " "limit." @@ -51,326 +44,246 @@ msgstr "" "Ðе Ñа избрани файлове — указана е опциÑта „--merge“, но нÑма неÑлети файлове " "в ограничениÑта." -#: gitk:430 gitk:585 msgid "Error executing git log:" msgstr "Грешка при изпълнение на „git log“:" -#: gitk:448 gitk:601 msgid "Reading" msgstr "Прочитане" -#: gitk:508 gitk:4596 msgid "Reading commits..." msgstr "Прочитане на подаваниÑта…" -#: gitk:511 gitk:1660 gitk:4599 msgid "No commits selected" msgstr "Ðе Ñа избрани подаваниÑ" -#: gitk:1468 gitk:4116 gitk:12738 msgid "Command line" msgstr "Команден ред" -#: gitk:1534 msgid "Can't parse git log output:" msgstr "Изходът от „git log“ не може да Ñе анализира:" -#: gitk:1763 msgid "No commit information available" msgstr "ЛипÑва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° подаваниÑ" -#: gitk:1930 gitk:1959 gitk:4386 gitk:9875 gitk:11485 gitk:11805 msgid "OK" msgstr "Добре" -#: gitk:1961 gitk:4388 gitk:9311 gitk:9390 gitk:9520 gitk:9606 gitk:9877 -#: gitk:11486 gitk:11806 msgid "Cancel" msgstr "Отказ" -#: gitk:2114 msgid "&Update" msgstr "&ОбновÑване" -#: gitk:2115 msgid "&Reload" msgstr "&Презареждане" -#: gitk:2116 msgid "Reread re&ferences" msgstr "Прочитане &наново" -#: gitk:2117 msgid "&List references" msgstr "&ИзброÑване на указателите" -#: gitk:2119 msgid "Start git &gui" msgstr "&Стартиране на „git gui“" -#: gitk:2121 msgid "&Quit" msgstr "&Спиране на програмата" -#: gitk:2113 msgid "&File" msgstr "&Файл" -#: gitk:2125 msgid "&Preferences" msgstr "&ÐаÑтройки" -#: gitk:2124 msgid "&Edit" msgstr "&Редактиране" -#: gitk:2129 msgid "&New view..." msgstr "&Ðов изглед…" -#: gitk:2130 msgid "&Edit view..." msgstr "&Редактиране на изгледа…" -#: gitk:2131 msgid "&Delete view" msgstr "&Изтриване на изгледа" -#: gitk:2133 msgid "&All files" msgstr "&Ð’Ñички файлове" -#: gitk:2128 msgid "&View" msgstr "&Изглед" -#: gitk:2138 gitk:2148 msgid "&About gitk" msgstr "&ОтноÑно gitk" -#: gitk:2139 gitk:2153 msgid "&Key bindings" msgstr "&Клавишни комбинации" -#: gitk:2137 gitk:2152 msgid "&Help" msgstr "Помо&щ" -#: gitk:2230 gitk:8767 msgid "Commit ID:" msgstr "Подаване:" -#: gitk:2274 msgid "Row" msgstr "Ред" -#: gitk:2312 msgid "Find" msgstr "ТърÑене" -#: gitk:2340 msgid "commit" msgstr "подаване" -#: gitk:2344 gitk:2346 gitk:4758 gitk:4781 gitk:4805 gitk:6826 gitk:6898 -#: gitk:6983 msgid "containing:" msgstr "Ñъдържащо:" -#: gitk:2347 gitk:3597 gitk:3602 gitk:4834 msgid "touching paths:" msgstr "в пътищата:" -#: gitk:2348 gitk:4848 msgid "adding/removing string:" msgstr "добавÑщо/премахващо низ" -#: gitk:2349 gitk:4850 msgid "changing lines matching:" msgstr "променÑщо редове напаÑващи:" -#: gitk:2358 gitk:2360 gitk:4837 msgid "Exact" msgstr "Точно" -#: gitk:2360 gitk:4925 gitk:6794 msgid "IgnCase" msgstr "Без региÑтър" -#: gitk:2360 gitk:4807 gitk:4923 gitk:6790 msgid "Regexp" msgstr "Рег. израз" -#: gitk:2362 gitk:2363 gitk:4945 gitk:4975 gitk:4982 gitk:6919 gitk:6987 msgid "All fields" msgstr "Ð’Ñички полета" -#: gitk:2363 gitk:4942 gitk:4975 gitk:6857 msgid "Headline" msgstr "Първи ред" -#: gitk:2364 gitk:4942 gitk:6857 gitk:6987 gitk:7499 msgid "Comments" msgstr "Коментари" -#: gitk:2364 gitk:4942 gitk:4947 gitk:4982 gitk:6857 gitk:7434 gitk:8945 -#: gitk:8960 msgid "Author" msgstr "Ðвтор" -#: gitk:2364 gitk:4942 gitk:6857 gitk:7436 msgid "Committer" msgstr "Подаващ" -#: gitk:2398 msgid "Search" msgstr "ТърÑене" -#: gitk:2406 msgid "Diff" msgstr "Разлики" -#: gitk:2408 msgid "Old version" msgstr "Стара верÑиÑ" -#: gitk:2410 msgid "New version" msgstr "Ðова верÑиÑ" -#: gitk:2413 msgid "Lines of context" msgstr "КонтекÑÑ‚ в редове" -#: gitk:2423 msgid "Ignore space change" msgstr "Празните знаци без значение" -#: gitk:2427 gitk:2429 gitk:8069 gitk:8321 msgid "Line diff" msgstr "Поредови разлики" -#: gitk:2502 msgid "Patch" msgstr "Кръпка" -#: gitk:2504 msgid "Tree" msgstr "Дърво" -#: gitk:2674 gitk:2695 +msgid "Unknown windowing system, cannot bind mouse" +msgstr "Ðепозната графична ÑиÑтема, не може да Ñе уÑтанови връзка Ñ Ð¼Ð¸ÑˆÐºÐ°" + msgid "Diff this -> selected" msgstr "Разлики между това и избраното" -#: gitk:2675 gitk:2696 msgid "Diff selected -> this" msgstr "Разлики между избраното и това" -#: gitk:2676 gitk:2697 msgid "Make patch" msgstr "Създаване на кръпка" -#: gitk:2677 gitk:9369 msgid "Create tag" msgstr "Създаване на етикет" -#: gitk:2678 msgid "Copy commit reference" msgstr "Копиране на ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ Ð½Ð° подаване" -#: gitk:2679 gitk:9500 msgid "Write commit to file" msgstr "Запазване на подаването във файл" -#: gitk:2680 msgid "Create new branch" msgstr "Създаване на нов клон" -#: gitk:2681 msgid "Cherry-pick this commit" msgstr "Отбиране на това подаване" -#: gitk:2682 msgid "Reset HEAD branch to here" msgstr "Привеждане на върха на клона към текущото подаване" -#: gitk:2683 msgid "Mark this commit" msgstr "ОтбелÑзване на това подаване" -#: gitk:2684 msgid "Return to mark" msgstr "Връщане към отбелÑзаното подаване" -#: gitk:2685 msgid "Find descendant of this and mark" msgstr "Откриване и отбелÑзване на наÑледниците" -#: gitk:2686 msgid "Compare with marked commit" msgstr "Сравнение Ñ Ð¾Ñ‚Ð±ÐµÐ»Ñзаното подаване" -#: gitk:2687 gitk:2698 msgid "Diff this -> marked commit" msgstr "Разлики между това и отбелÑзаното" -#: gitk:2688 gitk:2699 msgid "Diff marked commit -> this" msgstr "Разлики между отбелÑзаното и това" -#: gitk:2689 msgid "Revert this commit" msgstr "ОтмÑна на това подаване" -#: gitk:2705 msgid "Check out this branch" msgstr "ИзтеглÑне на този клон" -#: gitk:2706 msgid "Rename this branch" msgstr "Преименуване на този клон" -#: gitk:2707 msgid "Remove this branch" msgstr "Изтриване на този клон" -#: gitk:2708 msgid "Copy branch name" msgstr "Копиране на името на клона" -#: gitk:2715 msgid "Highlight this too" msgstr "ОтбелÑзване и на това" -#: gitk:2716 msgid "Highlight this only" msgstr "ОтбелÑзване Ñамо на това" -#: gitk:2717 msgid "External diff" msgstr "Външна програма за разлики" -#: gitk:2718 msgid "Blame parent commit" msgstr "Ðнотиране на родителÑкото подаване" -#: gitk:2719 msgid "Copy path" msgstr "Копиране на пътÑ" -#: gitk:2726 msgid "Show origin of this line" msgstr "Показване на произхода на този ред" -#: gitk:2727 msgid "Run git gui blame on this line" msgstr "Изпълнение на „git gui blame“ върху този ред" -#: gitk:3081 msgid "About gitk" msgstr "ОтноÑно gitk" -#: gitk:3083 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -386,324 +299,250 @@ msgstr "" "\n" "Използвайте и разпроÑтранÑвайте при уÑловиÑта на ОПЛ на ГÐУ" -#: gitk:3091 gitk:3158 gitk:10090 msgid "Close" msgstr "ЗатварÑне" -#: gitk:3112 msgid "Gitk key bindings" msgstr "Клавишни комбинации" -#: gitk:3115 msgid "Gitk key bindings:" msgstr "Клавишни комбинации:" -#: gitk:3117 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tСпиране на програмата" -#: gitk:3118 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tЗатварÑне на прозореца" -#: gitk:3119 msgid "<Home>\t\tMove to first commit" msgstr "<Home>\t\tКъм първото подаване" -#: gitk:3120 msgid "<End>\t\tMove to last commit" msgstr "<End>\t\tКъм поÑледното подаване" -#: gitk:3121 msgid "<Up>, p, k\tMove up one commit" msgstr "<Up>, p, k\tЕдно подаване нагоре" -#: gitk:3122 msgid "<Down>, n, j\tMove down one commit" msgstr "<Down>, n, j\tЕдно подаване надолу" -#: gitk:3123 msgid "<Left>, z, h\tGo back in history list" msgstr "<Left>, z, h\tÐазад в иÑториÑта" -#: gitk:3124 msgid "<Right>, x, l\tGo forward in history list" msgstr "<Right>, x, l\tÐапред в иÑториÑта" -#: gitk:3125 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tКъм n-Ñ‚Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ» на текущото подаване в иÑториÑта" -#: gitk:3126 msgid "<PageUp>\tMove up one page in commit list" msgstr "<PageUp>\tСтраница нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3127 msgid "<PageDown>\tMove down one page in commit list" msgstr "<PageDown>\tСтраница надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3128 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tКъм началото на ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3129 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tКъм ÐºÑ€Ð°Ñ Ð½Ð° ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3130 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tРед нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3131 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tРед надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3132 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tСтраница нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3133 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tСтраница надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3134 msgid "<Shift-Up>\tFind backwards (upwards, later commits)" msgstr "<Shift-Up>\tТърÑене назад (визуално нагоре, иÑторичеÑки — поÑледващи)" -#: gitk:3135 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)" msgstr "" "<Shift-Down>\tТърÑене напред (визуално надолу, иÑторичеÑки — предхождащи)" -#: gitk:3136 msgid "<Delete>, b\tScroll diff view up one page" msgstr "<Delete>, b\tСтраница нагоре в изгледа за разлики" -#: gitk:3137 msgid "<Backspace>\tScroll diff view up one page" msgstr "<Backspace>\tСтраница надолу в изгледа за разлики" -#: gitk:3138 msgid "<Space>\t\tScroll diff view down one page" msgstr "<Space>\t\tСтраница надолу в изгледа за разлики" -#: gitk:3139 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\t18 реда нагоре в изгледа за разлики" -#: gitk:3140 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\t18 реда надолу в изгледа за разлики" -#: gitk:3141 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tТърÑене" -#: gitk:3142 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tКъм Ñледващата поÑва" -#: gitk:3143 msgid "<Return>\tMove to next find hit" msgstr "<Return>\tКъм Ñледващата поÑва" -#: gitk:3144 msgid "g\t\tGo to commit" msgstr "g\t\tКъм поÑледното подаване" -#: gitk:3145 msgid "/\t\tFocus the search box" msgstr "/\t\tÐ¤Ð¾ÐºÑƒÑ Ð²ÑŠÑ€Ñ…Ñƒ полето за търÑене" -#: gitk:3146 msgid "?\t\tMove to previous find hit" msgstr "?\t\tКъм предишната поÑва" -#: gitk:3147 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tСледващ файл в изгледа за разлики" -#: gitk:3148 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tТърÑене на Ñледващата поÑва в изгледа за разлики" -#: gitk:3149 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tТърÑене на предишната поÑва в изгледа за разлики" -#: gitk:3150 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tПо-голÑм размер на шрифта" -#: gitk:3151 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tПо-голÑм размер на шрифта" -#: gitk:3152 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tПо-малък размер на шрифта" -#: gitk:3153 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tПо-малък размер на шрифта" -#: gitk:3154 msgid "<F5>\t\tUpdate" msgstr "<F5>\t\tОбновÑване" -#: gitk:3621 gitk:3630 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Грешка при Ñъздаването на временната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ â€ž%s“:" -#: gitk:3643 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Грешка при получаването на „%s“ от %s:" -#: gitk:3706 msgid "command failed:" msgstr "неуÑпешно изпълнение на команда:" -#: gitk:3855 msgid "No such commit" msgstr "Такова подаване нÑма" -#: gitk:3869 msgid "git gui blame: command failed:" msgstr "„git gui blame“: неуÑпешно изпълнение на команда:" -#: gitk:3900 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Върхът за Ñливане не може да Ñе прочете: %s" -#: gitk:3908 #, tcl-format msgid "Error reading index: %s" msgstr "Грешка при прочитане на индекÑа: %s" -#: gitk:3933 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Командата „git blame“ не може да Ñе Ñтартира: %s" -#: gitk:3936 gitk:6825 msgid "Searching" msgstr "ТърÑене" -#: gitk:3968 #, tcl-format msgid "Error running git blame: %s" msgstr "Грешка при изпълнението на „git blame“: %s" -#: gitk:3996 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Този ред идва от подаването %s, което не е в изгледа" -#: gitk:4010 msgid "External diff viewer failed:" msgstr "ÐеуÑпешно изпълнение на външната програма за разлики:" -#: gitk:4114 msgid "All files" msgstr "Ð’Ñички файлове" -#: gitk:4138 msgid "View" msgstr "Изглед" -#: gitk:4141 msgid "Gitk view definition" msgstr "Ð”ÐµÑ„Ð¸Ð½Ð¸Ñ†Ð¸Ñ Ð½Ð° изглед в Gitk" -#: gitk:4145 msgid "Remember this view" msgstr "Запазване на този изглед" -#: gitk:4146 msgid "References (space separated list):" msgstr "Указатели (ÑпиÑък Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ» интервал):" -#: gitk:4147 msgid "Branches & tags:" msgstr "Клони и етикети:" -#: gitk:4148 msgid "All refs" msgstr "Ð’Ñички указатели" -#: gitk:4149 msgid "All (local) branches" msgstr "Ð’Ñички (локални) клони" -#: gitk:4150 msgid "All tags" msgstr "Ð’Ñички етикети" -#: gitk:4151 msgid "All remote-tracking branches" msgstr "Ð’Ñички ÑледÑщи клони" -#: gitk:4152 msgid "Commit Info (regular expressions):" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° подаване (рег. изр.):" -#: gitk:4153 msgid "Author:" msgstr "Ðвтор:" -#: gitk:4154 msgid "Committer:" msgstr "Подал:" -#: gitk:4155 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: gitk:4156 msgid "Matches all Commit Info criteria" msgstr "Съвпадение по вÑички характериÑтики на подаването" -#: gitk:4157 msgid "Matches no Commit Info criteria" msgstr "Ðе Ñъвпада по Ð½Ð¸ÐºÐ¾Ñ Ð¾Ñ‚ характериÑтиките на подаването" -#: gitk:4158 msgid "Changes to Files:" msgstr "Промени по файловете:" -#: gitk:4159 msgid "Fixed String" msgstr "ДоÑловен низ" -#: gitk:4160 msgid "Regular Expression" msgstr "РегулÑрен израз" -#: gitk:4161 msgid "Search string:" msgstr "Ðиз за търÑене:" -#: gitk:4162 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -711,208 +550,159 @@ msgstr "" "Дата на подаване („2 weeks ago“ (преди 2 Ñедмици), „2009-03-17 15:27:38“, " "„March 17, 2009 15:27:38“):" -#: gitk:4163 msgid "Since:" msgstr "От:" -#: gitk:4164 msgid "Until:" msgstr "До:" -#: gitk:4165 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "" "Ограничаване и/или преÑкачане на определен брой верÑии (неотрицателно цÑло " "чиÑло):" -#: gitk:4166 msgid "Number to show:" msgstr "Брой показани:" -#: gitk:4167 msgid "Number to skip:" msgstr "Брой преÑкочени:" -#: gitk:4168 msgid "Miscellaneous options:" msgstr "Разни:" -#: gitk:4169 msgid "Strictly sort by date" msgstr "Подреждане по дата" -#: gitk:4170 msgid "Mark branch sides" msgstr "ОтбелÑзване на Ñтраните по клона" -#: gitk:4171 msgid "Limit to first parent" msgstr "Само Ð¿ÑŠÑ€Ð²Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»" -#: gitk:4172 msgid "Simple history" msgstr "ОпроÑтена иÑториÑ" -#: gitk:4173 msgid "Additional arguments to git log:" msgstr "Допълнителни аргументи към „git log“:" -#: gitk:4174 msgid "Enter files and directories to include, one per line:" msgstr "Въведете файловете и директориите за включване, по елемент на ред" -#: gitk:4175 msgid "Command to generate more commits to include:" msgstr "" "Команда за генерирането на допълнителни подаваниÑ, които да Ñе включат:" -#: gitk:4299 msgid "Gitk: edit view" msgstr "Gitk: редактиране на изглед" -#: gitk:4307 msgid "-- criteria for selecting revisions" msgstr "— критерии за избор на верÑии" -#: gitk:4312 msgid "View Name" msgstr "Име на изглед" -#: gitk:4387 msgid "Apply (F5)" msgstr "Прилагане (F5)" -#: gitk:4425 msgid "Error in commit selection arguments:" msgstr "Грешка в аргументите за избор на подаваниÑ:" -#: gitk:4480 gitk:4533 gitk:4995 gitk:5009 gitk:6279 gitk:12679 gitk:12680 msgid "None" msgstr "ÐÑма" -#: gitk:5092 gitk:5097 msgid "Descendant" msgstr "ÐаÑледник" -#: gitk:5093 msgid "Not descendant" msgstr "Ðе е наÑледник" -#: gitk:5100 gitk:5105 msgid "Ancestor" msgstr "ПредшеÑтвеник" -#: gitk:5101 msgid "Not ancestor" msgstr "Ðе е предшеÑтвеник" -#: gitk:5395 msgid "Local changes checked in to index but not committed" msgstr "Локални промени добавени към индекÑа, но неподадени" -#: gitk:5431 msgid "Local uncommitted changes, not checked in to index" msgstr "Локални промени извън индекÑа" -#: gitk:7179 msgid "Error starting web browser:" msgstr "Грешка при Ñтартирането на уеб браузър:" -#: gitk:7240 msgid "and many more" msgstr "и още много" -#: gitk:7243 msgid "many" msgstr "много" -#: gitk:7438 msgid "Tags:" msgstr "Етикети:" -#: gitk:7455 gitk:7461 gitk:8940 msgid "Parent" msgstr "Родител" -#: gitk:7466 msgid "Child" msgstr "Дете" -#: gitk:7475 msgid "Branch" msgstr "Клон" -#: gitk:7478 msgid "Follows" msgstr "Следва" -#: gitk:7481 msgid "Precedes" msgstr "ПредшеÑтва" -#: gitk:8076 #, tcl-format msgid "Error getting diffs: %s" msgstr "Грешка при получаването на разликите: %s" -#: gitk:8765 msgid "Goto:" msgstr "Към ред:" -#: gitk:8786 #, tcl-format msgid "Short commit ID %s is ambiguous" msgstr "Съкратената контролна Ñума %s не е еднозначна" -#: gitk:8793 #, tcl-format msgid "Revision %s is not known" msgstr "Ðепозната верÑÐ¸Ñ %s" -#: gitk:8803 #, tcl-format msgid "Commit ID %s is not known" msgstr "Ðепозната контролна Ñума %s" -#: gitk:8805 #, tcl-format msgid "Revision %s is not in the current view" msgstr "ВерÑÐ¸Ñ %s не е в Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´" -#: gitk:8947 gitk:8962 msgid "Date" msgstr "Дата" -#: gitk:8950 msgid "Children" msgstr "Деца" -#: gitk:9013 #, tcl-format msgid "Reset %s branch to here" msgstr "ЗанулÑване на клона „%s“ към текущото подаване" -#: gitk:9015 msgid "Detached head: can't reset" msgstr "ÐеÑвързан връх: невъзможно занулÑване" -#: gitk:9120 gitk:9126 msgid "Skipping merge commit " msgstr "ПропуÑкане на подаването на Ñливането" -#: gitk:9135 gitk:9140 msgid "Error getting patch ID for " msgstr "Грешка при получаването на идентификатора на " -#: gitk:9136 gitk:9141 msgid " - stopping\n" msgstr " — Ñпиране\n" -#: gitk:9146 gitk:9149 gitk:9157 gitk:9171 gitk:9180 msgid "Commit " msgstr "Подаване" -#: gitk:9150 msgid "" " is the same patch as\n" " " @@ -920,7 +710,6 @@ msgstr "" " е Ñъщата кръпка като\n" " " -#: gitk:9158 msgid "" " differs from\n" " " @@ -928,7 +717,6 @@ msgstr "" " Ñе различава от\n" " " -#: gitk:9160 msgid "" "Diff of commits:\n" "\n" @@ -936,147 +724,113 @@ msgstr "" "Разлика между подаваниÑта:\n" "\n" -#: gitk:9172 gitk:9181 #, tcl-format msgid " has %s children - stopping\n" msgstr " има %s деца — Ñпиране\n" -#: gitk:9200 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Грешка при запазването на подаването във файл: %s" -#: gitk:9206 #, tcl-format msgid "Error diffing commits: %s" msgstr "Грешка при изчиÑлÑването на разликите между подаваниÑта: %s" -#: gitk:9252 msgid "Top" msgstr "Ðай-горе" -#: gitk:9253 msgid "From" msgstr "От" -#: gitk:9258 msgid "To" msgstr "До" -#: gitk:9282 msgid "Generate patch" msgstr "Генериране на кръпка" -#: gitk:9284 msgid "From:" msgstr "От:" -#: gitk:9293 msgid "To:" msgstr "До:" -#: gitk:9302 msgid "Reverse" msgstr "Обръщане" -#: gitk:9304 gitk:9514 msgid "Output file:" msgstr "Запазване във файла:" -#: gitk:9310 msgid "Generate" msgstr "Генериране" -#: gitk:9348 msgid "Error creating patch:" msgstr "Грешка при Ñъздаването на кръпка:" -#: gitk:9371 gitk:9502 gitk:9590 msgid "ID:" msgstr "Идентификатор:" -#: gitk:9380 msgid "Tag name:" msgstr "Име на етикет:" -#: gitk:9383 msgid "Tag message is optional" msgstr "Съобщението за етикет е незадължително" -#: gitk:9385 msgid "Tag message:" msgstr "Съобщение за етикет:" -#: gitk:9389 gitk:9560 msgid "Create" msgstr "Създаване" -#: gitk:9407 msgid "No tag name specified" msgstr "ЛипÑва име на етикет" -#: gitk:9411 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Етикетът „%s“ вече ÑъщеÑтвува" -#: gitk:9421 msgid "Error creating tag:" msgstr "Грешка при Ñъздаването на етикет:" -#: gitk:9511 msgid "Command:" msgstr "Команда:" -#: gitk:9519 msgid "Write" msgstr "Запазване" -#: gitk:9537 msgid "Error writing commit:" msgstr "Грешка при запазването на подаването:" -#: gitk:9559 msgid "Create branch" msgstr "Създаване на клон" -#: gitk:9575 #, tcl-format msgid "Rename branch %s" msgstr "Преименуване на клона „%s“" -#: gitk:9576 msgid "Rename" msgstr "Преименуване" -#: gitk:9600 msgid "Name:" msgstr "Име:" -#: gitk:9624 msgid "Please specify a name for the new branch" msgstr "Укажете име за Ð½Ð¾Ð²Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: gitk:9629 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "Клонът „%s“ вече ÑъщеÑтвува. Да Ñе презапише ли?" -#: gitk:9673 msgid "Please specify a new name for the branch" msgstr "Укажете ново име за клона" -#: gitk:9736 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Подаването „%s“ вече е включено в клона „%s“ — да Ñе приложи ли отново?" -#: gitk:9741 msgid "Cherry-picking" msgstr "Отбиране" -#: gitk:9750 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1085,7 +839,6 @@ msgstr "" "ÐеуÑпешно отбиране, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги Ñкатайте и пробвайте отново." -#: gitk:9756 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1093,20 +846,16 @@ msgstr "" "ÐеуÑпешно отбиране поради конфликти при Ñливане.\n" "ИÑкате ли да ги коригирате чрез „git citool“?" -#: gitk:9772 gitk:9830 msgid "No changes committed" msgstr "Ðе Ñа подадени промени" -#: gitk:9799 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "Подаването „%s“ не е включено в клона „%s“. Да Ñе отменени ли?" -#: gitk:9804 msgid "Reverting" msgstr "ОтмÑна" -#: gitk:9812 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " @@ -1115,7 +864,6 @@ msgstr "" "ÐеуÑпешна отмÑна, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги Ñкатайте и пробвайте отново." -#: gitk:9816 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1123,28 +871,22 @@ msgstr "" "ÐеуÑпешно отмÑна поради конфликти при Ñливане.\n" "ИÑкате ли да ги коригирате чрез „git citool“?" -#: gitk:9859 msgid "Confirm reset" msgstr "Потвърждаване на занулÑването" -#: gitk:9861 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Да Ñе занули ли клонът „%s“ към „%s“?" -#: gitk:9863 msgid "Reset type:" msgstr "Вид занулÑване:" -#: gitk:9866 msgid "Soft: Leave working tree and index untouched" msgstr "Слабо: работното дърво и индекÑа оÑтават Ñъщите" -#: gitk:9869 msgid "Mixed: Leave working tree untouched, reset index" msgstr "СмеÑено: работното дърво оÑтава Ñъщото, индекÑÑŠÑ‚ Ñе занулÑва" -#: gitk:9872 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" @@ -1152,24 +894,19 @@ msgstr "" "Силно: занулÑване и на работното дърво, и на индекÑа\n" "(ВСИЧКИ локални промени ще Ñе загубÑÑ‚ безвъзвратно)" -#: gitk:9889 msgid "Resetting" msgstr "ЗанулÑване" -#: gitk:9962 #, tcl-format msgid "A local branch named %s exists already" msgstr "Вече ÑъщеÑтвува локален клон „%s“." -#: gitk:9970 msgid "Checking out" msgstr "ИзтеглÑне" -#: gitk:10029 msgid "Cannot delete the currently checked-out branch" msgstr "Текущо изтеглениÑÑ‚ клон не може да Ñе изтрие" -#: gitk:10035 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1178,16 +915,16 @@ msgstr "" "ПодаваниÑта на клона „%s“ не Ñа на никой друг клон.\n" "ÐаиÑтина ли иÑкате да изтриете клона „%s“?" -#: gitk:10066 #, tcl-format msgid "Tags and heads: %s" msgstr "Етикети и върхове: %s" -#: gitk:10083 msgid "Filter" msgstr "Филтриране" -#: gitk:10390 +msgid "Sort refs by type" +msgstr "Подредба на указателите по вид" + msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1195,253 +932,167 @@ msgstr "" "Грешка при прочитането на топологиÑта на подаваниÑта. ИнформациÑта за клона " "и предшеÑтващите/Ñледващите етикети ще е непълна." -#: gitk:11367 msgid "Tag" msgstr "Етикет" -#: gitk:11371 msgid "Id" msgstr "Идентификатор" -#: gitk:11454 -msgid "Gitk font chooser" -msgstr "Избор на шрифт за Gitk" - -#: gitk:11471 -msgid "B" -msgstr "Ч" - -#: gitk:11474 -msgid "I" -msgstr "К" - -#: gitk:11593 msgid "Commit list display options" msgstr "ÐаÑтройки на ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:11596 msgid "Maximum graph width (lines)" msgstr "МакÑимална широчина на графа (в редове)" -#: gitk:11600 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "МакÑимална широчина на графа (% от панела)" -#: gitk:11603 msgid "Show local changes" msgstr "Показване на локалните промени" -#: gitk:11606 msgid "Hide remote refs" msgstr "Скриване на отдалечените указатели" -#: gitk:11610 msgid "Copy commit ID to clipboard" msgstr "Копиране на контролната Ñума към буфера за обмен" -#: gitk:11614 msgid "Copy commit ID to X11 selection" msgstr "Копиране на контролната Ñума в ÑелекциÑта на X11" -#: gitk:11619 msgid "Length of commit ID to copy" msgstr "Дължина на контролната Ñума, коÑто Ñе копира" -#: gitk:11622 +msgid "Wheel scrolling multiplier" +msgstr "Множител за колелцето на мишката" + msgid "Diff display options" msgstr "ÐаÑтройки на показването на разликите" -#: gitk:11624 msgid "Tab spacing" msgstr "Широчина на табулатора" -#: gitk:11628 msgid "Wrap comment text" msgstr "ПренаÑÑне на думите в коментарите" -#: gitk:11633 msgid "Wrap other text" msgstr "ПренаÑÑне на Ð´Ñ€ÑƒÐ³Ð¸Ñ Ñ‚ÐµÐºÑÑ‚" -#: gitk:11638 msgid "Display nearby tags/heads" msgstr "Извеждане на близките етикети и върхове" -#: gitk:11641 msgid "Maximum # tags/heads to show" msgstr "МакÑимален брой етикети/върхове за показване" -#: gitk:11644 msgid "Limit diffs to listed paths" msgstr "Разлика Ñамо в избраните пътища" -#: gitk:11647 msgid "Support per-file encodings" msgstr "Поддръжка на различни ÐºÐ¾Ð´Ð¸Ñ€Ð°Ð½Ð¸Ñ Ð·Ð° вÑеки файл" -#: gitk:11653 gitk:11820 msgid "External diff tool" msgstr "Външен инÑтрумент за разлики" -#: gitk:11654 msgid "Choose..." msgstr "Избор…" -#: gitk:11661 msgid "Web browser" msgstr "Уеб браузър" -#: gitk:11666 -msgid "General options" -msgstr "Общи наÑтройки" - -#: gitk:11669 -msgid "Use themed widgets" -msgstr "Използване на тема за графичните обекти" - -#: gitk:11671 -msgid "(change requires restart)" -msgstr "(промÑната изиÑква реÑтартиране на Gitk)" - -#: gitk:11673 -msgid "(currently unavailable)" -msgstr "(в момента недоÑтъпно)" - -#: gitk:11685 msgid "Colors: press to choose" msgstr "Цветове: избира Ñе Ñ Ð½Ð°Ñ‚Ð¸Ñкане" -#: gitk:11688 msgid "Interface" msgstr "ИнтерфейÑ" -#: gitk:11689 msgid "interface" msgstr "интерфейÑ" -#: gitk:11692 msgid "Background" msgstr "Фон" -#: gitk:11693 gitk:11735 msgid "background" msgstr "фон" -#: gitk:11696 msgid "Foreground" msgstr "Знаци" -#: gitk:11697 msgid "foreground" msgstr "знаци" -#: gitk:11700 msgid "Diff: old lines" msgstr "Разлика: Ñтари редове" -#: gitk:11701 msgid "diff old lines" msgstr "разлика, Ñтари редове" -#: gitk:11705 msgid "Diff: old lines bg" msgstr "Разлика: фон на Ñтари редове" -#: gitk:11707 msgid "diff old lines bg" msgstr "разлика, фон на Ñтари редове" -#: gitk:11711 msgid "Diff: new lines" msgstr "Разлика: нови редове" -#: gitk:11712 msgid "diff new lines" msgstr "разлика, нови редове" -#: gitk:11716 msgid "Diff: new lines bg" msgstr "Разлика: фон на нови редове" -#: gitk:11718 msgid "diff new lines bg" msgstr "разлика, фон на нови редове" -#: gitk:11722 msgid "Diff: hunk header" msgstr "Разлика: начало на парче" -#: gitk:11724 msgid "diff hunk header" msgstr "разлика, начало на парче" -#: gitk:11728 msgid "Marked line bg" msgstr "Фон на отбелÑзан ред" -#: gitk:11730 msgid "marked line background" msgstr "фон на отбелÑзан ред" -#: gitk:11734 msgid "Select bg" msgstr "Избор на фон" -#: gitk:11743 msgid "Fonts: press to choose" msgstr "Шрифтове: избира Ñе Ñ Ð½Ð°Ñ‚Ð¸Ñкане" -#: gitk:11745 msgid "Main font" msgstr "ОÑновен шрифт" -#: gitk:11746 msgid "Diff display font" msgstr "Шрифт за разликите" -#: gitk:11747 msgid "User interface font" msgstr "Шрифт на интерфейÑа" -#: gitk:11769 msgid "Gitk preferences" msgstr "ÐаÑтройки на Gitk" -#: gitk:11778 msgid "General" msgstr "Общи" -#: gitk:11779 msgid "Colors" msgstr "Цветове" -#: gitk:11780 msgid "Fonts" msgstr "Шрифтове" -#: gitk:11830 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: избор на цвÑÑ‚ на „%s“" -#: gitk:12350 -msgid "" -"Sorry, gitk cannot run with this version of Tcl/Tk.\n" -" Gitk requires at least Tcl/Tk 8.4." -msgstr "" -"Тази верÑÐ¸Ñ Ð½Ð° Tcl/Tk не Ñе поддържа от Gitk.\n" -" Ðеобходима ви е поне Tcl/Tk 8.4." - -#: gitk:12571 msgid "Cannot find a git repository here." msgstr "Тук липÑва хранилище на Git." -#: gitk:12618 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Ðееднозначен аргумент „%s“: има и такава верÑиÑ, и такъв файл" -#: gitk:12630 msgid "Bad arguments to gitk:" msgstr "Ðеправилни аргументи на gitk:" diff --git a/gpg-interface.c b/gpg-interface.c index d26c7135b0..06e7fb5060 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -25,7 +25,7 @@ static void gpg_interface_lazy_init(void) if (done) return; done = 1; - git_config(git_gpg_config, NULL); + repo_config(the_repository, git_gpg_config, NULL); } static char *configured_signing_key; @@ -332,7 +332,7 @@ static int get_colopts(const char *var, const char *value, void list_commands(struct cmdnames *main_cmds, struct cmdnames *other_cmds) { unsigned int colopts = 0; - git_config(get_colopts, &colopts); + repo_config(the_repository, get_colopts, &colopts); if (main_cmds->cnt) { const char *exec_path = git_exec_path(); @@ -417,7 +417,7 @@ void list_cmds_by_config(struct string_list *list) { const char *cmd_list; - if (git_config_get_string_tmp("completion.commands", &cmd_list)) + if (repo_config_get_string_tmp(the_repository, "completion.commands", &cmd_list)) return; string_list_sort(list); @@ -502,7 +502,7 @@ static void list_all_cmds_help_aliases(int longest) struct cmdname_help *aliases; int i; - git_config(get_alias, &alias_list); + repo_config(the_repository, get_alias, &alias_list); string_list_sort(&alias_list); for (i = 0; i < alias_list.nr; i++) { diff --git a/http-backend.c b/http-backend.c index ad8c403749..d5dfe762bb 100644 --- a/http-backend.c +++ b/http-backend.c @@ -246,13 +246,13 @@ static void http_config(void) int i, value = 0; struct strbuf var = STRBUF_INIT; - git_config_get_bool("http.getanyfile", &getanyfile); - git_config_get_ulong("http.maxrequestbuffer", &max_request_buffer); + repo_config_get_bool(the_repository, "http.getanyfile", &getanyfile); + repo_config_get_ulong(the_repository, "http.maxrequestbuffer", &max_request_buffer); for (i = 0; i < ARRAY_SIZE(rpc_service); i++) { struct rpc_service *svc = &rpc_service[i]; strbuf_addf(&var, "http.%s", svc->config_name); - if (!git_config_get_bool(var.buf, &value)) + if (!repo_config_get_bool(the_repository, var.buf, &value)) svc->enabled = value; strbuf_reset(&var); } diff --git a/http-fetch.c b/http-fetch.c index 02ab80533f..1922e23fcd 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -2,6 +2,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "http.h" @@ -150,7 +151,7 @@ int cmd_main(int argc, const char **argv) trace2_cmd_name("http-fetch"); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); if (packfile) { if (!index_pack_args.nr) @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "git-curl-compat.h" +#include "environment.h" #include "hex.h" #include "http.h" #include "config.h" @@ -1315,7 +1316,7 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) http_is_verbose = 0; normalized_url = url_normalize(url, &config.url); - git_config(urlmatch_config_entry, &config); + repo_config(the_repository, urlmatch_config_entry, &config); free(normalized_url); string_list_clear(&config.vars, 1); @@ -2331,7 +2332,7 @@ int http_get_file(const char *url, const char *filename, ret = http_request_reauth(url, result, HTTP_REQUEST_FILE, options); fclose(result); - if (ret == HTTP_OK && finalize_object_file(tmpfile.buf, filename)) + if (ret == HTTP_OK && finalize_object_file(the_repository, tmpfile.buf, filename)) ret = HTTP_ERROR; cleanup: strbuf_release(&tmpfile); @@ -2815,7 +2816,7 @@ int finish_http_object_request(struct http_object_request *freq) return -1; } odb_loose_path(the_repository->objects->sources, &filename, &freq->oid); - freq->rename = finalize_object_file(freq->tmpfile.buf, filename.buf); + freq->rename = finalize_object_file(the_repository, freq->tmpfile.buf, filename.buf); strbuf_release(&filename); return freq->rename; @@ -272,7 +272,7 @@ static void strbuf_addstr_without_crud(struct strbuf *sb, const char *src) * can still be NULL if the input line only has the name/email part * (e.g. reading from a reflog entry). */ -int split_ident_line(struct ident_split *split, const char *line, int len) +int split_ident_line(struct ident_split *split, const char *line, size_t len) { const char *cp; size_t span; @@ -35,7 +35,7 @@ void reset_ident_date(void); * Signals an success with 0, but time part of the result may be NULL * if the input lacks timestamp and zone */ -int split_ident_line(struct ident_split *, const char *, int); +int split_ident_line(struct ident_split *, const char *, size_t); /* * Given a commit or tag object buffer and the commit or tag headers, replaces diff --git a/imap-send.c b/imap-send.c index f5a656ac71..254ec83ab7 100644 --- a/imap-send.c +++ b/imap-send.c @@ -28,6 +28,7 @@ #include "advice.h" #include "config.h" #include "credential.h" +#include "environment.h" #include "gettext.h" #include "run-command.h" #include "parse-options.h" @@ -1776,7 +1777,7 @@ int cmd_main(int argc, const char **argv) int ret; setup_git_directory_gently(&nongit_ok); - git_config(git_imap_config, &server); + repo_config(the_repository, git_imap_config, &server); argc = parse_options(argc, (const char **)argv, "", imap_send_options, imap_send_usage, 0); diff --git a/line-log.c b/line-log.c index 07f2154e84..188d387d40 100644 --- a/line-log.c +++ b/line-log.c @@ -1087,13 +1087,6 @@ static struct diff_filepair *diff_filepair_dup(struct diff_filepair *pair) return new_filepair; } -static void free_diffqueues(int n, struct diff_queue_struct *dq) -{ - for (int i = 0; i < n; i++) - diff_queue_clear(&dq[i]); - free(dq); -} - static int process_all_files(struct line_log_data **range_out, struct rev_info *rev, struct diff_queue_struct *queue, @@ -1189,7 +1182,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c struct line_log_data *range) { struct commit *parent = NULL; - struct diff_queue_struct queue; + struct diff_queue_struct queue = DIFF_QUEUE_INIT; struct line_log_data *parent_range; int changed; @@ -1209,9 +1202,7 @@ static int process_ranges_ordinary_commit(struct rev_info *rev, struct commit *c static int process_ranges_merge_commit(struct rev_info *rev, struct commit *commit, struct line_log_data *range) { - struct diff_queue_struct *diffqueues; struct line_log_data **cand; - struct commit **parents; struct commit_list *p; int i; int nparents = commit_list_count(commit->parents); @@ -1220,28 +1211,27 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm if (nparents > 1 && rev->first_parent_only) nparents = 1; - ALLOC_ARRAY(diffqueues, nparents); CALLOC_ARRAY(cand, nparents); - ALLOC_ARRAY(parents, nparents); - - p = commit->parents; - for (i = 0; i < nparents; i++) { - parents[i] = p->item; - p = p->next; - queue_diffs(range, &rev->diffopt, &diffqueues[i], commit, parents[i]); - } - for (i = 0; i < nparents; i++) { + for (p = commit->parents, i = 0; + p && i < nparents; + p = p->next, i++) { + struct commit *parent = p->item; + struct diff_queue_struct diffqueue = DIFF_QUEUE_INIT; int changed; - changed = process_all_files(&cand[i], rev, &diffqueues[i], range); + + queue_diffs(range, &rev->diffopt, &diffqueue, commit, parent); + + changed = process_all_files(&cand[i], rev, &diffqueue, range); + diff_queue_clear(&diffqueue); if (!changed) { /* * This parent can take all the blame, so we * don't follow any other path in history */ - add_line_range(rev, parents[i], cand[i]); + add_line_range(rev, parent, cand[i]); free_commit_list(commit->parents); - commit_list_append(parents[i], &commit->parents); + commit_list_append(parent, &commit->parents); ret = 0; goto out; @@ -1252,14 +1242,15 @@ static int process_ranges_merge_commit(struct rev_info *rev, struct commit *comm * No single parent took the blame. We add the candidates * from the above loop to the parents. */ - for (i = 0; i < nparents; i++) - add_line_range(rev, parents[i], cand[i]); + for (p = commit->parents, i = 0; + p && i < nparents; + p = p->next, i++) + add_line_range(rev, p->item, cand[i]); ret = 1; out: clear_commit_line_range(rev, commit); - free(parents); for (i = 0; i < nparents; i++) { if (!cand[i]) continue; @@ -1267,7 +1258,6 @@ out: free(cand[i]); } free(cand); - free_diffqueues(nparents, diffqueues); return ret; /* NEEDSWORK evil merge detection stuff */ @@ -1283,10 +1273,10 @@ int line_log_process_ranges_arbitrary_commit(struct rev_info *rev, struct commit struct line_log_data *prange = line_log_data_copy(range); add_line_range(rev, commit->parents->item, prange); clear_commit_line_range(rev, commit); - } else if (!commit->parents || !commit->parents->next) - changed = process_ranges_ordinary_commit(rev, commit, range); - else + } else if (commit->parents && commit->parents->next) changed = process_ranges_merge_commit(rev, commit, range); + else + changed = process_ranges_ordinary_commit(rev, commit, range); } if (!changed) diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index 948376d42d..7420bf81fe 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -350,7 +350,7 @@ void partial_clone_register( /* Add promisor config for the remote */ cfg_name = xstrfmt("remote.%s.promisor", remote); - git_config_set(cfg_name, "true"); + repo_config_set(the_repository, cfg_name, "true"); free(cfg_name); } @@ -360,8 +360,8 @@ void partial_clone_register( */ filter_name = xstrfmt("remote.%s.partialclonefilter", remote); /* NEEDSWORK: 'expand' result leaking??? */ - git_config_set(filter_name, - expand_list_objects_filter_spec(filter_options)); + repo_config_set(the_repository, filter_name, + expand_list_objects_filter_spec(filter_options)); free(filter_name); /* Make sure the config info are reset */ @@ -166,7 +166,8 @@ errout: return -1; } -static int write_one_object(struct repository *repo, const struct object_id *oid, +static int write_one_object(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid) { struct lock_file lock; @@ -174,7 +175,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid struct stat st; struct strbuf buf = STRBUF_INIT, path = STRBUF_INIT; - repo_common_path_replace(repo, &path, "objects/loose-object-idx"); + strbuf_addf(&path, "%s/loose-object-idx", source->path); hold_lock_file_for_update_timeout(&lock, path.buf, LOCK_DIE_ON_ERROR, -1); fd = open(path.buf, O_WRONLY | O_CREAT | O_APPEND, 0666); @@ -190,7 +191,7 @@ static int write_one_object(struct repository *repo, const struct object_id *oid goto errout; if (close(fd)) goto errout; - adjust_shared_perm(repo, path.buf); + adjust_shared_perm(source->odb->repo, path.buf); rollback_lock_file(&lock); strbuf_release(&buf); strbuf_release(&path); @@ -204,17 +205,18 @@ errout: return -1; } -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid, +int repo_add_loose_object_map(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid) { int inserted = 0; - if (!should_use_loose_object_map(repo)) + if (!should_use_loose_object_map(source->odb->repo)) return 0; - inserted = insert_loose_map(repo->objects->sources, oid, compat_oid); + inserted = insert_loose_map(source, oid, compat_oid); if (inserted) - return write_one_object(repo, oid, compat_oid); + return write_one_object(source, oid, compat_oid); return 0; } @@ -4,6 +4,7 @@ #include "khash.h" struct repository; +struct odb_source; struct loose_object_map { kh_oid_map_t *to_compat; @@ -16,7 +17,8 @@ int repo_loose_object_map_oid(struct repository *repo, const struct object_id *src, const struct git_hash_algo *dest_algo, struct object_id *dest); -int repo_add_loose_object_map(struct repository *repo, const struct object_id *oid, +int repo_add_loose_object_map(struct odb_source *source, + const struct object_id *oid, const struct object_id *compat_oid); int repo_read_loose_object_map(struct repository *repo); int repo_write_loose_object_map(struct repository *repo); @@ -159,7 +159,7 @@ int ls_refs(struct repository *r, struct packet_reader *request) strbuf_init(&data.buf, 0); strvec_init(&data.hidden_refs); - git_config(ls_refs_config, &data); + repo_config(the_repository, ls_refs_config, &data); while (packet_reader_read(request) == PACKET_READ_NORMAL) { const char *arg = request->line; diff --git a/mailinfo.c b/mailinfo.c index b4e815b2d8..99ac596e09 100644 --- a/mailinfo.c +++ b/mailinfo.c @@ -2,6 +2,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "hex-ll.h" #include "utf8.h" diff --git a/match-trees.c b/match-trees.c index 5a8a5c39b0..4216933d06 100644 --- a/match-trees.c +++ b/match-trees.c @@ -246,7 +246,7 @@ static int splice_tree(struct repository *r, rewrite_with = oid2; } hashcpy(rewrite_here, rewrite_with->hash, r->hash_algo); - status = write_object_file(buf, sz, OBJ_TREE, result); + status = odb_write_object(r->objects, buf, sz, OBJ_TREE, result); free(buf); return status; } diff --git a/merge-ll.c b/merge-ll.c index b2dc26da4f..fafe2c9197 100644 --- a/merge-ll.c +++ b/merge-ll.c @@ -357,7 +357,7 @@ static void initialize_ll_merge(void) if (ll_user_merge_tail) return; ll_user_merge_tail = &ll_user_merge; - git_config(read_merge_config, NULL); + repo_config(the_repository, read_merge_config, NULL); } static const struct ll_merge_driver *find_ll_merge_driver(const char *merge_attr) diff --git a/merge-ort.c b/merge-ort.c index 473ff61e36..29858074f9 100644 --- a/merge-ort.c +++ b/merge-ort.c @@ -316,9 +316,14 @@ struct merge_options_internal { * (e.g. "drivers/firmware/raspberrypi.c"). * * store all relevant paths in the repo, both directories and * files (e.g. drivers, drivers/firmware would also be included) - * * these keys serve to intern all the path strings, which allows - * us to do pointer comparison on directory names instead of - * strcmp; we just have to be careful to use the interned strings. + * * these keys serve to intern *all* path strings, which allows us + * to do pointer comparisons on file & directory names instead of + * using strcmp; however, for this pointer-comparison optimization + * to work, any code path that independently computes a path needs + * to check for it existing in this strmap, and if so, point to + * the path in this strmap instead of their computed copy. See + * the "reuse known pointer" comment in + * apply_directory_rename_modifications() for an example. * * The values of paths: * * either a pointer to a merged_info, or a conflict_info struct @@ -2163,7 +2168,7 @@ static int handle_content_merge(struct merge_options *opt, /* * FIXME: If opt->priv->call_depth && !clean, then we really * should not make result->mode match either a->mode or - * b->mode; that causes t6036 "check conflicting mode for + * b->mode; that causes t6416 "check conflicting mode for * regular file" to fail. It would be best to use some other * mode, but we'll confuse all kinds of stuff if we use one * where S_ISREG(result->mode) isn't true, and if we use @@ -2216,8 +2221,8 @@ static int handle_content_merge(struct merge_options *opt, } if (!ret && record_object && - write_object_file(result_buf.ptr, result_buf.size, - OBJ_BLOB, &result->oid)) { + odb_write_object(the_repository->objects, result_buf.ptr, result_buf.size, + OBJ_BLOB, &result->oid)) { path_msg(opt, ERROR_OBJECT_WRITE_FAILED, 0, pathnames[0], pathnames[1], pathnames[2], NULL, _("error: unable to add %s to database"), path); @@ -2313,14 +2318,20 @@ static char *apply_dir_rename(struct strmap_entry *rename_info, return strbuf_detach(&new_path, NULL); } -static int path_in_way(struct strmap *paths, const char *path, unsigned side_mask) +static int path_in_way(struct strmap *paths, + const char *path, + unsigned side_mask, + struct diff_filepair *p) { struct merged_info *mi = strmap_get(paths, path); struct conflict_info *ci; if (!mi) return 0; INITIALIZE_CI(ci, mi); - return mi->clean || (side_mask & (ci->filemask | ci->dirmask)); + return mi->clean || (side_mask & (ci->filemask | ci->dirmask)) + /* See testcases 12[npq] of t6423 for this next condition */ + || ((ci->filemask & 0x01) && + strcmp(p->one->path, path)); } /* @@ -2332,6 +2343,7 @@ static int path_in_way(struct strmap *paths, const char *path, unsigned side_mas static char *handle_path_level_conflicts(struct merge_options *opt, const char *path, unsigned side_index, + struct diff_filepair *p, struct strmap_entry *rename_info, struct strmap *collisions) { @@ -2366,7 +2378,7 @@ static char *handle_path_level_conflicts(struct merge_options *opt, */ if (c_info->reported_already) { clean = 0; - } else if (path_in_way(&opt->priv->paths, new_path, 1 << side_index)) { + } else if (path_in_way(&opt->priv->paths, new_path, 1 << side_index, p)) { c_info->reported_already = 1; strbuf_add_separated_string_list(&collision_paths, ", ", &c_info->source_files); @@ -2520,7 +2532,7 @@ static void compute_collisions(struct strmap *collisions, * happening, and fall back to no-directory-rename detection * behavior for those paths. * - * See testcases 9e and all of section 5 from t6043 for examples. + * See testcases 9e and all of section 5 from t6423 for examples. */ for (i = 0; i < pairs->nr; ++i) { struct strmap_entry *rename_info; @@ -2573,6 +2585,7 @@ static void free_collisions(struct strmap *collisions) static char *check_for_directory_rename(struct merge_options *opt, const char *path, unsigned side_index, + struct diff_filepair *p, struct strmap *dir_renames, struct strmap *dir_rename_exclusions, struct strmap *collisions, @@ -2580,7 +2593,6 @@ static char *check_for_directory_rename(struct merge_options *opt, { char *new_path; struct strmap_entry *rename_info; - struct strmap_entry *otherinfo; const char *new_dir; int other_side = 3 - side_index; @@ -2615,14 +2627,13 @@ static char *check_for_directory_rename(struct merge_options *opt, * to not let Side1 do the rename to dumbdir, since we know that is * the source of one of our directory renames. * - * That's why otherinfo and dir_rename_exclusions is here. + * That's why dir_rename_exclusions is here. * * As it turns out, this also prevents N-way transient rename - * confusion; See testcases 9c and 9d of t6043. + * confusion; See testcases 9c and 9d of t6423. */ new_dir = rename_info->value; /* old_dir = rename_info->key; */ - otherinfo = strmap_get_entry(dir_rename_exclusions, new_dir); - if (otherinfo) { + if (strmap_contains(dir_rename_exclusions, new_dir)) { path_msg(opt, INFO_DIR_RENAME_SKIPPED_DUE_TO_RERENAME, 1, rename_info->key, path, new_dir, NULL, _("WARNING: Avoiding applying %s -> %s rename " @@ -2631,7 +2642,7 @@ static char *check_for_directory_rename(struct merge_options *opt, return NULL; } - new_path = handle_path_level_conflicts(opt, path, side_index, + new_path = handle_path_level_conflicts(opt, path, side_index, p, rename_info, &collisions[side_index]); *clean_merge &= (new_path != NULL); @@ -2876,6 +2887,20 @@ static int process_renames(struct merge_options *opt, } /* + * Directory renames can result in rename-to-self; the code + * below assumes we have A->B with different A & B, and tries + * to move all entries to path B. If A & B are the same path, + * the logic can get confused, so skip further processing when + * A & B are already the same path. + * + * As a reminder, we can avoid strcmp here because all paths + * are interned in opt->priv->paths; see the comment above + * "paths" in struct merge_options_internal. + */ + if (oldpath == newpath) + continue; + + /* * If pair->one->path isn't in opt->priv->paths, that means * that either directory rename detection removed that * path, or a parent directory of oldpath was resolved and @@ -3419,7 +3444,7 @@ static int collect_renames(struct merge_options *opt, } new_path = check_for_directory_rename(opt, p->two->path, - side_index, + side_index, p, dir_renames_for_side, rename_exclusions, collisions, @@ -3772,7 +3797,8 @@ static int write_tree(struct object_id *result_oid, } /* Write this object file out, and record in result_oid */ - if (write_object_file(buf.buf, buf.len, OBJ_TREE, result_oid)) + if (odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_TREE, result_oid)) ret = -1; strbuf_release(&buf); return ret; @@ -5353,20 +5379,20 @@ static void merge_recursive_config(struct merge_options *opt, int ui) { char *value = NULL; int renormalize = 0; - git_config_get_int("merge.verbosity", &opt->verbosity); - git_config_get_int("diff.renamelimit", &opt->rename_limit); - git_config_get_int("merge.renamelimit", &opt->rename_limit); - git_config_get_bool("merge.renormalize", &renormalize); + repo_config_get_int(the_repository, "merge.verbosity", &opt->verbosity); + repo_config_get_int(the_repository, "diff.renamelimit", &opt->rename_limit); + repo_config_get_int(the_repository, "merge.renamelimit", &opt->rename_limit); + repo_config_get_bool(the_repository, "merge.renormalize", &renormalize); opt->renormalize = renormalize; - if (!git_config_get_string("diff.renames", &value)) { + if (!repo_config_get_string(the_repository, "diff.renames", &value)) { opt->detect_renames = git_config_rename("diff.renames", value); free(value); } - if (!git_config_get_string("merge.renames", &value)) { + if (!repo_config_get_string(the_repository, "merge.renames", &value)) { opt->detect_renames = git_config_rename("merge.renames", value); free(value); } - if (!git_config_get_string("merge.directoryrenames", &value)) { + if (!repo_config_get_string(the_repository, "merge.directoryrenames", &value)) { int boolval = git_parse_maybe_bool(value); if (0 <= boolval) { opt->detect_directory_renames = boolval ? @@ -5379,7 +5405,7 @@ static void merge_recursive_config(struct merge_options *opt, int ui) free(value); } if (ui) { - if (!git_config_get_string("diff.algorithm", &value)) { + if (!repo_config_get_string(the_repository, "diff.algorithm", &value)) { long diff_algorithm = parse_algorithm_value(value); if (diff_algorithm < 0) die(_("unknown value for config '%s': %s"), "diff.algorithm", value); @@ -5387,7 +5413,7 @@ static void merge_recursive_config(struct merge_options *opt, int ui) free(value); } } - git_config(git_xmerge_config, NULL); + repo_config(the_repository, git_xmerge_config, NULL); } static void init_merge_options(struct merge_options *opt, diff --git a/meson.build b/meson.build index 77a3416b1c..b3dfcc0497 100644 --- a/meson.build +++ b/meson.build @@ -646,6 +646,7 @@ builtin_sources = [ 'builtin/repack.c', 'builtin/replace.c', 'builtin/replay.c', + 'builtin/repo.c', 'builtin/rerere.c', 'builtin/reset.c', 'builtin/rev-list.c', @@ -695,9 +696,14 @@ third_party_excludes = [ headers_to_check = [] if git.found() and fs.exists(meson.project_source_root() / '.git') - foreach header : run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: true).stdout().split() - headers_to_check += header - endforeach + ls_headers = run_command(git, '-C', meson.project_source_root(), 'ls-files', '--deduplicate', '*.h', third_party_excludes, check: false) + if ls_headers.returncode() == 0 + foreach header : ls_headers.stdout().split() + headers_to_check += header + endforeach + else + warning('could not list headers, disabling static analysis targets') + endif endif if not get_option('breaking_changes') @@ -1058,7 +1064,33 @@ else build_options_config.set('NO_ICONV', '1') endif -pcre2 = dependency('libpcre2-8', required: get_option('pcre2'), default_options: ['default_library=static', 'test=false']) +# can't use enable_auto_if() because it is only available in meson 1.1 +if host_machine.system() == 'windows' and get_option('pcre2').allowed() + pcre2_feature = true +else + pcre2_feature = get_option('pcre2') +endif +pcre2 = dependency('libpcre2-8', required: pcre2_feature, default_options: ['default_library=static', 'test=false']) +if pcre2.found() and pcre2.type_name() != 'internal' and host_machine.system() == 'darwin' + # macOS installs a broken system package, double check + if not compiler.has_header('pcre2.h', dependencies: pcre2) + if pcre2_feature.enabled() + pcre2_fallback = ['pcre2', 'libpcre2_8'] + else + pcre2_fallback = [] + endif + # Attempt to fallback or replace with not-found-dependency + pcre2 = dependency('', required: false, fallback: pcre2_fallback, default_options: ['default_library=static', 'test=false']) + if not pcre2.found() + if pcre2_feature.enabled() + error('only a broken pcre2 install found and pcre2 is required') + else + warning('broken pcre2 install found, disabling pcre2 feature') + endif + endif + endif +endif + if pcre2.found() libgit_dependencies += pcre2 libgit_c_args += '-DUSE_LIBPCRE2' diff --git a/meson_options.txt b/meson_options.txt index e7f768df24..1668f260a1 100644 --- a/meson_options.txt +++ b/meson_options.txt @@ -45,7 +45,7 @@ option('gitweb', type: 'feature', value: 'auto', description: 'Build Git web interface. Requires Perl.') option('iconv', type: 'feature', value: 'auto', description: 'Support reencoding strings with different encodings.') -option('pcre2', type: 'feature', value: 'enabled', +option('pcre2', type: 'feature', value: 'auto', description: 'Support Perl-compatible regular expressions in e.g. git-grep(1).') option('perl', type: 'feature', value: 'auto', description: 'Build tools written in Perl.') diff --git a/midx-write.c b/midx-write.c index f2cfb85476..a0aceab5e0 100644 --- a/midx-write.c +++ b/midx-write.c @@ -667,7 +667,7 @@ static void write_midx_reverse_index(struct write_midx_context *ctx, tmp_file = write_rev_file_order(ctx->repo, NULL, ctx->pack_order, ctx->entries_nr, midx_hash, WRITE_REV); - if (finalize_object_file(tmp_file, buf.buf)) + if (finalize_object_file(ctx->repo, tmp_file, buf.buf)) die(_("cannot store reverse index file")); strbuf_release(&buf); @@ -916,26 +916,8 @@ cleanup: static struct multi_pack_index *lookup_multi_pack_index(struct repository *r, const char *object_dir) { - struct multi_pack_index *result = NULL; - struct multi_pack_index *cur; - char *obj_dir_real = real_pathdup(object_dir, 1); - struct strbuf cur_path_real = STRBUF_INIT; - - /* Ensure the given object_dir is local, or a known alternate. */ - odb_find_source(r->objects, obj_dir_real); - - for (cur = get_multi_pack_index(r); cur; cur = cur->next) { - strbuf_realpath(&cur_path_real, cur->object_dir, 1); - if (!strcmp(obj_dir_real, cur_path_real.buf)) { - result = cur; - goto cleanup; - } - } - -cleanup: - free(obj_dir_real); - strbuf_release(&cur_path_real); - return result; + struct odb_source *source = odb_find_source(r->objects, object_dir); + return get_multi_pack_index(source); } static int fill_packs_from_midx(struct write_midx_context *ctx, @@ -401,7 +401,6 @@ void close_midx(struct multi_pack_index *m) if (!m) return; - close_midx(m->next); close_midx(m->base_midx); munmap((unsigned char *)m->data, m->data_len); @@ -724,32 +723,20 @@ int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id) return 0; } -int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local) +int prepare_multi_pack_index_one(struct odb_source *source, int local) { - struct multi_pack_index *m; - struct multi_pack_index *m_search; + struct repository *r = source->odb->repo; prepare_repo_settings(r); if (!r->settings.core_multi_pack_index) return 0; - for (m_search = r->objects->multi_pack_index; m_search; m_search = m_search->next) - if (!strcmp(object_dir, m_search->object_dir)) - return 1; - - m = load_multi_pack_index(r, object_dir, local); - - if (m) { - struct multi_pack_index *mp = r->objects->multi_pack_index; - if (mp) { - m->next = mp->next; - mp->next = m; - } else - r->objects->multi_pack_index = m; + if (source->midx) return 1; - } - return 0; + source->midx = load_multi_pack_index(r, source->path, local); + + return !!source->midx; } int midx_checksum_valid(struct multi_pack_index *m) @@ -834,9 +821,14 @@ void clear_midx_file(struct repository *r) get_midx_filename(r->hash_algo, &midx, r->objects->sources->path); - if (r->objects && r->objects->multi_pack_index) { - close_midx(r->objects->multi_pack_index); - r->objects->multi_pack_index = NULL; + if (r->objects) { + struct odb_source *source; + + for (source = r->objects->sources; source; source = source->next) { + if (source->midx) + close_midx(source->midx); + source->midx = NULL; + } } if (remove_path(midx.buf)) @@ -8,6 +8,7 @@ struct pack_entry; struct repository; struct bitmapped_pack; struct git_hash_algo; +struct odb_source; #define MIDX_SIGNATURE 0x4d494458 /* "MIDX" */ #define MIDX_VERSION 1 @@ -34,8 +35,6 @@ struct git_hash_algo; "GIT_TEST_MULTI_PACK_INDEX_WRITE_INCREMENTAL" struct multi_pack_index { - struct multi_pack_index *next; - const unsigned char *data; size_t data_len; @@ -123,7 +122,7 @@ int fill_midx_entry(struct repository *r, const struct object_id *oid, struct pa int midx_contains_pack(struct multi_pack_index *m, const char *idx_or_pack_name); int midx_preferred_pack(struct multi_pack_index *m, uint32_t *pack_int_id); -int prepare_multi_pack_index_one(struct repository *r, const char *object_dir, int local); +int prepare_multi_pack_index_one(struct odb_source *source, int local); /* * Variant of write_midx_file which writes a MIDX containing only the packs diff --git a/notes-cache.c b/notes-cache.c index dd56feed6e..bf5bb1f6c1 100644 --- a/notes-cache.c +++ b/notes-cache.c @@ -98,7 +98,8 @@ int notes_cache_put(struct notes_cache *c, struct object_id *key_oid, { struct object_id value_oid; - if (write_object_file(data, size, OBJ_BLOB, &value_oid) < 0) + if (odb_write_object(the_repository->objects, data, + size, OBJ_BLOB, &value_oid) < 0) return -1; return add_note(&c->tree, key_oid, &value_oid, NULL); } diff --git a/notes-utils.c b/notes-utils.c index ac66b82dd3..6a50c6d564 100644 --- a/notes-utils.c +++ b/notes-utils.c @@ -162,7 +162,7 @@ struct notes_rewrite_cfg *init_copy_notes_for_rewrite(const char *cmd) c->refs_from_env = 1; string_list_add_refs_from_colon_sep(c->refs, rewrite_refs_env); } - git_config(notes_rewrite_config, c); + repo_config(the_repository, notes_rewrite_config, c); if (!c->enabled || !c->refs->nr) { string_list_clear(c->refs, 0); free(c->refs); @@ -682,7 +682,8 @@ static int tree_write_stack_finish_subtree(struct tree_write_stack *tws) ret = tree_write_stack_finish_subtree(n); if (ret) return ret; - ret = write_object_file(n->buf.buf, n->buf.len, OBJ_TREE, &s); + ret = odb_write_object(the_repository->objects, n->buf.buf, + n->buf.len, OBJ_TREE, &s); if (ret) return ret; strbuf_release(&n->buf); @@ -847,7 +848,8 @@ int combine_notes_concatenate(struct object_id *cur_oid, free(new_msg); /* create a new blob object from buf */ - ret = write_object_file(buf, buf_len, OBJ_BLOB, cur_oid); + ret = odb_write_object(the_repository->objects, buf, + buf_len, OBJ_BLOB, cur_oid); free(buf); return ret; } @@ -892,7 +894,7 @@ static int string_list_add_note_lines(struct string_list *list, * later, along with any empty strings that came from empty * lines within the file. */ - string_list_split(list, data, '\n', -1); + string_list_split(list, data, "\n", -1); free(data); return 0; } @@ -927,7 +929,8 @@ int combine_notes_cat_sort_uniq(struct object_id *cur_oid, string_list_join_lines_helper, &buf)) goto out; - ret = write_object_file(buf.buf, buf.len, OBJ_BLOB, cur_oid); + ret = odb_write_object(the_repository->objects, buf.buf, + buf.len, OBJ_BLOB, cur_oid); out: strbuf_release(&buf); @@ -970,8 +973,8 @@ void string_list_add_refs_from_colon_sep(struct string_list *list, char *globs_copy = xstrdup(globs); int i; - string_list_split_in_place(&split, globs_copy, ":", -1); - string_list_remove_empty_items(&split, 0); + string_list_split_in_place_f(&split, globs_copy, ":", -1, + STRING_LIST_SPLIT_NONEMPTY); for (i = 0; i < split.nr; i++) string_list_add_refs_by_glob(list, split.items[i].string); @@ -1123,7 +1126,7 @@ void load_display_notes(struct display_notes_opt *opt) load_config_refs = 1; } - git_config(notes_display_config, &load_config_refs); + repo_config(the_repository, notes_display_config, &load_config_refs); if (opt) { struct string_list_item *item; @@ -1215,7 +1218,8 @@ int write_notes_tree(struct notes_tree *t, struct object_id *result) ret = for_each_note(t, flags, write_each_note, &cb_data) || write_each_non_note_until(NULL, &cb_data) || tree_write_stack_finish_subtree(&root) || - write_object_file(root.buf.buf, root.buf.len, OBJ_TREE, result); + odb_write_object(the_repository->objects, root.buf.buf, + root.buf.len, OBJ_TREE, result); strbuf_release(&root.buf); return ret; } diff --git a/object-file.c b/object-file.c index 3d674d1093..2bc36ab3ee 100644 --- a/object-file.c +++ b/object-file.c @@ -8,7 +8,6 @@ */ #define USE_THE_REPOSITORY_VARIABLE -#define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" #include "bulk-checkin.h" @@ -26,6 +25,7 @@ #include "pack.h" #include "packfile.h" #include "path.h" +#include "read-cache-ll.h" #include "setup.h" #include "streaming.h" @@ -42,10 +42,11 @@ static int get_conv_flags(unsigned flags) return 0; } -static void fill_loose_path(struct strbuf *buf, const struct object_id *oid) +static void fill_loose_path(struct strbuf *buf, + const struct object_id *oid, + const struct git_hash_algo *algop) { - int i; - for (i = 0; i < the_hash_algo->rawsz; i++) { + for (size_t i = 0; i < algop->rawsz; i++) { static char hex[] = "0123456789abcdef"; unsigned int val = oid->hash[i]; strbuf_addch(buf, hex[val >> 4]); @@ -62,7 +63,7 @@ const char *odb_loose_path(struct odb_source *source, strbuf_reset(buf); strbuf_addstr(buf, source->path); strbuf_addch(buf, '/'); - fill_loose_path(buf, oid); + fill_loose_path(buf, oid, source->odb->repo->hash_algo); return buf->buf; } @@ -88,46 +89,19 @@ int check_and_freshen_file(const char *fn, int freshen) return 1; } -static int check_and_freshen_odb(struct odb_source *source, - const struct object_id *oid, - int freshen) +static int check_and_freshen_source(struct odb_source *source, + const struct object_id *oid, + int freshen) { static struct strbuf path = STRBUF_INIT; odb_loose_path(source, &path, oid); return check_and_freshen_file(path.buf, freshen); } -static int check_and_freshen_local(const struct object_id *oid, int freshen) +int has_loose_object(struct odb_source *source, + const struct object_id *oid) { - return check_and_freshen_odb(the_repository->objects->sources, oid, freshen); -} - -static int check_and_freshen_nonlocal(const struct object_id *oid, int freshen) -{ - struct odb_source *source; - - odb_prepare_alternates(the_repository->objects); - for (source = the_repository->objects->sources->next; source; source = source->next) { - if (check_and_freshen_odb(source, oid, freshen)) - return 1; - } - return 0; -} - -static int check_and_freshen(const struct object_id *oid, int freshen) -{ - return check_and_freshen_local(oid, freshen) || - check_and_freshen_nonlocal(oid, freshen); -} - -int has_loose_object_nonlocal(const struct object_id *oid) -{ - return check_and_freshen_nonlocal(oid, 0); -} - -int has_loose_object(const struct object_id *oid) -{ - return check_and_freshen(oid, 0); + return check_and_freshen_source(source, oid, 0); } int format_object_header(char *str, size_t size, enum object_type type, @@ -327,9 +301,8 @@ static void *unpack_loose_rest(git_zstream *stream, void *buffer, unsigned long size, const struct object_id *oid) { - int bytes = strlen(buffer) + 1; + size_t bytes = strlen(buffer) + 1, n; unsigned char *buf = xmallocz(size); - unsigned long n; int status = Z_OK; n = stream->total_out - bytes; @@ -448,7 +421,7 @@ int loose_object_info(struct repository *r, enum object_type type_scratch; if (oi->delta_base_oid) - oidclr(oi->delta_base_oid, the_repository->hash_algo); + oidclr(oi->delta_base_oid, r->hash_algo); /* * If we don't care about type or size, then we don't @@ -596,7 +569,7 @@ static int check_collision(const char *source, const char *dest) goto out; } - if (sz_a < sizeof(buf_source)) + if ((size_t) sz_a < sizeof(buf_source)) break; } @@ -611,12 +584,14 @@ out: /* * Move the just written object into its final resting place. */ -int finalize_object_file(const char *tmpfile, const char *filename) +int finalize_object_file(struct repository *repo, + const char *tmpfile, const char *filename) { - return finalize_object_file_flags(tmpfile, filename, 0); + return finalize_object_file_flags(repo, tmpfile, filename, 0); } -int finalize_object_file_flags(const char *tmpfile, const char *filename, +int finalize_object_file_flags(struct repository *repo, + const char *tmpfile, const char *filename, enum finalize_object_file_flags flags) { unsigned retries = 0; @@ -676,7 +651,7 @@ retry: } out: - if (adjust_shared_perm(the_repository, filename)) + if (adjust_shared_perm(repo, filename)) return error(_("unable to set permission to '%s'"), filename); return 0; } @@ -692,9 +667,10 @@ void hash_object_file(const struct git_hash_algo *algo, const void *buf, } /* Finalize a file on disk, and close it. */ -static void close_loose_object(int fd, const char *filename) +static void close_loose_object(struct odb_source *source, + int fd, const char *filename) { - if (the_repository->objects->sources->will_destroy) + if (source->will_destroy) goto out; if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) @@ -726,7 +702,8 @@ static inline int directory_size(const char *filename) * We want to avoid cross-directory filename renames, because those * can have problems on various filesystems (FAT, NFS, Coda). */ -static int create_tmpfile(struct strbuf *tmp, const char *filename) +static int create_tmpfile(struct repository *repo, + struct strbuf *tmp, const char *filename) { int fd, dirlen = directory_size(filename); @@ -745,7 +722,7 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) strbuf_add(tmp, filename, dirlen - 1); if (mkdir(tmp->buf, 0777) && errno != EEXIST) return -1; - if (adjust_shared_perm(the_repository, tmp->buf)) + if (adjust_shared_perm(repo, tmp->buf)) return -1; /* Try again */ @@ -766,26 +743,26 @@ static int create_tmpfile(struct strbuf *tmp, const char *filename) * Returns a "fd", which should later be provided to * end_loose_object_common(). */ -static int start_loose_object_common(struct strbuf *tmp_file, +static int start_loose_object_common(struct odb_source *source, + struct strbuf *tmp_file, const char *filename, unsigned flags, git_zstream *stream, unsigned char *buf, size_t buflen, struct git_hash_ctx *c, struct git_hash_ctx *compat_c, char *hdr, int hdrlen) { - struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *algo = source->odb->repo->hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int fd; - fd = create_tmpfile(tmp_file, filename); + fd = create_tmpfile(source->odb->repo, tmp_file, filename); if (fd < 0) { - if (flags & WRITE_OBJECT_FILE_SILENT) + if (flags & WRITE_OBJECT_SILENT) return -1; else if (errno == EACCES) return error(_("insufficient permission for adding " "an object to repository database %s"), - repo_get_object_directory(the_repository)); + source->path); else return error_errno( _("unable to create temporary file")); @@ -815,14 +792,14 @@ static int start_loose_object_common(struct strbuf *tmp_file, * Common steps for the inner git_deflate() loop for writing loose * objects. Returns what git_deflate() returns. */ -static int write_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, +static int write_loose_object_common(struct odb_source *source, + struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, const int flush, unsigned char *in0, const int fd, unsigned char *compressed, const size_t compressed_len) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int ret; ret = git_deflate(stream, flush ? Z_FINISH : 0); @@ -843,12 +820,12 @@ static int write_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx * - End the compression of zlib stream. * - Get the calculated oid to "oid". */ -static int end_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx *compat_c, +static int end_loose_object_common(struct odb_source *source, + struct git_hash_ctx *c, struct git_hash_ctx *compat_c, git_zstream *stream, struct object_id *oid, struct object_id *compat_oid) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; int ret; ret = git_deflate_end_gently(stream); @@ -861,7 +838,8 @@ static int end_loose_object_common(struct git_hash_ctx *c, struct git_hash_ctx * return Z_OK; } -static int write_loose_object(const struct object_id *oid, char *hdr, +static int write_loose_object(struct odb_source *source, + const struct object_id *oid, char *hdr, int hdrlen, const void *buf, unsigned long len, time_t mtime, unsigned flags) { @@ -876,9 +854,9 @@ static int write_loose_object(const struct object_id *oid, char *hdr, if (batch_fsync_enabled(FSYNC_COMPONENT_LOOSE_OBJECT)) prepare_loose_object_bulk_checkin(); - odb_loose_path(the_repository->objects->sources, &filename, oid); + odb_loose_path(source, &filename, oid); - fd = start_loose_object_common(&tmp_file, filename.buf, flags, + fd = start_loose_object_common(source, &tmp_file, filename.buf, flags, &stream, compressed, sizeof(compressed), &c, NULL, hdr, hdrlen); if (fd < 0) @@ -890,14 +868,14 @@ static int write_loose_object(const struct object_id *oid, char *hdr, do { unsigned char *in0 = stream.next_in; - ret = write_loose_object_common(&c, NULL, &stream, 1, in0, fd, + ret = write_loose_object_common(source, &c, NULL, &stream, 1, in0, fd, compressed, sizeof(compressed)); } while (ret == Z_OK); if (ret != Z_STREAM_END) die(_("unable to deflate new object %s (%d)"), oid_to_hex(oid), ret); - ret = end_loose_object_common(&c, NULL, &stream, ¶no_oid, NULL); + ret = end_loose_object_common(source, &c, NULL, &stream, ¶no_oid, NULL); if (ret != Z_OK) die(_("deflateEnd on object %s failed (%d)"), oid_to_hex(oid), ret); @@ -905,30 +883,36 @@ static int write_loose_object(const struct object_id *oid, char *hdr, die(_("confused by unstable object source data for %s"), oid_to_hex(oid)); - close_loose_object(fd, tmp_file.buf); + close_loose_object(source, fd, tmp_file.buf); if (mtime) { struct utimbuf utb; utb.actime = mtime; utb.modtime = mtime; if (utime(tmp_file.buf, &utb) < 0 && - !(flags & WRITE_OBJECT_FILE_SILENT)) + !(flags & WRITE_OBJECT_SILENT)) warning_errno(_("failed utime() on %s"), tmp_file.buf); } - return finalize_object_file_flags(tmp_file.buf, filename.buf, + return finalize_object_file_flags(source->odb->repo, tmp_file.buf, filename.buf, FOF_SKIP_COLLISION_CHECK); } -static int freshen_loose_object(const struct object_id *oid) +static int freshen_loose_object(struct object_database *odb, + const struct object_id *oid) { - return check_and_freshen(oid, 1); + odb_prepare_alternates(odb); + for (struct odb_source *source = odb->sources; source; source = source->next) + if (check_and_freshen_source(source, oid, 1)) + return 1; + return 0; } -static int freshen_packed_object(const struct object_id *oid) +static int freshen_packed_object(struct object_database *odb, + const struct object_id *oid) { struct pack_entry e; - if (!find_pack_entry(the_repository, oid, &e)) + if (!find_pack_entry(odb->repo, oid, &e)) return 0; if (e.p->is_cruft) return 0; @@ -940,10 +924,11 @@ static int freshen_packed_object(const struct object_id *oid) return 1; } -int stream_loose_object(struct input_stream *in_stream, size_t len, +int stream_loose_object(struct odb_source *source, + struct input_stream *in_stream, size_t len, struct object_id *oid) { - const struct git_hash_algo *compat = the_repository->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; struct object_id compat_oid; int fd, ret, err = 0, flush = 0; unsigned char compressed[4096]; @@ -959,7 +944,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, prepare_loose_object_bulk_checkin(); /* Since oid is not determined, save tmp file to odb path. */ - strbuf_addf(&filename, "%s/", repo_get_object_directory(the_repository)); + strbuf_addf(&filename, "%s/", source->path); hdrlen = format_object_header(hdr, sizeof(hdr), OBJ_BLOB, len); /* @@ -970,7 +955,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, * - Setup zlib stream for compression. * - Start to feed header to zlib stream. */ - fd = start_loose_object_common(&tmp_file, filename.buf, 0, + fd = start_loose_object_common(source, &tmp_file, filename.buf, 0, &stream, compressed, sizeof(compressed), &c, &compat_c, hdr, hdrlen); if (fd < 0) { @@ -990,7 +975,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, if (in_stream->is_finished) flush = 1; } - ret = write_loose_object_common(&c, &compat_c, &stream, flush, in0, fd, + ret = write_loose_object_common(source, &c, &compat_c, &stream, flush, in0, fd, compressed, sizeof(compressed)); /* * Unlike write_loose_object(), we do not have the entire @@ -1013,17 +998,18 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, */ if (ret != Z_STREAM_END) die(_("unable to stream deflate new object (%d)"), ret); - ret = end_loose_object_common(&c, &compat_c, &stream, oid, &compat_oid); + ret = end_loose_object_common(source, &c, &compat_c, &stream, oid, &compat_oid); if (ret != Z_OK) die(_("deflateEnd on stream object failed (%d)"), ret); - close_loose_object(fd, tmp_file.buf); + close_loose_object(source, fd, tmp_file.buf); - if (freshen_packed_object(oid) || freshen_loose_object(oid)) { + if (freshen_packed_object(source->odb, oid) || + freshen_loose_object(source->odb, oid)) { unlink_or_warn(tmp_file.buf); goto cleanup; } - odb_loose_path(the_repository->objects->sources, &filename, oid); + odb_loose_path(source, &filename, oid); /* We finally know the object path, and create the missing dir. */ dirlen = directory_size(filename.buf); @@ -1031,7 +1017,7 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, struct strbuf dir = STRBUF_INIT; strbuf_add(&dir, filename.buf, dirlen); - if (safe_create_dir_in_gitdir(the_repository, dir.buf) && + if (safe_create_dir_in_gitdir(source->odb->repo, dir.buf) && errno != EEXIST) { err = error_errno(_("unable to create directory %s"), dir.buf); strbuf_release(&dir); @@ -1040,23 +1026,23 @@ int stream_loose_object(struct input_stream *in_stream, size_t len, strbuf_release(&dir); } - err = finalize_object_file_flags(tmp_file.buf, filename.buf, + err = finalize_object_file_flags(source->odb->repo, tmp_file.buf, filename.buf, FOF_SKIP_COLLISION_CHECK); if (!err && compat) - err = repo_add_loose_object_map(the_repository, oid, &compat_oid); + err = repo_add_loose_object_map(source, oid, &compat_oid); cleanup: strbuf_release(&tmp_file); strbuf_release(&filename); return err; } -int write_object_file_flags(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid, - struct object_id *compat_oid_in, unsigned flags) +int write_object_file(struct odb_source *source, + const void *buf, unsigned long len, + enum object_type type, struct object_id *oid, + struct object_id *compat_oid_in, unsigned flags) { - struct repository *repo = the_repository; - const struct git_hash_algo *algo = repo->hash_algo; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *algo = source->odb->repo->hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; struct object_id compat_oid; char hdr[MAX_HEADER_LEN]; int hdrlen = sizeof(hdr); @@ -1069,7 +1055,7 @@ int write_object_file_flags(const void *buf, unsigned long len, hash_object_file(compat, buf, len, type, &compat_oid); else { struct strbuf converted = STRBUF_INIT; - convert_object_file(the_repository, &converted, algo, compat, + convert_object_file(source->odb->repo, &converted, algo, compat, buf, len, type, 0); hash_object_file(compat, converted.buf, converted.len, type, &compat_oid); @@ -1081,19 +1067,20 @@ int write_object_file_flags(const void *buf, unsigned long len, * it out into .git/objects/??/?{38} file. */ write_object_file_prepare(algo, buf, len, type, oid, hdr, &hdrlen); - if (freshen_packed_object(oid) || freshen_loose_object(oid)) + if (freshen_packed_object(source->odb, oid) || + freshen_loose_object(source->odb, oid)) return 0; - if (write_loose_object(oid, hdr, hdrlen, buf, len, 0, flags)) + if (write_loose_object(source, oid, hdr, hdrlen, buf, len, 0, flags)) return -1; if (compat) - return repo_add_loose_object_map(repo, oid, &compat_oid); + return repo_add_loose_object_map(source, oid, &compat_oid); return 0; } -int force_object_loose(const struct object_id *oid, time_t mtime) +int force_object_loose(struct odb_source *source, + const struct object_id *oid, time_t mtime) { - struct repository *repo = the_repository; - const struct git_hash_algo *compat = repo->compat_hash_algo; + const struct git_hash_algo *compat = source->odb->repo->compat_hash_algo; void *buf; unsigned long len; struct object_info oi = OBJECT_INFO_INIT; @@ -1103,22 +1090,24 @@ int force_object_loose(const struct object_id *oid, time_t mtime) int hdrlen; int ret; - if (has_loose_object(oid)) - return 0; + for (struct odb_source *s = source->odb->sources; s; s = s->next) + if (has_loose_object(s, oid)) + return 0; + oi.typep = &type; oi.sizep = &len; oi.contentp = &buf; - if (odb_read_object_info_extended(the_repository->objects, oid, &oi, 0)) + if (odb_read_object_info_extended(source->odb, oid, &oi, 0)) return error(_("cannot read object for %s"), oid_to_hex(oid)); if (compat) { - if (repo_oid_to_algop(repo, oid, compat, &compat_oid)) + if (repo_oid_to_algop(source->odb->repo, oid, compat, &compat_oid)) return error(_("cannot map object %s to %s"), oid_to_hex(oid), compat->name); } hdrlen = format_object_header(hdr, sizeof(hdr), type, len); - ret = write_loose_object(oid, hdr, hdrlen, buf, len, mtime, 0); + ret = write_loose_object(source, oid, hdr, hdrlen, buf, len, mtime, 0); if (!ret && compat) - ret = repo_add_loose_object_map(the_repository, oid, &compat_oid); + ret = repo_add_loose_object_map(source, oid, &compat_oid); free(buf); return ret; @@ -1168,15 +1157,15 @@ static int index_mem(struct index_state *istate, opts.strict = 1; opts.error_func = hash_format_check_report; - if (fsck_buffer(null_oid(the_hash_algo), type, buf, size, &opts)) + if (fsck_buffer(null_oid(istate->repo->hash_algo), type, buf, size, &opts)) die(_("refusing to create malformed object")); fsck_finish(&opts); } if (write_object) - ret = write_object_file(buf, size, type, oid); + ret = odb_write_object(istate->repo->objects, buf, size, type, oid); else - hash_object_file(the_hash_algo, buf, size, type, oid); + hash_object_file(istate->repo->hash_algo, buf, size, type, oid); strbuf_release(&nbuf); return ret; @@ -1199,10 +1188,10 @@ static int index_stream_convert_blob(struct index_state *istate, get_conv_flags(flags)); if (write_object) - ret = write_object_file(sbuf.buf, sbuf.len, OBJ_BLOB, - oid); + ret = odb_write_object(istate->repo->objects, sbuf.buf, sbuf.len, OBJ_BLOB, + oid); else - hash_object_file(the_hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, + hash_object_file(istate->repo->hash_algo, sbuf.buf, sbuf.len, OBJ_BLOB, oid); strbuf_release(&sbuf); return ret; @@ -1240,7 +1229,7 @@ static int index_core(struct index_state *istate, if (read_result < 0) ret = error_errno(_("read error while indexing %s"), path ? path : "<unknown>"); - else if (read_result != size) + else if ((size_t) read_result != size) ret = error(_("short read while indexing %s"), path ? path : "<unknown>"); else @@ -1268,7 +1257,7 @@ int index_fd(struct index_state *istate, struct object_id *oid, ret = index_stream_convert_blob(istate, oid, fd, path, flags); else if (!S_ISREG(st->st_mode)) ret = index_pipe(istate, oid, fd, type, path, flags); - else if (st->st_size <= repo_settings_get_big_file_threshold(the_repository) || + else if ((st->st_size >= 0 && (size_t) st->st_size <= repo_settings_get_big_file_threshold(istate->repo)) || type != OBJ_BLOB || (path && would_convert_to_git(istate, path))) ret = index_core(istate, oid, fd, xsize_t(st->st_size), @@ -1300,14 +1289,14 @@ int index_path(struct index_state *istate, struct object_id *oid, if (strbuf_readlink(&sb, path, st->st_size)) return error_errno("readlink(\"%s\")", path); if (!(flags & INDEX_WRITE_OBJECT)) - hash_object_file(the_hash_algo, sb.buf, sb.len, + hash_object_file(istate->repo->hash_algo, sb.buf, sb.len, OBJ_BLOB, oid); - else if (write_object_file(sb.buf, sb.len, OBJ_BLOB, oid)) + else if (odb_write_object(istate->repo->objects, sb.buf, sb.len, OBJ_BLOB, oid)) rc = error(_("%s: failed to insert into database"), path); strbuf_release(&sb); break; case S_IFDIR: - return repo_resolve_gitlink_ref(the_repository, path, "HEAD", oid); + return repo_resolve_gitlink_ref(istate->repo, path, "HEAD", oid); default: return error(_("%s: unsupported file type"), path); } @@ -1329,12 +1318,13 @@ int read_pack_header(int fd, struct pack_header *header) return 0; } -int for_each_file_in_obj_subdir(unsigned int subdir_nr, - struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data) +static int for_each_file_in_obj_subdir(unsigned int subdir_nr, + struct strbuf *path, + const struct git_hash_algo *algop, + each_loose_object_fn obj_cb, + each_loose_cruft_fn cruft_cb, + each_loose_subdir_fn subdir_cb, + void *data) { size_t origlen, baselen; DIR *dir; @@ -1367,12 +1357,12 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr, namelen = strlen(de->d_name); strbuf_setlen(path, baselen); strbuf_add(path, de->d_name, namelen); - if (namelen == the_hash_algo->hexsz - 2 && + if (namelen == algop->hexsz - 2 && !hex_to_bytes(oid.hash + 1, de->d_name, - the_hash_algo->rawsz - 1)) { - oid_set_algo(&oid, the_hash_algo); - memset(oid.hash + the_hash_algo->rawsz, 0, - GIT_MAX_RAWSZ - the_hash_algo->rawsz); + algop->rawsz - 1)) { + oid_set_algo(&oid, algop); + memset(oid.hash + algop->rawsz, 0, + GIT_MAX_RAWSZ - algop->rawsz); if (obj_cb) { r = obj_cb(&oid, path->buf, data); if (r) @@ -1398,26 +1388,7 @@ int for_each_file_in_obj_subdir(unsigned int subdir_nr, return r; } -int for_each_loose_file_in_objdir_buf(struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data) -{ - int r = 0; - int i; - - for (i = 0; i < 256; i++) { - r = for_each_file_in_obj_subdir(i, path, obj_cb, cruft_cb, - subdir_cb, data); - if (r) - break; - } - - return r; -} - -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_source(struct odb_source *source, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, @@ -1426,22 +1397,27 @@ int for_each_loose_file_in_objdir(const char *path, struct strbuf buf = STRBUF_INIT; int r; - strbuf_addstr(&buf, path); - r = for_each_loose_file_in_objdir_buf(&buf, obj_cb, cruft_cb, - subdir_cb, data); - strbuf_release(&buf); + strbuf_addstr(&buf, source->path); + for (int i = 0; i < 256; i++) { + r = for_each_file_in_obj_subdir(i, &buf, source->odb->repo->hash_algo, + obj_cb, cruft_cb, subdir_cb, data); + if (r) + break; + } + strbuf_release(&buf); return r; } -int for_each_loose_object(each_loose_object_fn cb, void *data, +int for_each_loose_object(struct object_database *odb, + each_loose_object_fn cb, void *data, enum for_each_object_flags flags) { struct odb_source *source; - odb_prepare_alternates(the_repository->objects); - for (source = the_repository->objects->sources; source; source = source->next) { - int r = for_each_loose_file_in_objdir(source->path, cb, NULL, + odb_prepare_alternates(odb); + for (source = odb->sources; source; source = source->next) { + int r = for_each_loose_file_in_source(source, cb, NULL, NULL, data); if (r) return r; @@ -1472,7 +1448,7 @@ struct oidtree *odb_loose_cache(struct odb_source *source, uint32_t *bitmap; if (subdir_nr < 0 || - subdir_nr >= bitsizeof(source->loose_objects_subdir_seen)) + (size_t) subdir_nr >= bitsizeof(source->loose_objects_subdir_seen)) BUG("subdir_nr out of range"); bitmap = &source->loose_objects_subdir_seen[word_index]; @@ -1484,6 +1460,7 @@ struct oidtree *odb_loose_cache(struct odb_source *source, } strbuf_addstr(&buf, source->path); for_each_file_in_obj_subdir(subdir_nr, &buf, + source->odb->repo->hash_algo, append_loose_object, NULL, NULL, source->loose_objects_cache); @@ -1504,7 +1481,8 @@ static int check_stream_oid(git_zstream *stream, const char *hdr, unsigned long size, const char *path, - const struct object_id *expected_oid) + const struct object_id *expected_oid, + const struct git_hash_algo *algop) { struct git_hash_ctx c; struct object_id real_oid; @@ -1512,7 +1490,7 @@ static int check_stream_oid(git_zstream *stream, unsigned long total_read; int status = Z_OK; - the_hash_algo->init_fn(&c); + algop->init_fn(&c); git_hash_update(&c, hdr, stream->total_out); /* @@ -1557,7 +1535,8 @@ static int check_stream_oid(git_zstream *stream, return 0; } -int read_loose_object(const char *path, +int read_loose_object(struct repository *repo, + const char *path, const struct object_id *expected_oid, struct object_id *real_oid, void **contents, @@ -1596,8 +1575,9 @@ int read_loose_object(const char *path, } if (*oi->typep == OBJ_BLOB && - *size > repo_settings_get_big_file_threshold(the_repository)) { - if (check_stream_oid(&stream, hdr, *size, path, expected_oid) < 0) + *size > repo_settings_get_big_file_threshold(repo)) { + if (check_stream_oid(&stream, hdr, *size, path, expected_oid, + repo->hash_algo) < 0) goto out_inflate; } else { *contents = unpack_loose_rest(&stream, hdr, *size, expected_oid); @@ -1605,7 +1585,7 @@ int read_loose_object(const char *path, error(_("unable to unpack contents of %s"), path); goto out_inflate; } - hash_object_file(the_repository->hash_algo, + hash_object_file(repo->hash_algo, *contents, *size, *oi->typep, real_oid); if (!oideq(expected_oid, real_oid)) diff --git a/object-file.h b/object-file.h index 67b4ffc480..15d97630d3 100644 --- a/object-file.h +++ b/object-file.h @@ -45,13 +45,12 @@ const char *odb_loose_path(struct odb_source *source, const struct object_id *oid); /* - * Return true iff an alternate object database has a loose object + * Return true iff an object database source has a loose object * with the specified name. This function does not respect replace * references. */ -int has_loose_object_nonlocal(const struct object_id *); - -int has_loose_object(const struct object_id *); +int has_loose_object(struct odb_source *source, + const struct object_id *oid); void *map_loose_object(struct repository *r, const struct object_id *oid, unsigned long *size); @@ -87,22 +86,11 @@ typedef int each_loose_cruft_fn(const char *basename, typedef int each_loose_subdir_fn(unsigned int nr, const char *path, void *data); -int for_each_file_in_obj_subdir(unsigned int subdir_nr, - struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data); -int for_each_loose_file_in_objdir(const char *path, +int for_each_loose_file_in_source(struct odb_source *source, each_loose_object_fn obj_cb, each_loose_cruft_fn cruft_cb, each_loose_subdir_fn subdir_cb, void *data); -int for_each_loose_file_in_objdir_buf(struct strbuf *path, - each_loose_object_fn obj_cb, - each_loose_cruft_fn cruft_cb, - each_loose_subdir_fn subdir_cb, - void *data); /* * Iterate over all accessible loose objects without respect to @@ -111,7 +99,8 @@ int for_each_loose_file_in_objdir_buf(struct strbuf *path, * * Any flags specific to packs are ignored. */ -int for_each_loose_object(each_loose_object_fn, void *, +int for_each_loose_object(struct object_database *odb, + each_loose_object_fn, void *, enum for_each_object_flags flags); @@ -157,29 +146,10 @@ enum unpack_loose_header_result unpack_loose_header(git_zstream *stream, struct object_info; int parse_loose_header(const char *hdr, struct object_info *oi); -enum { - /* - * By default, `write_object_file()` does not actually write - * anything into the object store, but only computes the object ID. - * This flag changes that so that the object will be written as a loose - * object and persisted. - */ - WRITE_OBJECT_FILE_PERSIST = (1 << 0), - - /* - * Do not print an error in case something gose wrong. - */ - WRITE_OBJECT_FILE_SILENT = (1 << 1), -}; - -int write_object_file_flags(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid, - struct object_id *compat_oid_in, unsigned flags); -static inline int write_object_file(const void *buf, unsigned long len, - enum object_type type, struct object_id *oid) -{ - return write_object_file_flags(buf, len, type, oid, NULL, 0); -} +int write_object_file(struct odb_source *source, + const void *buf, unsigned long len, + enum object_type type, struct object_id *oid, + struct object_id *compat_oid_in, unsigned flags); struct input_stream { const void *(*read)(struct input_stream *, unsigned long *len); @@ -187,10 +157,12 @@ struct input_stream { int is_finished; }; -int stream_loose_object(struct input_stream *in_stream, size_t len, +int stream_loose_object(struct odb_source *source, + struct input_stream *in_stream, size_t len, struct object_id *oid); -int force_object_loose(const struct object_id *oid, time_t mtime); +int force_object_loose(struct odb_source *source, + const struct object_id *oid, time_t mtime); /** * With in-core object data in "buf", rehash it to make sure the @@ -218,8 +190,10 @@ enum finalize_object_file_flags { FOF_SKIP_COLLISION_CHECK = 1, }; -int finalize_object_file(const char *tmpfile, const char *filename); -int finalize_object_file_flags(const char *tmpfile, const char *filename, +int finalize_object_file(struct repository *repo, + const char *tmpfile, const char *filename); +int finalize_object_file_flags(struct repository *repo, + const char *tmpfile, const char *filename, enum finalize_object_file_flags flags); void hash_object_file(const struct git_hash_algo *algo, const void *buf, @@ -237,7 +211,8 @@ int check_and_freshen_file(const char *fn, int freshen); * * Returns 0 on success, negative on error (details may be written to stderr). */ -int read_loose_object(const char *path, +int read_loose_object(struct repository *repo, + const char *path, const struct object_id *expected_oid, struct object_id *real_oid, void **contents, diff --git a/object-name.c b/object-name.c index 41930609e3..732056ff5e 100644 --- a/object-name.c +++ b/object-name.c @@ -199,16 +199,20 @@ static void unique_in_pack(struct packed_git *p, static void find_short_packed_object(struct disambiguate_state *ds) { - struct multi_pack_index *m; + struct odb_source *source; struct packed_git *p; /* Skip, unless oids from the storage hash algorithm are wanted */ if (ds->bin_pfx.algo && (&hash_algos[ds->bin_pfx.algo] != ds->repo->hash_algo)) return; - for (m = get_multi_pack_index(ds->repo); m && !ds->ambiguous; - m = m->next) - unique_in_midx(m, ds); + odb_prepare_alternates(ds->repo->objects); + for (source = ds->repo->objects->sources; source && !ds->ambiguous; source = source->next) { + struct multi_pack_index *m = get_multi_pack_index(source); + if (m) + unique_in_midx(m, ds); + } + for (p = get_packed_git(ds->repo); p && !ds->ambiguous; p = p->next) unique_in_pack(p, ds); @@ -793,11 +797,15 @@ static void find_abbrev_len_for_pack(struct packed_git *p, static void find_abbrev_len_packed(struct min_abbrev_data *mad) { - struct multi_pack_index *m; struct packed_git *p; - for (m = get_multi_pack_index(mad->repo); m; m = m->next) - find_abbrev_len_for_midx(m, mad); + odb_prepare_alternates(mad->repo->objects); + for (struct odb_source *source = mad->repo->objects->sources; source; source = source->next) { + struct multi_pack_index *m = get_multi_pack_index(source); + if (m) + find_abbrev_len_for_midx(m, mad); + } + for (p = get_packed_git(mad->repo); p; p = p->next) find_abbrev_len_for_pack(p, mad); } @@ -1517,7 +1525,8 @@ struct grab_nth_branch_switch_cbdata { struct strbuf *sb; }; -static int grab_nth_branch_switch(struct object_id *ooid UNUSED, +static int grab_nth_branch_switch(const char *refname UNUSED, + struct object_id *ooid UNUSED, struct object_id *noid UNUSED, const char *email UNUSED, timestamp_t timestamp UNUSED, @@ -980,6 +980,16 @@ void odb_assert_oid_type(struct object_database *odb, type_name(expect)); } +int odb_write_object_ext(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid, + struct object_id *compat_oid, + unsigned flags) +{ + return write_object_file(odb->sources, buf, len, type, oid, compat_oid, flags); +} + struct object_database *odb_new(struct repository *repo) { struct object_database *o = xmalloc(sizeof(*o)); @@ -13,6 +13,7 @@ struct oidmap; struct oidtree; struct strbuf; struct repository; +struct multi_pack_index; /* * Compute the exact path an alternate is at and returns it. In case of @@ -56,6 +57,13 @@ struct odb_source { struct loose_object_map *loose_map; /* + * private data + * + * should only be accessed directly by packfile.c and midx.c + */ + struct multi_pack_index *midx; + + /* * This is a temporary object store created by the tmp_objdir * facility. Disable ref updates since the objects in the store * might be discarded on rollback. @@ -75,7 +83,6 @@ struct odb_source { }; struct packed_git; -struct multi_pack_index; struct cached_object_entry; /* @@ -119,13 +126,6 @@ struct object_database { /* * private data * - * should only be accessed directly by packfile.c and midx.c - */ - struct multi_pack_index *multi_pack_index; - - /* - * private data - * * should only be accessed directly by packfile.c */ @@ -437,6 +437,44 @@ enum for_each_object_flags { FOR_EACH_OBJECT_SKIP_ON_DISK_KEPT_PACKS = (1<<4), }; +enum { + /* + * By default, `odb_write_object()` does not actually write anything + * into the object store, but only computes the object ID. This flag + * changes that so that the object will be written as a loose object + * and persisted. + */ + WRITE_OBJECT_PERSIST = (1 << 0), + + /* + * Do not print an error in case something goes wrong. + */ + WRITE_OBJECT_SILENT = (1 << 1), +}; + +/* + * Write an object into the object database. The object is being written into + * the local alternate of the repository. If provided, the converted object ID + * as well as the compatibility object ID are written to the respective + * pointers. + * + * Returns 0 on success, a negative error code otherwise. + */ +int odb_write_object_ext(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid, + struct object_id *compat_oid, + unsigned flags); + +static inline int odb_write_object(struct object_database *odb, + const void *buf, unsigned long len, + enum object_type type, + struct object_id *oid) +{ + return odb_write_object_ext(odb, buf, len, type, oid, NULL, 0); +} + /* Compatibility wrappers, to be removed once Git 2.51 has been released. */ #include "repository.h" diff --git a/oss-fuzz/fuzz-commit-graph.c b/oss-fuzz/fuzz-commit-graph.c index fbb77fec19..fb8b8787a4 100644 --- a/oss-fuzz/fuzz-commit-graph.c +++ b/oss-fuzz/fuzz-commit-graph.c @@ -4,9 +4,6 @@ #include "commit-graph.h" #include "repository.h" -struct commit_graph *parse_commit_graph(struct repo_settings *s, - void *graph_map, size_t graph_size); - int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size); int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) @@ -22,9 +19,10 @@ int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) * possible. */ repo_set_hash_algo(the_repository, GIT_HASH_SHA1); + the_repository->settings.initialized = 1; the_repository->settings.commit_graph_generation_version = 2; the_repository->settings.commit_graph_changed_paths_version = 1; - g = parse_commit_graph(&the_repository->settings, (void *)data, size); + g = parse_commit_graph(the_repository, (void *)data, size); repo_clear(the_repository); free_commit_graph(g); diff --git a/pack-bitmap.c b/pack-bitmap.c index 15cf51166e..d14421ee20 100644 --- a/pack-bitmap.c +++ b/pack-bitmap.c @@ -683,13 +683,15 @@ static int open_pack_bitmap(struct repository *r, static int open_midx_bitmap(struct repository *r, struct bitmap_index *bitmap_git) { + struct odb_source *source; int ret = -1; - struct multi_pack_index *midx; assert(!bitmap_git->map); - for (midx = get_multi_pack_index(r); midx; midx = midx->next) { - if (!open_midx_bitmap_1(bitmap_git, midx)) + odb_prepare_alternates(r->objects); + for (source = r->objects->sources; source; source = source->next) { + struct multi_pack_index *midx = get_multi_pack_index(source); + if (midx && !open_midx_bitmap_1(bitmap_git, midx)) ret = 0; } return ret; @@ -3345,11 +3347,18 @@ static int verify_bitmap_file(const struct git_hash_algo *algop, int verify_bitmap_files(struct repository *r) { + struct odb_source *source; int res = 0; - for (struct multi_pack_index *m = get_multi_pack_index(r); - m; m = m->next) { - char *midx_bitmap_name = midx_bitmap_filename(m); + odb_prepare_alternates(r->objects); + for (source = r->objects->sources; source; source = source->next) { + struct multi_pack_index *m = get_multi_pack_index(source); + char *midx_bitmap_name; + + if (!m) + continue; + + midx_bitmap_name = midx_bitmap_filename(m); res |= verify_bitmap_file(r->hash_algo, midx_bitmap_name); free(midx_bitmap_name); } diff --git a/pack-write.c b/pack-write.c index eccdc798e3..83eaf88541 100644 --- a/pack-write.c +++ b/pack-write.c @@ -538,22 +538,24 @@ struct hashfile *create_tmp_packfile(struct repository *repo, return hashfd(repo->hash_algo, fd, *pack_tmp_name); } -static void rename_tmp_packfile(struct strbuf *name_prefix, const char *source, +static void rename_tmp_packfile(struct repository *repo, + struct strbuf *name_prefix, const char *source, const char *ext) { size_t name_prefix_len = name_prefix->len; strbuf_addstr(name_prefix, ext); - if (finalize_object_file(source, name_prefix->buf)) + if (finalize_object_file(repo, source, name_prefix->buf)) die("unable to rename temporary file to '%s'", name_prefix->buf); strbuf_setlen(name_prefix, name_prefix_len); } -void rename_tmp_packfile_idx(struct strbuf *name_buffer, +void rename_tmp_packfile_idx(struct repository *repo, + struct strbuf *name_buffer, char **idx_tmp_name) { - rename_tmp_packfile(name_buffer, *idx_tmp_name, "idx"); + rename_tmp_packfile(repo, name_buffer, *idx_tmp_name, "idx"); } void stage_tmp_packfiles(struct repository *repo, @@ -586,11 +588,11 @@ void stage_tmp_packfiles(struct repository *repo, hash); } - rename_tmp_packfile(name_buffer, pack_tmp_name, "pack"); + rename_tmp_packfile(repo, name_buffer, pack_tmp_name, "pack"); if (rev_tmp_name) - rename_tmp_packfile(name_buffer, rev_tmp_name, "rev"); + rename_tmp_packfile(repo, name_buffer, rev_tmp_name, "rev"); if (mtimes_tmp_name) - rename_tmp_packfile(name_buffer, mtimes_tmp_name, "mtimes"); + rename_tmp_packfile(repo, name_buffer, mtimes_tmp_name, "mtimes"); free(rev_tmp_name); free(mtimes_tmp_name); @@ -145,7 +145,8 @@ void stage_tmp_packfiles(struct repository *repo, struct pack_idx_option *pack_idx_opts, unsigned char hash[], char **idx_tmp_name); -void rename_tmp_packfile_idx(struct strbuf *basename, +void rename_tmp_packfile_idx(struct repository *repo, + struct strbuf *basename, char **idx_tmp_name); #endif diff --git a/packfile.c b/packfile.c index af9ccfdba6..5d73932f50 100644 --- a/packfile.c +++ b/packfile.c @@ -361,6 +361,7 @@ void close_pack(struct packed_git *p) void close_object_store(struct object_database *o) { + struct odb_source *source; struct packed_git *p; for (p = o->packed_git; p; p = p->next) @@ -369,9 +370,10 @@ void close_object_store(struct object_database *o) else close_pack(p); - if (o->multi_pack_index) { - close_midx(o->multi_pack_index); - o->multi_pack_index = NULL; + for (source = o->sources; source; source = source->next) { + if (source->midx) + close_midx(source->midx); + source->midx = NULL; } close_commit_graph(o); @@ -933,22 +935,17 @@ static void prepare_pack(const char *full_name, size_t full_name_len, report_garbage(PACKDIR_FILE_GARBAGE, full_name); } -static void prepare_packed_git_one(struct repository *r, char *objdir, int local) +static void prepare_packed_git_one(struct odb_source *source, int local) { - struct prepare_pack_data data; struct string_list garbage = STRING_LIST_INIT_DUP; + struct prepare_pack_data data = { + .m = source->midx, + .r = source->odb->repo, + .garbage = &garbage, + .local = local, + }; - data.m = r->objects->multi_pack_index; - - /* look for the multi-pack-index for this object directory */ - while (data.m && strcmp(data.m->object_dir, objdir)) - data.m = data.m->next; - - data.r = r; - data.garbage = &garbage; - data.local = local; - - for_each_file_in_pack_dir(objdir, prepare_pack, &data); + for_each_file_in_pack_dir(source->path, prepare_pack, &data); report_pack_garbage(data.garbage); string_list_clear(data.garbage, 0); @@ -965,14 +962,18 @@ static void prepare_packed_git(struct repository *r); unsigned long repo_approximate_object_count(struct repository *r) { if (!r->objects->approximate_object_count_valid) { - unsigned long count; - struct multi_pack_index *m; + struct odb_source *source; + unsigned long count = 0; struct packed_git *p; prepare_packed_git(r); - count = 0; - for (m = get_multi_pack_index(r); m; m = m->next) - count += m->num_objects; + + for (source = r->objects->sources; source; source = source->next) { + struct multi_pack_index *m = get_multi_pack_index(source); + if (m) + count += m->num_objects; + } + for (p = r->objects->packed_git; p; p = p->next) { if (open_pack_index(p)) continue; @@ -1037,8 +1038,8 @@ static void prepare_packed_git(struct repository *r) odb_prepare_alternates(r->objects); for (source = r->objects->sources; source; source = source->next) { int local = (source == r->objects->sources); - prepare_multi_pack_index_one(r, source->path, local); - prepare_packed_git_one(r, source->path, local); + prepare_multi_pack_index_one(source, local); + prepare_packed_git_one(source, local); } rearrange_packed_git(r); @@ -1076,31 +1077,21 @@ struct packed_git *get_packed_git(struct repository *r) return r->objects->packed_git; } -struct multi_pack_index *get_multi_pack_index(struct repository *r) +struct multi_pack_index *get_multi_pack_index(struct odb_source *source) { - prepare_packed_git(r); - return r->objects->multi_pack_index; -} - -struct multi_pack_index *get_local_multi_pack_index(struct repository *r) -{ - struct multi_pack_index *m = get_multi_pack_index(r); - - /* no need to iterate; we always put the local one first (if any) */ - if (m && m->local) - return m; - - return NULL; + prepare_packed_git(source->odb->repo); + return source->midx; } struct packed_git *get_all_packs(struct repository *r) { - struct multi_pack_index *m; - prepare_packed_git(r); - for (m = r->objects->multi_pack_index; m; m = m->next) { - uint32_t i; - for (i = 0; i < m->num_packs + m->num_packs_in_base; i++) + + for (struct odb_source *source = r->objects->sources; source; source = source->next) { + struct multi_pack_index *m = source->midx; + if (!m) + continue; + for (uint32_t i = 0; i < m->num_packs + m->num_packs_in_base; i++) prepare_midx_pack(r, m, i); } @@ -2083,16 +2074,15 @@ static int fill_pack_entry(const struct object_id *oid, int find_pack_entry(struct repository *r, const struct object_id *oid, struct pack_entry *e) { struct list_head *pos; - struct multi_pack_index *m; prepare_packed_git(r); - if (!r->objects->packed_git && !r->objects->multi_pack_index) - return 0; - for (m = r->objects->multi_pack_index; m; m = m->next) { - if (fill_midx_entry(r, oid, e, m)) + for (struct odb_source *source = r->objects->sources; source; source = source->next) + if (source->midx && fill_midx_entry(r, oid, e, source->midx)) return 1; - } + + if (!r->objects->packed_git) + return 0; list_for_each(pos, &r->objects->packed_git_mru) { struct packed_git *p = list_entry(pos, struct packed_git, mru); diff --git a/packfile.h b/packfile.h index 53c3b7d3b4..f16753f2a9 100644 --- a/packfile.h +++ b/packfile.h @@ -147,8 +147,7 @@ void install_packed_git(struct repository *r, struct packed_git *pack); struct packed_git *get_packed_git(struct repository *r); struct list_head *get_packed_git_mru(struct repository *r); -struct multi_pack_index *get_multi_pack_index(struct repository *r); -struct multi_pack_index *get_local_multi_pack_index(struct repository *r); +struct multi_pack_index *get_multi_pack_index(struct odb_source *source); struct packed_git *get_all_packs(struct repository *r); /* diff --git a/parallel-checkout.c b/parallel-checkout.c index 57c2dcaa8f..fba6aa65a6 100644 --- a/parallel-checkout.c +++ b/parallel-checkout.c @@ -57,12 +57,12 @@ void get_parallel_checkout_configs(int *num_workers, int *threshold) return; } - if (git_config_get_int("checkout.workers", num_workers)) + if (repo_config_get_int(the_repository, "checkout.workers", num_workers)) *num_workers = DEFAULT_NUM_WORKERS; else if (*num_workers < 1) *num_workers = online_cpus(); - if (git_config_get_int("checkout.thresholdForParallelism", threshold)) + if (repo_config_get_int(the_repository, "checkout.thresholdForParallelism", threshold)) *threshold = DEFAULT_THRESHOLD_FOR_PARALLELISM; } diff --git a/parse-options.c b/parse-options.c index 5224203ffe..992ec9631f 100644 --- a/parse-options.c +++ b/parse-options.c @@ -953,10 +953,16 @@ static void free_preprocessed_options(struct option *options) free(options); } +#define USAGE_NORMAL 0 +#define USAGE_FULL 1 +#define USAGE_TO_STDOUT 0 +#define USAGE_TO_STDERR 1 + static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t *, const char * const *, const struct option *, - int, int); + int full_usage, + int usage_to_stderr); enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx, const struct option *options, @@ -1088,7 +1094,8 @@ enum parse_opt_result parse_options_step(struct parse_opt_ctx_t *ctx, } if (internal_help && !strcmp(arg + 2, "help-all")) - return usage_with_options_internal(ctx, usagestr, options, 1, 0); + return usage_with_options_internal(ctx, usagestr, options, + USAGE_FULL, USAGE_TO_STDOUT); if (internal_help && !strcmp(arg + 2, "help")) goto show_usage; switch (parse_long_opt(ctx, arg + 2, options)) { @@ -1129,7 +1136,8 @@ unknown: return PARSE_OPT_DONE; show_usage: - return usage_with_options_internal(ctx, usagestr, options, 0, 0); + return usage_with_options_internal(ctx, usagestr, options, + USAGE_NORMAL, USAGE_TO_STDOUT); } int parse_options_end(struct parse_opt_ctx_t *ctx) @@ -1338,7 +1346,7 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t if (!saw_empty_line && !*str) saw_empty_line = 1; - string_list_split(&list, str, '\n', -1); + string_list_split(&list, str, "\n", -1); for (j = 0; j < list.nr; j++) { const char *line = list.items[j].string; @@ -1444,7 +1452,8 @@ static enum parse_opt_result usage_with_options_internal(struct parse_opt_ctx_t void NORETURN usage_with_options(const char * const *usagestr, const struct option *opts) { - usage_with_options_internal(NULL, usagestr, opts, 0, 1); + usage_with_options_internal(NULL, usagestr, opts, + USAGE_NORMAL, USAGE_TO_STDERR); exit(129); } @@ -1452,9 +1461,16 @@ void show_usage_with_options_if_asked(int ac, const char **av, const char * const *usagestr, const struct option *opts) { - if (ac == 2 && !strcmp(av[1], "-h")) { - usage_with_options_internal(NULL, usagestr, opts, 0, 0); - exit(129); + if (ac == 2) { + if (!strcmp(av[1], "-h")) { + usage_with_options_internal(NULL, usagestr, opts, + USAGE_NORMAL, USAGE_TO_STDOUT); + exit(129); + } else if (!strcmp(av[1], "--help-all")) { + usage_with_options_internal(NULL, usagestr, opts, + USAGE_FULL, USAGE_TO_STDOUT); + exit(129); + } } } diff --git a/parse-options.h b/parse-options.h index 312045604d..706de9729f 100644 --- a/parse-options.h +++ b/parse-options.h @@ -623,6 +623,8 @@ int parse_opt_tracking_mode(const struct option *, const char *, int); #define OPT_PATHSPEC_FROM_FILE(v) OPT_FILENAME(0, "pathspec-from-file", v, N_("read pathspec from file")) #define OPT_PATHSPEC_FILE_NUL(v) OPT_BOOL(0, "pathspec-file-nul", v, N_("with --pathspec-from-file, pathspec elements are separated with NUL character")) #define OPT_AUTOSTASH(v) OPT_BOOL(0, "autostash", v, N_("automatically stash/stash pop before and after")) +#define OPT_DIFF_UNIFIED(v) OPT_INTEGER_F('U', "unified", v, N_("generate diffs with <n> lines context"), PARSE_OPT_NONEG) +#define OPT_DIFF_INTERHUNK_CONTEXT(v) OPT_INTEGER_F(0, "inter-hunk-context", v, N_("show context between diff hunks up to the specified number of lines"), PARSE_OPT_NONEG) #define OPT_IPVERSION(v) \ OPT_SET_INT_F('4', "ipv4", (v), N_("use IPv4 addresses only"), \ diff --git a/path-walk.c b/path-walk.c index 2d4ddbadd5..f1ceed99e9 100644 --- a/path-walk.c +++ b/path-walk.c @@ -105,6 +105,24 @@ static void push_to_stack(struct path_walk_context *ctx, prio_queue_put(&ctx->path_stack, xstrdup(path)); } +static void add_path_to_list(struct path_walk_context *ctx, + const char *path, + enum object_type type, + struct object_id *oid, + int interesting) +{ + struct type_and_oid_list *list = strmap_get(&ctx->paths_to_lists, path); + + if (!list) { + CALLOC_ARRAY(list, 1); + list->type = type; + strmap_put(&ctx->paths_to_lists, path, list); + } + + list->maybe_interesting |= interesting; + oid_array_append(&list->oids, oid); +} + static int add_tree_entries(struct path_walk_context *ctx, const char *base_path, struct object_id *oid) @@ -129,7 +147,6 @@ static int add_tree_entries(struct path_walk_context *ctx, init_tree_desc(&desc, &tree->object.oid, tree->buffer, tree->size); while (tree_entry(&desc, &entry)) { - struct type_and_oid_list *list; struct object *o; /* Not actually true, but we will ignore submodules later. */ enum object_type type = S_ISDIR(entry.mode) ? OBJ_TREE : OBJ_BLOB; @@ -190,17 +207,10 @@ static int add_tree_entries(struct path_walk_context *ctx, continue; } - if (!(list = strmap_get(&ctx->paths_to_lists, path.buf))) { - CALLOC_ARRAY(list, 1); - list->type = type; - strmap_put(&ctx->paths_to_lists, path.buf, list); - } - push_to_stack(ctx, path.buf); - - if (!(o->flags & UNINTERESTING)) - list->maybe_interesting = 1; + add_path_to_list(ctx, path.buf, type, &entry.oid, + !(o->flags & UNINTERESTING)); - oid_array_append(&list->oids, &entry.oid); + push_to_stack(ctx, path.buf); } free_tree_buffer(tree); @@ -377,15 +387,9 @@ static int setup_pending_objects(struct path_walk_info *info, if (!info->trees) continue; if (pending->path) { - struct type_and_oid_list *list; char *path = *pending->path ? xstrfmt("%s/", pending->path) : xstrdup(""); - if (!(list = strmap_get(&ctx->paths_to_lists, path))) { - CALLOC_ARRAY(list, 1); - list->type = OBJ_TREE; - strmap_put(&ctx->paths_to_lists, path, list); - } - oid_array_append(&list->oids, &obj->oid); + add_path_to_list(ctx, path, OBJ_TREE, &obj->oid, 1); free(path); } else { /* assume a root tree, such as a lightweight tag. */ @@ -396,19 +400,10 @@ static int setup_pending_objects(struct path_walk_info *info, case OBJ_BLOB: if (!info->blobs) continue; - if (pending->path) { - struct type_and_oid_list *list; - char *path = pending->path; - if (!(list = strmap_get(&ctx->paths_to_lists, path))) { - CALLOC_ARRAY(list, 1); - list->type = OBJ_BLOB; - strmap_put(&ctx->paths_to_lists, path, list); - } - oid_array_append(&list->oids, &obj->oid); - } else { - /* assume a root tree, such as a lightweight tag. */ + if (pending->path) + add_path_to_list(ctx, pending->path, OBJ_BLOB, &obj->oid, 1); + else oid_array_append(&tagged_blobs->oids, &obj->oid); - } break; case OBJ_COMMIT: diff --git a/pathspec.c b/pathspec.c index a3ddd701c7..5993c4afa0 100644 --- a/pathspec.c +++ b/pathspec.c @@ -201,8 +201,7 @@ static void parse_pathspec_attr_match(struct pathspec_item *item, const char *va if (!value || !*value) die(_("attr spec must not be empty")); - string_list_split(&list, value, ' ', -1); - string_list_remove_empty_items(&list, 0); + string_list_split_f(&list, value, " ", -1, STRING_LIST_SPLIT_NONEMPTY); item->attr_check = attr_check_alloc(); CALLOC_ARRAY(item->attr_match, list.nr); @@ -61,6 +61,7 @@ # dirty нечиÑÑ‚, мръÑен (файл, индекÑ) # fallback резервен вариант # pathspec magic Ð¾Ð¿Ñ†Ð¸Ñ Ð·Ð° магичеÑки пътища +# pathspec шаблон за пътища # bitmap index Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки # multi-pack bitmap многопакетната битова маÑка # ewah bitmap битова маÑка във формат EWAH @@ -237,6 +238,7 @@ # exit code изходен код # score оценка за Ñъвпадение # raw необработен +# mbox файл Ñ Ð¿Ð¾Ñ‰Ð° # # # ------------------------ @@ -266,8 +268,8 @@ msgid "" msgstr "" "Project-Id-Version: git 2.48\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-05-29 13:50+0200\n" -"PO-Revision-Date: 2025-05-29 20:25+0200\n" +"POT-Creation-Date: 2025-08-13 22:06+0200\n" +"PO-Revision-Date: 2025-08-13 22:07+0200\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -277,6 +279,10 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s трÑбва да е неотрицателно" + +#, c-format msgid "Huh (%s)?" msgstr "ÐеуÑпешен анализ — „%s“." @@ -980,8 +986,8 @@ msgid "" "outside of your sparse-checkout definition, so will not be\n" "updated in the index:\n" msgstr "" -"Следните пътища напаÑват Ñ Ð¿ÑŠÑ‚Ð¸Ñ‰Ð° извън дефинициÑта за чаÑтично\n" -"изтеглÑне и нÑма да Ñе обновÑÑ‚ в индекÑа:\n" +"Следните пътища и шаблони напаÑват Ñ Ð¿ÑŠÑ‚Ð¸Ñ‰Ð° извън дефинициÑта\n" +"за чаÑтично изтеглÑне и нÑма да Ñе обновÑÑ‚ в индекÑа:\n" msgid "" "If you intend to update such entries, try one of the following:\n" @@ -1644,11 +1650,11 @@ msgstr "файлът „%s“ не може да Ñе прочете" #, c-format msgid "pathspec '%s' matches files outside the current directory" -msgstr "пътÑÑ‚ „%s“ Ñъвпада Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ извън текущата директориÑ" +msgstr "шаблонът за пътища „%s“ Ñъвпада Ñ Ñ„Ð°Ð¹Ð»Ð¾Ð²Ðµ извън текущата директориÑ" #, c-format msgid "pathspec '%s' did not match any files" -msgstr "пътÑÑ‚ „%s“ не Ñъвпада Ñ Ð½Ð¸ÐºÐ¾Ð¹ файл" +msgstr "шаблонът за пътища „%s“ не Ñъвпада Ñ Ð½Ð¸ÐºÐ¾Ð¹ файл" #, c-format msgid "no such ref: %.*s" @@ -2115,7 +2121,7 @@ msgid "'%s' is already used by worktree at '%s'" msgstr "„%s“ вече Ñе ползва от работното дърво в „%s“" msgid "git add [<options>] [--] <pathspec>..." -msgstr "git add [ОПЦИЯ…] [--] ПЪТ…" +msgstr "git add [ОПЦИЯ…] [--] ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…" #, c-format msgid "cannot chmod %cx '%s'" @@ -2242,12 +2248,16 @@ msgid "adding files failed" msgstr "неуÑпешно добавÑне на файлове" #, c-format +msgid "'%s' cannot be negative" +msgstr "„%s“ трÑбва да е неотрицателно" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "параметърът към „--chmod“ — „%s“ може да е или „-x“, или „+x“" #, c-format msgid "'%s' and pathspec arguments cannot be used together" -msgstr "опциÑта „%s“ и път Ñа неÑъвмеÑтими" +msgstr "опциÑта „%s“ и шаблони за пътища Ñа неÑъвмеÑтими" #, c-format msgid "Nothing specified, nothing added.\n" @@ -2678,7 +2688,7 @@ msgid "" msgstr "" "git bisect start [--term-(new,bad)=УПРÐВЛЯВÐЩÐ_ДУМР--term-" "(old,good)=УПРÐВЛЯВÐЩÐ_ДУМÐ] [--no-checkout] [--first-parent] [ЛОШО " -"[ДОБРО…]] [--] [ПЪТ…]" +"[ДОБРО…]] [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "git bisect (good|bad) [<rev>...]" msgstr "git bisect (good|bad) [ВЕРСИЯ…]" @@ -4251,7 +4261,7 @@ msgid "checkout their version for unmerged files" msgstr "изтеглÑне на чуждата верÑÐ¸Ñ Ð½Ð° неÑлетите файлове" msgid "do not limit pathspecs to sparse entries only" -msgstr "без ограничаване на изброените пътища Ñамо до чаÑтично изтеглените" +msgstr "без ограничаване на шаблоните за пътища Ñамо до чаÑтично изтеглените" #, c-format msgid "options '-%c', '-%c', and '%s' cannot be used together" @@ -4341,7 +4351,9 @@ msgstr "използване на припокриващ режим" msgid "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] " "[<pathspec>...]" -msgstr "git clean [-d] [-f] [-i] [-n] [-q] [-e ШÐБЛОÐ] [-x|-X] [--] [ПЪТ…]" +msgstr "" +"git clean [-d] [-f] [-i] [-n] [-q] [-e ШÐБЛОÐ] [-x|-X] [--] " +"[ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" #, c-format msgid "Removing %s\n" @@ -4595,7 +4607,7 @@ msgid "setup as shared repository" msgstr "наÑтройване за Ñподелено хранилище" msgid "pathspec" -msgstr "път" +msgstr "ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ" msgid "initialize submodules in the clone" msgstr "инициализиране на подмодулите при това клониране" @@ -5007,10 +5019,10 @@ msgstr "" " [-i|-o] [--pathspec-from-file=ФÐЙЛ [--pathspec-file-nul]]\n" " [(--trailer ЛЕКСЕМÐ[(=|:)СТОЙÐОСТ])…] [-" "S[ИДЕÐТИФИКÐТОР_ÐÐ_КЛЮЧ]]\n" -" [--] [ПЪТ…]" +" [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "git status [<options>] [--] [<pathspec>...]" -msgstr "git status [ОПЦИЯ…] [--] [ПЪТ…]" +msgstr "git status [ОПЦИЯ…] [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "" "You asked to amend the most recent commit, but doing so would make\n" @@ -5516,24 +5528,24 @@ msgstr "git config list [ОПЦИЯ_ЗÐ_ФÐЙЛ] [ОПЦИЯ_ЗÐ_ИЗВЕЖД msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [ОПЦИЯ_ЗÐ_ФÐЙЛ] [ОПЦИЯ_ЗÐ_ИЗВЕЖДÐÐЕ] [--includes] [--all] [--" -"regexp] [--value=СТОЙÐОСТ] [--fixed-value] [--default=СТÐÐДÐРТÐО] ИМЕ" +"regexp] [--value=ШÐБЛОÐ] [--fixed-value] [--default=СТÐÐДÐРТÐО] ИМЕ" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [ОПЦИЯ_ЗÐ_ФÐЙЛ] [--type=ВИД] [--all] [--value=СТОЙÐОСТ] [--" +"git config set [ОПЦИЯ_ЗÐ_ФÐЙЛ] [--type=ВИД] [--all] [--value=ШÐБЛОÐ] [--" "fixed-value] ИМЕ СТОЙÐОСТ" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [ОПЦИЯ_ЗÐ_ФÐЙЛ] [--all] [--value=СТОЙÐОСТ] [--fixed-value] " -"ИМЕ" +"git config unset [ОПЦИЯ_ЗÐ_ФÐЙЛ] [--all] [--value=ШÐБЛОÐ] [--fixed-value] ИМЕ" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [ОПЦИЯ_ЗÐ_ФÐЙЛ] СТÐРО_ИМЕ ÐОВО_ИМЕ" @@ -5550,18 +5562,18 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [ОПЦИЯ_ЗÐ_ФÐЙЛ] [ОПЦИЯ_ЗÐ_ИЗВЕЖДÐÐЕ] [--includes] [--all] [--" -"regexp=РЕГ_ИЗР][--value=СТОЙÐОСТ] [--fixed-value] [--default=СТÐÐДÐРТÐО] ИМЕ" +"regexp=РЕГ_ИЗР][--value=ШÐБЛОÐ] [--fixed-value] [--default=СТÐÐДÐРТÐО] ИМЕ" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [ОПЦИЯ_ЗÐ_ФÐЙЛ] [--type=ВИД] [--comment=СЪОБЩЕÐИЕ] [--all] [--" -"value=СТОЙÐОСТ] [--fixed-value] ИМЕ СТОЙÐОСТ" +"value=ШÐБЛОÐ] [--fixed-value] ИМЕ СТОЙÐОСТ" msgid "Config file location" msgstr "МеÑтоположение на ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¾Ð½Ð½Ð¸Ñ Ñ„Ð°Ð¹Ð»" @@ -6087,7 +6099,7 @@ msgid "working without -z is not supported" msgstr "опциÑта „-z“ е задължителна" msgid "pathspec arguments not supported" -msgstr "не Ñе поддържат опции за пътища" +msgstr "не Ñе поддържат аргументи Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¸ за пътища" msgid "revision arguments not allowed" msgstr "не Ñе поддържат опции за верÑии" @@ -6244,7 +6256,7 @@ msgstr "git fast-export [ОПЦИЯ_ЗÐ_СПИСЪКÐ_С_ВЕРСИИ…]" msgid "Error: Cannot export nested tags unless --mark-tags is specified." msgstr "" -"Грешка: непреките етикети не Ñе изнаÑÑÑ‚, оÑвен ако не зададете „--mark-tags“." +"ГРЕШКÐ: непреките етикети не Ñе изнаÑÑÑ‚, оÑвен ако не зададете „--mark-tags“." msgid "--anonymize-map token cannot be empty" msgstr "опциÑта „--anonymize-map“ изиÑква аргумент" @@ -6437,23 +6449,6 @@ msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "" "отхвърлÑне на „%s“, защото плитките върхове не може да бъдат обновÑвани" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"нÑкои локални указатели не може да бъдат обновени. Изпълнете командата\n" -"„git remote prune %s“, за да премахнете оÑтарелите клони, които\n" -"предизвикват конфликта" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (обектът „%s“ ще Ñе окаже извън клон)" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (обектът „%s“ вече е извън клон)" - msgid "[deleted]" msgstr "[изтрит]" @@ -6501,6 +6496,19 @@ msgstr "" "ще изключи предупреждението, докато отдалечениÑÑ‚ указател HEAD не\n" "започне да Ñочи нещо друго." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"нÑкои локални указатели не може да бъдат обновени. Изпълнете командата\n" +"„git remote prune %s“, за да премахнете оÑтарелите клони, които\n" +"предизвикват конфликта" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "неуÑпешно доÑтавÑне на ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ %s: %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "" "заÑечени Ñа множеÑтво клони, това е неÑъвмеÑтимо Ñ Ð¾Ð¿Ñ†Ð¸Ñта „--set-upstream“" @@ -6747,6 +6755,9 @@ msgstr "git for-each-ref [--merged [ПОДÐÐ’ÐÐЕ]] [--no-merged [ПОДÐÐ’Ð msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [ПОДÐÐ’ÐÐЕ]] [--no-contains [ПОДÐÐ’ÐÐЕ]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after МÐРКЕР]" + msgid "quote placeholders suitably for shells" msgstr "цитиране подходÑщо за командни интерпретатори на обвивката" @@ -6762,6 +6773,12 @@ msgstr "цитиране подходÑщо за tcl" msgid "show only <n> matched refs" msgstr "извеждане Ñамо на този БРОЙ напаÑнати указатели" +msgid "marker" +msgstr "МÐРКЕР" + +msgid "start iteration after the provided marker" +msgstr "начало на итерирането Ñлед ÑƒÐºÐ°Ð·Ð°Ð½Ð¸Ñ Ð¼Ð°Ñ€ÐºÐµÑ€" + msgid "respect format colors" msgstr "Ñпазване на цветовете на форма̀та" @@ -6786,9 +6803,15 @@ msgstr "изчитане на шаблоните за указатели от Ñ msgid "also include HEAD ref and pseudorefs" msgstr "включване и на ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»Ñ â€žHEAD“ както и пÑевдо указателите" +msgid "cannot use --start-after with custom sort options" +msgstr "опциÑта „--start-after“ е неÑъвмеÑтима Ñ Ð¸Ð·Ñ€Ð¸Ñ‡Ð½Ð° подредба" + msgid "unknown arguments supplied with --stdin" msgstr "непознат аргумент към опциÑта „--stdin“" +msgid "cannot use --start-after with patterns" +msgstr "опциÑта „--start-after“ е неÑъвмеÑтима ÑÑŠÑ Ð·Ð°Ð´Ð°Ð²Ð°Ð½ÐµÑ‚Ð¾ на шаблони" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=ÐÐСТРОЙКР[--] ÐРГУМЕÐТ…" @@ -7190,6 +7213,10 @@ msgstr "препакетиране на вÑичко без най-Ð³Ð¾Ð»ÐµÐ¼Ð¸Ñ msgid "pack prefix to store a pack containing pruned objects" msgstr "Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ Ð½Ð° имената на пакетите за окаÑтрени обекти" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "" +"преÑкачане на дейноÑтите по поддръжката — типично за работа на преден режим" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "неразпозната ÑтойноÑÑ‚ на „gc.logExpiry“ %s" @@ -7268,14 +7295,14 @@ msgstr "" "„core.multiPackIndex“ е изключена" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "заключващиÑÑ‚ файл „%s“ ÑъщеÑтвува. ДейÑтвието Ñе преÑкача" - -#, c-format msgid "task '%s' failed" msgstr "неуÑпешно изпълнение на задачата „%s“" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "заключващиÑÑ‚ файл „%s“ ÑъщеÑтвува. ДейÑтвието Ñе преÑкача" + +#, c-format msgid "'%s' is not a valid task" msgstr "„%s“ не е правилна задача" @@ -7304,9 +7331,6 @@ msgstr "задача" msgid "run a specific task" msgstr "изпълнение на определена задача" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "опциите „--auto“ и „--schedule=ЧЕСТОТГ Ñа неÑъвмеÑтими" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "неуÑпешно добавÑне на ÑтойноÑÑ‚ на „%s“ за „%s“" @@ -8199,11 +8223,7 @@ msgstr "" "във ФÐЙЛа" msgid "-L<range>:<file> cannot be used with pathspec" -msgstr "опциÑта „-LДИÐПÐЗОÐ:ФÐЙЛ“ не може да Ñе ползва Ñ Ð¿ÑŠÑ‚" - -#, c-format -msgid "Final output: %d %s\n" -msgstr "Резултат: %d %s\n" +msgstr "опциÑта „-LДИÐПÐЗОÐ:ФÐЙЛ“ не може да Ñе ползва Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½ за пътища" #, c-format msgid "git show %s: bad file" @@ -8934,6 +8954,9 @@ msgstr "извеждане на ÑтатиÑтиката Ñлед завършв msgid "(synonym to --stat)" msgstr "(пÑевдоним на „--stat“)" +msgid "show a compact-summary at the end of the merge" +msgstr "извеждане на кратко-обобщение Ñлед завършване на Ñливане" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "добавÑне (на макÑимум такъв БРОЙ) запиÑи от ÑÑŠÐºÑ€Ð°Ñ‚ÐµÐ½Ð¸Ñ Ð¶ÑƒÑ€Ð½Ð°Ð» в Ñъобщението " @@ -9209,10 +9232,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "ГРЕШКÐ: аргументът-етикет не минава проверка Ñ â€žfsck“: %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) никога не трÑбва да задейÑтва тази функциÑ" - -#, c-format msgid "could not read tagged object '%s'" msgstr "обектът Ñ ÐµÑ‚Ð¸ÐºÐµÑ‚ не може да Ñе прочете: %s" @@ -9746,15 +9765,26 @@ msgstr "да Ñе използва бележката Ñочена от този msgid "unknown subcommand: `%s'" msgstr "непозната подкоманда: „%s“" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [ОПЦИЯ…] [< СПИСЪК_С_УКÐЗÐТЕЛИ|< СПИСЪК_С_ОБЕКТИ]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" msgstr "" -"git pack-objects [ОПЦИЯ…] ПРЕФИКС_ÐÐ_ИМЕТО [< СПИСЪК_С_УКÐЗÐТЕЛИ|< " -"СПИСЪК_С_ОБЕКТИ]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=БРОЙ] [--depth=БРОЙ]\n" +" [--revs [--unpacked | --all]] [--keep-pack=ИМЕ_ÐÐ_ПÐКЕТ]\n" +" [--cruft] [--cruft-expiration=ВРЕМЕ]\n" +" [--stdout [--filter=ФИЛТЪР] | ОСÐОВÐО_ИМЕ]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=ВЕРСИЯ] [--path-walk] < СПИСЪК_С_ОБЕКТИ" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9863,6 +9893,15 @@ msgstr "" msgid "unable to get type of object %s" msgstr "видът на обекта „%s“ не може да Ñе определи" +msgid "Compressing objects by path" +msgstr "КомпреÑиране на обектите на база пътÑ" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Делта компреÑиÑта на база път ще използва до %d нишка" +msgstr[1] "Делта компреÑиÑта на база път ще използва до %d нишки" + msgid "Compressing objects" msgstr "КомпреÑиране на обектите" @@ -9941,6 +9980,9 @@ msgstr "непакетираниÑÑ‚ обект в „%s“ не може да Ñ msgid "unable to force loose object" msgstr "оÑтаването на обекта непакетиран не може да Ñе наложи" +msgid "failed to pack objects via path-walk" +msgstr "неуÑпешно пакетиране на обекти чрез обхождане на дървото" + #, c-format msgid "not a rev '%s'" msgstr "„%s“ не е верÑиÑ" @@ -10058,6 +10100,11 @@ msgstr "използване на алгоритъм за чаÑтична Ð´Ð¾Ñ msgid "create thin packs" msgstr "Ñъздаване на Ñъкратени пакети" +msgid "use the path-walk API to walk objects when possible" +msgstr "" +"когато е възможно, използване на Ð¿Ñ€Ð¾Ð³Ñ€Ð°Ð¼Ð½Ð¸Ñ Ð¸Ð½Ñ‚ÐµÑ€Ñ„ÐµÐ¹Ñ Ð·Ð° обхождане на " +"обектите" + msgid "create packs suitable for shallow fetches" msgstr "пакетиране подходÑщо за плитко доÑтавÑне" @@ -10120,6 +10167,10 @@ msgstr "" "ползва %d" #, c-format +msgid "cannot use %s with %s" +msgstr "„%s“ и „%s“ Ñа неÑъвмеÑтими" + +#, c-format msgid "bad pack compression level %d" msgstr "неправилно ниво на компреÑиране при пакетиране: %d" @@ -10136,9 +10187,6 @@ msgstr "" "опциÑта „--thin“не може да Ñе използва за Ñъздаване на пакетни файлове Ñ " "индекÑ" -msgid "cannot use --filter with --stdin-packs" -msgstr "опциите „--filter“ и „--stdin-packs“ Ñа неÑъвмеÑтими" - msgid "cannot use internal rev list with --stdin-packs" msgstr "" "вътрешниÑÑ‚ ÑпиÑък на указатели и опциÑта „--stdin-packs“ Ñа неÑъвмеÑтими" @@ -10146,9 +10194,6 @@ msgstr "" msgid "cannot use internal rev list with --cruft" msgstr "вътрешниÑÑ‚ ÑпиÑък на верÑии и опциÑта „--cruft“ Ñа неÑъвмеÑтими" -msgid "cannot use --stdin-packs with --cruft" -msgstr "опциите „--stdin-packs“ и „--cruft“ Ñа неÑъвмеÑтими" - msgid "Enumerating objects" msgstr "ИзброÑване на обектите" @@ -10161,22 +10206,6 @@ msgstr "" "%<PRIu32>), преизползвани при пакетиране: %<PRIu32> (от %<PRIuMAX>)" 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 "" -"Командата „git pack-redundant“ е оÑтарÑла и предÑтои\n" -"пълното Ñ Ð¿Ñ€ÐµÐ¼Ð°Ñ…Ð²Ð°Ð½Ðµ. Ðко вÑе още Ñ Ð¿Ð¾Ð»Ð·Ð²Ð°Ñ‚Ðµ, добавете\n" -"опциÑта „--i-still-use-this“ на ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´ и молим да\n" -"ни извеÑтите Ñ Ðµ-пиÑмо до пощенÑÐºÐ¸Ñ ÑпиÑък:\n" -"<git@vger.kernel.org>.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "трÑбва да добавите и опциÑта „--i-still-use-this“" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -11511,6 +11540,18 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "неправилна ÑтойноÑÑ‚ за „--mirror“: %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "" +"името на отдалеченото хранилище „%s“ Ñе Ñъдържа в името на ÑъщеÑтвуващо " +"отдалечено хранилище „%s“ като подниз" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "" +"името на отдалеченото хранилище „%s“ Ñъдържа в името Ñи ÑъщеÑтвуващо " +"отдалечено хранилище „%s“ като подниз" + msgid "fetch the remote branches" msgstr "отдалечените клони не може да бъдат доÑтавени" @@ -11821,14 +11862,6 @@ msgid "Could not set up %s" msgstr "„%s“ не може да Ñе наÑтрои" #, c-format -msgid " %s will become dangling!" -msgstr "„%s“ ще Ñе превърне в обект извън клоните!" - -#, c-format -msgid " %s has become dangling!" -msgstr "„%s“ Ñе превърна в обект извън клоните!" - -#, c-format msgid "Pruning %s" msgstr "ОкаÑтрÑне на „%s“" @@ -11892,11 +11925,11 @@ msgstr "повече подробноÑти. ПоÑÑ‚Ð°Ð²Ñ Ñе пред поРmsgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=БРОЙ] [--depth=БРОЙ] [--threads=БРОЙ] [--keep-pack=ИМЕ_ÐÐ_ПÐКЕТ]\n" -"[--write-midx] [--name-hash-version=БРОЙ]" +"[--write-midx] [--name-hash-version=ВЕРСИЯ] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11994,6 +12027,9 @@ msgid "" msgstr "" "укажете Ñ„ÑƒÐ½ÐºÑ†Ð¸Ñ Ð·Ð° контролни Ñуми за групиране на подобните обекти по път" +msgid "pass --path-walk to git-pack-objects" +msgstr "подаване на опциÑта „--path-walk“ на командата „git-pack-objects“" + msgid "do not run git-update-server-info" msgstr "без изпълнение на командата „git-update-server-info“" @@ -12328,7 +12364,7 @@ msgstr "не Ñе поддържа прилагане наново и на поРmsgid "" "git rerere [clear | forget <pathspec>... | diff | status | remaining | gc]" -msgstr "git rerere [clear|forget ПЪТ…|diff|status|remaining|gc]" +msgstr "git rerere [clear|forget ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…|diff|status|remaining|gc]" msgid "register clean resolutions in index" msgstr "региÑтриране на чиÑти корекции на конфликти в индекÑа" @@ -12345,7 +12381,7 @@ msgid "" msgstr "git reset [--mixed|--soft|--hard|--merge|--keep] [-q] [ПОДÐÐ’ÐÐЕ]" msgid "git reset [-q] [<tree-ish>] [--] <pathspec>..." -msgstr "git reset [-q] [УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [--] ПЪТИЩÐ…" +msgstr "git reset [-q] [УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [--] ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…" msgid "" "git reset [-q] [--pathspec-from-file [--pathspec-file-nul]] [<tree-ish>]" @@ -12354,7 +12390,7 @@ msgstr "" "[УКÐЗÐТЕЛ_КЪМ_ДЪРВО]" msgid "git reset --patch [<tree-ish>] [--] [<pathspec>...]" -msgstr "git reset --patch [УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [--] [ПЪТИЩÐ…]" +msgstr "git reset --patch [УКÐЗÐТЕЛ_КЪМ_ДЪРВО] [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "mixed" msgstr "ÑмеÑено (mixed)" @@ -12639,7 +12675,7 @@ msgid "" msgstr "" "git rm [-f|--force] [-n] [-r] [--cached] [--ignore-unmatch]\n" " [--quiet] [--pathspec-from-file=ФÐЙЛ [--pathspec-file-nul]]\n" -" [--] [ПЪТ…]" +" [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "" "the following file has staged content different from both the\n" @@ -12699,7 +12735,7 @@ msgstr "" "изтриване" msgid "No pathspec was given. Which files should I remove?" -msgstr "Ðе Ñа зададени пътища. Кои файлове да Ñе изтриÑÑ‚?" +msgstr "Ðе Ñа зададени шаблони за пътища. Кои файлове да Ñе изтриÑÑ‚?" msgid "please stage your changes to .gitmodules or stash them to proceed" msgstr "" @@ -13148,7 +13184,7 @@ msgstr "" "quiet]\n" " [-u|--include-untracked] [-a|--all] [(-m|--message) СЪОБЩЕÐИЕ]\n" " [--pathspec-from-file=ФÐЙЛ [--pathspec-file-nul]]\n" -" [--] [ПЪТ…]]" +" [--] [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]]" msgid "" "git stash save [-p | --patch] [-S | --staged] [-k | --[no-]keep-index] [-q | " @@ -13162,17 +13198,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [СЪОБЩЕÐИЕ]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref УКÐЗÐТЕЛ) [СКÐТÐÐО…]" + +msgid "git stash import <commit>" +msgstr "git bisect import ПОДÐÐ’ÐÐЕ" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "„%s“ не е подаване, приличащо на нещо Ñкатано" +msgid "No stash entries found." +msgstr "Ðе е открито нищо Ñкатано." + #, c-format msgid "Too many revisions specified:%s" msgstr "Указани Ñа прекалено много верÑии:%s" -msgid "No stash entries found." -msgstr "Ðе е открито нищо Ñкатано." - #, c-format msgid "%s is not a valid reference" msgstr "„%s“ е неправилно име за указател" @@ -13327,19 +13369,74 @@ msgstr "Ñкатаване и на неÑледените файлове" msgid "include ignore files" msgstr "Ñкатаване и на игнорираните файлове" -msgid "skip and remove all lines starting with comment character" -msgstr "пропуÑкане на вÑички редове, които започват Ñ â€ž#“" +#, c-format +msgid "cannot parse commit %s" +msgstr "подаването „%s“ не може да Ñе анализира" -msgid "prepend comment character and space to each line" -msgstr "добавÑне на „# “ в началото на вÑеки ред" +#, c-format +msgid "invalid author or committer for %s" +msgstr "неправилен автор или подаващ на „%s“" + +msgid "could not write commit" +msgstr "подаването не може да Ñе запази" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "ИзиÑква Ñе пълно име на указател, а не „%s“" +msgid "not a valid revision: %s" +msgstr "не е верÑиÑ: %s" #, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "не може да Ñе получи връзка към хранилище за подмодула „%s“" +msgid "not a commit: %s" +msgstr "не е подаване: „%s“" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "„%s“ не е изнеÑено Ñкатано подаване" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "открито е начално подаване „%s“ Ñ Ð½ÐµÐ¿Ñ€Ð°Ð²Ð¸Ð»Ð½Ð¸ данни" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "открито е Ñкатано подаване „%s“ без Ð¾Ñ‡Ð°ÐºÐ²Ð°Ð½Ð¸Ñ Ð¿Ñ€ÐµÑ„Ð¸ÐºÑ" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "не може да Ñе анализират родителÑките Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ Ð½Ð°: „%s“" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "„%s“ не изглежда да е Ñкатано подаване" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "буферът за подаване на „%s“ не може да Ñе прочете" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "Ñкатаното за „%s“ не може да Ñе запази" + +msgid "unable to write base commit" +msgstr "базовото подаване не може да Ñе запише" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "ÑкатаниÑÑ‚ Ð·Ð°Ð¿Ð¸Ñ Ð·Ð° „%s“ не може да Ñе открие" + +msgid "print the object ID instead of writing it to a ref" +msgstr "извеждане на идентификатор на обект вмеÑто запазването му в указател" + +msgid "save the data to the given ref" +msgstr "запазване на данните в Ð´Ð°Ð´ÐµÐ½Ð¸Ñ ÑƒÐºÐ°Ð·Ð°Ñ‚ÐµÐ»" + +msgid "exactly one of --print and --to-ref is required" +msgstr "необходима е точно една от опциите „--print“ и „--to-ref“" + +msgid "skip and remove all lines starting with comment character" +msgstr "пропуÑкане на вÑички редове, които започват Ñ â€ž#“" + +msgid "prepend comment character and space to each line" +msgstr "добавÑне на „# “ в началото на вÑеки ред" #, c-format msgid "" @@ -13350,6 +13447,10 @@ msgstr "" "за Ñебе Ñи." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "не може да Ñе получи връзка към хранилище за подмодула „%s“" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "Във файла „.gitmodules“ не е открит Ð°Ð´Ñ€ÐµÑ Ð·Ð° Ð¿ÑŠÑ‚Ñ ÐºÑŠÐ¼ подмодул „%s“" @@ -13709,6 +13810,10 @@ msgstr "" "но той не е на никой клон" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "ИзиÑква Ñе пълно име на указател, а не „%s“" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "Текущата верÑÐ¸Ñ Ð·Ð° подмодула в „%s“ липÑва" @@ -13914,6 +14019,10 @@ msgstr "" "или „../“" #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "името на подмодул „%s“ вече Ñе ползва за Ð¿ÑŠÑ‚Ñ â€ž%s“" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "„%s“ е неправилно име за подмодул" @@ -14568,10 +14677,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "ПриготвÑне на работното дърво (изтеглÑне на „%s“)" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "недоÑтижим обект: неправилен указател: %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "ПодготвÑне на работно дърво (указателÑÑ‚ „HEAD“ не Ñвързан: %s)" @@ -14752,7 +14857,7 @@ msgstr "поправÑне: %s: „%s“" #, c-format msgid "error: %s: %s" -msgstr "грешка: %s: „%s“" +msgstr "ГРЕШКÐ: %s: „%s“" msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]" msgstr "git write-tree [--missing-ok] [--prefix=ПРЕФИКС/]" @@ -14876,8 +14981,9 @@ msgstr "Пратката изиÑква ÑÐ»ÐµÐ´Ð½Ð¸Ñ Ñ„Ð¸Ð»Ñ‚ÑŠÑ€: %s" msgid "unable to dup bundle descriptor" msgstr "неуÑпешно дублиране на деÑкриптора на пратката Ñ â€ždup“" +# заради git-po-helper не ползваме „git pack-objects“ msgid "Could not spawn pack-objects" -msgstr "Командата „git pack-objects“ не може да Ñе Ñтартира" +msgstr "ПроцеÑÑŠÑ‚ на git — „pack-objects“ не може да Ñе Ñтартира" msgid "pack-objects died" msgstr "Командата „git pack-objects“ не завърши уÑпешно" @@ -15684,7 +15790,7 @@ msgid "Finding commits for commit graph among packed objects" msgstr "Откриване на подаваниÑта в гра̀фа измежду пакетираните обекти" msgid "Finding extra edges in commit graph" -msgstr "Откриване на още върхове в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" +msgstr "Откриване на още ребра в гра̀фа Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" msgid "failed to write correct number of base graph ids" msgstr "" @@ -16238,14 +16344,6 @@ msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "неправилна чиÑлова ÑтойноÑÑ‚ „%s“ за „%s“ в %s: %s" #, c-format -msgid "invalid value for variable %s" -msgstr "неправилна ÑтойноÑÑ‚ за променливата „%s“" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "преÑкачане на Ð½ÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚ в наÑтройката „core.fsync“: „%s“" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "неправилна булева ÑтойноÑÑ‚ „%s“ за „%s“" @@ -16258,49 +16356,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "„%s“ не е правилна ÑтойноÑÑ‚ за време за „%s“" #, c-format -msgid "abbrev length out of range: %d" -msgstr "дължината на Ñъкращаване е извън диапазона ([4; 40]): %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "неправилно ниво на компреÑиране: %d" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s не може да Ñъдържа нови редове" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s трÑбва да Ñъдържа поне един знак" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "непознатата ÑтойноÑÑ‚ за „core.fsyncMethod“ — „%s“ Ñе преÑкача" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "" -"наÑтройката „core.fsyncObjectFiles“ е оÑтарÑла и е заменена Ñ â€žcore.fsync“" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "неправилен режим за Ñъздаването на обекти: %s" - -#, c-format -msgid "malformed value for %s" -msgstr "неправилна ÑтойноÑÑ‚ за „%s“" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "неправилна ÑтойноÑÑ‚ за „%s“: „%s“" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "" -"трÑбва да е една от Ñледните ÑтойноÑти: „nothing“ (без изтлаÑкване при липÑа " -"на указател), „matching“ (вÑички клони ÑÑŠÑ Ñъвпадащи имена), „simple“ " -"(клонът ÑÑŠÑ Ñъщото име, от който Ñе издърпва), „upstream“ (клонът, от който " -"Ñе издърпва) или „current“ (клонът ÑÑŠÑ Ñъщото име)" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "обектът-BLOB „%s“ Ñ ÐºÐ¾Ð½Ñ„Ð¸Ð³ÑƒÑ€Ð°Ñ†Ð¸Ð¸ не може да Ñе зареди" @@ -16833,8 +16888,8 @@ msgstr "ÑтандартниÑÑ‚ вход не може да Ñе Ñравни Ñ msgid "cannot compare a named pipe to a directory" msgstr "именован канал не може да Ñе Ñравни Ñ Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [ОПЦИЯ…] ПЪТ ПЪТ" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [ОПЦИЯ…] ПЪТ ПЪТ [ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -16843,6 +16898,13 @@ msgstr "" "Ðе е хранилище на git. Ползвайте опциÑта „--no-index“, за да Ñравните " "пътища извън работно дърво" +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"Ограничаването на Ñравнението чрез шаблони за пътища Ñе поддържа, Ñамо " +"когато и двата Ð¿ÑŠÑ‚Ñ Ñа директории." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" @@ -16902,7 +16964,7 @@ msgstr "" "външната програма за разлики завърши неуÑпешно. Спиране на работата при „%s“" msgid "--follow requires exactly one pathspec" -msgstr "опциÑта „--follow“ изиÑква точно един път" +msgstr "опциÑта „--follow“ изиÑква точно един шаблон за пътища" #, c-format msgid "pathspec magic not supported by --follow: %s" @@ -17365,7 +17427,7 @@ msgstr "ÐÑма път на име „%s“ в разликата" #, c-format msgid "pathspec '%s' did not match any file(s) known to git" -msgstr "пътÑÑ‚ „%s“ не Ñъвпада Ñ Ð½Ð¸ÐºÐ¾Ð¹ файл в git" +msgstr "шаблонът за пътища „%s“ не Ñъвпада Ñ Ð½Ð¸ÐºÐ¾Ð¹ файл в git" #, c-format msgid "unrecognized pattern: '%s'" @@ -17438,6 +17500,57 @@ msgid "bad git namespace path \"%s\"" msgstr "неправилен път към проÑтранÑтва от имена „%s“" #, c-format +msgid "invalid value for variable %s" +msgstr "неправилна ÑтойноÑÑ‚ за променливата „%s“" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "преÑкачане на Ð½ÐµÐ¿Ð¾Ð·Ð½Ð°Ñ‚Ð¸Ñ ÐºÐ¾Ð¼Ð¿Ð¾Ð½ÐµÐ½Ñ‚ в наÑтройката „core.fsync“: „%s“" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "дължината на Ñъкращаване е извън диапазона ([4; 40]): %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "неправилно ниво на компреÑиране: %d" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s не може да Ñъдържа нови редове" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s трÑбва да Ñъдържа поне един знак" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "непознатата ÑтойноÑÑ‚ за „core.fsyncMethod“ — „%s“ Ñе преÑкача" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "" +"наÑтройката „core.fsyncObjectFiles“ е оÑтарÑла и е заменена Ñ â€žcore.fsync“" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "неправилен режим за Ñъздаването на обекти: %s" + +#, c-format +msgid "malformed value for %s" +msgstr "неправилна ÑтойноÑÑ‚ за „%s“" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "неправилна ÑтойноÑÑ‚ за „%s“: „%s“" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "" +"трÑбва да е една от Ñледните ÑтойноÑти: „nothing“ (без изтлаÑкване при липÑа " +"на указател), „matching“ (вÑички клони ÑÑŠÑ Ñъвпадащи имена), „simple“ " +"(клонът ÑÑŠÑ Ñъщото име, от който Ñе издърпва), „upstream“ (клонът, от който " +"Ñе издърпва) или „current“ (клонът ÑÑŠÑ Ñъщото име)" + +#, c-format msgid "too many args to run %s" msgstr "прекалено много аргументи за изпълнение „%s“" @@ -18173,6 +18286,36 @@ msgstr "не може да Ñе ползва празно име като иде msgid "name consists only of disallowed characters: %s" msgstr "името Ñъдържа Ñамо непозволени знаци: „%s“" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) ПÐПКÐ] < ФÐЙЛ_С_ПОЩÐ" + +msgid "no IMAP host specified" +msgstr "не е указан хоÑÑ‚ за IMAP" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"задайте хоÑта за IMAP Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°:\n" +"\n" +" git config imap.host ХОСТ\n" +"\n" +"(например: „git config imap.host imaps://imap.example.com“)" + +msgid "no IMAP folder specified" +msgstr "не е указана папка за IMAP" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"задайте целевата папка Ñ ÐºÐ¾Ð¼Ð°Ð½Ð´Ð°Ñ‚Ð°:\n" +"\n" +" git config imap.folder ПÐПКÐ\n" +"\n" +"(например: „git config imap.folder Drafts“)" + msgid "expected 'tree:<depth>'" msgstr "очаква Ñе „tree:ДЪЛБОЧИÐГ" @@ -19174,6 +19317,26 @@ msgid "invalid object name '%.*s'." msgstr "неправилно име на обект: „%.*s“" #, c-format +msgid "invalid object type \"%s\"" +msgstr "неправилен вид обект: „%s“" + +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "обектът „%s“ е %s, а не %s" + +#, c-format +msgid "object %s has unknown type id %d" +msgstr "обектът „%s“ е непознат вид: %d" + +#, c-format +msgid "unable to parse object: %s" +msgstr "обектът „%s“ не може да Ñе анализира" + +#, c-format +msgid "hash mismatch %s" +msgstr "разлика в контролната Ñума: „%s“" + +#, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "" "директориÑта за обекти „%s“ не ÑъщеÑтвува, проверете „.git/objects/info/" @@ -19243,26 +19406,6 @@ msgid "%s is not a valid '%s' object" msgstr "„%s“ е неправилен обект от вид „%s“" #, c-format -msgid "invalid object type \"%s\"" -msgstr "неправилен вид обект: „%s“" - -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "обектът „%s“ е %s, а не %s" - -#, c-format -msgid "object %s has unknown type id %d" -msgstr "обектът „%s“ е непознат вид: %d" - -#, c-format -msgid "unable to parse object: %s" -msgstr "обектът „%s“ не може да Ñе анализира" - -#, c-format -msgid "hash mismatch %s" -msgstr "разлика в контролната Ñума: „%s“" - -#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "повтарÑщ Ñе Ð·Ð°Ð¿Ð¸Ñ Ð¿Ñ€Ð¸ запазване на Ð¸Ð½Ð´ÐµÐºÑ Ð½Ð° база битови маÑки: „%s“" @@ -19273,9 +19416,6 @@ msgstr "опит за ÑъхранÑване на подаване, което Ð msgid "too many pseudo-merges" msgstr "прекалено много пÑевдо ÑливаниÑ" -msgid "trying to write commit not in index" -msgstr "опит за запиÑване на обект за подаване извън индекÑа" - msgid "failed to load bitmap index (corrupted?)" msgstr "" "индекÑÑŠÑ‚ на база битови маÑки не може да Ñе зареди (възможно е да е повреден)" @@ -19556,6 +19696,10 @@ msgid "%s isn't available" msgstr "опциÑта „%s“ не е налична" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "ÑтойноÑтта %s е над %<PRIdMAX>" + +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "ÑтойноÑтта %s за „%s“ е извън диапазона [%<PRIdMAX>,%<PRIdMAX>]" @@ -19711,7 +19855,7 @@ msgid "how to strip spaces and #comments from message" msgstr "кои празни знаци и #коментари да Ñе махат от ÑъобщениÑта" msgid "read pathspec from file" -msgstr "изчитане на пътищата от ФÐЙЛ" +msgstr "изчитане на шаблоните за пътища от ФÐЙЛ" msgid "" "with --pathspec-from-file, pathspec elements are separated with NUL character" @@ -19757,14 +19901,15 @@ msgid "invalid attribute name %s" msgstr "неправилно име на атрибут: „%s“" msgid "global 'glob' and 'noglob' pathspec settings are incompatible" -msgstr "глобалните наÑтройки за пътища „glob“ и „noglob“ Ñа неÑъвмеÑтими" +msgstr "" +"глобалните наÑтройки за шаблони за пътища „glob“ и „noglob“ Ñа неÑъвмеÑтими" msgid "" "global 'literal' pathspec setting is incompatible with all other global " "pathspec settings" msgstr "" "глобалната наÑтройка за доÑловни пътища „literal“ е неÑъвмеÑтима Ñ Ð²Ñички " -"други глобални наÑтройки за пътища" +"други глобални наÑтройки за шаблони за пътища" msgid "invalid parameter for pathspec magic 'prefix'" msgstr "неправилен параметър за опциÑта за магичеÑки пътища „prefix“" @@ -19803,7 +19948,7 @@ msgstr "%s: магичеÑките пътища не Ñе поддържат Ð¾Ñ #, c-format msgid "pathspec '%s' is beyond a symbolic link" -msgstr "пътÑÑ‚ „%s“ е Ñлед Ñимволна връзка" +msgstr "шаблонът за пътища „%s“ е Ñлед Ñимволна връзка" #, c-format msgid "line is badly quoted: %s" @@ -20548,6 +20693,14 @@ msgid "%s does not point to a valid object!" msgstr "„%s“ не Ñочи към позволен обект!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s„%s“ ще оÑтане извън клоните Ñлед изтриването на „%s“\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s„%s“ оÑтана извън клоните Ñлед изтриването на „%s“\n" + +#, 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" @@ -21605,7 +21758,7 @@ msgid "" msgstr "" "След коригирането на конфликтите отбележете решаването им чрез:\n" "\n" -" git add/rm ПЪТ…\n" +" git add/rm ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…\n" "\n" "и изпълнете:\n" "\n" @@ -21630,7 +21783,7 @@ msgid "" msgstr "" "След коригирането на конфликтите отбележете решаването им чрез:\n" "\n" -" git add/rm ПЪТ…\n" +" git add/rm ШÐБЛОÐ_ЗÐ_ПЪТИЩÐ…\n" "\n" "и изпълнете:\n" "\n" @@ -22950,6 +23103,9 @@ msgid "toggle pruning of uninteresting paths" msgstr "" "превключване на окаÑтрÑнето на пътищата, които не предÑтавлÑват интереÑ" +msgid "toggle aggressive edge walk" +msgstr "превключване на агреÑивно обхождане на ребрата" + msgid "read a pattern list over stdin" msgstr "изчитане на ÑпиÑък Ñ ÑˆÐ°Ð±Ð»Ð¾Ð½Ð¸ от ÑÑ‚Ð°Ð½Ð´Ð°Ñ€Ñ‚Ð½Ð¸Ñ Ð²Ñ…Ð¾Ð´" @@ -23584,12 +23740,29 @@ msgid "fatal: " msgstr "фатална грешка: " msgid "error: " -msgstr "грешка: " +msgstr "ГРЕШКÐ: " msgid "warning: " msgstr "предупреждение: " #, c-format +msgid "" +"'%s' 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 "" +"ПредÑтои пълното премахване на „%s“.\n" +"Ðко вÑе още ползвате тази команда, добавете\n" +"опциÑта „--i-still-use-this“ на ÐºÐ¾Ð¼Ð°Ð½Ð´Ð½Ð¸Ñ Ñ€ÐµÐ´ и молим да\n" +"ни извеÑтите Ñ Ðµ-пиÑмо до пощенÑÐºÐ¸Ñ ÑпиÑък:\n" +"<git@vger.kernel.org>. Предварително благодарим.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "трÑбва да добавите и опциÑта „--i-still-use-this“" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "грешка при изпълнението на „uname()“ — „%s“ (%d)\n" @@ -24180,7 +24353,7 @@ msgstr "непознат Ñтил „%s“ за „%s“" msgid "" "Error: Your local changes to the following files would be overwritten by " "merge" -msgstr "Грешка: Сливането ще презапише локалните промѐни на тези файлове:" +msgstr "ГРЕШКÐ: Сливането ще презапише локалните промѐни на тези файлове:" msgid "Automated merge did not work." msgstr "Ðвтоматичното Ñливане не Ñработи." @@ -24541,6 +24714,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(Ñ‚Ñло) ДобавÑне на „Ñк: %s“ от ред „%s“\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "ГРЕШКÐ: неправилен порт за SMTP: „%s“\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Ðе може да Ñе изпълни „%s“" @@ -2,6 +2,7 @@ # This file is distributed under the same license as the Git package. # Alex Henrie <alexhenrie24@gmail.com>, 2014-2016. # Jordi Mas i Hernà ndez <jmas@softcatala.org>, 2016-2024 +# Mikel Forcada <mikel.forcada@gmail.com> 2024- # # Terminologia # @@ -18,17 +19,19 @@ # cover letter | carta de presentació # cruft | superflu # delta | diferència -# deprecated | en desús +# deprecated | en desús / obsolet # detached | separat # dry-run | fer una prova # fatal | fatal # fetch | obtenir # flush | buidar / buidatge # graph | graf +# graft | empelt / empeltar # hash | resum # hint | consell # hook | lligam # hunk | tros +# lock | blocatge, blocar # multi-pack-index | Ãndex multipaquet # not supported | no està admès # pull | baixar @@ -46,7 +49,7 @@ # upstream | font # # Alguns termes que són ordres especÃfiques del git i d'à mbit molt tècnic -# hem decidit no traduir-los per facilitar-ne la compressió a l'usuari i perquè +# hem decidit no traduir-los per a facilitar-ne la compressió a l'usuari i perquè # no tenen una transcendència al gran públic. Es tracta de casos similars # a «ping» en l'à mbit de xarxes. # @@ -77,8 +80,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2024-10-05 01:20+0000\n" -"PO-Revision-Date: 2024-10-05 09:03+0200\n" +"POT-Creation-Date: 2025-08-12 20:20-0400\n" +"PO-Revision-Date: 2025-08-15 22:35+0200\n" "Last-Translator: Mikel Forcada <mikel.forcada@gmail.com>\n" "Language-Team: Catalan\n" "Language: ca\n" @@ -90,6 +93,11 @@ msgstr "" #: add-interactive.c #, c-format +msgid "%s cannot be negative" +msgstr "%s no pot ser negatiu" + +#: add-interactive.c +#, c-format msgid "Huh (%s)?" msgstr "Perdó (%s)?" @@ -504,8 +512,8 @@ msgstr "" #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " msgstr "" -"Descarta el canvi de mode de l'Ãndex i de l'arbre de treball [y,n,q,a," -"d%s,?]? " +"Descarta el canvi de mode de l'Ãndex i de l'arbre de treball [y,n,q,a,d" +"%s,?]? " #: add-patch.c #, c-format @@ -832,10 +840,10 @@ msgstr "Només han canviat els fitxers binaris." #, c-format msgid "" "\n" -"Disable this message with \"git config advice.%s false\"" +"Disable this message with \"git config set advice.%s false\"" msgstr "" "\n" -"Desactiva aquest missatge amb «git config advice.%s false»" +"Desactiva aquest missatge amb «git config set advice.%s false»" #: advice.c #, c-format @@ -930,7 +938,7 @@ msgid "" "* Use the --sparse option.\n" "* Disable or modify the sparsity rules." msgstr "" -"Si voleu actualitzar aquestes entrades, proveu les següents solucions:\n" +"Si voleu actualitzar aquestes entrades, proveu les solucions següents:\n" "* Utilitzeu l'opció --sparse.\n" "* Inhabiliteu o modifiqueu les regles de dispersió." @@ -1024,11 +1032,10 @@ msgstr "opció ignora l'espai en blanc «%s» no reconeguda" #: builtin/describe.c builtin/diff-tree.c builtin/difftool.c #: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c #: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c -#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c -#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-list.c -#: builtin/rev-parse.c builtin/show-branch.c builtin/stash.c -#: builtin/submodule--helper.c builtin/tag.c builtin/worktree.c parse-options.c -#: range-diff.c revision.c +#: builtin/merge-tree.c builtin/merge.c builtin/rebase.c builtin/repack.c +#: builtin/replay.c builtin/reset.c builtin/rev-parse.c builtin/show-branch.c +#: builtin/stash.c builtin/submodule--helper.c builtin/tag.c builtin/worktree.c +#: parse-options.c range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "les opcions «%s» i «%s» no es poden usar juntes" @@ -1380,7 +1387,7 @@ msgstr "S'està comprovant el pedaç %s..." #: apply.c #, c-format msgid "sha1 information is lacking or useless for submodule %s" -msgstr "falta la informació sha1 o és inútil per al submòdul %s" +msgstr "hi manca la informació sha1 o és inútil per al submòdul %s" #: apply.c #, c-format @@ -1390,7 +1397,7 @@ msgstr "canvi de mode per a %s, el qual no està en la HEAD actual" #: apply.c #, c-format msgid "sha1 information is lacking or useless (%s)." -msgstr "falta informació sha1 o és inútil (%s)." +msgstr "hi manca informació sha1 o és inútil (%s)." #: apply.c #, c-format @@ -1779,7 +1786,7 @@ msgstr "cometes no tancades: «%s»" #: archive.c #, c-format msgid "missing colon: '%s'" -msgstr "falten els dos punts: «%s»" +msgstr "hi manquen els dos punts: «%s»" #: archive.c #, c-format @@ -1927,12 +1934,12 @@ msgstr "no es pot fer fstat gitattributes al fitxer «%s»" #: attr.c #, c-format msgid "ignoring overly large gitattributes file '%s'" -msgstr "s'ignorarà el fitxer «%s» gitattributes per a ser massa gran" +msgstr "s'ignorarà el fitxer «%s» gitattributes per ser massa gran" #: attr.c #, c-format msgid "ignoring overly large gitattributes blob '%s'" -msgstr "s'ignorarà el blob «%s» gitattributes per a ser massa gran" +msgstr "s'ignorarà el blob «%s» gitattributes per ser massa gran" #: attr.c msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo" @@ -1942,7 +1949,7 @@ msgstr "no es pot usar --attr-source o GIT_ATTR_SOURCE sense repository" msgid "bad --attr-source or GIT_ATTR_SOURCE" msgstr "--attr-source incorrecte o GIT_ATTR_SOURCE" -#: attr.c read-cache.c +#: attr.c read-cache.c refs/packed-backend.c #, c-format msgid "unable to stat '%s'" msgstr "no s'ha pogut fer «stat» a «%s»" @@ -2462,6 +2469,12 @@ msgstr "\"Useu -f si realment voleu afegir-los." msgid "adding files failed" msgstr "l'afegiment de fitxers ha fallat" +#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c +#: builtin/stash.c +#, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' no pot ser negatiu" + #: builtin/add.c #, c-format msgid "--chmod param '%s' must be either -x or +x" @@ -2500,7 +2513,7 @@ msgid "bad action '%s' for '%s'" msgstr "acció «%s» incorrecta per a «%s»" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c +#: builtin/pull.c builtin/revert.c diff-merges.c environment.c gpg-interface.c #: ls-refs.c parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" @@ -2794,7 +2807,7 @@ msgstr "executa interactivament" msgid "bypass pre-applypatch and applypatch-msg hooks" msgstr "evita els lligams pre-applypatch i applypatch-msg" -#: builtin/am.c +#: builtin/am.c builtin/cat-file.c msgid "historical option -- no-op" msgstr "opció històrica -- no-op" @@ -2982,6 +2995,22 @@ msgstr "git archive: error de protocol" msgid "git archive: expected a flush" msgstr "git archive: s'esperava una neteja" +#: builtin/backfill.c +msgid "git backfill [--min-batch-size=<n>] [--[no-]sparse]" +msgstr "git backfill [--min-batch-size=<n>] [--[no-]sparse]" + +#: builtin/backfill.c +msgid "problem loading sparse-checkout" +msgstr "s'ha produït un problema en carregar sparse-checkout" + +#: builtin/backfill.c +msgid "Minimum number of objects to request at a time" +msgstr "Nombre mÃnim d'objectes a sol·licitar d'una vegada." + +#: builtin/backfill.c +msgid "Restrict the missing objects to the current sparse-checkout" +msgstr "Restringeix els objectes que manquen al sparse-checkout actual" + #: builtin/bisect.c msgid "" "git bisect start [--term-(new|bad)=<term> --term-(old|good)=<term>] [--no-" @@ -3420,7 +3449,7 @@ msgstr "" msgid "ignore whitespace differences" msgstr "ignora les diferències d'espai en blanc" -#: builtin/blame.c builtin/log.c +#: builtin/blame.c builtin/clone.c builtin/log.c msgid "rev" msgstr "rev" @@ -3773,7 +3802,7 @@ msgstr "mou/canvia de nom una branca i el seu registre de referències" #: builtin/branch.c msgid "move/rename a branch, even if target exists" -msgstr "mou/canvia de nom una branca, encara que el destà existeixi" +msgstr "mou/canvia de nom una branca, encara que la destinació existeixi" #: builtin/branch.c builtin/for-each-ref.c builtin/tag.c msgid "do not output a newline after empty formatted refs" @@ -3785,7 +3814,7 @@ msgstr "copia una branca i el seu registre de referències" #: builtin/branch.c msgid "copy a branch, even if target exists" -msgstr "copia una branca, encara que el destà existeixi" +msgstr "copia una branca, encara que la destinació existeixi" #: builtin/branch.c msgid "list branch names" @@ -3944,11 +3973,6 @@ msgid "git version:\n" msgstr "versió de git:\n" #: builtin/bugreport.c -#, c-format -msgid "uname() failed with error '%s' (%d)\n" -msgstr "uname() ha fallat amb l'error «%s» (%d)\n" - -#: builtin/bugreport.c msgid "compiler info: " msgstr "informació del compilador: " @@ -4005,8 +4029,8 @@ msgstr "" "Reviseu la resta de l'informe d'error de sota.\n" "Podeu eliminar qualsevol lÃnia que vulgueu.\n" -#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c -#: parse-options.h +#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c +#: builtin/pack-objects.c builtin/rebase.c parse-options.h msgid "mode" msgstr "mode" @@ -4126,7 +4150,7 @@ msgstr "Cal un repositori per a desfer un farcell." msgid "Unbundling objects" msgstr "S'estan desagrupant objectes" -#: builtin/cat-file.c merge-recursive.c +#: builtin/cat-file.c #, c-format msgid "cannot read object %s '%s'" msgstr "no es pot llegir l'objecte %s «%s»" @@ -4163,12 +4187,8 @@ msgid "git cat-file <type> <object>" msgstr "git cat-file <tipus> <objecte>" #: builtin/cat-file.c -msgid "git cat-file (-e | -p) <object>" -msgstr "git cat-file (-e | -p) <objecte>" - -#: builtin/cat-file.c -msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objecte>" +msgid "git cat-file (-e | -p | -t | -s) <object>" +msgstr "git cat-file (-e | -p | -t | -s) <objecte>" #: builtin/cat-file.c msgid "" @@ -4216,10 +4236,6 @@ msgstr "" msgid "show object size" msgstr "mostra la mida de l'objecte" -#: builtin/cat-file.c -msgid "allow -s and -t to work with broken/corrupt objects" -msgstr "permet que -s i -t funcionin amb objectes trencats/malmesos" - #: builtin/cat-file.c builtin/log.c msgid "use mail map file" msgstr "usa el fitxer de mapa de correu" @@ -4293,6 +4309,15 @@ msgid "use a <path> for (--textconv | --filters); Not with 'batch'" msgstr "useu un <camÃ> per a (--textconv | --filters); no amb «batch»" #: builtin/cat-file.c +msgid "objects filter only supported in batch mode" +msgstr "el filtre d'objectes només s'admet en mode batch" + +#: builtin/cat-file.c +#, c-format +msgid "objects filter not supported: '%s'" +msgstr "filtre d'objectes no admès: %s" + +#: builtin/cat-file.c #, c-format msgid "'%s=<%s>' needs '%s' or '%s'" msgstr "«%s=<%s>» necessita «%s» o «%s»" @@ -4881,7 +4906,7 @@ msgstr "estil de conflicte desconegut «%s»" msgid "perform a 3-way merge with the new branch" msgstr "realitza una fusió de 3 vies amb la branca nova" -#: builtin/checkout.c builtin/log.c parse-options.h +#: builtin/checkout.c builtin/log.c builtin/range-diff.c parse-options.h msgid "style" msgstr "estil" @@ -4910,8 +4935,8 @@ msgid "update ignored files (default)" msgstr "actualitza els fitxers ignorats (per defecte)" #: builtin/checkout.c -msgid "do not check if another worktree is holding the given ref" -msgstr "no comprovis si un altre arbre de treball té la referència donada" +msgid "do not check if another worktree is using this branch" +msgstr "no comprovis si un altre arbre de treball usa aquesta branca" #: builtin/checkout.c msgid "checkout our version for unmerged files" @@ -4937,7 +4962,7 @@ msgstr "--track necessita un nom de branca" #: builtin/checkout.c #, c-format msgid "missing branch name; try -%c" -msgstr "falta el nom de la branca; proveu -%c" +msgstr "hi manca el nom de la branca; proveu -%c" #: builtin/checkout.c #, c-format @@ -5207,8 +5232,114 @@ msgstr "" "netejar" #: builtin/clone.c -msgid "git clone [<options>] [--] <repo> [<dir>]" -msgstr "git clone [<opcions>] [--] <repositori> [<directori>]" +#, c-format +msgid "info: Could not add alternate for '%s': %s\n" +msgstr "info: No s'ha pogut afegir un alternatiu per a «%s»: %s\n" + +#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c +#, c-format +msgid "failed to stat '%s'" +msgstr "s'ha produït un error en fer stat a «%s»" + +#: builtin/clone.c +#, c-format +msgid "%s exists and is not a directory" +msgstr "%s existeix i no és directori" + +#: builtin/clone.c +#, c-format +msgid "'%s' is a symlink, refusing to clone with --local" +msgstr "«%s» és un enllaç simbòlic, es rebutja clonar amb --local" + +#: builtin/clone.c +#, c-format +msgid "failed to start iterator over '%s'" +msgstr "no s'ha pogut iniciar l'iterador sobre «%s»" + +#: builtin/clone.c +#, c-format +msgid "symlink '%s' exists, refusing to clone with --local" +msgstr "l'enllaç simbòlic «%s» existeix, es rebutja a clonar amb --local" + +#: builtin/clone.c compat/precompose_utf8.c +#, c-format +msgid "failed to unlink '%s'" +msgstr "s'ha produït un error en desenllaçar «%s»" + +#: builtin/clone.c +#, c-format +msgid "hardlink cannot be checked at '%s'" +msgstr "no es pot comprovar l'enllaç fÃsic en «%s»" + +#: builtin/clone.c +#, c-format +msgid "hardlink different from source at '%s'" +msgstr "l'enllaç fÃsic és diferent de la font en «%s»" + +#: builtin/clone.c +#, c-format +msgid "failed to create link '%s'" +msgstr "s'ha produït un error en crear l'enllaç «%s»" + +#: builtin/clone.c +#, c-format +msgid "failed to copy file to '%s'" +msgstr "s'ha produït un error en copiar el fitxer a «%s»" + +#: builtin/clone.c refs/files-backend.c +#, c-format +msgid "failed to iterate over '%s'" +msgstr "no s'ha pogut iterar sobre «%s»" + +#: builtin/clone.c +#, c-format +msgid "done.\n" +msgstr "fet.\n" + +#: builtin/clone.c +msgid "" +"Clone succeeded, but checkout failed.\n" +"You can inspect what was checked out with 'git status'\n" +"and retry with 'git restore --source=HEAD :/'\n" +msgstr "" +"El clonatge ha tingut èxit, però no s'ha pogut agafar.\n" +"Podeu inspeccionar el que s'ha agafat amb «git status»\n" +"i tornar-ho a provar amb «git restore --source=HEAD :/»\n" + +#: builtin/clone.c fetch-pack.c +msgid "remote did not send all necessary objects" +msgstr "el remot no ha enviat tots els objectes necessaris" + +#: builtin/clone.c +#, c-format +msgid "unable to update %s" +msgstr "no s'ha pogut actualitzar %s" + +#: builtin/clone.c +msgid "failed to initialize sparse-checkout" +msgstr "no s'ha pogut inicialitzar «sparse-checkout»" + +#: builtin/clone.c +msgid "remote HEAD refers to nonexistent ref, unable to checkout" +msgstr "" +"el HEAD remot es refereix a una referència que no existeix, no s'ha pogut " +"agafar" + +#: builtin/clone.c +msgid "unable to checkout working tree" +msgstr "no s'ha pogut agafar l'arbre de treball" + +#: builtin/clone.c +msgid "unable to write parameters to config file" +msgstr "no s'han pogut escriure els parà metres al fitxer de configuració" + +#: builtin/clone.c +msgid "cannot repack to clean up" +msgstr "no es pot reempaquetar per a netejar" + +#: builtin/clone.c +msgid "cannot unlink temporary alternates file" +msgstr "no es pot desenllaçar el fitxer d'alternatives temporal" #: builtin/clone.c msgid "don't clone shallow repository" @@ -5281,6 +5412,10 @@ msgid "checkout <branch> instead of the remote's HEAD" msgstr "agafa <branca> en lloc de la HEAD del remot" #: builtin/clone.c +msgid "clone single revision <rev> and check out" +msgstr "clona només la revisió <rev> i agafa" + +#: builtin/clone.c msgid "path to git-upload-pack on the remote" msgstr "camà a git-upload-pack en el remot" @@ -5296,23 +5431,21 @@ msgstr "crea un clon superficial d'aquesta profunditat" msgid "create a shallow clone since a specific time" msgstr "crea un clon superficial des d'una data especÃfica" -#: builtin/clone.c builtin/fetch.c builtin/pull.c builtin/rebase.c -#: builtin/replay.c -msgid "revision" -msgstr "revisió" +#: builtin/clone.c builtin/fetch.c builtin/pull.c +msgid "ref" +msgstr "ref" #: builtin/clone.c builtin/fetch.c builtin/pull.c -msgid "deepen history of shallow clone, excluding rev" -msgstr "aprofundeix la història d'un clon superficial, excloent una revisió" +msgid "deepen history of shallow clone, excluding ref" +msgstr "aprofundeix la història d'un clon superficial, excloent referències" #: builtin/clone.c builtin/submodule--helper.c msgid "clone only one branch, HEAD or --branch" msgstr "clona només una branca, HEAD o --branch" #: builtin/clone.c -msgid "don't clone any tags, and make later fetches not to follow them" -msgstr "" -"no cloneu cap etiqueta, i feu que els «fetch» següents no les segueixin" +msgid "clone tags, and make later fetches not to follow them" +msgstr "cloneu les etiquetes, i feu que els «fetch» següents no les segueixin" #: builtin/clone.c msgid "any cloned submodules will be shallow" @@ -5371,119 +5504,8 @@ msgid "a URI for downloading bundles before fetching from origin remote" msgstr "un URI per a baixar paquets abans d'obtenir des del remot origen" #: builtin/clone.c -#, c-format -msgid "info: Could not add alternate for '%s': %s\n" -msgstr "info: No s'ha pogut afegir un alternatiu per a «%s»: %s\n" - -#: builtin/clone.c builtin/diff.c builtin/rm.c grep.c setup.c -#, c-format -msgid "failed to stat '%s'" -msgstr "s'ha produït un error en fer stat a «%s»" - -#: builtin/clone.c -#, c-format -msgid "%s exists and is not a directory" -msgstr "%s existeix i no és directori" - -#: builtin/clone.c -#, c-format -msgid "'%s' is a symlink, refusing to clone with --local" -msgstr "«%s» és un enllaç simbòlic, es rebutja clonar amb --local" - -#: builtin/clone.c -#, c-format -msgid "failed to start iterator over '%s'" -msgstr "no s'ha pogut iniciar l'iterador sobre «%s»" - -#: builtin/clone.c -#, c-format -msgid "symlink '%s' exists, refusing to clone with --local" -msgstr "l'enllaç simbòlic «%s» existeix, es rebutja a clonar amb --local" - -#: builtin/clone.c compat/precompose_utf8.c -#, c-format -msgid "failed to unlink '%s'" -msgstr "s'ha produït un error en desenllaçar «%s»" - -#: builtin/clone.c -#, c-format -msgid "hardlink cannot be checked at '%s'" -msgstr "no es pot comprovar l'enllaç fÃsic en «%s»" - -#: builtin/clone.c -#, c-format -msgid "hardlink different from source at '%s'" -msgstr "l'enllaç fÃsic és diferent de la font en «%s»" - -#: builtin/clone.c -#, c-format -msgid "failed to create link '%s'" -msgstr "s'ha produït un error en crear l'enllaç «%s»" - -#: builtin/clone.c -#, c-format -msgid "failed to copy file to '%s'" -msgstr "s'ha produït un error en copiar el fitxer a «%s»" - -#: builtin/clone.c refs/files-backend.c -#, c-format -msgid "failed to iterate over '%s'" -msgstr "no s'ha pogut iterar sobre «%s»" - -#: builtin/clone.c -#, c-format -msgid "done.\n" -msgstr "fet.\n" - -#: builtin/clone.c -msgid "" -"Clone succeeded, but checkout failed.\n" -"You can inspect what was checked out with 'git status'\n" -"and retry with 'git restore --source=HEAD :/'\n" -msgstr "" -"El clonatge ha tingut èxit, però no s'ha pogut agafar.\n" -"Podeu inspeccionar el que s'ha agafat amb «git status»\n" -"i tornar-ho a provar amb «git restore --source=HEAD :/»\n" - -#: builtin/clone.c -#, c-format -msgid "Could not find remote branch %s to clone." -msgstr "No s'ha pogut trobar la branca remota %s per a clonar." - -#: builtin/clone.c fetch-pack.c -msgid "remote did not send all necessary objects" -msgstr "el remot no ha enviat tots els objectes necessaris" - -#: builtin/clone.c -#, c-format -msgid "unable to update %s" -msgstr "no s'ha pogut actualitzar %s" - -#: builtin/clone.c -msgid "failed to initialize sparse-checkout" -msgstr "no s'ha pogut inicialitzar «sparse-checkout»" - -#: builtin/clone.c -msgid "remote HEAD refers to nonexistent ref, unable to checkout" -msgstr "" -"el HEAD remot es refereix a una referència que no existeix, no s'ha pogut " -"agafar" - -#: builtin/clone.c -msgid "unable to checkout working tree" -msgstr "no s'ha pogut agafar l'arbre de treball" - -#: builtin/clone.c -msgid "unable to write parameters to config file" -msgstr "no s'han pogut escriure els parà metres al fitxer de configuració" - -#: builtin/clone.c -msgid "cannot repack to clean up" -msgstr "no es pot reempaquetar per a netejar" - -#: builtin/clone.c -msgid "cannot unlink temporary alternates file" -msgstr "no es pot desenllaçar el fitxer d'alternatives temporal" +msgid "git clone [<options>] [--] <repo> [<dir>]" +msgstr "git clone [<opcions>] [--] <repositori> [<directori>]" #: builtin/clone.c msgid "Too many arguments." @@ -5512,12 +5534,12 @@ msgstr "la profunditat %s no és un nombre positiu" #: builtin/clone.c #, c-format msgid "destination path '%s' already exists and is not an empty directory." -msgstr "el camà destà «%s» ja existeix i no és un directori buit." +msgstr "el camà de destinació «%s» ja existeix i no és un directori buit." #: builtin/clone.c #, c-format msgid "repository path '%s' already exists and is not an empty directory." -msgstr "el camà destà «%s» ja existeix i no és un directori buit." +msgstr "el camà de destinació «%s» ja existeix i no és un directori buit." #: builtin/clone.c #, c-format @@ -5614,6 +5636,11 @@ msgid "Remote branch %s not found in upstream %s" msgstr "La branca remota %s no es troba en la font %s" #: builtin/clone.c +#, c-format +msgid "Remote revision %s not found in upstream %s" +msgstr "La branca remota %s no es troba en la font %s " + +#: builtin/clone.c msgid "You appear to have cloned an empty repository." msgstr "Sembla que heu clonat un repositori buit." @@ -5676,7 +5703,8 @@ msgstr "" "[no-]progress]\n" " <split-options>" -#: builtin/commit-graph.c builtin/fetch.c builtin/log.c builtin/repack.c +#: builtin/commit-graph.c builtin/fetch.c builtin/gc.c builtin/log.c +#: builtin/repack.c msgid "dir" msgstr "directori" @@ -5836,7 +5864,7 @@ msgstr "git commit-tree: ha fallat en llegir" #: builtin/commit.c msgid "" -"git commit [-a | --interactive | --patch] [-s] [-v] [-u<mode>] [--amend]\n" +"git commit [-a | --interactive | --patch] [-s] [-v] [-u[<mode>]] [--amend]\n" " [--dry-run] [(-c | -C | --squash) <commit> | --fixup [(amend|" "reword):]<commit>]\n" " [-F <file> | -m <msg>] [--reset-author] [--allow-empty]\n" @@ -6466,28 +6494,30 @@ msgstr "git config list [<opció-fitxer>] [<opció-presentació>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<opció-fitxer>] [<opció-presentació>] [--includes] [--all] " -"[--regexp] [--value=<valor>] [--fixed-value] [--default=<default>] <nom>" +"[--regexp] [--value=<patró>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <nom>" # Cal traduir els parà metres amb <...>? #: builtin/config.c msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<opció-fitxer>] [--type=<tipus>] [--all] [--value=<valor>] " +"git config set [<opció-fitxer>] [--type=<tipus>] [--all] [--value=<patró>] " "[--fixed-value] <nom> <valor>" # Cal traduir els parà metres amb <...>? #: builtin/config.c msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " -"<name> <value>" +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " +"<name>" msgstr "" -"git config unset [<opció-fitxer>] [--all] [--value=<valor>] [--fixed-value] " -"<name> <valor>" +"git config unset [<opció-fitxer>] [--all] [--value=<patró>] [--fixed-value] " +"<nom>" #: builtin/config.c msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -6512,21 +6542,21 @@ msgstr "git config [<opció-fitxer>] --get-colorbool <nom> [<stdout-is-tty>]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<opció-fitxer>] [<opció-presentació>] [--includes] [--all] " -"[--regexp=<expr-reg>] [--value=<valor>] [--fixed-value] [--" +"[--regexp=<expr-reg>] [--value=<patró>] [--fixed-value] [--" "default=<default>] <nom>" # Cal traduir els parà metres amb <...>? #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<opció-fitxer>] [--type=<tipus>] [--comment=<missatge>] [--" -"all] [--value=<valor>] [--fixed-value] <nom> <valor>" +"all] [--value=<patró>] [--fixed-value] <nom> <valor>" #: builtin/config.c msgid "Config file location" @@ -6778,7 +6808,7 @@ msgstr "valor" #: builtin/config.c msgid "use default value when missing entry" -msgstr "utilitza el valor per defecte quan falti una entrada" +msgstr "utilitza el valor per defecte quan hi manqui una entrada" #: builtin/config.c msgid "--fixed-value only applies with 'value-pattern'" @@ -6916,7 +6946,7 @@ msgstr "troba la configuració de color: slot [<stdout-is-tty>]" #: builtin/config.c msgid "with --get, use default value when missing entry" -msgstr "amb --get utilitza el valor per defecte quan falti una entrada" +msgstr "amb --get utilitza el valor per defecte quan hi manqui una entrada" #: builtin/config.c msgid "--get-color and variable type are incoherent" @@ -6983,7 +7013,7 @@ msgstr "" #, c-format msgid "unable to get credential storage lock in %d ms" msgstr "" -"no s'ha pogut obtenir el bloqueig de l'emmagatzematge de credencials en %d ms" +"no s'ha pogut obtenir el blocatge de l'emmagatzematge de credencials en %d ms" #: builtin/describe.c msgid "" @@ -7065,12 +7095,8 @@ msgstr "%lu comissions recorregudes\n" #: builtin/describe.c #, c-format -msgid "" -"more than %i tags found; listed %i most recent\n" -"gave up search at %s\n" -msgstr "" -"s'han trobat més de %i etiquetes: s'han llistat les %i més recents\n" -"s'ha renunciat la cerca a %s\n" +msgid "found %i tags; gave up search at %s\n" +msgstr "trobades %i etiquetes; s'ha abandonat la recerca en %s\n" #: builtin/describe.c #, c-format @@ -7172,6 +7198,64 @@ msgstr "especifiqueu un sufix en format strftime per al nom de fitxer" msgid "specify the content of the diagnostic archive" msgstr "especifica el contingut de l'arxiu de diagnòstic" +#: builtin/diff-pairs.c +#, c-format +msgid "unable to parse mode: %s" +msgstr "no s'ha pogut analitzar el mode: %s" + +#: builtin/diff-pairs.c +#, c-format +msgid "unable to parse object id: %s" +msgstr "no s'ha pogut analitzar l'identificador d'objecte: %s" + +#: builtin/diff-pairs.c +msgid "git diff-pairs -z [<diff-options>]" +msgstr "git diff-pairs -z [<opcions-diferencia>]" + +#: builtin/diff-pairs.c builtin/log.c builtin/replay.c builtin/shortlog.c +#: bundle.c +#, c-format +msgid "unrecognized argument: %s" +msgstr "argument no reconegut: %s" + +#: builtin/diff-pairs.c +msgid "working without -z is not supported" +msgstr "no s'admet treballar sense -z" + +#: builtin/diff-pairs.c +msgid "pathspec arguments not supported" +msgstr "arguments de l'especificació de camà no admesos" + +#: builtin/diff-pairs.c +msgid "revision arguments not allowed" +msgstr "arguments de revisió no permesos" + +#: builtin/diff-pairs.c +msgid "invalid raw diff input" +msgstr "entrada de diff crua invà lida" + +#: builtin/diff-pairs.c +msgid "tree objects not supported" +msgstr "no s'admeten els objectes d'arbre" + +#: builtin/diff-pairs.c +msgid "got EOF while reading path" +msgstr "rebut un EOF durant la lectura del camÃ" + +#: builtin/diff-pairs.c +msgid "got EOF while reading destination path" +msgstr "rebut un EOF durant la lectura del camà de destinació" + +#: builtin/diff-pairs.c +#, c-format +msgid "unable to parse rename/copy score: %s" +msgstr "no s'ha pogut analitzar puntuació de canvi de nom/còpia: %s" + +#: builtin/diff-pairs.c +#, c-format +msgid "unknown diff status: %c" +msgstr "estat de diff desconegut: %c" + #: builtin/diff-tree.c msgid "--merge-base only works with two commits" msgstr "--merge-base només funciona amb dues comissions" @@ -7354,6 +7438,10 @@ msgid "select handling of signed tags" msgstr "selecciona la gestió de les etiquetes signades" #: builtin/fast-export.c +msgid "select handling of signed commits" +msgstr "selecciona la gestió de les etiquetes signades" + +#: builtin/fast-export.c msgid "select handling of tags that tag filtered objects" msgstr "selecciona la gestió de les etiquetes que etiquetin objectes filtrats" @@ -7460,7 +7548,7 @@ msgstr "" #: builtin/fetch-pack.c #, c-format msgid "Lockfile created but not reported: %s" -msgstr "S'ha creat el fitxer de bloqueig però no s'ha informat: %s" +msgstr "S'ha creat el fitxer de blocatge però no s'ha informat: %s" #: builtin/fetch.c msgid "git fetch [<options>] [<repository> [<refspec>...]]" @@ -7581,26 +7669,6 @@ msgstr "" "s'ha rebutjat %s perquè no es permeten actualitzar les arrels superficials" #: builtin/fetch.c -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"algunes referències locals no s'han pogut actualitzar;\n" -" intenteu executar «git remote prune %s» per a eliminar\n" -" qualsevol branca antiga o conflictiva" - -#: builtin/fetch.c -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s es tornarà despenjat)" - -#: builtin/fetch.c -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s s'ha quedat despenjat)" - -#: builtin/fetch.c msgid "[deleted]" msgstr "[suprimit]" @@ -7623,7 +7691,7 @@ msgstr "l'opció «%s» amb valor «%s» no és và lida per a %s" msgid "option \"%s\" is ignored for %s" msgstr "l'opció «%s» s'ignora per a «%s»" -#: builtin/fetch.c object-file.c +#: builtin/fetch.c odb.c #, c-format msgid "%s is not a valid object" msgstr "%s no és un objecte và lid" @@ -7634,6 +7702,36 @@ msgid "the object %s does not exist" msgstr "l'objecte %s no existeix" #: builtin/fetch.c +#, c-format +msgid "" +"Run 'git remote set-head %s %s' to follow the change, or set\n" +"'remote.%s.followRemoteHEAD' configuration option to a different value\n" +"if you do not want to see this message. Specifically running\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"will disable the warning until the remote changes HEAD to something else." +msgstr "" +"Executeu 'git remote set-head %s %s' per a seguir el canvi, o fixeu\n" +"l'opció de configuració 'remote.%s.followRemoteHEAD' a un valor diferent\n" +"si no voleu veure aquest missatge. EspecÃficament, si executeu\n" +"'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" +"es deshabilitarà l'avÃs fins que el remot canviï HEAD a alguna altra cosa." + +#: builtin/fetch.c +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"algunes referències locals no s'han pogut actualitzar;\n" +" intenteu executar «git remote prune %s» per a eliminar\n" +" qualsevol branca antiga o conflictiva" + +#: builtin/fetch.c +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "l'obtenció de la referència %s ha fallat: %s" + +#: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "s'han detectat múltiples branques, incompatible amb --set-upstream" @@ -7810,6 +7908,10 @@ msgstr "mapa de referències" msgid "specify fetch refmap" msgstr "especÃfica l'obtenció del mapa de referències" +#: builtin/fetch.c builtin/pull.c builtin/rebase.c builtin/replay.c +msgid "revision" +msgstr "revisió" + #: builtin/fetch.c builtin/pull.c msgid "report that we have only objects reachable from this object" msgstr "informa que només hi ha objectes abastables des d'aquest objecte" @@ -7919,7 +8021,7 @@ msgstr "usa <text> com a inici de missatge" #: builtin/fmt-merge-msg.c msgid "use <name> instead of the real target branch" -msgstr "usa <nom> en lloc de la branca de destà real" +msgstr "usa <nom> en lloc de la branca de destinació real" #: builtin/fmt-merge-msg.c msgid "file to read from" @@ -7943,6 +8045,10 @@ msgstr "" "git for-each-ref [--contains [<comissió>]] [--no-contains [<comissió>]]" #: builtin/for-each-ref.c +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <marcador>]" + +#: builtin/for-each-ref.c msgid "quote placeholders suitably for shells" msgstr "" "posa els marcadors de posició entre cometes adequades per a intèrprets " @@ -7964,6 +8070,14 @@ msgstr "posa els marcadors de posició entre cometes adequades per al Tcl" msgid "show only <n> matched refs" msgstr "mostra només <n> referències coincidents" +#: builtin/for-each-ref.c +msgid "marker" +msgstr "marca" + +#: builtin/for-each-ref.c +msgid "start iteration after the provided marker" +msgstr "comença la iteració després del marcador proporcionat" + #: builtin/for-each-ref.c builtin/tag.c msgid "respect format colors" msgstr "respecta els colors del format" @@ -7997,9 +8111,18 @@ msgid "also include HEAD ref and pseudorefs" msgstr "inclou també la referència HEAD i les pseudoreferències" #: builtin/for-each-ref.c +msgid "cannot use --start-after with custom sort options" +msgstr "" +"no es pot utilitzar --start-after amb opcions personalitzades d'ordenació" + +#: builtin/for-each-ref.c msgid "unknown arguments supplied with --stdin" msgstr "s'han proporcionat arguments desconeguts amb --stdin" +#: builtin/for-each-ref.c +msgid "cannot use --start-after with patterns" +msgstr "no es pot utilitzar --start-after amb patrons" + #: builtin/for-each-repo.c msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<config> [--] <arguments>" @@ -8018,7 +8141,7 @@ msgstr "continua fins i tot si l'ordre falla en un repositori" #: builtin/for-each-repo.c msgid "missing --config=<config>" -msgstr "falta --config=<config>" +msgstr "hi manca --config=<config>" #: builtin/for-each-repo.c #, c-format @@ -8163,11 +8286,6 @@ msgstr "%s: objecte corrupte o no trobat: %s" #: builtin/fsck.c #, c-format -msgid "%s: object is of unknown type '%s': %s" -msgstr "%s: l'objecte és de tipus desconegut «%s»: %s" - -#: builtin/fsck.c -#, c-format msgid "%s: object could not be parsed: %s" msgstr "%s: no s'ha pogut analitzar l'objecte: %s" @@ -8239,11 +8357,15 @@ msgid "invalid rev-index for pack '%s'" msgstr "rev-index no và lid per al paquet «%s»" #: builtin/fsck.c +msgid "Checking ref database" +msgstr "S'està comprovant la base de dades de referències" + +#: builtin/fsck.c msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" -" [--[no-]name-objects] [<object>...]" +" [--[no-]name-objects] [--[no-]references] [<object>...]" msgstr "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" @@ -8298,6 +8420,10 @@ msgstr "mostra el progrés" msgid "show verbose names for reachable objects" msgstr "mostra els noms detallats dels objectes abastables" +#: builtin/fsck.c +msgid "check reference database consistency" +msgstr "comprova la consistència de les base de dades de referències" + #: builtin/fsck.c builtin/index-pack.c msgid "Checking objects" msgstr "S'estan comprovant els objectes" @@ -8305,7 +8431,7 @@ msgstr "S'estan comprovant els objectes" #: builtin/fsck.c #, c-format msgid "%s: object missing" -msgstr "%s: falta l'objecte" +msgstr "%s: hi manca l'objecte" #: builtin/fsck.c #, c-format @@ -8496,6 +8622,15 @@ msgstr "" msgid "repack all other packs except the largest pack" msgstr "reempaqueta tots els altres paquets excepte el paquet més gran" +#: builtin/gc.c builtin/repack.c +msgid "pack prefix to store a pack containing pruned objects" +msgstr "" +"prefix del paquet per a emmagatzemar un paquet que contingui objectes podats" + +#: builtin/gc.c +msgid "skip maintenance tasks typically done in the foreground" +msgstr "omet les tasques de manteniment que es fan tÃpicament en primer pla" + #: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" @@ -8590,13 +8725,13 @@ msgstr "" #: builtin/gc.c #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "el fitxer de bloqueig «%s» existeix, s'omet el manteniment" +msgid "task '%s' failed" +msgstr "la tasca «%s» ha fallat" #: builtin/gc.c #, c-format -msgid "task '%s' failed" -msgstr "la tasca «%s» ha fallat" +msgid "lock file '%s' exists, skipping maintenance" +msgstr "el fitxer de blocatge «%s» existeix, s'omet el manteniment" #: builtin/gc.c #, c-format @@ -8637,10 +8772,6 @@ msgid "run a specific task" msgstr "executa una tasca especÃfica" #: builtin/gc.c -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "usa com a mà xim un entre --auto i --schedule=<freqüència>" - -#: builtin/gc.c #, c-format msgid "unable to add '%s' value of '%s'" msgstr "no es pot afegir el valor «%s» de «%s»" @@ -8742,8 +8873,28 @@ msgid "%s scheduler is not available" msgstr "el planificador %s no està disponible" #: builtin/gc.c -msgid "another process is scheduling background maintenance" -msgstr "un altre procés està planificant un manteniment en segon pla" +#, c-format +msgid "" +"unable to create '%s.lock': %s.\n" +"\n" +"Another scheduled git-maintenance(1) process seems to be running in this\n" +"repository. Please make sure no other maintenance processes are running and\n" +"then try again. If it still fails, a git-maintenance(1) process may have\n" +"crashed in this repository earlier: remove the file manually to continue." +msgstr "" +"No s'ha pogut crear «%s.lock»: %s.\n" +"\n" +"Sembla que un altre procés git-maintenance(1) s'està executant en aquest\n" +"repositori. Assegureu-vos que no hi ha cap altre proés de manteniment en " +"execució\n" +"i llavors proveu de nou. Si encara falla, potser un procés git-" +"maintenance(1) \n" +"ha fallat en aquest repositori abans: elimineu el fitxer manualment per a " +"continuar." + +#: builtin/gc.c +msgid "cannot acquire lock for scheduled background maintenance" +msgstr "no puc adquirir un blocatge per al manteniment en segona mà planificat" #: builtin/gc.c msgid "git maintenance start [--scheduler=<scheduler>]" @@ -9483,9 +9634,36 @@ msgstr[0] "longitud de cadena = %d: %lu objecte" msgstr[1] "longitud de cadena = %d: %lu objectes" #: builtin/index-pack.c +msgid "could not start pack-objects to repack local links" +msgstr "" +"no s'ha pogut iniciar pack-objects per a tornar a empaquetar els enllaços " +"locals" + +#: builtin/index-pack.c +msgid "failed to feed local object to pack-objects" +msgstr "no s'ha pogut alimentar pack-objects amb l'objecte local" + +#: builtin/index-pack.c +msgid "index-pack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"index-pack: s'esperen lÃnies amb l'identificador d'objecte hexadecimal " +"complet des de pack-objects." + +#: builtin/index-pack.c +msgid "could not finish pack-objects to repack local links" +msgstr "" +"no s'ha pogut finalitzar pack-objects per a tornar a empaquetar els enllaços " +"locals" + +#: builtin/index-pack.c msgid "Cannot come back to cwd" msgstr "No es pot tornar al directori de treball actual" +#: builtin/index-pack.c builtin/unpack-objects.c +#, c-format +msgid "bad --pack_header: %s" +msgstr "--pack_header incorrecte: %s" + #: builtin/index-pack.c #, c-format msgid "bad %s" @@ -9497,6 +9675,10 @@ msgid "unknown hash algorithm '%s'" msgstr "algorisme de resum desconegut «%s»" #: builtin/index-pack.c +msgid "--promisor cannot be used with a pack name" +msgstr "--promisor no es pot usar amb un nom de paquet" + +#: builtin/index-pack.c msgid "--stdin requires a git repository" msgstr "--stdin requereix un repositori git" @@ -9636,7 +9818,7 @@ msgstr "acció si el «trailer» ja existeix" #: builtin/interpret-trailers.c msgid "action if trailer is missing" -msgstr "acció si el «trailer» falta" +msgstr "acció si el «trailer» hi manca" #: builtin/interpret-trailers.c msgid "output only the trailers" @@ -9716,22 +9898,12 @@ msgstr "" "traça l'evolució del rang de lÃnia <inici>,<final> o funcions :<nom-funció> " "a <fitxer>" -#: builtin/log.c builtin/replay.c builtin/shortlog.c bundle.c -#, c-format -msgid "unrecognized argument: %s" -msgstr "argument no reconegut: %s" - #: builtin/log.c msgid "-L<range>:<file> cannot be used with pathspec" msgstr "-L<rang>:<fitxer> no es pot usar amb una especificació de camÃ" #: builtin/log.c #, c-format -msgid "Final output: %d %s\n" -msgstr "Sortida final: %d %s\n" - -#: builtin/log.c -#, c-format msgid "git show %s: bad file" msgstr "git show %s: fitxer incorrecte" @@ -10572,6 +10744,10 @@ msgid "also show informational/conflict messages" msgstr "també mostra missatges informatius i de conflictes" #: builtin/merge-tree.c +msgid "suppress all output; only exit status wanted" +msgstr "suprimeix tota la sortida; només es vol l'estat de sortida" + +#: builtin/merge-tree.c msgid "list filenames without modes/oids/stages" msgstr "llista els noms de fitxer sense modes/oids/stages" @@ -10609,11 +10785,6 @@ msgstr "opció d'estratègia desconeguda: -X%s" msgid "malformed input line: '%s'." msgstr "lÃnia d'entrada mal formada: «%s»." -#: builtin/merge-tree.c -#, c-format -msgid "merging cannot continue; got unclean result of %d" -msgstr "la fusió no pot continuar; s'ha obtingut un resultat no net de %d" - #: builtin/merge.c msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<opcions>] [<comissió>...]" @@ -10655,6 +10826,10 @@ msgid "(synonym to --stat)" msgstr "(sinònim de --stat)" #: builtin/merge.c builtin/pull.c +msgid "show a compact-summary at the end of the merge" +msgstr "mostra un compact-summary al final de la fusió" + +#: builtin/merge.c builtin/pull.c msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "afegeix (com a mà xim <n>) entrades del registre curt al missatge de comissió " @@ -10699,7 +10874,7 @@ msgstr "missatge de comissió de fusió (per a una fusió no d'avanç rà pid)" #: builtin/merge.c msgid "use <name> instead of the real target" -msgstr "usa <nom> en lloc de destà real" +msgstr "usa <nom> en lloc de destinació real" #: builtin/merge.c msgid "abort the current in-progress merge" @@ -10738,7 +10913,7 @@ msgstr "read-tree ha fallat" msgid "Already up to date. (nothing to squash)" msgstr "Ja està actualitzat. (res a fer «squash»)" -#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c +#: builtin/merge.c merge-ort-wrappers.c msgid "Already up to date." msgstr "Ja està al dia." @@ -10762,7 +10937,7 @@ msgstr "«%s» no assenyala una comissió" msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Cadena branch.%s.mergeoptions incorrecta: %s" -#: builtin/merge.c merge-recursive.c +#: builtin/merge.c merge-ort-wrappers.c msgid "Unable to write index." msgstr "No s'ha pogut escriure l'Ãndex." @@ -10793,7 +10968,8 @@ msgid "" "\n" msgstr "" "Introduïu un missatge de comissió per a explicar per què aquesta fusió és\n" -"necessà ria, especialment si es fusiona una branca amb funcionalitat nova.\n" +"necessà ria, especialment si es fusiona una font actualitzada amb una branca " +"de tòpic.\n" "\n" #: builtin/merge.c @@ -10926,7 +11102,7 @@ msgstr "Es pot fusionar només una comissió a una HEAD buida" msgid "Updating %s..%s\n" msgstr "S'estan actualitzant %s..%s\n" -#: builtin/merge.c merge-ort-wrappers.c merge-recursive.c +#: builtin/merge.c merge-ort-wrappers.c #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -10994,11 +11170,6 @@ msgstr "error: l'entrada d'etiqueta no passa fsck: %s" #: builtin/mktag.c #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) no hauria d'activar mai aquesta crida de retorn" - -#: builtin/mktag.c -#, c-format msgid "could not read tagged object '%s'" msgstr "no s'ha pogut llegir l'objecte etiquetat «%s»" @@ -11096,8 +11267,12 @@ msgstr "" "en un lot que és més gran que aquesta mida" #: builtin/mv.c -msgid "git mv [<options>] <source>... <destination>" -msgstr "git mv [<opcions>] <origen>... <destÃ>" +msgid "git mv [-v] [-f] [-n] [-k] <source> <destination>" +msgstr "git mv [-v] [-f] [-n] [-k] <origen> <destinacio>" + +#: builtin/mv.c +msgid "git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>" +msgstr "git mv [-v] [-f] [-n] [-k] <origen>... <directori-destinacio>" #: builtin/mv.c #, c-format @@ -11117,7 +11292,7 @@ msgstr "%.*s és en l'Ãndex" #: builtin/mv.c msgid "force move/rename even if target exists" -msgstr "força el moviment / canvi de nom encara que el destà existeixi" +msgstr "força el moviment / canvi de nom encara que la destinació existeixi" #: builtin/mv.c msgid "skip move/rename errors" @@ -11126,7 +11301,7 @@ msgstr "omet els errors de moviment / canvi de nom" #: builtin/mv.c #, c-format msgid "destination '%s' is not a directory" -msgstr "el destà «%s» no és un directori" +msgstr "la destinació «%s» no és un directori" #: builtin/mv.c #, c-format @@ -11139,7 +11314,7 @@ msgstr "origen incorrecte" #: builtin/mv.c msgid "destination exists" -msgstr "el destà existeix" +msgstr "la destinació existeix" #: builtin/mv.c msgid "can not move directory into itself" @@ -11172,20 +11347,25 @@ msgstr "No es pot sobreescriure" #: builtin/mv.c msgid "multiple sources for the same target" -msgstr "múltiples orÃgens per al mateix destÃ" +msgstr "múltiples orÃgens per a la mateixa destinació" #: builtin/mv.c msgid "destination directory does not exist" -msgstr "el directori destà no existeix" +msgstr "el directori de destinació no existeix" #: builtin/mv.c msgid "destination exists in the index" -msgstr "el destà existeix a l'Ãndex" +msgstr "la destinació existeix a l'Ãndex" #: builtin/mv.c #, c-format msgid "%s, source=%s, destination=%s" -msgstr "%s, origen=%s, destÃ=%s" +msgstr "%s, origen=%s, destinació=%s" + +#: builtin/mv.c +#, c-format +msgid "cannot move both '%s' and its parent directory '%s'" +msgstr "no puc moure «%s» i el seu directori pare «%s» simultà niament" #: builtin/mv.c #, c-format @@ -11247,60 +11427,59 @@ msgstr "desreferencia les etiquetes en l'entrada (ús intern)" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] [list [<object>]]" -msgstr "git notes [--ref <referència-de-notes>] [llista [<objecte>]]" +msgstr "git notes [--ref <referència-notes>] [llista [<objecte>]]" #: builtin/notes.c msgid "" "git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" -"git notes [--ref <notes-ref>] add [-f] [--allow-empty] [--[no-]separator|--" -"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <fitxer> | (-" -"c | -C) <object>] [<object>]" +"git notes [--ref <referència-notes>] add [-f] [--allow-empty] [--" +"[no-]separator|--separator=<salt-parà graf>] [--[no-]stripspace] [-m <msg> | -" +"F <fitxer> | (-c | -C) <objecte>] [<objecte>]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" msgstr "" -"git notes [--ref <referència-de-notes>] copy [-f] <objecte-de> <objecte-a>" +"git notes [--ref <referència-notes>] copy [-f] <objecte-de> <objecte-a>" #: builtin/notes.c msgid "" "git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" "separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <file> | (-c " -"| -C) <object>] [<object>]" +"| -C) <object>] [<object>] [-e]" msgstr "" -"git notes [--ref <notes-ref>] append [--allow-empty] [--[no-]separator|--" -"separator=<paragraph-break>] [--[no-]stripspace] [-m <msg> | -F <fitxer> | (-" -"c | -C) <objecte>] [<objecte>]" +"git notes [--ref <referència-notes>] append [--allow-empty] [--" +"[no-]separator|--separator=<salt-parà graf>] [--[no-]stripspace] [-m <msg> | -" +"F <fitxer> | (-c | -C) <objecte>] [<objecte>] [-e]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] edit [--allow-empty] [<object>]" -msgstr "" -"git notes [--ref <referència-de-notes>] edit [--allow-empty] [<objecte>]" +msgstr "git notes [--ref <referència-notes>] edit [--allow-empty] [<objecte>]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] show [<object>]" -msgstr "git notes [--ref <referència-de-notes>] show [<objecte>]" +msgstr "git notes [--ref <referència-notes>] show [<objecte>]" #: builtin/notes.c msgid "" "git notes [--ref <notes-ref>] merge [-v | -q] [-s <strategy>] <notes-ref>" msgstr "" -"git notes [--ref <referència-de-notes>] merge [-v | -q] [-s <estratègia>] " -"<referència-de-notes>" +"git notes [--ref <referència-notes>] merge [-v | -q] [-s <estratègia>] " +"<referència-notes>" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] remove [<object>...]" -msgstr "git notes [--ref <referència-de-notes>] remove [<objecte>...]" +msgstr "git notes [--ref <referència-notes>] remove [<objecte>...]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] prune [-n] [-v]" -msgstr "git notes [--ref <referència-de-notes>] prune [-n] [-v]" +msgstr "git notes [--ref <referència-notes>] prune [-n] [-v]" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] get-ref" -msgstr "git notes [--ref <referència-de-notes>] get-ref" +msgstr "git notes [--ref <referència-notes>] get-ref" #: builtin/notes.c msgid "git notes [list [<object>]]" @@ -11332,7 +11511,7 @@ msgstr "git notes show [<objecte>]" #: builtin/notes.c msgid "git notes merge [<options>] <notes-ref>" -msgstr "git notes merge [<opcions>] <referència-de-notes>" +msgstr "git notes merge [<opcions>] <referència-notes>" #: builtin/notes.c msgid "git notes merge --commit [<options>]" @@ -11428,6 +11607,10 @@ msgid "reuse and edit specified note object" msgstr "reusa i edita l'objecte de nota especificat" #: builtin/notes.c +msgid "edit note message in editor" +msgstr "edita el missatge d'anotació en l'editor" + +#: builtin/notes.c msgid "reuse specified note object" msgstr "reusa l'objecte de nota especificat" @@ -11644,7 +11827,7 @@ msgstr "referència de notes" #: builtin/notes.c msgid "use notes from <notes-ref>" -msgstr "usa les notes de <referència-de-notes>" +msgstr "usa les notes de <referència-notes>" #: builtin/notes.c builtin/remote.c parse-options.c #, c-format @@ -11652,14 +11835,35 @@ msgid "unknown subcommand: `%s'" msgstr "subordre desconeguda: «%s»" #: builtin/pack-objects.c -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "git pack-objects --stdout [<opcions>] [< <ref-list> | < <object-list>]" +msgid "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<nom-paquet>]\n" +" [--cruft] [--cruft-expiration=<data>]\n" +" [--stdout [--filter=<especificacio-filtre>] | <nom-base>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <lista-objectes>" #: builtin/pack-objects.c -msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects [<opcions>] <base-name> [< <ref-list> | < <object-list>]" +#, c-format +msgid "invalid --name-hash-version option: %d" +msgstr "opció --name-hash-version no và lida: %d" + +#: builtin/pack-objects.c +msgid "currently, --write-bitmap-index requires --name-hash-version=1" +msgstr "actualment, --write-bitmap-index requereix --name-hash-version=1" #: builtin/pack-objects.c #, c-format @@ -11786,6 +11990,17 @@ msgid "unable to get type of object %s" msgstr "no s'ha pogut obtenir el tipus de l'objecte: %s" #: builtin/pack-objects.c +msgid "Compressing objects by path" +msgstr "S'estan comprimint els objectes per camÃ" + +#: builtin/pack-objects.c +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "La compressió de diferències basada en camins usa fins a %d fil" +msgstr[1] "La compressió de diferències basada en camins usa fins a %d fils" + +#: builtin/pack-objects.c msgid "Compressing objects" msgstr "S'estan comprimint els objectes" @@ -11878,6 +12093,10 @@ msgid "unable to force loose object" msgstr "no s'ha pogut forçar l'objecte solt" #: builtin/pack-objects.c +msgid "failed to pack objects via path-walk" +msgstr "no s'ha pogut empaquetar els objectes via path-walk" + +#: builtin/pack-objects.c #, c-format msgid "not a rev '%s'" msgstr "«%s» no és una revisió" @@ -12030,6 +12249,10 @@ msgid "create thin packs" msgstr "crea paquets prims" #: builtin/pack-objects.c +msgid "use the path-walk API to walk objects when possible" +msgstr "useu l'API path-walk per a recórrer objectes sempre que sigui possible" + +#: builtin/pack-objects.c msgid "create packs suitable for shallow fetches" msgstr "crea paquets adequats per a les obtencions superficials" @@ -12072,6 +12295,10 @@ msgid "do not pack objects in promisor packfiles" msgstr "no empaquetis els objectes als fitxers de paquet «promisor»" #: builtin/pack-objects.c +msgid "implies --missing=allow-any" +msgstr "implica --missing=allow-any" + +#: builtin/pack-objects.c msgid "respect islands during delta compression" msgstr "respecta les illes durant la compressió delta" @@ -12085,6 +12312,10 @@ msgstr "" "exclou qualsevol uploadpack.blobpackfileuri configurat amb aquest protocol" #: builtin/pack-objects.c +msgid "use the specified name-hash function to group similar objects" +msgstr "usa la funció name-hash especificada per a agrupar objectes similars" + +#: builtin/pack-objects.c #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "la profunditat de la cadena delta %d és massa profunda, forçant %d" @@ -12094,7 +12325,12 @@ msgstr "la profunditat de la cadena delta %d és massa profunda, forçant %d" msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit és massa alt, forçant %d" -#: builtin/pack-objects.c config.c +#: builtin/pack-objects.c +#, c-format +msgid "cannot use %s with %s" +msgstr "no es pot usar %s amb %s" + +#: builtin/pack-objects.c environment.c #, c-format msgid "bad pack compression level %d" msgstr "nivell de compressió de paquet %d erroni" @@ -12114,10 +12350,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "--thin no es pot utilitzar per a construir un paquet indexable" #: builtin/pack-objects.c -msgid "cannot use --filter with --stdin-packs" -msgstr "no es pot utilitzar --filter sense --stdin-packs" - -#: builtin/pack-objects.c msgid "cannot use internal rev list with --stdin-packs" msgstr "no es pot utilitzar la llista de revisió interna amb --stdin-packs" @@ -12126,10 +12358,6 @@ msgid "cannot use internal rev list with --cruft" msgstr "no es pot utilitzar la llista de revisió interna amb --cruft" #: builtin/pack-objects.c -msgid "cannot use --stdin-packs with --cruft" -msgstr "no es pot --stdin-packs amb --cruft" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "S'estan enumerant els objectes" @@ -12142,24 +12370,6 @@ msgstr "" "Total %<PRIu32> (%<PRIu32> diferències), reusats %<PRIu32> (%<PRIu32> " "diferències), paquets reusats %<PRIu32> (de %<PRIuMAX>)" -#: builtin/pack-redundant.c -msgid "" -"'git pack-redundant' is nominated for removal.\n" -"If you still use this command, please add an extra\n" -"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 "" -"«git pack-redundant» està nominat per a la seva supressió.\n" -"Si encara feu servir aquesta ordre, afegiu-hi l'opció\n" -"addicional, «--i-still-use-this», a la lÃnia d'ordres\n" -"i feu-nos saber que encara l'useu enviant un correu electrònic\n" -"a <git@vger.kernel.org>. Grà cies.\n" - -#: builtin/pack-redundant.c -msgid "refusing to run without --i-still-use-this" -msgstr "es rebutja a executar sense --i-still-use-this" - #: builtin/pack-refs.c msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " @@ -12355,6 +12565,11 @@ msgstr "" msgid "unable to access commit %s" msgstr "no s'ha pogut accedir a la comissió %s" +#: builtin/pull.c refspec.c +#, c-format +msgid "invalid refspec '%s'" +msgstr "refspec no và lida: «%s»" + #: builtin/pull.c msgid "ignoring --verify-signatures for rebase" msgstr "s'està ignorant --verify-signatures en fer «rebase»" @@ -12463,7 +12678,7 @@ msgstr "abreviatura d'etiqueta sense <etiqueta>" #: builtin/push.c msgid "--delete only accepts plain target ref names" -msgstr "--delete només accepta noms de referència de destà senzills" +msgstr "--delete només accepta noms de referència de destinació senzills" #: builtin/push.c msgid "" @@ -12533,9 +12748,8 @@ msgid "" "upstream, see 'push.autoSetupRemote' in 'git help config'.\n" msgstr "" "\n" -"Per fer que això succeeixi automà ticament per a les branques sense " -"seguiment\n" -"font, vegeu «push.autoSetupRemote» a «git help config».\n" +"Per fer que això succeeixi automà ticament per a les fonts sense seguiment,\n" +"vegeu «push.autoSetupRemote» a «git help config».\n" #: builtin/push.c #, c-format @@ -12555,8 +12769,7 @@ msgstr "" #: builtin/push.c #, c-format msgid "The current branch %s has multiple upstream branches, refusing to push." -msgstr "" -"La branca actual %s té múltiples branques fonts, s'està refusant pujar." +msgstr "La branca actual %s té múltiples branques font; s'està refusant pujar." #: builtin/push.c msgid "" @@ -12759,7 +12972,7 @@ msgid "" "\n" " git push <name>\n" msgstr "" -"No hi ha cap destà de pujada configurat.\n" +"No hi ha cap destinació de pujada configurat.\n" "Especifiqueu l'URL des de la lÃnia d'ordres o bé configureu un repositori " "remot fent servir\n" "\n" @@ -12922,7 +13135,7 @@ msgid "" "[<upstream> [<branch>]]" msgstr "" "git rebase [-i] [options] [--exec <ordre>] [--onto <newbase> | --keep-base] " -"[<upstream> [<branca>]]" +"[<font> [<branca>]]" #: builtin/rebase.c msgid "" @@ -13018,8 +13231,8 @@ msgstr "--empty=ask és obslolet; utilitzeu '--empty=stop' en el seu lloc." #: builtin/rebase.c #, c-format msgid "" -"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " -"\"stop\"." +"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"stop" +"\"." msgstr "" "tipus buit «%s» no reconegut; els valors và lids són \"drop\", \"keep\" i " "\"stop\"." @@ -13510,6 +13723,10 @@ msgid "git reflog exists <ref>" msgstr "git reflog exists <referència>" #: builtin/reflog.c +msgid "git reflog drop [--all [--single-worktree] | <refs>...]" +msgstr "git reflog drop [--all [--single-worktree] | <refs>...]" + +#: builtin/reflog.c #, c-format msgid "invalid timestamp '%s' given to '--%s'" msgstr "marca de temps «%s» donada a «--%s» no és và lida" @@ -13577,8 +13794,8 @@ msgstr "S'estan marcant els objectes abastables..." #: builtin/reflog.c #, c-format -msgid "%s points nowhere!" -msgstr "%s no apunta a enlloc" +msgid "reflog could not be found: '%s'" +msgstr "no s'ha pogut trobar el reflog: «%s»" #: builtin/reflog.c msgid "no reflog specified to delete" @@ -13589,9 +13806,21 @@ msgstr "no s'ha especificat cap registre de referències per a suprimir" msgid "invalid ref format: %s" msgstr "format de referència no và lid: %s" +#: builtin/reflog.c +msgid "drop the reflogs of all references" +msgstr "descarta els reflogs de totes les referències" + +#: builtin/reflog.c +msgid "drop reflogs from the current worktree only" +msgstr "descarta només els reflogs de l'arbre de treball actual" + +#: builtin/reflog.c +msgid "references specified along with --all" +msgstr "referències especificades conjuntament amb --all" + #: builtin/refs.c -msgid "git refs migrate --ref-format=<format> [--dry-run]" -msgstr "git refs migrate --ref-format=<format> [--dry-run]" +msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" +msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" #: builtin/refs.c msgid "git refs verify [--strict] [--verbose]" @@ -13606,8 +13835,12 @@ msgid "perform a non-destructive dry-run" msgstr "fes una prova no destructiva" #: builtin/refs.c +msgid "drop reflogs entirely during the migration" +msgstr "descarta completament els reflogs durant la migració" + +#: builtin/refs.c msgid "missing --ref-format=<format>" -msgstr "falta --ref-format=<format>" +msgstr "hi manca --ref-format=<format>" #: builtin/refs.c #, c-format @@ -13725,6 +13958,18 @@ msgid "unknown --mirror argument: %s" msgstr "argument de «--mirror» desconegut: %s" #: builtin/remote.c +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "el nom remot «%s» és un subconjunt del remot existent «%s»" + +#: builtin/remote.c +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "" +"el nom remot «%s» és un supeconjunt\n" +" del remot existent «%s»" + +#: builtin/remote.c msgid "fetch the remote branches" msgstr "obtén les branques remotes" @@ -14040,6 +14285,35 @@ msgstr[0] " Referència local configurada per a «git push»%s:" msgstr[1] " Referències locals configurades per a «git push»%s:" #: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is unchanged and points to '%s'\n" +msgstr "«%s/HEAD» no ha canviat i apunta a «%s»\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' has changed from '%s' and now points to '%s'\n" +msgstr "«%s/HEAD» ha canviat des de «%s» i ara apunta a «%s»\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' is now created and points to '%s'\n" +msgstr "«%s/HEAD» s'ha creat ara i apunta a «%s»\n" + +#: builtin/remote.c +#, c-format +msgid "'%s/HEAD' was detached at '%s' and now points to '%s'\n" +msgstr "«%s/HEAD» s'ha separat en «%s» i ara apunta a «%s»\n" + +#: builtin/remote.c +#, c-format +msgid "" +"'%s/HEAD' used to point to '%s' (which is not a remote branch), but now " +"points to '%s'\n" +msgstr "" +"«%s/HEAD» solia apuntar a «%s» (que no és una branca remota), però ara " +"apunta a«%s»\n" + +#: builtin/remote.c msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "estableix refs/remotes/<nom>/HEAD segons el remot" @@ -14067,21 +14341,11 @@ msgstr "No és una referència và lida: %s" #: builtin/remote.c #, c-format -msgid "Could not setup %s" +msgid "Could not set up %s" msgstr "No s'ha pogut configurar %s" #: builtin/remote.c #, c-format -msgid " %s will become dangling!" -msgstr " %s es quedara despenjat!" - -#: builtin/remote.c -#, c-format -msgid " %s has become dangling!" -msgstr " %s s'ha quedat despenjat!" - -#: builtin/remote.c -#, c-format msgid "Pruning %s" msgstr "S'està podant %s" @@ -14160,8 +14424,14 @@ msgid "be verbose; must be placed before a subcommand" msgstr "sigues detallat; s'ha de col·locar abans d'una subordre" #: builtin/repack.c -msgid "git repack [<options>]" -msgstr "git repack [<opcions>]" +msgid "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" +msgstr "" +"git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" +"[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<nom-paquet>]\n" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" #: builtin/repack.c msgid "" @@ -14254,6 +14524,10 @@ msgid "with --cruft, expire objects older than this" msgstr "amb --cruft, vencen els objectes més antics que aquest" #: builtin/repack.c +msgid "with --cruft, only repack cruft packs smaller than this" +msgstr "amb --cruft, empaqueta només els objectes més petits que aquest" + +#: builtin/repack.c msgid "remove redundant packs, and run git-prune-packed" msgstr "elimina els paquets redundants, i executeu git-prune-packed" @@ -14266,6 +14540,17 @@ msgid "pass --no-reuse-object to git-pack-objects" msgstr "passa --no-reuse-object a git-pack-objects" #: builtin/repack.c +msgid "" +"specify the name hash version to use for grouping similar objects by path" +msgstr "" +"especifica la versió de hash de noms que s'ha d'usar per a agrupar objectes " +"similars per camÃ" + +#: builtin/repack.c +msgid "pass --path-walk to git-pack-objects" +msgstr "passa --path-walk a git-pack-objects" + +#: builtin/repack.c msgid "do not run git-update-server-info" msgstr "no executis git-update-server-info" @@ -14332,11 +14617,6 @@ msgid "write a multi-pack index of the resulting packs" msgstr "escriu un Ãndex multipaquet dels paquets resultants" #: builtin/repack.c -msgid "pack prefix to store a pack containing pruned objects" -msgstr "" -"prefix del paquet per a emmagatzemar un paquet que contingui objectes podats" - -#: builtin/repack.c msgid "pack prefix to store a pack containing filtered out objects" msgstr "" "prefix del paquet per a emmagatzemar un paquet que contingui objectes " @@ -14525,7 +14805,7 @@ msgstr "no s'ha pogut escriure la comissió de reemplaçament per a: «%s»" #: builtin/replace.c #, c-format msgid "graft for '%s' unnecessary" -msgstr "«graft» per a «%s» innecessari" +msgstr "l'empelt per a «%s» és innecessari" #: builtin/replace.c #, c-format @@ -14538,7 +14818,7 @@ msgid "" "could not convert the following graft(s):\n" "%s" msgstr "" -"no s'han pogut convertir els següents «grafts»:\n" +"no s'han pogut convertir els empelts següents:\n" "%s" #: builtin/replace.c @@ -14559,7 +14839,7 @@ msgstr "canvia els pares d'una comissió" #: builtin/replace.c msgid "convert existing graft file" -msgstr "converteix el fitxer «graft» existent" +msgstr "converteix el fitxer d'empelts existent" #: builtin/replace.c msgid "replace the ref if it exists" @@ -14614,10 +14894,6 @@ msgid "need some commits to replay" msgstr "calen algunes comissions per tornar a reproduir" #: builtin/replay.c -msgid "--onto and --advance are incompatible" -msgstr "--onto i --advance són incompatibles" - -#: builtin/replay.c msgid "all positive revisions given must be references" msgstr "totes les revisions positives que s'han donat han de ser referències" @@ -14867,6 +15143,10 @@ msgid "invalid value for '%s': '%s', the only allowed format is '%s'" msgstr "valor no và lid per a «%s»: «%s», l'únic format permès és «%s»" #: builtin/rev-list.c +msgid "-z option used with unsupported option" +msgstr "l'opció -z s'ha usat amb una opció no admesa" + +#: builtin/rev-list.c msgid "rev-list does not support display of notes" msgstr "el rev-list no permet mostrar notes" @@ -15733,20 +16013,28 @@ msgid "git stash create [<message>]" msgstr "git stash create [<missatge>]" #: builtin/stash.c +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <referència>) [<stash>...]" + +#: builtin/stash.c +msgid "git stash import <commit>" +msgstr "git stash import [<comissió>]" + +#: builtin/stash.c #, c-format msgid "'%s' is not a stash-like commit" msgstr "«%s» no és una comissió de tipus «stash»" #: builtin/stash.c +msgid "No stash entries found." +msgstr "No s'ha trobat cap entrada «stash»." + +#: builtin/stash.c #, c-format msgid "Too many revisions specified:%s" msgstr "S'han especificat massa revisions:%s" #: builtin/stash.c -msgid "No stash entries found." -msgstr "No s'ha trobat cap entrada «stash»." - -#: builtin/stash.c #, c-format msgid "%s is not a valid reference" msgstr "«%s» no és una referència và lida" @@ -15942,6 +16230,88 @@ msgstr "inclou els fitxers no seguits a «stash»" msgid "include ignore files" msgstr "inclou els fitxers ignorats" +#: builtin/stash.c +#, c-format +msgid "cannot parse commit %s" +msgstr "no s'ha pogut analitzar la comissió %s" + +#: builtin/stash.c +#, c-format +msgid "invalid author or committer for %s" +msgstr "autor o comissor invà lid per a %s" + +#: builtin/stash.c +msgid "could not write commit" +msgstr "no s'ha pogut escriure la comissió" + +#: builtin/stash.c +#, c-format +msgid "not a valid revision: %s" +msgstr "«%s» no és una revisió và lida" + +#: builtin/stash.c +#, c-format +msgid "not a commit: %s" +msgstr "no és una comissió: «%s»" + +#: builtin/stash.c +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "«%s» no és una comissió de «stash» exportada và lida" + +#: builtin/stash.c +#, c-format +msgid "found root commit %s with invalid data" +msgstr "s'ha trobat la comissió %s amb dades invà lides" + +#: builtin/stash.c +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "s'ha trobat una comissió de «stash» %s sense el prefix esperat" + +#: builtin/stash.c +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "no es poden analitzar els pares de la comissió: %s" + +#: builtin/stash.c +#, c-format +msgid "%s does not look like a stash commit" +msgstr "«%s» no sembla una comissió de «stash»" + +#: builtin/stash.c +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "no es pot llegir la memòria intermèdia de comissió per a %s" + +#: builtin/stash.c +#, c-format +msgid "cannot save the stash for %s" +msgstr "no es pot desar l'«stash» per a %s" + +#: builtin/stash.c +msgid "unable to write base commit" +msgstr "no s'ha pogut escriure la comissió base %s" + +#: builtin/stash.c +#, c-format +msgid "unable to find stash entry %s" +msgstr "no s'ha pogut trobar l'entrada de «stash» %s" + +#: builtin/stash.c +msgid "print the object ID instead of writing it to a ref" +msgstr "" +"imprimeix l'identificador de l'objecte en comptes d'escriure'l en una " +"referència" + +#: builtin/stash.c +msgid "save the data to the given ref" +msgstr "desa les dades en la referència donada" + +#: builtin/stash.c +msgid "exactly one of --print and --to-ref is required" +msgstr "es requereix exactament una de --print i --to-ref" + #: builtin/stripspace.c msgid "skip and remove all lines starting with comment character" msgstr "" @@ -15953,16 +16323,6 @@ msgstr "anteposa el carà cter de comentari i un espai a cada lÃnia" #: builtin/submodule--helper.c #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "S'espera un nom de referència ple, s'ha rebut %s" - -#: builtin/submodule--helper.c -#, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "no s'ha pogut obtenir el gestor del repositori pel submòdul «%s»" - -#: builtin/submodule--helper.c -#, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " "authoritative upstream." @@ -15972,6 +16332,11 @@ msgstr "" #: builtin/submodule--helper.c #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "no s'ha pogut obtenir el gestor del repositori pel submòdul «%s»" + +#: builtin/submodule--helper.c +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "No s'ha trobat cap url per al camà de submòdul «%s» a .gitmodules" @@ -16298,7 +16663,7 @@ msgid "" msgstr "" "git submodule--helper clone [--prefix=<camÃ>] [--quiet] [--reference " "<repositori>] [--name <nom>] [--depth <depth>] [--single-branch] [--filter " -"<filter-spec>] --url <url> --path <camÃ>" +"<especificacio-filtre>] --url <url> --path <camÃ>" #: builtin/submodule--helper.c #, c-format @@ -16412,6 +16777,11 @@ msgstr "" #: builtin/submodule--helper.c #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "S'espera un nom de referència ple, s'ha rebut %s" + +#: builtin/submodule--helper.c +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "No s'ha pogut trobar la revisió actual al camà del submòdul «%s»" @@ -16490,10 +16860,10 @@ msgid "" "shallow] [--reference <repository>] [--recursive] [--[no-]single-branch] " "[--] [<path>...]" msgstr "" -"git submodule [--quiet] update [--init [--filter=<filter-spec>]] [--remote] " -"[-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--[no-]recommend-" -"shallow] [--reference <repositori>] [--recursive] [--[no-]single-branch] " -"[--] [<camÃ>...]" +"git submodule [--quiet] update [--init [--filter=<especificacio-filtre>]] [--" +"remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--" +"[no-]recommend-shallow] [--reference <repositori>] [--recursive] [--" +"[no-]single-branch] [--] [<camÃ>...]" #: builtin/submodule--helper.c submodule.c msgid "Failed to resolve HEAD as a valid ref." @@ -16665,6 +17035,11 @@ msgstr "URL de repositori: «%s» ha de ser absolut o començar amb ./|../" #: builtin/submodule--helper.c #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "el nom de submòdul «%s» ja s'usa per al camà «%s»" + +#: builtin/submodule--helper.c +#, c-format msgid "'%s' is not a valid submodule name" msgstr "«%s» no és un nom de submòdul và lid" @@ -16714,7 +17089,7 @@ msgid "" " [(--trailer <token>[(=|:)<value>])...]\n" " <tagname> [<commit> | <object>]" msgstr "" -"git tag [-a | -s | -u <id-clau>] [-f] [-m <missatge> | -F <fitxer>] [-e]\n" +"git tag [-a | -s | -u <id-clau>] [-f] [-m <msg> | -F <fitxer>] [-e]\n" " [(--trailer <token>[(=|:)<valor>])...]\n" " <nom-etiqueta> [<comissió> | <objecte>]" @@ -17219,8 +17594,8 @@ msgid "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" msgstr "git update-ref [<opcions>] <nom-referència> <oid-nou> [<oid-vell>]" #: builtin/update-ref.c -msgid "git update-ref [<options>] --stdin [-z]" -msgstr "git update-ref [<opcions>] --stdin [-z]" +msgid "git update-ref [<options>] --stdin [-z] [--batch-updates]" +msgstr "git update-ref [<opcions>] --stdin [-z] [--batch-updates]" #: builtin/update-ref.c msgid "delete the reference" @@ -17238,6 +17613,10 @@ msgstr "stdin té arguments acabats amb NUL" msgid "read updates from stdin" msgstr "llegeix les actualitzacions des de stdin" +#: builtin/update-ref.c +msgid "batch reference updates" +msgstr "actualitzacions de les referències de batch" + #: builtin/update-server-info.c msgid "update the info files from scratch" msgstr "actualitza els fitxers d'informació des de zero" @@ -17464,11 +17843,6 @@ msgstr "S'està preparant l'arbre de treball (s'està agafant «%s»)" #: builtin/worktree.c #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "no accessible: referència no và lida: %s" - -#: builtin/worktree.c -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "S'està preparant l'arbre de treball (HEAD %s separat)" @@ -17529,6 +17903,10 @@ msgstr "" "prova de fer coincidir el nom de la branca nova amb una branca amb seguiment " "remot" +#: builtin/worktree.c +msgid "use relative paths for worktrees" +msgstr "usa camins relatius per als arbres de treball" + #: builtin/worktree.c diff.c parse-options.c #, c-format msgid "options '%s', '%s', and '%s' cannot be used together" @@ -17602,7 +17980,7 @@ msgstr "«%s» és un arbre de treball principal" #: builtin/worktree.c #, c-format msgid "could not figure out destination name from '%s'" -msgstr "no s'ha pogut deduir el nom de destà des de «%s»" +msgstr "no s'ha pogut deduir el nom de destinació des de «%s»" #: builtin/worktree.c #, c-format @@ -17610,7 +17988,7 @@ msgid "" "cannot move a locked working tree, lock reason: %s\n" "use 'move -f -f' to override or unlock first" msgstr "" -"no es pot moure un arbre de treball bloquejat, raó del bloqueig: %s\n" +"no es pot moure un arbre de treball bloquejat, raó del blocatge: %s\n" "useu primer «move -f -f» per a sobreescriure'l o desbloquejar-lo primer" #: builtin/worktree.c @@ -17658,7 +18036,7 @@ msgid "" "cannot remove a locked working tree, lock reason: %s\n" "use 'remove -f -f' to override or unlock first" msgstr "" -"no es pot suprimir un arbre de treball bloquejat, raó del bloqueig: %s\n" +"no es pot suprimir un arbre de treball bloquejat, raó del blocatge: %s\n" "useu primer «remove -f -f» per a sobreescriure'l o desbloquejar-lo" #: builtin/worktree.c @@ -17873,6 +18251,32 @@ msgstr "no es pot crear «%s»" msgid "index-pack died" msgstr "l'index-pack s'ha mort" +#: cache-tree.c +#, c-format +msgid "directory '%s' is present in index, but not sparse" +msgstr "El directori %s és en l'Ãndex però no és dispers" + +#: cache-tree.c unpack-trees.c +msgid "corrupted cache-tree has entries not present in index" +msgstr "el cache-tree corromput té entrades que no apareixen en l'Ãndex" + +#: cache-tree.c +#, c-format +msgid "%s with flags 0x%x should not be in cache-tree" +msgstr "%s amb els indicadors 0x%x no hauria de ser en el cache-tree" + +#: cache-tree.c +#, c-format +msgid "bad subtree '%.*s'" +msgstr "subarbre incorrecte «%.*s»" + +#: cache-tree.c +#, c-format +msgid "cache-tree for path %.*s does not match. Expected %s got %s" +msgstr "" +"el cache-tree per al camà %.*s no coincideix. S'esperava %s i s'ha obtingut " +"%s" + #: chunk-format.c msgid "terminating chunk id appears earlier than expected" msgstr "" @@ -17932,6 +18336,10 @@ msgid "Create an archive of files from a named tree" msgstr "Crea un arxiu de fitxers des d'un arbre amb nom" #: command-list.h +msgid "Download missing objects in a partial clone" +msgstr "Descarrega els objectes que manquen en un clon parcial" + +#: command-list.h msgid "Use binary search to find the commit that introduced a bug" msgstr "Troba per cerca binà ria el canvi que hagi introduït un defecte" @@ -18076,6 +18484,10 @@ msgid "Compare a tree to the working tree or index" msgstr "Compara un arbre amb l'arbre de treball o l'Ãndex" #: command-list.h +msgid "Compare the content and mode of provided blob pairs" +msgstr "Compara el contingut i el mode dels blobs proporcionats" + +#: command-list.h msgid "Compares the content and mode of blobs found via two tree objects" msgstr "" "Compara el contingut i el mode dels blobs trobats a través de dos objectes " @@ -19048,13 +19460,13 @@ msgid "" "to convert the grafts into replace refs.\n" "\n" "Turn this message off by running\n" -"\"git config advice.graftFileDeprecated false\"" +"\"git config set advice.graftFileDeprecated false\"" msgstr "" "La compatibilitat amb <GIT_DIR>/info/grafts és obsoleta\n" "i s'eliminarà en una futura versió del Git.\n" "\n" "Useu «git replace --convert-graft-file»\n" -"per a convertir els grafs en referències de reemplaçament.\n" +"per a convertir els empelts en referències de reemplaçament.\n" "\n" "Desactiveu aquest missatge executant\n" "«git config advice.graftFileDeprecated false»" @@ -19395,12 +19807,12 @@ msgstr "format de configuració no và lid: %s" #: config.c #, c-format msgid "missing environment variable name for configuration '%.*s'" -msgstr "falta el nom de la variable d'entorn per a la configuració «%.*s»" +msgstr "manca el nom de la variable d'entorn per a la configuració «%.*s»" #: config.c #, c-format msgid "missing environment variable '%s' for configuration '%.*s'" -msgstr "falta la variable d'entorn «%s» per a la configuració «%.*s»" +msgstr "hi manca la variable d'entorn «%s» per a la configuració «%.*s»" #: config.c #, c-format @@ -19449,12 +19861,12 @@ msgstr "hi ha massa arguments a %s" #: config.c #, c-format msgid "missing config key %s" -msgstr "falta la clau de configuració %s" +msgstr "hi manca la clau de configuració %s" #: config.c #, c-format msgid "missing config value %s" -msgstr "falta el valor de configuració %s" +msgstr "hi manca el valor de configuració %s" #: config.c #, c-format @@ -19536,16 +19948,6 @@ msgstr "valor de configuració numèric incorrecte «%s» per «%s» en %s: %s" #: config.c #, c-format -msgid "invalid value for variable %s" -msgstr "valor no và lid per a la variable %s" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "s'ignora el component core.fsync «%s» desconegut" - -#: config.c -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "valor de configuració booleà erroni «%s» per a «%s»" @@ -19561,57 +19963,6 @@ msgstr "«%s» per a «%s» no és una marca de temps và lida" #: config.c #, c-format -msgid "abbrev length out of range: %d" -msgstr "la longitud d'«abbrev» està fora de rang: %d" - -#: config.c -#, c-format -msgid "bad zlib compression level %d" -msgstr "nivell de compressió de zlib incorrecte %d" - -# newline → lÃnia nova o salt de lÃnia? -#: config.c -#, c-format -msgid "%s cannot contain newline" -msgstr "%s no pot contenir una nova lÃnia" - -#: config.c -#, c-format -msgid "%s must have at least one character" -msgstr "%s ha de tenir almenys un carà cter" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "s'ignora el valor desconegut «%s» de core.fsyncMethod" - -#: config.c -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles és obsolet; useu core.fsync" - -#: config.c -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "mode de creació d'objecte no và lid: %s" - -#: config.c -#, c-format -msgid "malformed value for %s" -msgstr "valor no và lid per a %s" - -#: config.c -#, c-format -msgid "malformed value for %s: %s" -msgstr "valor no và lid per a %s: %s" - -#: config.c -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "" -"ha de ser un dels elements següents: nothing, matching, simple, upstream o " -"current" - -#: config.c -#, c-format msgid "unable to load config blob object '%s'" msgstr "no s'ha pogut carregar l'objecte blob de configuració «%s»" @@ -19727,7 +20078,7 @@ msgstr "" #: config.c #, c-format msgid "missing value for '%s'" -msgstr "falta el valor per «%s»" +msgstr "hi manca el valor per a «%s»" #: connect.c msgid "the remote end hung up upon initial contact" @@ -20086,6 +20437,21 @@ msgstr "l'url no té esquema: %s" msgid "credential url cannot be parsed: %s" msgstr "no s'ha pogut analitzar l'URL de credencials: %s" +#: daemon.c +#, c-format +msgid "invalid timeout '%s', expecting a non-negative integer" +msgstr "el temps d'espera «%s» és invà lid; s'espera un enter no negatiu" + +#: daemon.c +#, c-format +msgid "invalid init-timeout '%s', expecting a non-negative integer" +msgstr "init-timeout invà lid «%s»; s'espera un enter no negatiu" + +#: daemon.c +#, c-format +msgid "invalid max-connections '%s', expecting an integer" +msgstr "max-connections «%s» invà lid; s'espera un enter" + #: date.c msgid "in the future" msgstr "en el futur" @@ -20189,7 +20555,7 @@ msgstr "no és và lid --%s amb valor «%s»" #: diagnose.c #, c-format msgid "could not archive missing directory '%s'" -msgstr "no s'ha pogut arxivar el directori que falta «%s»" +msgstr "no s'ha pogut arxivar el directori que hi manca «%s»" #: diagnose.c dir.c #, c-format @@ -20239,8 +20605,9 @@ msgid "cannot compare a named pipe to a directory" msgstr "no es pot comparar una canonada amb nom amb un directori" #: diff-no-index.c -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<opcions>] <camÃ> <camÃ>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "" +"git diff --no-index [<opcions>] <camÃ> <camÃ> [<especificacio-camÃ>...]" #: diff-no-index.c msgid "" @@ -20250,6 +20617,14 @@ msgstr "" "No és un repositori Git. Useu --no-index per a comparar dos camins fora del " "directori de treball" +#: diff-no-index.c +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"La comparació limitada entre especificacions de camà només s'admet si els " +"dos camins són directoris." + #: diff.c #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" @@ -20294,7 +20669,7 @@ msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "" "Valor desconegut de la variable de configuració de «diff.submodule»: «%s»" -#: diff.c merge-recursive.c transport.c +#: diff.c merge-ort.c transport.c #, c-format msgid "unknown value for config '%s': %s" msgstr "valor desconegut per al config «%s»': %s" @@ -20404,6 +20779,14 @@ msgid "invalid regex given to -I: '%s'" msgstr "expressió regular donada a -I: no và lida: «%s»" #: diff.c +msgid "-G requires a non-empty argument" +msgstr "-G requires a non-empty argument" + +#: diff.c +msgid "-S requires a non-empty argument" +msgstr "-S requereix un argument no buit" + +#: diff.c #, c-format msgid "failed to parse --submodule option parameter: '%s'" msgstr "" @@ -20426,7 +20809,7 @@ msgstr "genera el pedaç" msgid "<n>" msgstr "<n>" -#: diff.c +#: diff.c parse-options.h msgid "generate diffs with <n> lines context" msgstr "genera diffs amb <n> lÃnies de context" @@ -20574,13 +20957,13 @@ msgstr "afegir un prefix addicional per a cada lÃnia de sortida" #: diff.c msgid "do not show any source or destination prefix" -msgstr "no mostris cap prefix d'origen o destÃ" +msgstr "no mostris cap prefix d'origen o de destinació" #: diff.c msgid "use default prefixes a/ and b/" msgstr "utilitza els prefixos per defecte a/ i b/" -#: diff.c +#: diff.c parse-options.h msgid "show context between diff hunks up to the specified number of lines" msgstr "" "mostra el context entre trossos de diferència fins al nombre especificat de " @@ -20993,12 +21376,89 @@ msgstr "no s'ha pogut fer «stat» sobre el fitxer «%s»" msgid "bad git namespace path \"%s\"" msgstr "camà d'espai de noms git incorrecte «%s»" +#: environment.c +#, c-format +msgid "invalid value for variable %s" +msgstr "valor no và lid per a la variable %s" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "s'ignora el component core.fsync «%s» desconegut" + +#: environment.c +#, c-format +msgid "abbrev length out of range: %d" +msgstr "la longitud d'«abbrev» està fora de rang: %d" + +#: environment.c +#, c-format +msgid "bad zlib compression level %d" +msgstr "nivell de compressió de zlib incorrecte %d" + +# newline → lÃnia nova o salt de lÃnia? +#: environment.c +#, c-format +msgid "%s cannot contain newline" +msgstr "%s no pot contenir una nova lÃnia" + +#: environment.c +#, c-format +msgid "%s must have at least one character" +msgstr "%s ha de tenir almenys un carà cter" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "s'ignora el valor desconegut «%s» de core.fsyncMethod" + +#: environment.c +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles és obsolet; useu core.fsync" + +#: environment.c +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "mode de creació d'objecte no và lid: %s" + +#: environment.c +#, c-format +msgid "malformed value for %s" +msgstr "valor no và lid per a %s" + +#: environment.c +#, c-format +msgid "malformed value for %s: %s" +msgstr "valor no và lid per a %s: %s" + +#: environment.c +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "" +"ha de ser un dels elements següents: nothing, matching, simple, upstream o " +"current" + #: exec-cmd.c #, c-format msgid "too many args to run %s" msgstr "hi ha massa arguments per a executar %s" #: fetch-pack.c +#, c-format +msgid "" +"You are attempting to fetch %s, which is in the commit graph file but not in " +"the object database.\n" +"This is probably due to repo corruption.\n" +"If you are attempting to repair this repo corruption by refetching the " +"missing object, use 'git fetch --refetch' with the missing object." +msgstr "" +"Esteu intentant obtenir %s, el qual és en el graf de comissions però no en " +"la base de dades d'objectes\n" +"Això és degut probablement a la corrupció del repositori.\n" +"Si el que voleu és intentar reparar aquesta corrupció de repositori " +"reobtenint l'objecte que manca, useu 'git fetch --refetch' amb l'objecte que " +"manca" + +#: fetch-pack.c msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: llista shallow esperada" @@ -21506,7 +21966,9 @@ msgstr "s'ha produït un error en escriure la clau de signatura ssh a «%s»" #: gpg-interface.c #, c-format msgid "failed writing ssh signing key buffer to '%s'" -msgstr "s'ha produït un error en escriure la clau de signatura ssh a «%s»" +msgstr "" +"s'ha produït un error en escriure la memòria intermèdia de la clau de " +"signatura ssh a «%s»" #: gpg-interface.c msgid "" @@ -21519,7 +21981,9 @@ msgstr "" #: gpg-interface.c #, c-format msgid "failed reading ssh signing data buffer from '%s'" -msgstr "s'ha produït un error en llegir la signatura ssh des de «%s»" +msgstr "" +"s'ha produït un error en llegir la memòria intermèdia de les dades de " +"signatura ssh des de «%s»" #: graph.c #, c-format @@ -21722,10 +22186,10 @@ msgstr[1] "" #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" -"You can disable this warning with `git config advice.ignoredHook false`." +"You can disable this warning with `git config set advice.ignoredHook false`." msgstr "" "El lligam «%s» s'ha ignorat perquè no s'ha establert com a executable.\n" -"Podeu desactivar aquest avÃs amb «git config advice.ignoredHook false»." +"Podeu desactivar aquest avÃs amb «git config advice.ignoredHook false». " #: http-fetch.c msgid "not a git repository" @@ -21746,16 +22210,13 @@ msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "No s'admet el control de delegació amb el cURL < 7.22.0" #: http.c -msgid "Public key pinning not supported with cURL < 7.39.0" -msgstr "No s'admet la fixació de clau pública amb cURL < 7.39.0" - -#: http.c msgid "Unknown value for http.proactiveauth" msgstr "Valor desconegut de http.proactiveauth" -#: http.c -msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" -msgstr "CURLSSLOPT_NO_REVOKE no està admès amb cURL < 7.44.0" +#: http.c parse.c +#, c-format +msgid "failed to parse %s" +msgstr "s'ha produït un error en analitzar %s" #: http.c #, c-format @@ -21859,6 +22320,35 @@ msgstr "nom d'identitat buit (per <%s>) no és permès" msgid "name consists only of disallowed characters: %s" msgstr "el nom conté només carà cters no permesos: %s" +#: imap-send.c +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <carpeta>] < <bustia>" + +#: imap-send.c +msgid "no IMAP host specified" +msgstr "cap mà quina IMAP especificada" + +#: imap-send.c +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"establiu la mà quina d'IMAP amb 'git config imap.host <maquina>'.\n" +"(p. ex., 'git config imap.host imaps://imap.example.com')" + +#: imap-send.c +msgid "no IMAP folder specified" +msgstr "cap carpeta IMAP especificada" + +#: imap-send.c +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"establiu la carpeta de destinació amb 'git config imap.folder <carpeta>'.\n" +"(p. ex., 'git config imap.folder Drafts')" + #: list-objects-filter-options.c msgid "expected 'tree:<depth>'" msgstr "s'esperava «tree:<profunditat>»" @@ -21986,7 +22476,17 @@ msgstr "CRLF entre cometes detectat" msgid "unable to format message: %s" msgstr "no es pot formatar el missatge: %s" -#: merge-ort.c merge-recursive.c +#: merge-ll.c +#, c-format +msgid "invalid marker-size '%s', expecting an integer" +msgstr "marker-size «%s» invà lid; s'esperava un enter" + +#: merge-ort-wrappers.c +#, c-format +msgid "Could not parse object '%s'" +msgstr "No s'ha pogut analitzar l'objecte «%s»" + +#: merge-ort.c #, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "S'ha produït un error en fusionar el submòdul %s (no està agafat)" @@ -21996,7 +22496,7 @@ msgstr "S'ha produït un error en fusionar el submòdul %s (no està agafat)" msgid "Failed to merge submodule %s (no merge base)" msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha fusió base)" -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "Failed to merge submodule %s (commits not present)" msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha comissions)" @@ -22007,7 +22507,7 @@ msgstr "S'ha produït un error en fusionar el submòdul %s (no hi ha comissions) msgid "error: failed to merge submodule %s (repository corrupt)" msgstr "error: no s'ha pogut fusionar el submòdul %s (repositori malmès)" -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "Failed to merge submodule %s (commits don't follow merge-base)" msgstr "" @@ -22052,12 +22552,12 @@ msgstr "no s'ha pogut executar la fusió interna per a %s" msgid "error: unable to add %s to database" msgstr "error: no es pot afegir %s a la base de dades" -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "Auto-merging %s" msgstr "S'està autofusionant %s" -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of " @@ -22067,7 +22567,7 @@ msgstr "" "existent a %s en forma de canvi del nom del directori implÃcit, posant-hi " "els camins següents a: %s." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "CONFLICT (implicit dir rename): Cannot map more than one path to %s; " @@ -22088,7 +22588,7 @@ msgstr "" "%s; s'han canviat de nom a múltiples altres directoris, sense una destinació " "per a la majoria dels fitxers." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was " @@ -22097,7 +22597,7 @@ msgstr "" "AVÃS: S'està evitant aplicar el canvi de nom %s -> %s a %s, perquè %s ell " "mateix ja havia canviat de nom." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "Path updated: %s added in %s inside a directory that was renamed in %s; " @@ -22106,7 +22606,7 @@ msgstr "" "Pedaç actualitzat: %s afegit a %s dins d'un directori que va canviar de nom " "a %s; movent-lo a %s." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "Path updated: %s renamed to %s in %s, inside a directory that was renamed in " @@ -22115,7 +22615,7 @@ msgstr "" "Pedaç actualitzat: %s canviat al nom %s a %s, dins d'un directori que va " "canviar de nom a %s; movent-lo a %s." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "CONFLICT (file location): %s added in %s inside a directory that was renamed " @@ -22124,7 +22624,7 @@ msgstr "" "CONFLICTE (ubicació del fitxer): %s afegit a %s dins d'un directori que va " "canviar de nom a %s suggerint que potser hauria de moure's a %s." -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "" "CONFLICT (file location): %s renamed to %s in %s, inside a directory that " @@ -22196,19 +22696,19 @@ msgstr "" "canviat el nom d'un d'ells per tal que cadascun pugui ser registrat en algun " "lloc." -#: merge-ort.c merge-recursive.c +#: merge-ort.c msgid "content" msgstr "contingut" -#: merge-ort.c merge-recursive.c +#: merge-ort.c msgid "add/add" msgstr "afegiment/afegiment" -#: merge-ort.c merge-recursive.c +#: merge-ort.c msgid "submodule" msgstr "submòdul" -#: merge-ort.c merge-recursive.c +#: merge-ort.c #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "CONFLICTE (%s): Conflicte de fusió en %s" @@ -22271,329 +22771,6 @@ msgid "collecting merge info failed for trees %s, %s, %s" msgstr "" "ha fallat la recollida de la informació de fusió per als arbres %s, %s, %s" -#: merge-recursive.c -msgid "(bad commit)\n" -msgstr "(comissió errònia)\n" - -#: merge-recursive.c -#, c-format -msgid "add_cacheinfo failed for path '%s'; merge aborting." -msgstr "add_cacheinfo ha fallat per al camà «%s»; interrompent la fusió." - -#: merge-recursive.c -#, c-format -msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." -msgstr "" -"add_cacheinfo ha fallat al refrescar el camà «%s»; interrompent la fusió." - -#: merge-recursive.c -#, c-format -msgid "failed to create path '%s'%s" -msgstr "s'ha produït un error en crear el camà «%s»%s" - -#: merge-recursive.c -#, c-format -msgid "Removing %s to make room for subdirectory\n" -msgstr "S'està eliminant %s per a fer espai per al subdirectori\n" - -#: merge-recursive.c -msgid ": perhaps a D/F conflict?" -msgstr ": potser un conflicte D/F?" - -#: merge-recursive.c -#, c-format -msgid "refusing to lose untracked file at '%s'" -msgstr "s'està refusant perdre el fitxer no seguit a «%s»" - -#: merge-recursive.c -#, c-format -msgid "blob expected for %s '%s'" -msgstr "blob esperat per a %s «%s»" - -#: merge-recursive.c -#, c-format -msgid "failed to open '%s': %s" -msgstr "s'ha produït un error en obrir «%s»: %s" - -#: merge-recursive.c -#, c-format -msgid "failed to symlink '%s': %s" -msgstr "s'ha produït un error en fer l'enllaç simbòlic «%s»: %s" - -#: merge-recursive.c -#, c-format -msgid "do not know what to do with %06o %s '%s'" -msgstr "no se sap què fer amb %06o %s «%s»" - -#: merge-recursive.c -#, c-format -msgid "Failed to merge submodule %s (repository corrupt)" -msgstr "No s'ha pogut fusionar el submòdul %s (repositori malmès)" - -#: merge-recursive.c -#, c-format -msgid "Fast-forwarding submodule %s to the following commit:" -msgstr "Avançament rà pid del submòdul %s a la següent comissió:" - -#: merge-recursive.c -#, c-format -msgid "Fast-forwarding submodule %s" -msgstr "Avançament rà pid al submòdul %s" - -#: merge-recursive.c -#, c-format -msgid "Failed to merge submodule %s (merge following commits not found)" -msgstr "" -"Ha fallat en fusionar el submòdul %s (no s'ha trobat les comissions següents)" - -#: merge-recursive.c -#, c-format -msgid "Failed to merge submodule %s (not fast-forward)" -msgstr "" -"S'ha produït un error en fusionar el submòdul %s (sense avançament rà pid)" - -#: merge-recursive.c -msgid "Found a possible merge resolution for the submodule:\n" -msgstr "S'ha trobat una possible resolució de fusió pel submòdul:\n" - -#: merge-recursive.c -#, c-format -msgid "" -"If this is correct simply add it to the index for example\n" -"by using:\n" -"\n" -" git update-index --cacheinfo 160000 %s \"%s\"\n" -"\n" -"which will accept this suggestion.\n" -msgstr "" -"Si això és correcte simplement afegiu-ho a l'Ãndex per exemple\n" -"utilitzant:\n" -"\n" -" git update-index --cacheinfo 160000 %s «%s»\n" -"\n" -"que acceptarà aquest suggeriment.\n" - -#: merge-recursive.c -#, c-format -msgid "Failed to merge submodule %s (multiple merges found)" -msgstr "" -"S'ha produït un error en fusionar el submòdul %s (s'han trobat múltiples " -"fusions)" - -#: merge-recursive.c -msgid "failed to execute internal merge" -msgstr "no s'ha pogut executar la fusió interna" - -#: merge-recursive.c -#, c-format -msgid "unable to add %s to database" -msgstr "no s'ha pogut afegir %s a la base de dades" - -#: merge-recursive.c -#, c-format -msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." -msgstr "" -"Error: s'està refusant perdre el fitxer no seguit a %s; en comptes s'ha " -"escrit a %s." - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree." -msgstr "" -"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " -"s'ha deixat en l'arbre." - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree." -msgstr "" -"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s " -"de %s s'ha deixat en l'arbre." - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree at %s." -msgstr "" -"CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de %s " -"s'ha deixat en l'arbre a %s." - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree at %s." -msgstr "" -"CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió %s " -"de %s s'ha deixat en l'arbre a %s." - -#: merge-recursive.c -msgid "rename" -msgstr "canvi de nom" - -#: merge-recursive.c -msgid "renamed" -msgstr "canviat de nom" - -#: merge-recursive.c -#, c-format -msgid "Refusing to lose dirty file at %s" -msgstr "S'està refusant a perdre el fitxer brut a %s" - -#: merge-recursive.c -#, c-format -msgid "Refusing to lose untracked file at %s, even though it's in the way." -msgstr "" -"S'està refusant perdre el fitxer no seguit a «%s», malgrat que està en mig " -"de l'operació." - -#: merge-recursive.c -#, c-format -msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -msgstr "" -"CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s a %s. S'ha afegit " -"%s a %s" - -#: merge-recursive.c -#, c-format -msgid "%s is a directory in %s adding as %s instead" -msgstr "%s és un directori en %s; s'està afegint com a %s en lloc d'això" - -#: merge-recursive.c -#, c-format -msgid "Refusing to lose untracked file at %s; adding as %s instead" -msgstr "" -"S'està refusant perdre el fitxer no seguit a %s; en comptes, s'està afegint " -"com a %s" - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " -"\"%s\"->\"%s\" in \"%s\"%s" -msgstr "" -"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom «%s»->«%s» en la branca " -"«%s» canvi de nom «%s»->«%s» en «%s»%s" - -#: merge-recursive.c -msgid " (left unresolved)" -msgstr " (deixat sense resolució)" - -#: merge-recursive.c -#, c-format -msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -msgstr "" -"CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi de " -"nom %s->%s en %s" - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (directory rename split): Unclear where to place %s because " -"directory %s was renamed to multiple other directories, with no destination " -"getting a majority of the files." -msgstr "" -"CONFLICTE (divisió de canvi de nom de directori): no està clar on col·locar " -"%s perquè el directori %s s'han canviat de nom a múltiples altres " -"directoris, sense una destinació per a la majoria dels fitxers." - -#: merge-recursive.c -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" -">%s in %s" -msgstr "" -"CONFLICTE (canvi de nom/canvi de nom): canvi de nom %s->%s en %s. Canvi de " -"nom de directori %s->%s en %s" - -#: merge-recursive.c -#, c-format -msgid "cannot read object %s" -msgstr "no es pot llegir l'objecte %s" - -#: merge-recursive.c -#, c-format -msgid "object %s is not a blob" -msgstr "l'objecte %s no és un blob" - -#: merge-recursive.c -msgid "modify" -msgstr "modificació" - -#: merge-recursive.c -msgid "modified" -msgstr "modificat" - -#: merge-recursive.c -#, c-format -msgid "Skipped %s (merged same as existing)" -msgstr "S'ha omès %s (el fusionat és igual a l'existent)" - -#: merge-recursive.c -#, c-format -msgid "Adding as %s instead" -msgstr "S'està afegint com a %s en lloc d'això" - -#: merge-recursive.c -#, c-format -msgid "Removing %s" -msgstr "S'està eliminant %s" - -#: merge-recursive.c -msgid "file/directory" -msgstr "fitxer/directori" - -#: merge-recursive.c -msgid "directory/file" -msgstr "directori/fitxer" - -#: merge-recursive.c -#, c-format -msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" -msgstr "" -"CONFLICTE (%s): Hi ha un directori amb nom %s en %s. S'està afegint %s com a " -"%s" - -#: merge-recursive.c -#, c-format -msgid "Adding %s" -msgstr "S'està afegint %s" - -#: merge-recursive.c -#, c-format -msgid "CONFLICT (add/add): Merge conflict in %s" -msgstr "CONFLICTE (afegiment/afegiment): Conflicte de fusió en %s" - -#: merge-recursive.c -#, c-format -msgid "merging of trees %s and %s failed" -msgstr "la fusió dels arbres %s i %s ha fallat" - -#: merge-recursive.c -msgid "Merging:" -msgstr "S'està fusionant:" - -#: merge-recursive.c -#, c-format -msgid "found %u common ancestor:" -msgid_plural "found %u common ancestors:" -msgstr[0] "s'ha trobat %u avantpassat en comú:" -msgstr[1] "s'han trobat %u avantpassats en comú:" - -#: merge-recursive.c -msgid "merge returned no commit" -msgstr "la fusió no ha retornat cap comissió" - -#: merge-recursive.c -#, c-format -msgid "Could not parse object '%s'" -msgstr "No s'ha pogut analitzar l'objecte «%s»" - #: merge.c msgid "failed to read the cache" msgstr "s'ha produït un error en llegir la memòria cau" @@ -22647,16 +22824,17 @@ msgid "failed to clear multi-pack-index at %s" msgstr "no s'ha pogut netejar l'Ãndex multipaquet a %s" #: midx-write.c -msgid "cannot write incremental MIDX with bitmap" -msgstr "no es pot escriure un MIDX incremental amb mapa de bits" - -#: midx-write.c msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "" "s'està ignorant l'Ãndex multipaquet existent; la suma de verificació no " "coincideix" #: midx-write.c +#, c-format +msgid "could not load reverse index for MIDX %s" +msgstr "no s'ha pogut carregar l'Ãndex invers per al MIDX %s" + +#: midx-write.c msgid "Adding packfiles to multi-pack-index" msgstr "S'estan afegint fitxers empaquetats a l'Ãndex multipaquet" @@ -22762,8 +22940,8 @@ msgstr "el fitxer de l'Ãndex multipaquet %s és massa petit" #, c-format msgid "multi-pack-index signature 0x%08x does not match signature 0x%08x" msgstr "" -"la signatura de l'Ãndex multipaquet 0x%08x no coincideix amb la signatura " -"0x%08x" +"la signatura de l'Ãndex multipaquet 0x%08x no coincideix amb la signatura 0x" +"%08x" #: midx.c #, c-format @@ -22995,83 +23173,6 @@ msgstr "No s'ha pogut convertir l'objecte de %s a %s" #: object-file.c #, c-format -msgid "object directory %s does not exist; check .git/objects/info/alternates" -msgstr "" -"no existeix el directori d'objecte %s; comproveu .git/objects/info/alternates" - -#: object-file.c -#, c-format -msgid "unable to normalize alternate object path: %s" -msgstr "no s'ha pogut normalitzar el camà a l'objecte alternatiu: %s" - -#: object-file.c -#, c-format -msgid "%s: ignoring alternate object stores, nesting too deep" -msgstr "" -"%s: s'estan ignorant els emmagatzematges alternatius d'objectes, imbricació " -"massa profunda" - -#: object-file.c -msgid "unable to fdopen alternates lockfile" -msgstr "no s'ha pogut fer «fdopen» al fitxer de bloqueig alternatiu" - -#: object-file.c -msgid "unable to read alternates file" -msgstr "no es pot llegir el fitxer «alternates»" - -#: object-file.c -msgid "unable to move new alternates file into place" -msgstr "no s'ha pogut moure el nou fitxer «alternates» al lloc" - -#: object-file.c -#, c-format -msgid "path '%s' does not exist" -msgstr "el camà «%s» no existeix" - -#: object-file.c -#, c-format -msgid "reference repository '%s' as a linked checkout is not supported yet." -msgstr "" -"encara no s'admet el repositori de referència «%s» com a agafament enllaçat." - -#: object-file.c -#, c-format -msgid "reference repository '%s' is not a local repository." -msgstr "el repositori de referència «%s» no és un repositori local." - -#: object-file.c -#, c-format -msgid "reference repository '%s' is shallow" -msgstr "el repositori de referència «%s» és superficial" - -#: object-file.c -#, c-format -msgid "reference repository '%s' is grafted" -msgstr "el repositori de referència «%s» és empeltat" - -#: object-file.c -#, c-format -msgid "could not find object directory matching %s" -msgstr "no s'ha pogut trobar el directori de l'objecte que coincideixi amb %s" - -#: object-file.c -#, c-format -msgid "invalid line while parsing alternate refs: %s" -msgstr "" -"lÃnia no và lida quan s'analitzaven les referències de l'«alternate»: %s" - -#: object-file.c -#, c-format -msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" -msgstr "s'està intentant fer mmap %<PRIuMAX> per sobre del lÃmit %<PRIuMAX>" - -#: object-file.c -#, c-format -msgid "mmap failed%s" -msgstr "mmap ha fallat%s" - -#: object-file.c -#, c-format msgid "object file %s is empty" msgstr "el tipus d'objecte %s és buit" @@ -23116,21 +23217,6 @@ msgstr "l'objecte solt %s (emmagatzemat a %s) és corrupte" #: object-file.c #, c-format -msgid "replacement %s not found for %s" -msgstr "no s'ha trobat el reemplaçament %s per a %s" - -#: object-file.c -#, c-format -msgid "packed object %s (stored in %s) is corrupt" -msgstr "l'objecte empaquetat %s (emmagatzemat a %s) és corrupte" - -#: object-file.c -#, c-format -msgid "missing mapping of %s to %s" -msgstr "manca el mapatge de %s a %s" - -#: object-file.c -#, c-format msgid "unable to open %s" msgstr "no s'ha pogut obrir %s" @@ -23146,6 +23232,11 @@ msgstr "no s'ha pogut escriure al fitxer %s" #: object-file.c #, c-format +msgid "unable to write repeatedly vanishing file %s" +msgstr "no puc escriure el fitxer %s que desapareix repetidament" + +#: object-file.c +#, c-format msgid "unable to set permission to '%s'" msgstr "no s'ha pogut establir el permÃs a «%s»" @@ -23244,11 +23335,6 @@ msgstr "%s: tipus de fitxer no suportat" #: object-file.c #, c-format -msgid "%s is not a valid '%s' object" -msgstr "%s no és un objecte de «%s» và lid" - -#: object-file.c -#, c-format msgid "hash mismatch for %s (expected %s)" msgstr "no coincideix el resum per a %s (s'esperava %s)" @@ -23269,6 +23355,11 @@ msgstr "no s'ha pogut analitzar la capçalera de %s" #: object-file.c #, c-format +msgid "unable to parse type from header '%s' of %s" +msgstr "no s'ha pogut analitzar el tipus de la capçalera «%s» de %s" + +#: object-file.c +#, c-format msgid "unable to unpack contents of %s" msgstr "no s'han pogut desempaquetar els continguts de %s" @@ -23362,7 +23453,7 @@ msgid "" "\n" "where \"$br\" is somehow empty and a 40-hex ref is created. Please\n" "examine these refs and maybe delete them. Turn this message off by\n" -"running \"git config advice.objectNameWarning false\"" +"running \"git config set advice.objectNameWarning false\"" msgstr "" "Git normalment mai crea una referència que acabi amb 40 carà cters\n" "hexadecimals perquè s'ignorarà quan només especifiqueu 40 carà cters\n" @@ -23473,6 +23564,93 @@ msgstr "no s'ha pogut analitzar l'objecte: %s" msgid "hash mismatch %s" msgstr "el resum no coincideix %s" +#: odb.c +#, c-format +msgid "object directory %s does not exist; check .git/objects/info/alternates" +msgstr "" +"no existeix el directori d'objecte %s; comproveu .git/objects/info/alternates" + +#: odb.c +#, c-format +msgid "unable to normalize alternate object path: %s" +msgstr "no s'ha pogut normalitzar el camà a l'objecte alternatiu: %s" + +#: odb.c +#, c-format +msgid "%s: ignoring alternate object stores, nesting too deep" +msgstr "" +"%s: s'estan ignorant els emmagatzematges alternatius d'objectes, imbricació " +"massa profunda" + +#: odb.c +msgid "unable to fdopen alternates lockfile" +msgstr "no s'ha pogut fer «fdopen» al fitxer de blocatge alternatiu" + +#: odb.c +msgid "unable to read alternates file" +msgstr "no es pot llegir el fitxer «alternates»" + +#: odb.c +msgid "unable to move new alternates file into place" +msgstr "no s'ha pogut moure el nou fitxer «alternates» al lloc" + +#: odb.c +#, c-format +msgid "path '%s' does not exist" +msgstr "el camà «%s» no existeix" + +#: odb.c +#, c-format +msgid "reference repository '%s' as a linked checkout is not supported yet." +msgstr "" +"encara no s'admet el repositori de referència «%s» com a agafament enllaçat." + +#: odb.c +#, c-format +msgid "reference repository '%s' is not a local repository." +msgstr "el repositori de referència «%s» no és un repositori local." + +#: odb.c +#, c-format +msgid "reference repository '%s' is shallow" +msgstr "el repositori de referència «%s» és superficial" + +#: odb.c +#, c-format +msgid "reference repository '%s' is grafted" +msgstr "el repositori de referència «%s» és empeltat" + +#: odb.c +#, c-format +msgid "could not find object directory matching %s" +msgstr "no s'ha pogut trobar el directori de l'objecte que coincideixi amb %s" + +#: odb.c +#, c-format +msgid "invalid line while parsing alternate refs: %s" +msgstr "" +"lÃnia no và lida quan s'analitzaven les referències de l'«alternate»: %s" + +#: odb.c +#, c-format +msgid "replacement %s not found for %s" +msgstr "no s'ha trobat el reemplaçament %s per a %s" + +#: odb.c +#, c-format +msgid "packed object %s (stored in %s) is corrupt" +msgstr "l'objecte empaquetat %s (emmagatzemat a %s) és corrupte" + +#: odb.c +#, c-format +msgid "missing mapping of %s to %s" +msgstr "manca el mapatge de %s a %s" + +#: odb.c +#, c-format +msgid "%s is not a valid '%s' object" +msgstr "%s no és un objecte de «%s» và lid" + #: pack-bitmap-write.c #, c-format msgid "duplicate entry when writing bitmap index: %s" @@ -23487,10 +23665,6 @@ msgstr "s'ha intentat emmagatzemar una comissió no seleccionada: «%s»" msgid "too many pseudo-merges" msgstr "massa pseudo-fusions" -#: pack-bitmap-write.c -msgid "trying to write commit not in index" -msgstr "s'està intentant no escriure la comissió a l'Ãndex" - #: pack-bitmap.c msgid "failed to load bitmap index (corrupted?)" msgstr "" @@ -23574,22 +23748,13 @@ msgstr "la suma de verificació no coincideix amb el MIDX i el mapa de bits" #: pack-bitmap.c msgid "multi-pack bitmap is missing required reverse index" -msgstr "falta l'Ãndex invers necessari al mapa de bits multipaquet" +msgstr "hi manca l'Ãndex invers necessari al mapa de bits multipaquet" #: pack-bitmap.c #, c-format msgid "could not open pack %s" msgstr "no s'ha pogut obrir el paquet %s" -#: pack-bitmap.c t/helper/test-read-midx.c -msgid "could not determine MIDX preferred pack" -msgstr "no s'ha pogut determinar el paquet preferit MIDX" - -#: pack-bitmap.c -#, c-format -msgid "preferred pack (%s) is invalid" -msgstr "el paquet preferit (%s) no és và lid" - #: pack-bitmap.c msgid "corrupt bitmap lookup table: triplet position out of index" msgstr "" @@ -23830,6 +23995,21 @@ msgstr "%s no és disponible" #: parse-options.c #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "el valor de %s supera %<PRIdMAX> " + +#: parse-options.c +#, c-format +msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" +msgstr "el valor %s de %s no està dins del rang [%<PRIdMAX>,%<PRIdMAX>]" + +#: parse-options.c +#, c-format +msgid "%s expects an integer value with an optional k/m/g suffix" +msgstr "%s espera un valor enter amb un sufix opcional k/m/g" + +#: parse-options.c +#, c-format msgid "%s expects a non-negative integer value with an optional k/m/g suffix" msgstr "%s espera un valor enter no negatiu amb un sufix opcional k/m/g" @@ -23867,6 +24047,55 @@ msgstr "opció «%c» desconeguda" msgid "unknown non-ascii option in string: `%s'" msgstr "opció no ascii desconeguda en la cadena: «%s»" +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the long form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[=<%s>]" +msgstr "[=<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string +#. stands for an optional value given to a command +#. line option in the short form, and "<>" is there +#. as a convention to signal that it is a +#. placeholder (i.e. the user should substitute it +#. with the real value). If your language uses a +#. different convention, you can change "<%s>" part +#. to match yours, e.g. it might use "|%s|" instead, +#. or if the alphabet is different enough it may use +#. "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid "[<%s>]" +msgstr "[<%s>]" + +#. TRANSLATORS: The "<%s>" part of this string stands for a +#. value given to a command line option, and "<>" is there +#. as a convention to signal that it is a placeholder +#. (i.e. the user should substitute it with the real value). +#. If your language uses a different convention, you can +#. change "<%s>" part to match yours, e.g. it might use +#. "|%s|" instead, or if the alphabet is different enough it +#. may use "%s" without any placeholder signal. Most +#. translations leave this message as is. +#. +#: parse-options.c +#, c-format +msgid " <%s>" +msgstr " <%s>" + #: parse-options.c msgid "..." msgstr "..." @@ -23966,10 +24195,24 @@ msgstr "" msgid "bad boolean environment value '%s' for '%s'" msgstr "el valor «%s» booleà de l'entorn és incorrecte per a «%s»" -#: parse.c +#: path-walk.c #, c-format -msgid "failed to parse %s" -msgstr "s'ha produït un error en analitzar %s" +msgid "failed to walk children of tree %s: not found" +msgstr "no s'ha pogut recórrer els descendents de l'arbre %s: no s'han trobat" + +#: path-walk.c +#, c-format +msgid "failed to find object %s" +msgstr "no s'ha pogut trobar l'objecte %s" + +#: path-walk.c +#, c-format +msgid "failed to find tag %s" +msgstr "no s'ha pogut trobar l'etiqueta %s" + +#: path-walk.c +msgid "failed to setup revision walk" +msgstr "no s'ha pogut configurar un recorregut de revisió" #: path.c #, c-format @@ -24165,6 +24408,31 @@ msgstr "el nom remot «promisor» no pot començar amb «/»: %s" msgid "could not fetch %s from promisor remote" msgstr "no s'ha pogut obtenir «%s» del «promisor» remot" +#: promisor-remote.c +#, c-format +msgid "no or empty URL advertised for remote '%s'" +msgstr "no hi ha URL configurat per al remot «%s» o és buit" + +#: promisor-remote.c +#, c-format +msgid "known remote named '%s' but with URL '%s' instead of '%s'" +msgstr "remot conegut nomenat «%s» però amb URL «%s» en comptes de «%s»" + +#: promisor-remote.c +#, c-format +msgid "unknown '%s' value for '%s' config option" +msgstr "valor desconegut «%s» per a l'opció «%s» de configuració" + +#: promisor-remote.c +#, c-format +msgid "unknown element '%s' from remote info" +msgstr "valor desconegut «%s» en la informació del remot" + +#: promisor-remote.c +#, c-format +msgid "accepted promisor remote '%s' not found" +msgstr "no s'ha trobat el remot promisor acceptat «%s»" + #: protocol-caps.c msgid "object-info: expected flush after arguments" msgstr "object-info: s'esperava una neteja després dels arguments" @@ -24943,6 +25211,16 @@ msgstr "%s no apunta a un objecte và lid" #: refs.c #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr " %s%s es quedarà despenjat després d'esborrar %s\n" + +#: refs.c +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr " %s%s s'ha quedat despenjat després d'esborrar %s\n" + +#: refs.c +#, 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" @@ -25000,9 +25278,20 @@ msgid "log for %s is empty" msgstr "el registre per a %s és buit" #: refs.c -msgid "refusing to force and skip creation of reflog" +#, c-format +msgid "refusing to update reflog for pseudoref '%s'" msgstr "" -"s'ha rebutjat l'acció forçada i l'omissió de crear un registre de referències" +"s'ha rebutjat l'actualització del reflog per a la pseudoreferència «%s»" + +#: refs.c +#, c-format +msgid "refusing to update pseudoref '%s'" +msgstr "s'ha rebutjat l'actualització de la pseudoreferència «%s»" + +#: refs.c +#, c-format +msgid "refusing to update reflog with bad name '%s'" +msgstr "s'està refusant el reflog amb el nom incorrecte «%s»" #: refs.c #, c-format @@ -25010,9 +25299,9 @@ msgid "refusing to update ref with bad name '%s'" msgstr "s'està refusant la referència amb nom malmès «%s»" #: refs.c -#, c-format -msgid "refusing to update pseudoref '%s'" -msgstr "s'ha rebutjat l'actualització de la pseudoreferència «%s»" +msgid "refusing to force and skip creation of reflog" +msgstr "" +"s'ha rebutjat l'acció forçada i l'omissió de crear un registre de referències" #: refs.c #, c-format @@ -25082,6 +25371,11 @@ msgstr "" #: refs/files-backend.c #, c-format +msgid "cannot read ref file '%s'" +msgstr "no es pot llegir el fitxer de referències «%s»" + +#: refs/files-backend.c +#, c-format msgid "cannot open directory %s" msgstr "no es pot obrir el directori «%s»" @@ -25089,6 +25383,11 @@ msgstr "no es pot obrir el directori «%s»" msgid "Checking references consistency" msgstr "S'està comprovant la consistència de les referències" +#: refs/packed-backend.c +#, c-format +msgid "unable to open '%s'" +msgstr "no s'ha pogut obrir %s" + #: refs/reftable-backend.c #, c-format msgid "refname is dangerous: %s" @@ -25185,8 +25484,13 @@ msgstr "" #: refspec.c #, c-format -msgid "invalid refspec '%s'" -msgstr "refspec no và lida: «%s»" +msgid "pattern '%s' has no '*'" +msgstr "el patró «%s» no té cap «*»" + +#: refspec.c +#, c-format +msgid "replacement '%s' has no '*'" +msgstr "el reemplaçament «%s» no té cap «*»" #: remote-curl.c #, c-format @@ -25318,7 +25622,7 @@ msgstr "El transport http no admet %s" #: remote-curl.c msgid "protocol error: expected '<url> <path>', missing space" msgstr "" -"s'ha produït un error de protocol: s'esperava «<url> <camÃ>», falta espai" +"s'ha produït un error de protocol: s'esperava «<url> <camÃ>», hi manca espai" #: remote-curl.c #, c-format @@ -25348,6 +25652,31 @@ msgstr "remote-curl: ordre «%s» desconeguda del git" #: remote.c #, c-format +msgid "" +"reading remote from \"%s/%s\", which is nominated for removal.\n" +"\n" +"If you still use the \"remotes/\" directory it is recommended to\n" +"migrate to config-based remotes:\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"If you cannot, please let us know why you still need to use it by\n" +"sending an e-mail to <git@vger.kernel.org>." +msgstr "" +"s'està llegint el remot des de «%s/%s», el qual està nominat per a la seva " +"supressió.\n" +"\n" +"Si encara feu servir el directori «remotes/», es recomana la migració a\n" +"remots basats en configuració\n" +"\n" +"\tgit remote rename %s %s\n" +"\n" +"Si no podeu, feu-nos saber, per favor, per què necessiteu fer-lo servir " +"encara\n" +"tot enviant correu electrònic a <git@vger.kernel.org>." + +#: remote.c +#, c-format msgid "config remote shorthand cannot begin with '/': %s" msgstr "" "l'abreviatura del fitxer de configuració remot no pot començar amb «/»: %s" @@ -25362,6 +25691,11 @@ msgstr "més d'un paquet de cà rrega donat, usant el primer" #: remote.c #, c-format +msgid "unrecognized followRemoteHEAD value '%s' ignored" +msgstr "valor de followRemoteHEAD no reconegut «%s» ignorat" + +#: remote.c +#, c-format msgid "unrecognized value transfer.credentialsInUrl: '%s'" msgstr "valor no conegut per a transfer.credentialsInUrl: «%s»" @@ -25387,16 +25721,6 @@ msgstr "%s segueix ambdós %s i %s" #: remote.c #, c-format -msgid "key '%s' of pattern had no '*'" -msgstr "la clau «%s» del patró no té «*»" - -#: remote.c -#, c-format -msgid "value '%s' of pattern has no '*'" -msgstr "el valor «%s» del patró no té «*»" - -#: remote.c -#, c-format msgid "src refspec %s does not match any" msgstr "l'especificació de referència font %s no coincideix amb cap referència" @@ -25431,7 +25755,8 @@ msgstr "" " és una referència «refs/{heads,tags}/». Si és aixÃ, afegim el prefix\n" " refs/{heads,tags}/ corresponent al costat remot.\n" "\n" -"Res d'això ha funcionat. Cal que proporcioneu una referència completa." +"Res d'això ha funcionat, i per això ho hem abandonat. Cal que proporcioneu " +"una referència completa." #: remote.c #, c-format @@ -25520,7 +25845,8 @@ msgstr "la branca font «%s» no s'emmagatzema com a branca amb seguiment remot" #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "" -"el destà de pujada «%s» en el remot «%s» no té cap branca amb seguiment remot" +"la destinació de pujada «%s» en el remot «%s» no té cap branca amb seguiment " +"remot" #: remote.c #, c-format @@ -25534,11 +25860,11 @@ msgstr "les especificacions de referència de pujada «%s» no inclouen «%s»" #: remote.c msgid "push has no destination (push.default is 'nothing')" -msgstr "push no té destà (push.default és «nothing»)" +msgstr "push no té destinació (push.default és «nothing»)" #: remote.c msgid "cannot resolve 'simple' push to a single destination" -msgstr "no es pot resoldre una pujada «simple» a un sol destÃ" +msgstr "no es pot resoldre una pujada «simple» a una sola destinació" #: remote.c #, c-format @@ -25838,8 +26164,8 @@ msgid "could not set recommended config" msgstr "no s'ha pogut establir la configuració recomanada" #: scalar.c -msgid "could not turn on maintenance" -msgstr "no s'ha pogut activar el manteniment" +msgid "could not toggle maintenance" +msgstr "no s'ha pogut commutar el manteniment" #: scalar.c msgid "could not start the FSMonitor daemon" @@ -25900,14 +26226,17 @@ msgstr "crea un repositori dins del directori «src»" msgid "specify if tags should be fetched during clone" msgstr "especifica si les etiquetes s'han d'obtenir durant el clon" -# Deixem <enlistment> sense traduir de moment +#: scalar.c +msgid "specify if background maintenance should be enabled" +msgstr "especifica si cal activar el manteniment en segon pla" + #: scalar.c msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <branca-principal>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] <url> [<allistament>]" #: scalar.c #, c-format @@ -25949,27 +26278,44 @@ msgstr "no s'ha pogut configurar per a una clonació completa" #: scalar.c msgid "scalar diagnose [<enlistment>]" -msgstr "scalar diagnose [<enlistment>]" +msgstr "scalar diagnose [<allistament>]" #: scalar.c msgid "`scalar list` does not take arguments" msgstr "«scalar list» no accepta arguments" #: scalar.c -msgid "scalar register [<enlistment>]" -msgstr "scalar register [<enlistment>]" +msgid "scalar register [--[no-]maintenance] [<enlistment>]" +msgstr "scalar register [--[no-]maintenance] [<allistament>]" #: scalar.c msgid "reconfigure all registered enlistments" msgstr "reconfigura tots els allistaments registrats" #: scalar.c -msgid "scalar reconfigure [--all | <enlistment>]" -msgstr "scalar reconfigure [--all | <enlistment>]" +msgid "(enable|disable|keep)" +msgstr "(enable|disable|keep)" + +#: scalar.c +msgid "signal how to adjust background maintenance" +msgstr "assenyala com ajustar el manteniment en segon pla" + +#: scalar.c +msgid "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<enlistment>]" +msgstr "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<allistament>]" #: scalar.c msgid "--all or <enlistment>, but not both" -msgstr "--all o <enlistment>, però no ambdós" +msgstr "--all o <allistament>, però no ambdós" + +#: scalar.c +#, c-format +msgid "unknown mode for --maintenance option: %s" +msgstr "mode desconegut per a l'opció de --maintenance: %s" #: scalar.c #, c-format @@ -26010,7 +26356,7 @@ msgid "" "scalar run <task> [<enlistment>]\n" "Tasks:\n" msgstr "" -"scalar run <task> {<enlistment>]\n" +"scalar run <task> {<allistament>]\n" "Tasques:\n" #: scalar.c @@ -26020,11 +26366,11 @@ msgstr "no existeix la tasca: «%s»" #: scalar.c msgid "scalar unregister [<enlistment>]" -msgstr "scalar unregister [<enlistment>]" +msgstr "scalar unregister [<allistament>]" #: scalar.c msgid "scalar delete <enlistment>" -msgstr "supressió de l'escalar <enlistment>" +msgstr "supressió de l'escalar <allistament>" #: scalar.c msgid "refusing to delete current working directory" @@ -26097,27 +26443,27 @@ msgstr "" #: send-pack.c msgid "the receiving end does not support this repository's hash algorithm" -msgstr "el receptor de destà no admet l'algorisme de resum del repositori" +msgstr "el receptor de destinació no admet l'algorisme de resum del repositori" #: send-pack.c msgid "the receiving end does not support --signed push" -msgstr "el destà receptor no admet pujar --signed" +msgstr "la destinació receptora no admet pujar --signed" #: send-pack.c msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" msgstr "" -"no s'està enviant una certificació de pujada perquè el destà receptor no " -"admet pujar --signed" +"no s'està enviant una certificació de pujada perquè la destinació " +"receptorano admet pujar --signed" #: send-pack.c msgid "the receiving end does not support --atomic push" -msgstr "el destà receptor no admet pujar --atomic" +msgstr "la destinació receptora no admet pujar --atomic" #: send-pack.c msgid "the receiving end does not support push options" -msgstr "el receptor al destà no admet opcions de pujada" +msgstr "el receptor a la destinació no admet opcions de pujada" #: sequencer.c #, c-format @@ -26271,15 +26617,15 @@ msgstr "variable «%s» desconeguda" #: sequencer.c msgid "missing 'GIT_AUTHOR_NAME'" -msgstr "falta «GIT_AUTHOR_NAME»" +msgstr "hi manca «GIT_AUTHOR_NAME»" #: sequencer.c msgid "missing 'GIT_AUTHOR_EMAIL'" -msgstr "falta «GIT_AUTHOR_EMAIL»" +msgstr "hi manca «GIT_AUTHOR_EMAIL»" #: sequencer.c msgid "missing 'GIT_AUTHOR_DATE'" -msgstr "falta «GIT_AUTHOR_DATE»" +msgstr "hi manca «GIT_AUTHOR_DATE»" #: sequencer.c #, c-format @@ -26413,7 +26759,7 @@ msgstr "identitat d'autor no và lida: «%s»" #: sequencer.c msgid "corrupt author: missing date information" -msgstr "autor malmès: falta la informació de la data" +msgstr "autor malmès: hi manca la informació de la data" #: sequencer.c #, c-format @@ -26602,7 +26948,7 @@ msgstr "ordre no và lida «%.*s»" #: sequencer.c #, c-format msgid "missing arguments for %s" -msgstr "falten els arguments per a %s" +msgstr "hi manquen els arguments per a %s" #: sequencer.c #, c-format @@ -26881,7 +27227,7 @@ msgid "" "Updated the following refs with %s:\n" "%s" msgstr "" -"S'han actualitzat els següents refs amb %s:\n" +"S'han actualitzat les referències següents amb %s:\n" "%s" #: sequencer.c @@ -27728,6 +28074,42 @@ msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "" "nombre d'entrades a l'arbre de la memòria cau a invalidar (per defecte 0)" +#: t/helper/test-pack-deltas.c +msgid "the number of objects to write" +msgstr "el nombre d'objectes a escriure" + +#: t/helper/test-path-walk.c +msgid "test-tool path-walk <options> -- <revision-options>" +msgstr "test-tool path-walk <opcions> -- <opcions-revisio>" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of blob objects" +msgstr "commuta la inclusió d'objectes de blob" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of commit objects" +msgstr "commuta la inclusió d'objectes de comissió" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tag objects" +msgstr "commuta la inclusió d'objectes d'etiqueta" + +#: t/helper/test-path-walk.c +msgid "toggle inclusion of tree objects" +msgstr "commuta la inclusió d'objectes d'arbre" + +#: t/helper/test-path-walk.c +msgid "toggle pruning of uninteresting paths" +msgstr "commuta la poda de camins no interessants" + +#: t/helper/test-path-walk.c +msgid "toggle aggressive edge walk" +msgstr "commuta el recorregut agressiu de vores" + +#: t/helper/test-path-walk.c +msgid "read a pattern list over stdin" +msgstr "llegeix una llista patrons de l'entrada està ndard" + #: t/helper/test-reach.c #, c-format msgid "commit %s is not marked reachable" @@ -27737,6 +28119,10 @@ msgstr "la comissió %s no està marcada com abastable" msgid "too many commits marked reachable" msgstr "hi ha massa comissions marcades com abastables" +#: t/helper/test-read-midx.c +msgid "could not determine MIDX preferred pack" +msgstr "no s'ha pogut determinar el paquet preferit MIDX" + #: t/helper/test-serve-v2.c msgid "test-tool serve-v2 [<options>]" msgstr "test-tool serve-v2 [<opcions>]" @@ -28498,6 +28884,30 @@ msgstr "error: " msgid "warning: " msgstr "avÃs: " +#: usage.c +#, c-format +msgid "" +"'%s' 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 "" +"«%s» està nominat per a la seva supressió.\n" +"Si encara feu servir aquesta ordre, afegiu-hi l'opció\n" +"addicional, «--i-still-use-this», a la lÃnia d'ordres\n" +"i feu-nos saber que encara l'useu enviant un correu electrònic\n" +"a <git@vger.kernel.org>. Grà cies.\n" + +#: usage.c +msgid "refusing to run without --i-still-use-this" +msgstr "es rebutja a executar sense --i-still-use-this" + +#: version.c +#, c-format +msgid "uname() failed with error '%s' (%d)\n" +msgstr "uname() ha fallat amb l'error «%s» (%d)\n" + #: walker.c msgid "Fetching objects" msgstr "S'estan obtenint objectes" @@ -28540,6 +28950,10 @@ msgid ".git file incorrect" msgstr "fitxer .git incorrecte" #: worktree.c +msgid ".git file absolute/relative path mismatch" +msgstr "el camins absoluts/relatius del fitxer .git no coincideixen " + +#: worktree.c msgid "not a valid path" msgstr "no és un camà và lid" @@ -28562,6 +28976,10 @@ msgid "gitdir unreadable" msgstr "gitdir illegible" #: worktree.c +msgid "gitdir absolute/relative path mismatch" +msgstr "el camins absoluts/relatius del directori git no coincideixen " + +#: worktree.c msgid "gitdir incorrect" msgstr "gitdir incorrecte" @@ -28605,6 +29023,16 @@ msgstr "no s'ha pogut desassignar %s en «%s»" msgid "failed to set extensions.worktreeConfig setting" msgstr "no s'ha pogut establir el parà metre extensions.worktreeConfig" +#: worktree.c +msgid "unable to upgrade repository format to support relative worktrees" +msgstr "" +"no s'ha pogut actualitzar el format del repositori perquè admeti arbres de " +"treball relatius" + +#: worktree.c +msgid "unable to set extensions.relativeWorktrees setting" +msgstr "no s'ha pogut establir el parà metre extensions.relativeWorktrees" + #: wrapper.c #, c-format msgid "could not setenv '%s'" @@ -28633,6 +29061,16 @@ msgstr "no s'ha pogut obtenir el directori de treball actual" msgid "unable to get random bytes" msgstr "no s'han pogut obtenir octets aleatoris" +#: wrapper.c +#, c-format +msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" +msgstr "s'està intentant fer mmap %<PRIuMAX> per sobre del lÃmit %<PRIuMAX>" + +#: wrapper.c +#, c-format +msgid "mmap failed%s" +msgstr "mmap ha fallat%s" + #: wt-status.c msgid "Unmerged paths:" msgstr "Camins sense fusionar:" @@ -29562,6 +30000,16 @@ msgstr "" #: git-send-email.perl #, perl-format +msgid "Outlook reassigned Message-ID to: %s\n" +msgstr "Outlook ha reassignat el Message-ID a %s\n" + +#: git-send-email.perl +msgid "Warning: Could not retrieve Message-ID from server response.\n" +msgstr "" +"AvÃs: no s'ha pogut recuperar el Message-ID de la resposta del servidor.\n" + +#: git-send-email.perl +#, perl-format msgid "Failed to send %s\n" msgstr "S'ha produït un error en enviar %s\n" @@ -29619,6 +30067,11 @@ msgstr "(cos) S'està afegint cc: %s des de la lÃnia «%s»\n" #: git-send-email.perl #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "error: port SMTP invà lid: «%s»\n" + +#: git-send-email.perl +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) no s'ha pogut executar «%s»" @@ -29681,6 +30134,367 @@ msgstr "S'està ometent %s amb el sufix de còpia de seguretat «%s».\n" msgid "Do you really want to send %s? [y|N]: " msgstr "Esteu segur que voleu enviar %s? [y|N]: " +#~ msgid "start-after" +#~ msgstr "start-after" + +#~ msgid "compact-summary" +#~ msgstr "compact-summary" + +#~ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" +#~ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objecte>" + +#~ msgid "allow -s and -t to work with broken/corrupt objects" +#~ msgstr "permet que -s i -t funcionin amb objectes trencats/malmesos" + +#, c-format +#~ msgid "Could not find remote branch %s to clone." +#~ msgstr "No s'ha pogut trobar la branca remota %s per a clonar." + +#, c-format +#~ msgid "" +#~ "more than %i tags found; listed %i most recent\n" +#~ "gave up search at %s\n" +#~ msgstr "" +#~ "s'han trobat més de %i etiquetes: s'han llistat les %i més recents\n" +#~ "s'ha renunciat la cerca a %s\n" + +#, c-format +#~ msgid " (%s will become dangling)" +#~ msgstr " (%s es tornarà despenjat)" + +#, c-format +#~ msgid " (%s has become dangling)" +#~ msgstr " (%s s'ha quedat despenjat)" + +#, c-format +#~ msgid "%s: object is of unknown type '%s': %s" +#~ msgstr "%s: l'objecte és de tipus desconegut «%s»: %s" + +#~ msgid "use at most one of --auto and --schedule=<frequency>" +#~ msgstr "usa com a mà xim un entre --auto i --schedule=<freqüència>" + +#, c-format +#~ msgid "Final output: %d %s\n" +#~ msgstr "Sortida final: %d %s\n" + +#, c-format +#~ msgid "merging cannot continue; got unclean result of %d" +#~ msgstr "la fusió no pot continuar; s'ha obtingut un resultat no net de %d" + +#, c-format +#~ msgid "%d (FSCK_IGNORE?) should never trigger this callback" +#~ msgstr "%d (FSCK_IGNORE?) no hauria d'activar mai aquesta crida de retorn" + +#~ msgid "" +#~ "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" +#~ msgstr "" +#~ "git pack-objects --stdout [<opcions>] [< <ref-list> | < <object-list>]" + +#~ msgid "" +#~ "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +#~ msgstr "" +#~ "git pack-objects [<opcions>] <base-name> [< <ref-list> | < <object-list>]" + +#~ msgid "cannot use --stdin-packs with --cruft" +#~ msgstr "no es pot --stdin-packs amb --cruft" + +#, c-format +#~ msgid "%s points nowhere!" +#~ msgstr "%s no apunta a enlloc" + +#~ msgid "--onto and --advance are incompatible" +#~ msgstr "--onto i --advance són incompatibles" + +#, c-format +#~ msgid "unreachable: invalid reference: %s" +#~ msgstr "no accessible: referència no và lida: %s" + +#~ msgid "Public key pinning not supported with cURL < 7.39.0" +#~ msgstr "No s'admet la fixació de clau pública amb cURL < 7.39.0" + +#~ msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" +#~ msgstr "CURLSSLOPT_NO_REVOKE no està admès amb cURL < 7.44.0" + +#~ msgid "(bad commit)\n" +#~ msgstr "(comissió errònia)\n" + +#, c-format +#~ msgid "add_cacheinfo failed for path '%s'; merge aborting." +#~ msgstr "add_cacheinfo ha fallat per al camà «%s»; interrompent la fusió." + +#, c-format +#~ msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." +#~ msgstr "" +#~ "add_cacheinfo ha fallat al refrescar el camà «%s»; interrompent la fusió." + +#, c-format +#~ msgid "failed to create path '%s'%s" +#~ msgstr "s'ha produït un error en crear el camà «%s»%s" + +#, c-format +#~ msgid "Removing %s to make room for subdirectory\n" +#~ msgstr "S'està eliminant %s per a fer espai per al subdirectori\n" + +#~ msgid ": perhaps a D/F conflict?" +#~ msgstr ": potser un conflicte D/F?" + +#, c-format +#~ msgid "refusing to lose untracked file at '%s'" +#~ msgstr "s'està refusant perdre el fitxer no seguit a «%s»" + +#, c-format +#~ msgid "blob expected for %s '%s'" +#~ msgstr "blob esperat per a %s «%s»" + +#, c-format +#~ msgid "failed to open '%s': %s" +#~ msgstr "s'ha produït un error en obrir «%s»: %s" + +#, c-format +#~ msgid "failed to symlink '%s': %s" +#~ msgstr "s'ha produït un error en fer l'enllaç simbòlic «%s»: %s" + +#, c-format +#~ msgid "do not know what to do with %06o %s '%s'" +#~ msgstr "no se sap què fer amb %06o %s «%s»" + +#, c-format +#~ msgid "Failed to merge submodule %s (repository corrupt)" +#~ msgstr "No s'ha pogut fusionar el submòdul %s (repositori malmès)" + +#, c-format +#~ msgid "Fast-forwarding submodule %s to the following commit:" +#~ msgstr "Avançament rà pid del submòdul %s a la següent comissió:" + +#, c-format +#~ msgid "Fast-forwarding submodule %s" +#~ msgstr "Avançament rà pid al submòdul %s" + +#, c-format +#~ msgid "Failed to merge submodule %s (merge following commits not found)" +#~ msgstr "" +#~ "Ha fallat en fusionar el submòdul %s (no s'ha trobat les comissions " +#~ "següents)" + +#, c-format +#~ msgid "Failed to merge submodule %s (not fast-forward)" +#~ msgstr "" +#~ "S'ha produït un error en fusionar el submòdul %s (sense avançament rà pid)" + +#~ msgid "Found a possible merge resolution for the submodule:\n" +#~ msgstr "S'ha trobat una possible resolució de fusió pel submòdul:\n" + +#, 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 "" +#~ "Si això és correcte simplement afegiu-ho a l'Ãndex per exemple\n" +#~ "utilitzant:\n" +#~ "\n" +#~ " git update-index --cacheinfo 160000 %s «%s»\n" +#~ "\n" +#~ "que acceptarà aquest suggeriment.\n" + +#, c-format +#~ msgid "Failed to merge submodule %s (multiple merges found)" +#~ msgstr "" +#~ "S'ha produït un error en fusionar el submòdul %s (s'han trobat múltiples " +#~ "fusions)" + +#~ msgid "failed to execute internal merge" +#~ msgstr "no s'ha pogut executar la fusió interna" + +#, c-format +#~ msgid "unable to add %s to database" +#~ msgstr "no s'ha pogut afegir %s a la base de dades" + +#, c-format +#~ msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." +#~ msgstr "" +#~ "Error: s'està refusant perdre el fitxer no seguit a %s; en comptes s'ha " +#~ "escrit a %s." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " +#~ "left in tree." +#~ msgstr "" +#~ "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de " +#~ "%s s'ha deixat en l'arbre." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of " +#~ "%s left in tree." +#~ msgstr "" +#~ "CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió " +#~ "%s de %s s'ha deixat en l'arbre." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " +#~ "left in tree at %s." +#~ msgstr "" +#~ "CONFLICTE: (%s/supressió): %s suprimit en %s i %s en %s. La versió %s de " +#~ "%s s'ha deixat en l'arbre a %s." + +#, 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 "" +#~ "CONFLICTE: (%s/supressió): %s suprimit en %s i %s a %s en %s. La versió " +#~ "%s de %s s'ha deixat en l'arbre a %s." + +#~ msgid "rename" +#~ msgstr "canvi de nom" + +#~ msgid "renamed" +#~ msgstr "canviat de nom" + +#, c-format +#~ msgid "Refusing to lose dirty file at %s" +#~ msgstr "S'està refusant a perdre el fitxer brut a %s" + +#, c-format +#~ msgid "Refusing to lose untracked file at %s, even though it's in the way." +#~ msgstr "" +#~ "S'està refusant perdre el fitxer no seguit a «%s», malgrat que està en " +#~ "mig de l'operació." + +#, c-format +#~ msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" +#~ msgstr "" +#~ "CONFLICTE (canvi de nom/afegiment): Canvi de nom %s->%s a %s. S'ha " +#~ "afegit %s a %s" + +#, c-format +#~ msgid "%s is a directory in %s adding as %s instead" +#~ msgstr "%s és un directori en %s; s'està afegint com a %s en lloc d'això" + +#, c-format +#~ msgid "Refusing to lose untracked file at %s; adding as %s instead" +#~ msgstr "" +#~ "S'està refusant perdre el fitxer no seguit a %s; en comptes, s'està " +#~ "afegint com a %s" + +#, c-format +#~ msgid "" +#~ "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " +#~ "\"%s\"->\"%s\" in \"%s\"%s" +#~ msgstr "" +#~ "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom «%s»->«%s» en la " +#~ "branca «%s» canvi de nom «%s»->«%s» en «%s»%s" + +#~ msgid " (left unresolved)" +#~ msgstr " (deixat sense resolució)" + +#, c-format +#~ msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" +#~ msgstr "" +#~ "CONFLICTE (canvi de nom/canvi de nom): Canvi de nom %s->%s en %s. Canvi " +#~ "de nom %s->%s en %s" + +#, 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 "" +#~ "CONFLICTE (divisió de canvi de nom de directori): no està clar on " +#~ "col·locar %s perquè el directori %s s'han canviat de nom a múltiples " +#~ "altres directoris, sense una destinació per a la majoria dels fitxers." + +#, c-format +#~ msgid "" +#~ "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory " +#~ "%s->%s in %s" +#~ msgstr "" +#~ "CONFLICTE (canvi de nom/canvi de nom): canvi de nom %s->%s en %s. Canvi " +#~ "de nom de directori %s->%s en %s" + +#, c-format +#~ msgid "cannot read object %s" +#~ msgstr "no es pot llegir l'objecte %s" + +#, c-format +#~ msgid "object %s is not a blob" +#~ msgstr "l'objecte %s no és un blob" + +#~ msgid "modify" +#~ msgstr "modificació" + +#~ msgid "modified" +#~ msgstr "modificat" + +#, c-format +#~ msgid "Skipped %s (merged same as existing)" +#~ msgstr "S'ha omès %s (el fusionat és igual a l'existent)" + +#, c-format +#~ msgid "Adding as %s instead" +#~ msgstr "S'està afegint com a %s en lloc d'això" + +#, c-format +#~ msgid "Removing %s" +#~ msgstr "S'està eliminant %s" + +#~ msgid "file/directory" +#~ msgstr "fitxer/directori" + +#~ msgid "directory/file" +#~ msgstr "directori/fitxer" + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" +#~ msgstr "" +#~ "CONFLICTE (%s): Hi ha un directori amb nom %s en %s. S'està afegint %s " +#~ "com a %s" + +#, c-format +#~ msgid "Adding %s" +#~ msgstr "S'està afegint %s" + +#, c-format +#~ msgid "CONFLICT (add/add): Merge conflict in %s" +#~ msgstr "CONFLICTE (afegiment/afegiment): Conflicte de fusió en %s" + +#, c-format +#~ msgid "merging of trees %s and %s failed" +#~ msgstr "la fusió dels arbres %s i %s ha fallat" + +#~ msgid "Merging:" +#~ msgstr "S'està fusionant:" + +#, c-format +#~ msgid "found %u common ancestor:" +#~ msgid_plural "found %u common ancestors:" +#~ msgstr[0] "s'ha trobat %u avantpassat en comú:" +#~ msgstr[1] "s'han trobat %u avantpassats en comú:" + +#~ msgid "merge returned no commit" +#~ msgstr "la fusió no ha retornat cap comissió" + +#~ msgid "cannot write incremental MIDX with bitmap" +#~ msgstr "no es pot escriure un MIDX incremental amb mapa de bits" + +#~ msgid "trying to write commit not in index" +#~ msgstr "s'està intentant no escriure la comissió a l'Ãndex" + +#, c-format +#~ msgid "preferred pack (%s) is invalid" +#~ msgstr "el paquet preferit (%s) no és và lid" + +#, c-format +#~ msgid "key '%s' of pattern had no '*'" +#~ msgstr "la clau «%s» del patró no té «*»" + #~ msgid "revision walk setup failed\n" #~ msgstr "la configuració del recorregut de revisions ha fallat\n" @@ -29745,10 +30559,6 @@ msgstr "Esteu segur que voleu enviar %s? [y|N]: " #~ msgid "bad ls-files format: %%%.*s" #~ msgstr "format incorrecte de ls-files: %%%.*s" -#, c-format -#~ msgid "no URLs configured for remote '%s'" -#~ msgstr "cap URL configurat per al remot «%s»" - #~ msgid "keep redundant, empty commits" #~ msgstr "retén les comissions redundants i buides" @@ -87,8 +87,8 @@ msgid "" msgstr "" "Project-Id-Version: git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-05-27 22:57+0000\n" -"PO-Revision-Date: 2025-05-29 12:54+0200\n" +"POT-Creation-Date: 2025-08-12 17:01+0000\n" +"PO-Revision-Date: 2025-08-14 19:13+0200\n" "Last-Translator: Cédric Malard <c.malard-git@valdun.net>\n" "Language-Team: Jean-Noël Avila <jn.avila@free.fr>\n" "Language: fr\n" @@ -99,6 +99,10 @@ msgstr "" "X-Generator: Poedit 3.0.1\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s doit être non négatif" + +#, c-format msgid "Huh (%s)?" msgstr "Hein (%s) ?" @@ -2047,6 +2051,10 @@ msgid "adding files failed" msgstr "échec de l'ajout de fichiers" #, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' doit être non négatif" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "Le paramètre '%s' de --chmod doit être soit -x soit +x" @@ -5265,24 +5273,25 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<option-de-fichier>] [<option-d-affichage>] [--includes] [--" -"all] [--regexp] [--value=<valeur>] [--fixed-value] [--default=<défaut>] " -"<name>" +"all] [--regexp] [--value=<motif>] [--fixed-value] [--default=<défaut>] [--" +"url=<url>] <nom>" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" "git config set [<option-de-fichier>] [--type=<type>] [--all] [--" -"value=<valeur>] [--fixed-value] <nom> <valeur>" +"value=<motif>] [--fixed-value] <nom> <valeur>" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<option-de-fichier>] [--all] [--value=<valeur>] [--fixed-" +"git config unset [<option-de-fichier>] [--all] [--value=<motif>] [--fixed-" "value] <nom>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -5301,19 +5310,19 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<option-de-fichier>] [<option-d-affichage>] [--includes] [--" -"all] [--regexp=<regexp>] [--value=<valeur>] [--fixed-value] [--" -"default=<défaut>] <name>" +"all] [--regexp=<regexp>] [--value=<motif>] [--fixed-value] [--" +"default=<défaut>] <nom>" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<option-de-fichier>] [--type=<type>] [--comment=<message>] " -"[--all] [--value=<valeur>] [--fixed-value] <nom> <valeur>" +"[--all] [--value=<motif>] [--fixed-value] <nom> <valeur>" msgid "Config file location" msgstr "Emplacement du fichier de configuration" @@ -6179,22 +6188,6 @@ msgstr "" "%s rejeté parce que les mises à jour de racines superficielles ne sont pas " "permises" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"des références locales n'ont pas pu être mises à jour ; essayez de lancer\n" -" 'git remote prune %s' pour supprimer des branches anciennes en conflit" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s sera en suspens)" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s est devenu en suspens)" - msgid "[deleted]" msgstr "[supprimé]" @@ -6236,6 +6229,18 @@ msgstr "" "%s'\n" "va désactiver l'alerte jusqu'à ce que le distant change HEAD." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"des références locales n'ont pas pu être mises à jour ; essayez de lancer\n" +" 'git remote prune %s' pour supprimer des branches anciennes en conflit" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "échec de la récupération de %s : %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "branches multiples détectées, imcompatible avec --set-upstream" @@ -6483,6 +6488,9 @@ msgstr "git for-each-ref [--merged [<commit>]] [--no-merged [<commit>]]" msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <marqueur>]" + msgid "quote placeholders suitably for shells" msgstr "échapper les champs réservés pour les interpréteurs de commandes" @@ -6498,6 +6506,12 @@ msgstr "échapper les champs réservés pour compatibilité avec Tcl" msgid "show only <n> matched refs" msgstr "n'afficher que <n> références correspondant" +msgid "marker" +msgstr "marqueur" + +msgid "start iteration after the provided marker" +msgstr "commencer l'itération après le marqueur indiqué" + msgid "respect format colors" msgstr "respecter les couleurs de formatage" @@ -6522,9 +6536,16 @@ msgstr "lire les motifs de références depuis l'entrée standard" msgid "also include HEAD ref and pseudorefs" msgstr "inclure aussi la référence HEAD et les pseudo-réfs" +msgid "cannot use --start-after with custom sort options" +msgstr "" +"impossible d'utiliser --start-after avec des options de tri personnalisé" + msgid "unknown arguments supplied with --stdin" msgstr "arguments inconnus fournis avec l'option --stdin" +msgid "cannot use --start-after with patterns" +msgstr "impossible d'utiliser --start-after avec des motifs" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<config> [--] <arguments>" @@ -6924,6 +6945,9 @@ msgstr "recompacter tous les autres paquets excepté le plus gros paquet" msgid "pack prefix to store a pack containing pruned objects" msgstr "préfixe de paquet pour stocker un paquet contenant les objets élagués" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "passer les tâches de maintenance typiquement lancées en premier plan" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "impossible d'analyser gc.logExpiry %s" @@ -6998,14 +7022,14 @@ msgstr "" "tâche incremental-repack ignorée parce que core.multiPackIndex est désactivé" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "le fichier verrou '%s' existe, pas de maintenance" - -#, c-format msgid "task '%s' failed" msgstr "échec de la tâche '%s'" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "le fichier verrou '%s' existe, pas de maintenance" + +#, c-format msgid "'%s' is not a valid task" msgstr "'%s' n'est pas une tâche valide" @@ -7034,9 +7058,6 @@ msgstr "tâche" msgid "run a specific task" msgstr "lancer une tâche spécifique" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "--auto et --schedule=<fréquence> sont mutuellement exclusifs" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "impossible d'ajouter la valeur '%s' de '%s'" @@ -7932,10 +7953,6 @@ msgstr "" "-L<plage>:<fichier> ne peut pas être utilisé avec une spécificateur de chemin" #, c-format -msgid "Final output: %d %s\n" -msgstr "Sortie finale : %d %s\n" - -#, c-format msgid "git show %s: bad file" msgstr "git show %s : fichier incorrect" @@ -8659,6 +8676,9 @@ msgstr "afficher un diffstat à la fin de la fusion" msgid "(synonym to --stat)" msgstr "(synonyme de --stat)" +msgid "show a compact-summary at the end of the merge" +msgstr "afficher un résumé rapide à la fin de la fusion" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "ajouter (au plus <n>) éléments du journal court au message de validation de " @@ -8932,10 +8952,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "erreur : l'entrée d'étiquette ne passe pas fsck : %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) ne devrait jamais rappeler cette fonction" - -#, c-format msgid "could not read tagged object '%s'" msgstr "impossible de lire l'objet étiqueté '%s'" @@ -9456,16 +9472,27 @@ msgstr "utiliser les notes depuis <références-notes>" msgid "unknown subcommand: `%s'" msgstr "sous-commande inconnue : `%s'" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [<options>] [< <liste-références> | < <liste-" -"objets>]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects [<options>] <nom-de-base> [< <liste-références> | < <liste-" -"objets>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<nom-de-" +"paquet>]\n" +" [--cruft] [--cruft-expiration=<date>]\n" +" [--stdout [--filter=<spéc-de-filtre>] | <nom-de-base>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <liste-d-objets>" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9573,6 +9600,19 @@ msgstr "impossible d'empaqueter les objets joignables depuis l'étiquette %s" msgid "unable to get type of object %s" msgstr "impossible d'obtenir le type de l'objet %s" +msgid "Compressing objects by path" +msgstr "Compression des objets par chemin" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "" +"Compression par delta basé sur les chemins en utilisant jusqu'à %d fil " +"d'exécution" +msgstr[1] "" +"Compression par delta basé sur les chemins en utilisant jusqu'à %d fils " +"d'exécution" + msgid "Compressing objects" msgstr "Compression des objets" @@ -9648,6 +9688,9 @@ msgstr "l'objet libre à %s n'a pas pu être examiné" msgid "unable to force loose object" msgstr "impossible de forcer l'objet libre" +msgid "failed to pack objects via path-walk" +msgstr "échec du paquetage des objets par parcours de chemin" + #, c-format msgid "not a rev '%s'" msgstr "'%s' n'est pas une révision" @@ -9763,6 +9806,11 @@ msgstr "utiliser l'algorithme de joignabilité creuse" msgid "create thin packs" msgstr "créer des paquets légers" +msgid "use the path-walk API to walk objects when possible" +msgstr "" +"utiliser l'API de parcours de chemin pour parcourir les objets quand c'est " +"possible" + msgid "create packs suitable for shallow fetches" msgstr "créer des paquets permettant des récupérations superficielles" @@ -9821,6 +9869,10 @@ msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit est trop grand, forcé à %d" #, c-format +msgid "cannot use %s with %s" +msgstr "impossible d'utiliser %s avec %s" + +#, c-format msgid "bad pack compression level %d" msgstr "niveau de compression du paquet %d" @@ -9835,9 +9887,6 @@ msgstr "la taille limite minimale d'un paquet est 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ne peut pas être utilisé pour construire un paquet indexable" -msgid "cannot use --filter with --stdin-packs" -msgstr "impossible d'utiliser --filter avec --stdin-packs" - msgid "cannot use internal rev list with --stdin-packs" msgstr "" "impossible d'utiliser une liste interne de révisions avec --stdin-packs" @@ -9845,9 +9894,6 @@ msgstr "" msgid "cannot use internal rev list with --cruft" msgstr "impossible d'utiliser une liste interne de révisions avec --cruft" -msgid "cannot use --stdin-packs with --cruft" -msgstr "impossible d'utiliser --stdin-packs avec --cruft" - msgid "Enumerating objects" msgstr "Énumération des objets" @@ -9860,22 +9906,6 @@ msgstr "" "réutilisés du paquet %<PRIu32> (depuis %<PRIuMAX>)" 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 "" -"La suppression de 'git pack-redundant' est prévue.\n" -"Si vous utilisez cette commande, veuillez ajouter\n" -"une option supplémentaire, '--i-still-use-this',\n" -"sur la ligne de commande pour nous avertir par\n" -"un courriel à <git@vger.kernel.org>. Merci.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "refus de lancer sans --i-still-use-this" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -11198,6 +11228,14 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "argument de --mirror inconnu : %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "le nom distance '%s' est un sous-ensemble du distant existant '%s'" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "les nom distant '%s' est un sur-ensemble du distant existant '%s'" + msgid "fetch the remote branches" msgstr "rapatrier les branches distantes" @@ -11508,14 +11546,6 @@ msgid "Could not set up %s" msgstr "Impossible de paramétrer %s" #, c-format -msgid " %s will become dangling!" -msgstr " %s se retrouvera en suspens !" - -#, c-format -msgid " %s has become dangling!" -msgstr " %s se retrouve en suspens !" - -#, c-format msgid "Pruning %s" msgstr "Élimination de %s" @@ -11579,11 +11609,11 @@ msgstr "être verbeux : doit être placé avant une sous-commande" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<nom-de-paquet>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11673,6 +11703,9 @@ msgstr "" "spécifier la verison d'empreinte de nom à utiliser pour grouper les objets " "similaires par chemin" +msgid "pass --path-walk to git-pack-objects" +msgstr "passer --path-walk à git-pack-objects" + msgid "do not run git-update-server-info" msgstr "ne pas lancer git-update-server-info" @@ -12849,17 +12882,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [<message>]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <réf>) [<remise>...]" + +msgid "git stash import <commit>" +msgstr "git stash import <commit>" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' n'est pas une validation de type remisage" +msgid "No stash entries found." +msgstr "Aucune entrée de remisage trouvée." + #, c-format msgid "Too many revisions specified:%s" msgstr "Trop de révisions spécifiées : %s" -msgid "No stash entries found." -msgstr "Aucune entrée de remisage trouvée." - #, c-format msgid "%s is not a valid reference" msgstr "%s n'est pas une référence valide" @@ -13014,6 +13053,69 @@ msgstr "inclure les fichiers non suivis dans la remise" msgid "include ignore files" msgstr "inclure les fichiers ignorés" +#, c-format +msgid "cannot parse commit %s" +msgstr "impossible d'analyser le commit %s" + +#, c-format +msgid "invalid author or committer for %s" +msgstr "identité d'auteur ou de valideur invalide pour %s" + +msgid "could not write commit" +msgstr "impossible d'écrire le commit" + +#, c-format +msgid "not a valid revision: %s" +msgstr "révision invalide : %s" + +#, c-format +msgid "not a commit: %s" +msgstr "pas un commit : %s" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s n'est pas un commit de remisage exporté valide" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "commit racine %s trouvé avec des données invalides" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "commit de remisage %s trouvé sans le préfixe attendu" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "impossible d'analyser les parents du commit : %s" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s ne ressemble pas à un commit de remisage" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "impossible de lire le tampon de commit pour %s" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "impossible de sauvegarder le remisage pour %s" + +msgid "unable to write base commit" +msgstr "impossible d'écrire le commit de base" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "impossible de trouver l'entrée de remisage %s" + +msgid "print the object ID instead of writing it to a ref" +msgstr "afficher l'ID d'objet au lieu de l'écrire sur une réf" + +msgid "save the data to the given ref" +msgstr "sauvegarder la donnée sur la réf donnée" + +msgid "exactly one of --print and --to-ref is required" +msgstr "un seul des deux paramètres --print et --to-ref est requis" + msgid "skip and remove all lines starting with comment character" msgstr "" "sauter et supprimer toutes les lignes commençant par le caractère de " @@ -13023,14 +13125,6 @@ msgid "prepend comment character and space to each line" msgstr "ajouter devant chaque ligne le caractère de commentaire et un espace" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "Nom de référence complet attendu, %s obtenu" - -#, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "impossible de trouver une poignée de dépôt pour le sous-module '%s'" - -#, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " "authoritative upstream." @@ -13039,6 +13133,10 @@ msgstr "" "son propre amont d'autorité." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "impossible de trouver une poignée de dépôt pour le sous-module '%s'" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "URL non trouvée pour le chemin de sous-module '%s' dans .gitmodules" @@ -13400,6 +13498,10 @@ msgstr "" "super-projet, mais le super-projet n'est sur aucune branche" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "Nom de référence complet attendu, %s obtenu" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "" "Impossible de trouver la révision actuelle dans le chemin de sous-module '%s'" @@ -13605,6 +13707,10 @@ msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "l'URL de dépôt : '%s' doit être absolu ou commencer par ./|../" #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "Sous-module '%s' déjà utilisé pour le chemin '%s'" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "'%s' n'est pas un nom valide de sous-module" @@ -14251,10 +14357,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "Préparation de l'arbre de travail (extraction de '%s')" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "non joignable : référence invalide : %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Préparation de l'arbre de travail (HEAD détachée %s)" @@ -15930,14 +16032,6 @@ msgstr "" "valeur numérique de configuration incorrecte '%s' pour '%s' dans %s : %s" #, c-format -msgid "invalid value for variable %s" -msgstr "valeur invalide pour la variable %s" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "ignore le composant core.fsync inconne '%s'" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "valeur booléenne de configuration invalide '%s' pour '%s'" @@ -15950,44 +16044,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "'%s' pour '%s' n'est pas un horodatage valide" #, c-format -msgid "abbrev length out of range: %d" -msgstr "longueur d'abbrev hors plage : %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "niveau de compression zlib incorrect %d" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s ne peut pas contenir de retour à la ligne" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s doit contenir au moins un caractère" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "valeur inconnue '%s' de core.fsyncMethod" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles est obsolète ; utilisez core.fsync à la place" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "mode invalide pour la création d'objet : %s" - -#, c-format -msgid "malformed value for %s" -msgstr "valeur mal formée pour %s" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "valeur mal formée pour %s : %s" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "doit être parmi nothing, matching, simple, upstream ou current" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "impossible de charger l'objet blob de config '%s'" @@ -16512,8 +16568,9 @@ msgstr "impossible de comparer stdin à un répertoire" msgid "cannot compare a named pipe to a directory" msgstr "impossible de réparer un tuyau nommé à un répertoire" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<options>] <chemin> <chemin>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "" +"git diff --no-index [<options>] <chemin> <chemin> [<spéc-de-chemin>...]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -16522,6 +16579,13 @@ msgstr "" "Pas un dépôt git. Utilisez --no-index pour comparer deux chemins hors d'un " "arbre de travail" +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"La limitation de comparaison entre spécificateurs de chemins n'est prise en " +"charge que si les deux chemins sont des répertoires." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" @@ -17132,6 +17196,52 @@ msgid "bad git namespace path \"%s\"" msgstr "espaces de nom de Git \"%s\"" #, c-format +msgid "invalid value for variable %s" +msgstr "valeur invalide pour la variable %s" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "ignore le composant core.fsync inconne '%s'" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "longueur d'abbrev hors plage : %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "niveau de compression zlib incorrect %d" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s ne peut pas contenir de retour à la ligne" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s doit contenir au moins un caractère" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "valeur inconnue '%s' de core.fsyncMethod" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles est obsolète ; utilisez core.fsync à la place" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "mode invalide pour la création d'objet : %s" + +#, c-format +msgid "malformed value for %s" +msgstr "valeur mal formée pour %s" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "valeur mal formée pour %s : %s" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "doit être parmi nothing, matching, simple, upstream ou current" + +#, c-format msgid "too many args to run %s" msgstr "trop d'arguments pour lancer %s" @@ -17849,6 +17959,30 @@ msgstr "nom d'identifiant vide (pour <%s>) non permis" msgid "name consists only of disallowed characters: %s" msgstr "le nom n'est constitué que de caractères interdits : %s" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <répertoire>] < <mbox>" + +msgid "no IMAP host specified" +msgstr "serveur IMAP non spécifié" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"régler l'hôte IMAP avec 'git config imap.host <hôte>'\n" +"(par ex., 'git config imap.host imaps://imap.example.com')" + +msgid "no IMAP folder specified" +msgstr "dossier IMAP non spécifié" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"régler le dossier cible avec 'git config imap.folder <dossier>'\"\n" +"(par ex., 'git config imap.folder Drafts')" + msgid "expected 'tree:<depth>'" msgstr "attendu : 'tree:<profondeur>'" @@ -18656,7 +18790,7 @@ msgstr "%s : type de fichier non supporté" #, c-format msgid "hash mismatch for %s (expected %s)" -msgstr "incohérence de hachage pour %s (%s attendu)" +msgstr "incohérence d'empreinte pour %s (%s attendu)" #, c-format msgid "unable to mmap %s" @@ -18835,6 +18969,26 @@ msgid "invalid object name '%.*s'." msgstr "nom d'objet invalide : '%.*s'." #, c-format +msgid "invalid object type \"%s\"" +msgstr "type d'objet invalide \"%s\"" + +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "l'objet %s est de type %s, pas de type %s" + +#, c-format +msgid "object %s has unknown type id %d" +msgstr "l'objet %s a un id de type inconnu %d" + +#, c-format +msgid "unable to parse object: %s" +msgstr "impossible d'analyser l'objet : %s" + +#, c-format +msgid "hash mismatch %s" +msgstr "incohérence d'empreinte %s" + +#, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "" "le répertoire objet %s n'existe pas ; vérifiez .git/objects/info/alternates" @@ -18903,26 +19057,6 @@ msgid "%s is not a valid '%s' object" msgstr "%s n'est pas un objet '%s' valide" #, c-format -msgid "invalid object type \"%s\"" -msgstr "type d'objet invalide \"%s\"" - -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "l'objet %s est de type %s, pas de type %s" - -#, c-format -msgid "object %s has unknown type id %d" -msgstr "l'objet %s a un id de type inconnu %d" - -#, c-format -msgid "unable to parse object: %s" -msgstr "impossible d'analyser l'objet : %s" - -#, c-format -msgid "hash mismatch %s" -msgstr "incohérence de hachage %s" - -#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "entrée dupliquée dans l'index en bitmap : '%s'" @@ -18933,9 +19067,6 @@ msgstr "essai de stockage d'un commit non-sélectionné : '%s'" msgid "too many pseudo-merges" msgstr "trop de pseudo-fusions" -msgid "trying to write commit not in index" -msgstr "échec de l'écriture de l'objet commit absent de l'index" - msgid "failed to load bitmap index (corrupted?)" msgstr "échec du chargement de l'index en bitmap (corruption ?)" @@ -19187,6 +19318,10 @@ msgid "%s isn't available" msgstr "%s n'est pas disponible" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "la valeur pour %s est supérieure à %<PRIdMAX>" + +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "valeur %s pour %s pas dans la plage [%<PRIdMAX>,%<PRIdMAX>]" @@ -20178,6 +20313,14 @@ msgid "%s does not point to a valid object!" msgstr "%s ne pointe pas sur un objet valide!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s se retrouvera en suspens après que %s est effacé\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s est en suspens depuis que %s a été effacé\n" + +#, 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" @@ -22530,6 +22673,9 @@ msgstr "activer l'inclusion des objets arbre" msgid "toggle pruning of uninteresting paths" msgstr "activer l'élagage des chemins inintéressants" +msgid "toggle aggressive edge walk" +msgstr "activer le parcours agressif des arêtes" + msgid "read a pattern list over stdin" msgstr "lire les motifs depuis stdin" @@ -23180,6 +23326,23 @@ msgid "warning: " msgstr "avertissement : " #, c-format +msgid "" +"'%s' 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 "" +"La suppression de '%s' est prévue.\n" +"Si vous utilisez cette commande, veuillez ajouter\n" +"une option supplémentaire, '--i-still-use-this',\n" +"sur la ligne de commande pour nous avertir par\n" +"un courriel à <git@vger.kernel.org>. Merci.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "refus de lancer sans --i-still-use-this" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "échec de uname() avec l'erreur '%s' (%d)\n" @@ -24124,6 +24287,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(corps) Ajout de cc: %s depuis la ligne '%s'\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "erreur : port SMTP invalide '%s'\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Impossible d'exécuter '%s'" @@ -24176,293 +24343,8 @@ msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n" msgid "Do you really want to send %s? [y|N]: " msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " -#~ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -#~ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objet>" - -#~ msgid "allow -s and -t to work with broken/corrupt objects" -#~ msgstr "autoriser -s et -t à travailler sur des objets cassés/corrompus" +#~ msgid "start-after" +#~ msgstr "start-after" -#, c-format -#~ msgid "%s: object is of unknown type '%s': %s" -#~ msgstr "%s : l'objet a un type '%s' inconnu : %s" - -#, c-format -#~ msgid "%s points nowhere!" -#~ msgstr "%s ne pointe nulle part !" - -#~ msgid "(bad commit)\n" -#~ msgstr "(mauvais commit)\n" - -#, c-format -#~ msgid "add_cacheinfo failed for path '%s'; merge aborting." -#~ msgstr "échec de add_cacheinfo pour le chemin '%s' ; abandon de la fusion." - -#, c-format -#~ msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." -#~ msgstr "échec de add_cacheinfo pour le chemin '%s' ; abandon de la fusion." - -#, c-format -#~ msgid "failed to create path '%s'%s" -#~ msgstr "impossible de créer le chemin '%s' %s" - -#, c-format -#~ msgid "Removing %s to make room for subdirectory\n" -#~ msgstr "Suppression de %s pour faire de la place pour le sous-répertoire\n" - -#~ msgid ": perhaps a D/F conflict?" -#~ msgstr ": peut-être un conflit D/F ?" - -#, c-format -#~ msgid "refusing to lose untracked file at '%s'" -#~ msgstr "refus de perdre le fichier non suivi '%s'" - -#, c-format -#~ msgid "blob expected for %s '%s'" -#~ msgstr "blob attendu pour %s '%s'" - -#, c-format -#~ msgid "failed to open '%s': %s" -#~ msgstr "échec à l'ouverture de '%s' : %s" - -#, c-format -#~ msgid "failed to symlink '%s': %s" -#~ msgstr "échec à la création du lien symbolique '%s' : %s" - -#, c-format -#~ msgid "do not know what to do with %06o %s '%s'" -#~ msgstr "ne sait pas traiter %06o %s '%s'" - -#, c-format -#~ msgid "Failed to merge submodule %s (repository corrupt)" -#~ msgstr "Échec de la fusion du sous-module %s (dépôt corrompu)" - -#, c-format -#~ msgid "Fast-forwarding submodule %s to the following commit:" -#~ msgstr "Avance rapide du sous-module %s au commit suivant :" - -#, c-format -#~ msgid "Fast-forwarding submodule %s" -#~ msgstr "Avance rapide du sous-module %s" - -#, c-format -#~ msgid "Failed to merge submodule %s (merge following commits not found)" -#~ msgstr "" -#~ "Échec de fusion du sous-module %s (fusion suivant les commits non trouvée)" - -#, c-format -#~ msgid "Failed to merge submodule %s (not fast-forward)" -#~ msgstr "Échec de fusion du sous-module %s (pas en avance rapide)" - -#~ msgid "Found a possible merge resolution for the submodule:\n" -#~ msgstr "Résolution possible de fusion trouvée pour le sous-module :\n" - -#, 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 "" -#~ "Si c'est correct, ajoutez le simplement à l'index\n" -#~ "en utilisant par exemple :\n" -#~ "\n" -#~ " git update-index --cacheinfo 160000 %s \"%s\"\n" -#~ "\n" -#~ "qui acceptera cette suggestion.\n" - -#, c-format -#~ msgid "Failed to merge submodule %s (multiple merges found)" -#~ msgstr "Échec de fusion du sous-module %s (plusieurs fusions trouvées)" - -#~ msgid "failed to execute internal merge" -#~ msgstr "échec à l'exécution de la fusion interne" - -#, c-format -#~ msgid "unable to add %s to database" -#~ msgstr "impossible d'ajouter %s à la base de données" - -#, c-format -#~ msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." -#~ msgstr "" -#~ "Erreur : refus de perdre le fichier non suivi %s ; écriture dans %s à la " -#~ "place." - -#, c-format -#~ msgid "" -#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " -#~ "left in tree." -#~ msgstr "" -#~ "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s " -#~ "de %s laissée dans l'arbre." - -#, c-format -#~ msgid "" -#~ "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of " -#~ "%s left in tree." -#~ msgstr "" -#~ "CONFLIT (%s/suppression) : %s supprimé dans %s et %s à %s dans %s. " -#~ "Version %s de %s laissée dans l'arbre." - -#, c-format -#~ msgid "" -#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " -#~ "left in tree at %s." -#~ msgstr "" -#~ "CONFLIT (%s/suppression) : %s supprimé dans %s et %s dans %s. Version %s " -#~ "de %s laissée dans l'arbre dans le fichier %s." - -#, 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 "" -#~ "CONFLIT (%s/suppression) : %s supprimé dans %s et %s à %s dans %s. " -#~ "Version %s de %s laissée dans l'arbre dans le fichier %s." - -#~ msgid "rename" -#~ msgstr "renommage" - -#~ msgid "renamed" -#~ msgstr "renommé" - -#, c-format -#~ msgid "Refusing to lose dirty file at %s" -#~ msgstr "Refus de perdre le fichier modifié %s" - -#, c-format -#~ msgid "Refusing to lose untracked file at %s, even though it's in the way." -#~ msgstr "Refus de perdre le fichier non suivi %s, même s'il gêne." - -#, c-format -#~ msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -#~ msgstr "" -#~ "CONFLIT (renommage/ajout) : Renommage de %s->%s dans %s. %s ajouté dans %s" - -#, c-format -#~ msgid "%s is a directory in %s adding as %s instead" -#~ msgstr "%s est un répertoire dans %s ajouté plutôt comme %s" - -#, c-format -#~ msgid "Refusing to lose untracked file at %s; adding as %s instead" -#~ msgstr "Refus de perdre le fichier non suivi %s ; ajout comme %s à la place" - -#, c-format -#~ msgid "" -#~ "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " -#~ "\"%s\"->\"%s\" in \"%s\"%s" -#~ msgstr "" -#~ "CONFLIT (renommage/renommage) : Renommage de \"%s\"->\"%s\" dans la " -#~ "branche \"%s\" et renommage \"%s\"->\"%s\" dans \"%s\"%s" - -#~ msgid " (left unresolved)" -#~ msgstr " (laissé non résolu)" - -#, c-format -#~ msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -#~ msgstr "" -#~ "CONFLIT (renommage/renommage) : renommage '%s'->'%s' dans %s. Renommage " -#~ "'%s'->'%s' dans %s" - -#, 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 "" -#~ "CONFLIT (renommage de répertoire coupé) : la place de %s n'est pas claire " -#~ "parce que le répertoire %s a été renommé en plusieurs autres répertoires, " -#~ "sans aucune destination récupérant la majorité des fichiers." - -#, c-format -#~ msgid "" -#~ "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory " -#~ "%s->%s in %s" -#~ msgstr "" -#~ "CONFLIT (renommage/renommage) : renommage du répertoire %s->%s dans %s. " -#~ "Renommage de répertoire %s->%s dans %s" - -#, c-format -#~ msgid "cannot read object %s" -#~ msgstr "impossible de lire l'objet %s" - -#, c-format -#~ msgid "object %s is not a blob" -#~ msgstr "l'objet %s n'est pas un blob" - -#~ msgid "modify" -#~ msgstr "modification" - -#~ msgid "modified" -#~ msgstr "modifié" - -#, c-format -#~ msgid "Skipped %s (merged same as existing)" -#~ msgstr "%s sauté (fusion identique à l'existant)" - -#, c-format -#~ msgid "Adding as %s instead" -#~ msgstr "Ajout plutôt comme %s" - -#, c-format -#~ msgid "Removing %s" -#~ msgstr "Suppression de %s" - -#~ msgid "file/directory" -#~ msgstr "fichier/répertoire" - -#~ msgid "directory/file" -#~ msgstr "répertoire/fichier" - -#, c-format -#~ msgid "" -#~ "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" -#~ msgstr "" -#~ "CONFLIT (%s) : Il y a un répertoire nommé %s dans %s. Ajout de %s comme %s" - -#, c-format -#~ msgid "Adding %s" -#~ msgstr "Ajout de %s" - -#, c-format -#~ msgid "CONFLICT (add/add): Merge conflict in %s" -#~ msgstr "CONFLIT (ajout/ajout) : Conflit de fusion dans %s" - -#, c-format -#~ msgid "merging of trees %s and %s failed" -#~ msgstr "échec de fusion des arbres %s et %s" - -#~ msgid "Merging:" -#~ msgstr "Fusion :" - -#, c-format -#~ msgid "found %u common ancestor:" -#~ msgid_plural "found %u common ancestors:" -#~ msgstr[0] "%u ancêtre commun trouvé :" -#~ msgstr[1] "%u ancêtres communs trouvés :" - -#~ msgid "merge returned no commit" -#~ msgstr "la fusion n'a pas retourné de commit" - -#~ msgid "cannot write incremental MIDX with bitmap" -#~ msgstr "impossible d'écrire un MIDX incrémental avec des bitmap" - -#, c-format -#~ msgid "Could not find remote branch %s to clone." -#~ msgstr "Impossible de trouver la branche distante '%s' à cloner." - -#, c-format -#~ msgid "merging cannot continue; got unclean result of %d" -#~ msgstr "la fusion ne peut pas continuer ; résultat non propre retourné %d" - -#~ msgid "--onto and --advance are incompatible" -#~ msgstr "--onto et --advance sont incompatibles" - -#, c-format -#~ msgid "key '%s' of pattern had no '*'" -#~ msgstr "la clé '%s' du modèle n'a pas de '*'" - -#, c-format -#~ msgid "preferred pack (%s) is invalid" -#~ msgstr "le paquet préféré (%s) est invalide" +#~ msgid "compact-summary" +#~ msgstr "résumé-compact" @@ -7,8 +7,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-05-27 22:57+0000\n" -"PO-Revision-Date: 2025-06-07 08:26+0700\n" +"POT-Creation-Date: 2025-08-12 17:01+0000\n" +"PO-Revision-Date: 2025-08-15 17:33+0700\n" "Last-Translator: Bagas Sanjaya <bagasdotme@gmail.com>\n" "Language-Team: Indonesian\n" "Language: id\n" @@ -19,6 +19,11 @@ msgstr "" #: add-interactive.c #, c-format +msgid "%s cannot be negative" +msgstr "%s tidak boleh negatif" + +#: add-interactive.c +#, c-format msgid "Huh (%s)?" msgstr "Huh (%s)?" @@ -950,10 +955,10 @@ msgstr "opsi abai spasi putih tidak dikenal '%s'" #: builtin/describe.c builtin/diff-tree.c builtin/difftool.c #: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c #: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c -#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c -#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-parse.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: builtin/merge-tree.c builtin/merge.c builtin/rebase.c builtin/repack.c +#: builtin/replay.c builtin/reset.c builtin/rev-parse.c builtin/show-branch.c +#: builtin/stash.c builtin/submodule--helper.c builtin/tag.c builtin/worktree.c +#: parse-options.c range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "Opsi '%s' dan '%s' tidak dapat digunakan bersamaan" @@ -2369,6 +2374,12 @@ msgstr "Gunakan -f jika Anda benar-benar ingin menambahkannya." msgid "adding files failed" msgstr "gagal menambahkan berkas" +#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c +#: builtin/stash.c +#, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' tidak boleh negatif" + #: builtin/add.c #, c-format msgid "--chmod param '%s' must be either -x or +x" @@ -2407,7 +2418,7 @@ msgid "bad action '%s' for '%s'" msgstr "tindakan jelek '%s' untuk '%s'" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c +#: builtin/pull.c builtin/revert.c diff-merges.c environment.c gpg-interface.c #: ls-refs.c parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" @@ -3901,8 +3912,8 @@ msgstr "" "Mohon tinjau sisa laporan bug di bawah ini.\n" "Anda dapat menghapus baris-baris yang Anda tidak ingin dibagi.\n" -#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c -#: parse-options.h +#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c +#: builtin/pack-objects.c builtin/rebase.c parse-options.h msgid "mode" msgstr "mode" @@ -6350,25 +6361,27 @@ msgstr "git config list [<opsi berkas>] [<opsi tampilan>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<opsi berkas>] [<opsi tampilan>] [--includes] [--all] [--" -"regexp] [--value=<nilai>] [--fixed-value] [--default=<default>] <nama>" +"regexp] [--value=<nilai>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <nama>" #: builtin/config.c msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<opsi berkas>] [--type=<tipe>] [--all] [--value=<nilai>] [--" +"git config set [<opsi berkas>] [--type=<tipe>] [--all] [--value=<pola>] [--" "fixed-value] <nama> <nilai>" #: builtin/config.c msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<opsi berkas>] [--all] [--value=<nilai>] [--fixed-value] " +"git config unset [<opsi berkas>] [--all] [--value=<pola>] [--fixed-value] " "<nama>" #: builtin/config.c @@ -6390,20 +6403,19 @@ msgstr "git config [<opsi berkas>] --get-colorbool <nama> [<stdout-is-tty>]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<opsi berkas>] [<opsi tampilan] [--includes] [--all] [--" -"regexp=<regexp> [--value=<nilai>] [--fixed-value] [--default=<default>] " -"<nama>" +"regexp=<regexp> [--value=<pola>] [--fixed-value] [--default=<asali>] <nama>" #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<opsi berkas>] [--type=<tipe>] [--comment=<pesan>] [--all] " -"[--value=<nilai>] [--fixed-value] <nama> <nilai>" +"[--value=<pola>] [--fixed-value] <nama> <nilai>" #: builtin/config.c msgid "Config file location" @@ -7493,25 +7505,6 @@ msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "tolak %s karena akar dangkal tidak diperkenankan untuk diperbarui" #: builtin/fetch.c -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"beberapa referensi lokal tidak dapat diperbarui; coba jalankan\n" -" 'git remote prune %s' untuk hapus cabang yang lama dan berkonflik" - -#: builtin/fetch.c -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s akan menjadi terjuntai)" - -#: builtin/fetch.c -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s telah menjadi terjuntai)" - -#: builtin/fetch.c msgid "[deleted]" msgstr "[dihapus]" @@ -7534,7 +7527,7 @@ msgstr "opsi \"%s\" nilai \"%s\" tidak valid untuk %s" msgid "option \"%s\" is ignored for %s" msgstr "opsi \"%s\" diabaikan untuk %s" -#: builtin/fetch.c object-store.c +#: builtin/fetch.c odb.c #, c-format msgid "%s is not a valid object" msgstr "%s bukan sebuah objek valid" @@ -7560,6 +7553,20 @@ msgstr "" "mematikan peringatan ini sampai remote mengubah HEAD ke yang lain." #: builtin/fetch.c +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"beberapa referensi lokal tidak dapat diperbarui; coba jalankan\n" +" 'git remote prune %s' untuk hapus cabang yang lama dan berkonflik" + +#: builtin/fetch.c +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "gagal mengambil referensi %s: %s" + +#: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "banyak cabang terdeteksi, tidak kompatibel dengan --set-upstream" @@ -7868,6 +7875,10 @@ msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<komit>]] [--no-contains [<komit>]]" #: builtin/for-each-ref.c +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <penanda>]" + +#: builtin/for-each-ref.c msgid "quote placeholders suitably for shells" msgstr "kutip tempat penampung yang sesuai untuk cangkang" @@ -7887,6 +7898,14 @@ msgstr "kutip tempat penampung yang sesuai untuk Tcl" msgid "show only <n> matched refs" msgstr "hanya perlihatkan <n> referensi yang cocok" +#: builtin/for-each-ref.c +msgid "marker" +msgstr "penanda" + +#: builtin/for-each-ref.c +msgid "start iteration after the provided marker" +msgstr "mulai iterasi setelah penanda yang diberikan" + #: builtin/for-each-ref.c builtin/tag.c msgid "respect format colors" msgstr "hargai warna format" @@ -7920,9 +7939,17 @@ msgid "also include HEAD ref and pseudorefs" msgstr "juga termasuk referensi HEAD dan referensi semu" #: builtin/for-each-ref.c +msgid "cannot use --start-after with custom sort options" +msgstr "tidak dapat menggunakan --start-after dengan opsi urut kustom" + +#: builtin/for-each-ref.c msgid "unknown arguments supplied with --stdin" msgstr "argumen tidak dikenal diberikan dengan --stdin" +#: builtin/for-each-ref.c +msgid "cannot use --start-after with patterns" +msgstr "tidak dapat menggunakan --start-after dengan pola" + #: builtin/for-each-repo.c msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<konfigurasi> [--] <argumen perintah>" @@ -8427,6 +8454,10 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "awalan pak untuk menyimpan pak berisi objek terpangkas" #: builtin/gc.c +msgid "skip maintenance tasks typically done in the foreground" +msgstr "lewati tugas pemeliharaan yang umumnya dilakukan di depan layar" + +#: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "gagal menguraikan nilai gc.logExpiry %s" @@ -8516,13 +8547,13 @@ msgstr "" #: builtin/gc.c #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "berkas kunci '%s' ada, melewatkan pemeliharaan" +msgid "task '%s' failed" +msgstr "tugas '%s' gagal" #: builtin/gc.c #, c-format -msgid "task '%s' failed" -msgstr "tugas '%s' gagal" +msgid "lock file '%s' exists, skipping maintenance" +msgstr "berkas kunci '%s' ada, melewatkan pemeliharaan" #: builtin/gc.c #, c-format @@ -8564,10 +8595,6 @@ msgid "run a specific task" msgstr "jalankan tugas spesifik" #: builtin/gc.c -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "gunakan paling banyak satu dari --auto dan --schedule=<frekuensi>" - -#: builtin/gc.c #, c-format msgid "unable to add '%s' value of '%s'" msgstr "tidak dapat menambahkan nilai '%s' dari '%s'" @@ -9683,11 +9710,6 @@ msgstr "-L<rentang>:<berkas> tidak dapat digunakan dengan spek jalur" #: builtin/log.c #, c-format -msgid "Final output: %d %s\n" -msgstr "Keluaran terakhir: %d %s\n" - -#: builtin/log.c -#, c-format msgid "git show %s: bad file" msgstr "git show %s: berkas jelek" @@ -10606,6 +10628,10 @@ msgid "(synonym to --stat)" msgstr "(sinonim untuk --stat)" #: builtin/merge.c builtin/pull.c +msgid "show a compact-summary at the end of the merge" +msgstr "perlihatkan ringkasan kecil di akhir penggabungan" + +#: builtin/merge.c builtin/pull.c msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "tambah (paling banyak <n>) entri dari log pendek ke pesan komit penggabungan" @@ -10942,11 +10968,6 @@ msgstr "kesalahan: masukan tag tidak lolos fsck: %s" #: builtin/mktag.c #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) seharusnya tidak pernah memicu pemanggilan balik ini" - -#: builtin/mktag.c -#, c-format msgid "could not read tagged object '%s'" msgstr "tidak dapat membaca objek tertag '%s'" @@ -11603,17 +11624,26 @@ msgid "unknown subcommand: `%s'" msgstr "subperintah tidak dikenal: `%s'" #: builtin/pack-objects.c -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [<opsi>...] [< <daftar referensi> | < <daftar-" -"objek>]" - -#: builtin/pack-objects.c msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects [<opsi>...] <nama dasar> [< <daftar referensi> | < <daftar-" -"objek>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<nama pak>]\n" +" [--cruft] [--cruft-expiration=<waktu>]\n" +" [--stdout [--filter=<spek penyaring>] | <nama dasar>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <daftar objek>" #: builtin/pack-objects.c #, c-format @@ -11743,6 +11773,17 @@ msgid "unable to get type of object %s" msgstr "tidak dapat mendapatkan tipe objek %s" #: builtin/pack-objects.c +msgid "Compressing objects by path" +msgstr "Memampatkan objek berdasarkan jalur" + +#: builtin/pack-objects.c +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Kompresi delta berdasarkan jalur menggunakan sampai %d utas" +msgstr[1] "Kompresi delta berdasarkan jalur menggunakan sampai %d utas" + +#: builtin/pack-objects.c msgid "Compressing objects" msgstr "Memampatkan objek" @@ -11835,6 +11876,10 @@ msgid "unable to force loose object" msgstr "tidak dapat memaksakan objek longgar" #: builtin/pack-objects.c +msgid "failed to pack objects via path-walk" +msgstr "gagal mempak objek lewat jalan jalur" + +#: builtin/pack-objects.c #, c-format msgid "not a rev '%s'" msgstr "bukan sebuah revisi '%s'" @@ -11979,6 +12024,10 @@ msgid "create thin packs" msgstr "buat pak tipis" #: builtin/pack-objects.c +msgid "use the path-walk API to walk objects when possible" +msgstr "gunakan API path-walk untuk melangkahi objek apabila dimungkinkan" + +#: builtin/pack-objects.c msgid "create packs suitable for shallow fetches" msgstr "buat pak yang cocok untuk pengambilan dangkal" @@ -12052,7 +12101,12 @@ msgstr "kedalaman rantai delta %d terlalu dalam, memaksakan %d" msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit terlalu tinggi, memaksakan %d" -#: builtin/pack-objects.c config.c +#: builtin/pack-objects.c +#, c-format +msgid "cannot use %s with %s" +msgstr "tidak dapat menggunakan %s dengan %s" + +#: builtin/pack-objects.c environment.c #, c-format msgid "bad pack compression level %d" msgstr "level kompresi pak jelek %d" @@ -12073,10 +12127,6 @@ msgstr "" "--thin tidak dapat digunakan untuk membangun sebuah pak yang dapat diindeks" #: builtin/pack-objects.c -msgid "cannot use --filter with --stdin-packs" -msgstr "tidak dapat menggunakan --filter dengan --stdin-packs" - -#: builtin/pack-objects.c msgid "cannot use internal rev list with --stdin-packs" msgstr "tidak dapat menggunakan daftar revisi internal dengan --stdin-packs" @@ -12085,10 +12135,6 @@ msgid "cannot use internal rev list with --cruft" msgstr "tidak dapat menggunakan daftar revisi internal dengan --cruft" #: builtin/pack-objects.c -msgid "cannot use --stdin-packs with --cruft" -msgstr "tidak dapat menggunakan --stdin-packs dengan --cruft" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "Menghitung objek" @@ -12101,24 +12147,6 @@ msgstr "" "Total %<PRIu32> (delta %<PRIu32>), digunakan ulang %<PRIu32> (delta " "%<PRIu32>), pak yang digunakan ulang %<PRIu32> (dari %<PRIuMAX>)" -#: builtin/pack-redundant.c -msgid "" -"'git pack-redundant' is nominated for removal.\n" -"If you still use this command, please add an extra\n" -"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 "" -"'git pack-redundant' dinominasikan untuk dihapus.\n" -"Jika Anda masih menggunakan perintah ini, mohon tambahkan sebuah opsi\n" -"ekstra, '--i-still-use-this', pada baris perintah dan beri tahu kami jika\n" -"Anda masih menggunakannya dengan mengirimkan surel ke\n" -"<git@vger.kernel.org>. Terima kasih.\n" - -#: builtin/pack-redundant.c -msgid "refusing to run without --i-still-use-this" -msgstr "menolak menjalankan tanpa --i-still-use-this" - #: builtin/pack-refs.c msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " @@ -13695,6 +13723,16 @@ msgid "unknown --mirror argument: %s" msgstr "argumen --mirror tidak dikenal: %s" #: builtin/remote.c +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "nama remote '%s' adalah subset dari remote yang sudah ada '%s'" + +#: builtin/remote.c +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "nama remote '%s' adalah superset dari remote yang sudah ada '%s'" + +#: builtin/remote.c msgid "fetch the remote branches" msgstr "ambil cabang remote" @@ -14069,16 +14107,6 @@ msgstr "Tidak dapat menyiapkan %s" #: builtin/remote.c #, c-format -msgid " %s will become dangling!" -msgstr " %s akan menjadi teruntai!" - -#: builtin/remote.c -#, c-format -msgid " %s has become dangling!" -msgstr " %s telah menjadi teruntai!" - -#: builtin/remote.c -#, c-format msgid "Pruning %s" msgstr "Memangkas %s" @@ -14160,11 +14188,11 @@ msgstr "jadi lebih bertele-tele; harus ditempatkan sebelum subperintah" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<nama pak>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" #: builtin/repack.c msgid "" @@ -14269,6 +14297,10 @@ msgstr "" "serupa berdasarkan jalur" #: builtin/repack.c +msgid "pass --path-walk to git-pack-objects" +msgstr "lewatkan --path-walk ke git-pack-objects" + +#: builtin/repack.c msgid "do not run git-update-server-info" msgstr "jangan jalankan git-update-server-info" @@ -15721,20 +15753,28 @@ msgid "git stash create [<message>]" msgstr "git stash create [<pesan>]" #: builtin/stash.c +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <ref>) [<stase>...]" + +#: builtin/stash.c +msgid "git stash import <commit>" +msgstr "git stash import <komit>" + +#: builtin/stash.c #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' bukan komit mirip stase" #: builtin/stash.c +msgid "No stash entries found." +msgstr "Tidak ada entri stase ditemukan." + +#: builtin/stash.c #, c-format msgid "Too many revisions specified:%s" msgstr "Terlalu banyak revisi disebutkan:%s" #: builtin/stash.c -msgid "No stash entries found." -msgstr "Tidak ada entri stase ditemukan." - -#: builtin/stash.c #, c-format msgid "%s is not a valid reference" msgstr "%s bukan referensi valid" @@ -15934,6 +15974,86 @@ msgstr "masukkan berkas tak terlacak ke dalam stase" msgid "include ignore files" msgstr "masukkan berkas ignore" +#: builtin/stash.c +#, c-format +msgid "cannot parse commit %s" +msgstr "tidak dapat menguraikan komit %s" + +#: builtin/stash.c +#, c-format +msgid "invalid author or committer for %s" +msgstr "pengarang atau pengkomit tidak valid untuk %s" + +#: builtin/stash.c +msgid "could not write commit" +msgstr "tidak dapat menulis komit" + +#: builtin/stash.c +#, c-format +msgid "not a valid revision: %s" +msgstr "bukan revisi valid: %s" + +#: builtin/stash.c +#, c-format +msgid "not a commit: %s" +msgstr "bukan komit: %s" + +#: builtin/stash.c +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s bukan komit stase terekspor yang valid" + +#: builtin/stash.c +#, c-format +msgid "found root commit %s with invalid data" +msgstr "dapat komit akar %s dengan data invalid" + +#: builtin/stash.c +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "dapat komit stase %s tanpa prefiks yang diharapkan" + +#: builtin/stash.c +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "tidak dapat menguraikan induk komit: %s" + +#: builtin/stash.c +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s bukan terlihat seperti komit stase" + +#: builtin/stash.c +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "tidak dapat membaca penyangga komit untuk %s" + +#: builtin/stash.c +#, c-format +msgid "cannot save the stash for %s" +msgstr "tidak dapat menyimpan stase untuk %s" + +#: builtin/stash.c +msgid "unable to write base commit" +msgstr "tidak dapat menulis komit dasar" + +#: builtin/stash.c +#, c-format +msgid "unable to find stash entry %s" +msgstr "tidak dapat menemukan entri stase %s" + +#: builtin/stash.c +msgid "print the object ID instead of writing it to a ref" +msgstr "cetak ID objek daripada menulisnya ke referensi" + +#: builtin/stash.c +msgid "save the data to the given ref" +msgstr "simpan data ke referensi yang diberikan" + +#: builtin/stash.c +msgid "exactly one of --print and --to-ref is required" +msgstr "tepatnya salah satu dari --print dan --to-ref diperlukan" + #: builtin/stripspace.c msgid "skip and remove all lines starting with comment character" msgstr "lewati dan hapus semua baris yang diawali dengan karakter komentar" @@ -15944,16 +16064,6 @@ msgstr "tambahkan karakter komentar dan spasi di awal setiap baris" #: builtin/submodule--helper.c #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "Mengharapkan nama referensi penuh, dapat %s" - -#: builtin/submodule--helper.c -#, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "tidak dapat mendapat pegangan repositori untuk submodul '%s'" - -#: builtin/submodule--helper.c -#, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " "authoritative upstream." @@ -15963,6 +16073,11 @@ msgstr "" #: builtin/submodule--helper.c #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "tidak dapat mendapat pegangan repositori untuk submodul '%s'" + +#: builtin/submodule--helper.c +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "Tidak ada url yang ditemukan untuk jalur submodul '%s' di .gitmodules" @@ -16393,6 +16508,11 @@ msgstr "" #: builtin/submodule--helper.c #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "Mengharapkan nama referensi penuh, dapat %s" + +#: builtin/submodule--helper.c +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "Tidak dapat menemukan revisi saat ini pada jalur submodul '%s'" @@ -16642,6 +16762,11 @@ msgstr "URL repo: '%s' harus absolut atau diawali dengan ./|../" #: builtin/submodule--helper.c #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "nama submodul '%s' telah digunakan untuk jalur '%s'" + +#: builtin/submodule--helper.c +#, c-format msgid "'%s' is not a valid submodule name" msgstr "'%s' bukan nama submodul yang valid" @@ -17425,11 +17550,6 @@ msgstr "Menyiapkan pohon kerja (men-checkout '%s')" #: builtin/worktree.c #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "tidak dapat dicapat: referensi tidak valid: %s" - -#: builtin/worktree.c -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Menyiapkan pohon kerja (HEAD terpisah %s)" @@ -19479,16 +19599,6 @@ msgstr "nilai konfigurasi numerik '%s' jelek untuk '%s' dalam %s: %s" #: config.c #, c-format -msgid "invalid value for variable %s" -msgstr "nilai tidak valid untuk variabel %s" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "mengabaikan komponen core.fsync tidak dikenal '%s'" - -#: config.c -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "nilai konfigurasi boolean '%s' jelek untuk '%s'" @@ -19504,54 +19614,6 @@ msgstr "'%s' untuk '%s' bukan stempel waktu valid" #: config.c #, c-format -msgid "abbrev length out of range: %d" -msgstr "panjang singkatan di luar rentang: %d" - -#: config.c -#, c-format -msgid "bad zlib compression level %d" -msgstr "level kompresi zlib jelek %d" - -#: config.c -#, c-format -msgid "%s cannot contain newline" -msgstr "%s tidak dapat berisi baris baru" - -#: config.c -#, c-format -msgid "%s must have at least one character" -msgstr "%s harus ada sedikitnya satu karakter" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "mengabaikan nilai core.fsyncMethod tidak dikenal '%s'" - -#: config.c -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles usang; gunakan core.fsync sebagai gantinya" - -#: config.c -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "mode tidak valid untuk pembuatan objek: %s" - -#: config.c -#, c-format -msgid "malformed value for %s" -msgstr "nilai rusak untuk %s" - -#: config.c -#, c-format -msgid "malformed value for %s: %s" -msgstr "nilai rusak untuk %s: %s" - -#: config.c -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "harus salah satu dari nothing, matching, simple, upstream atau current" - -#: config.c -#, c-format msgid "unable to load config blob object '%s'" msgstr "tidak dapat memuat objek blob konfigurasi '%s'" @@ -20185,8 +20247,8 @@ msgid "cannot compare a named pipe to a directory" msgstr "tidak dapat membandingkan pipa bernama dan sebuah direktori" #: diff-no-index.c -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<opsi>] <jalur> <jalur>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [<opsi>] <jalur> <jalur> [<spek jalur>...]" #: diff-no-index.c msgid "" @@ -20196,6 +20258,14 @@ msgstr "" "Bukan sebuah repositori git. Gunakan --no-index untuk membandingkan dua " "jalur di luar pohon kerja" +#: diff-no-index.c +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"Membatasi perbandingan dengan spek jalur hanya didukung jika kedua jalur " +"merupakan direktori." + #: diff.c #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" @@ -20378,7 +20448,7 @@ msgstr "buat tambalan" msgid "<n>" msgstr "<n>" -#: diff.c +#: diff.c parse-options.h msgid "generate diffs with <n> lines context" msgstr "buat diff dengan <n> baris konteks" @@ -20529,7 +20599,7 @@ msgstr "jangan perlihatkan prefiks sumber atau tujuan apapun" msgid "use default prefixes a/ and b/" msgstr "gunakan awalan asali a/ dan b/" -#: diff.c +#: diff.c parse-options.h msgid "show context between diff hunks up to the specified number of lines" msgstr "" "perlihatkan konteks diantara bingkah diff hingga jumlah baris yang disebutkan" @@ -20929,6 +20999,64 @@ msgstr "tidak dapat men-stat berkas '%s'" msgid "bad git namespace path \"%s\"" msgstr "jalur ruang nama git jelek \"%s\"" +#: environment.c +#, c-format +msgid "invalid value for variable %s" +msgstr "nilai tidak valid untuk variabel %s" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "mengabaikan komponen core.fsync tidak dikenal '%s'" + +#: environment.c +#, c-format +msgid "abbrev length out of range: %d" +msgstr "panjang singkatan di luar rentang: %d" + +#: environment.c +#, c-format +msgid "bad zlib compression level %d" +msgstr "level kompresi zlib jelek %d" + +#: environment.c +#, c-format +msgid "%s cannot contain newline" +msgstr "%s tidak dapat berisi baris baru" + +#: environment.c +#, c-format +msgid "%s must have at least one character" +msgstr "%s harus ada sedikitnya satu karakter" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "mengabaikan nilai core.fsyncMethod tidak dikenal '%s'" + +#: environment.c +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles usang; gunakan core.fsync sebagai gantinya" + +#: environment.c +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "mode tidak valid untuk pembuatan objek: %s" + +#: environment.c +#, c-format +msgid "malformed value for %s" +msgstr "nilai rusak untuk %s" + +#: environment.c +#, c-format +msgid "malformed value for %s: %s" +msgstr "nilai rusak untuk %s: %s" + +#: environment.c +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "harus salah satu dari nothing, matching, simple, upstream atau current" + #: exec-cmd.c #, c-format msgid "too many args to run %s" @@ -21800,6 +21928,35 @@ msgstr "nama identitas kosong (untuk <%s>) tidak diperbolehkan" msgid "name consists only of disallowed characters: %s" msgstr "nama hanya terdiri dari karakter yang tidak diperbolehkan: %s" +#: imap-send.c +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" + +#: imap-send.c +msgid "no IMAP host specified" +msgstr "tidak ada host IMAP yang dirincikan" + +#: imap-send.c +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"setel host IMAP dengan 'git config imap.host <host>'.\n" +"(misalnya 'git config imap.host imaps://imap.example.com')" + +#: imap-send.c +msgid "no IMAP folder specified" +msgstr "tidak ada folder IMAP yang dirincikan" + +#: imap-send.c +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"setel folder target dengan 'git config imap.folder <folder>'.\n" +"(contohnya 'git config imap.folder Drafts')" + #: list-objects-filter-options.c msgid "expected 'tree:<depth>'" msgstr "'tree:<kedalaman> diharapkan'" @@ -22962,114 +23119,114 @@ msgstr "<objek>:<jalur> diperlukan, hanya <objek> '%s' diberikan" msgid "invalid object name '%.*s'." msgstr "nama objek tidak valid '%.*s'." -#: object-store.c +#: object.c +#, c-format +msgid "invalid object type \"%s\"" +msgstr "tipe objek tidak valid \"%s\"" + +#: object.c +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "objek %s adalah %s, bukan %s" + +#: object.c +#, c-format +msgid "object %s has unknown type id %d" +msgstr "objek %s punya id tipe tidak dikenal %d" + +#: object.c +#, c-format +msgid "unable to parse object: %s" +msgstr "tidak dapat menguraikan objek: %s" + +#: object.c +#, c-format +msgid "hash mismatch %s" +msgstr "hash tidak cocok %s" + +#: odb.c #, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "direktori objek %s tidak ada; periksa .git/objects/info/alternates" -#: object-store.c +#: odb.c #, c-format msgid "unable to normalize alternate object path: %s" msgstr "tidak dapat menormalisasikan jalur objek alternatif: %s" -#: object-store.c +#: odb.c #, c-format msgid "%s: ignoring alternate object stores, nesting too deep" msgstr "%s: mengabaikan penyimpanan objek alternatif, bersarang terlalu dalam" -#: object-store.c +#: odb.c msgid "unable to fdopen alternates lockfile" msgstr "tidak dapat men-fdopen berkas kunci alternatif" -#: object-store.c +#: odb.c msgid "unable to read alternates file" msgstr "tidak dapat membaca berkas alternatif" -#: object-store.c +#: odb.c msgid "unable to move new alternates file into place" msgstr "tidak dapat memindahkan berkas alternatif baru ke tempatnya" -#: object-store.c +#: odb.c #, c-format msgid "path '%s' does not exist" msgstr "jalur '%s' tidak ada" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "" "repositori referensi '%s' sebagai sebuah checkout tertaut belum didukung." -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is not a local repository." msgstr "repositori referensi '%s' bukan sebuah repositori lokal" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is shallow" msgstr "repositori referensi '%s' dangkal" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is grafted" msgstr "repositori referensi '%s' cangkok" -#: object-store.c +#: odb.c #, c-format msgid "could not find object directory matching %s" msgstr "tidak dapat menemukan direktori objek yang cocok dengan %s" -#: object-store.c +#: odb.c #, c-format msgid "invalid line while parsing alternate refs: %s" msgstr "baris tidak valid saat menguraikan referensi alternatif: %s" -#: object-store.c +#: odb.c #, c-format msgid "replacement %s not found for %s" msgstr "pengganti %s tidak ditemukan untuk %s" -#: object-store.c +#: odb.c #, c-format msgid "packed object %s (stored in %s) is corrupt" msgstr "objek terpak %s (disimpan di %s) rusak" -#: object-store.c +#: odb.c #, c-format msgid "missing mapping of %s to %s" msgstr "pemetaan %s ke %s hilang" -#: object-store.c +#: odb.c #, c-format msgid "%s is not a valid '%s' object" msgstr "%s bukan sebuah objek '%s' valid" -#: object.c -#, c-format -msgid "invalid object type \"%s\"" -msgstr "tipe objek tidak valid \"%s\"" - -#: object.c -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "objek %s adalah %s, bukan %s" - -#: object.c -#, c-format -msgid "object %s has unknown type id %d" -msgstr "objek %s punya id tipe tidak dikenal %d" - -#: object.c -#, c-format -msgid "unable to parse object: %s" -msgstr "tidak dapat menguraikan objek: %s" - -#: object.c -#, c-format -msgid "hash mismatch %s" -msgstr "hash tidak cocok %s" - #: pack-bitmap-write.c #, c-format msgid "duplicate entry when writing bitmap index: %s" @@ -23084,10 +23241,6 @@ msgstr "mencoba menyimpan komit yang tidak dipilih: '%s'" msgid "too many pseudo-merges" msgstr "terlalu banyak penggabungan semu" -#: pack-bitmap-write.c -msgid "trying to write commit not in index" -msgstr "mencoba menulis komit yang bukan di indeks" - #: pack-bitmap.c msgid "failed to load bitmap index (corrupted?)" msgstr "gagal menulis indeks bitmap (rusak?)" @@ -23398,6 +23551,11 @@ msgstr "%s tidak ada" #: parse-options.c #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "nilai %s melebihi %<PRIdMAX>" + +#: parse-options.c +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "nilai %s untuk %s di luar rentang [%<PRIdMAX>,%<PRIdMAX>]" @@ -24584,6 +24742,16 @@ msgstr "%s tidak menunjuk ke sebuah objek valid!" #: refs.c #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s akan menjadi teruntai setelah %s dihapus\n" + +#: refs.c +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s telah menjadi teruntai setelah %s dihapus\n" + +#: refs.c +#, 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" @@ -27417,6 +27585,10 @@ msgid "toggle pruning of uninteresting paths" msgstr "pangkas jalur yang tidak menarik" #: t/helper/test-path-walk.c +msgid "toggle aggressive edge walk" +msgstr "nyalakan jalan tepian agresif" + +#: t/helper/test-path-walk.c msgid "read a pattern list over stdin" msgstr "baca daftar pola dari masukan standar" @@ -28179,6 +28351,25 @@ msgstr "kesalahan: " msgid "warning: " msgstr "peringatan: " +#: usage.c +#, c-format +msgid "" +"'%s' 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 "" +"'%s' dinominasikan untuk dihapus.\n" +"Jika Anda masih menggunakan perintah ini, mohon tambahkan sebuah opsi\n" +"tambahan, '--i-still-use-this', pada baris perintah dan beri tahu kami jika\n" +"Anda masih menggunakannya dengan mengirimkan surel ke\n" +"<git@vger.kernel.org>. Terima kasih.\n" + +#: usage.c +msgid "refusing to run without --i-still-use-this" +msgstr "menolak menjalankan tanpa --i-still-use-this" + #: version.c #, c-format msgid "uname() failed with error '%s' (%d)\n" @@ -29328,6 +29519,11 @@ msgstr "(body) Menambahkan cc: %s dari baris '%s'\n" #: git-send-email.perl #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "galat: port SMTP tidak valid '%s'\n" + +#: git-send-email.perl +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Tidak dapat menjalankan '%s'" @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git 2.49.0\n" +"Project-Id-Version: git 2.51.0\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-03-10 17:45+0100\n" -"PO-Revision-Date: 2025-03-10 17:48+0100\n" +"POT-Creation-Date: 2025-08-14 09:52+0100\n" +"PO-Revision-Date: 2025-08-14 09:53+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Svenska <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -19,6 +19,10 @@ msgstr "" "X-Generator: Gtranslator 42.0\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s kan inte vara negativt" + +#, c-format msgid "Huh (%s)?" msgstr "VadÃ¥ (%s)?" @@ -1923,6 +1927,10 @@ msgid "adding files failed" msgstr "misslyckades lägga till filer" #, c-format +msgid "'%s' cannot be negative" +msgstr "â€%s†kan inte vara negativt" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "â€--chmodâ€-parametern â€%s†mÃ¥ste antingen vara -x eller +x" @@ -3241,11 +3249,8 @@ msgstr "endast en buntflagga kan anges" msgid "git cat-file <type> <object>" msgstr "git cat-file <typ> <objekt>" -msgid "git cat-file (-e | -p) <object>" -msgstr "git cat-file (-e | -p) <objekt>" - -msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -msgstr "git cat-file (-t | -s) [--allow-unknown-type] <objekt>" +msgid "git cat-file (-e | -p | -t | -s) <object>" +msgstr "git cat-file (-e | -p | -t | -s) <objekt>" msgid "" "git cat-file (--textconv | --filters)\n" @@ -3284,9 +3289,6 @@ msgstr "visa objekttyp (en av: â€blobâ€, â€treeâ€, â€commitâ€, â€tagâ€, msgid "show object size" msgstr "visa objektstorlek" -msgid "allow -s and -t to work with broken/corrupt objects" -msgstr "lÃ¥ter -s och -t att fungera med trasiga/sönderskrivna objekt" - msgid "use mail map file" msgstr "använd e-postmappningsfil" @@ -3342,6 +3344,13 @@ msgstr "blob|träd" msgid "use a <path> for (--textconv | --filters); Not with 'batch'" msgstr "använd en <sökväg> för (--textconv | --filters): Inte med â€batchâ€" +msgid "objects filter only supported in batch mode" +msgstr "objektfilter stöds endast i buntläge" + +#, c-format +msgid "objects filter not supported: '%s'" +msgstr "objektfilter stöds inte: â€%sâ€" + #, c-format msgid "'%s=<%s>' needs '%s' or '%s'" msgstr "â€%s=<%s>†behöver â€%s†eller â€%sâ€" @@ -5054,23 +5063,25 @@ msgstr "git config list [<filflagga>] [<visningsflagga>] [--includes]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<filflagga>] [<visningsflagga>] [--includes] [--all] [--" -"regexp] [--value=<värde>] [--fixed-value] [--default=<förval>] <namn>" +"regexp] [--value=<mönster>] [--fixed-value] [--default=<förval>] [--" +"url=<url>] <namn>" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<filflagga>] [--type=<typ>] [--all] [--value=<värde>] [--" +"git config set [<filflagga>] [--type=<typ>] [--all] [--value=<mönster>] [--" "fixed-value] <namn> <värde>" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<filflagga>] [--all] [--value=<värde>] [--fixed-value] " +"git config unset [<filflagga>] [--all] [--value=<mönster>] [--fixed-value] " "<namn>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -5087,19 +5098,19 @@ msgstr "git config [<filflagga>] --get-colorbool <namn> [<stdout-är-tty>]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<filflagga>] [<visningsflagga>] [--includes] [--all] [--" -"regexp=<reguttr>] [--value=<värde>] [--fixed-value] [--default=<förval>] " +"regexp=<reguttr>] [--value=<mönster>] [--fixed-value] [--default=<förval>] " "<namn>" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<filflagga>] [--type=<typ>] [--comment=<meddelande>] [--all] " -"[--value=<värde>] [--fixed-value] <namn> <värde>" +"[--value=<mönster>] [--fixed-value] <namn> <värde>" msgid "Config file location" msgstr "Konfigurationsfilens plats" @@ -5585,6 +5596,50 @@ msgstr "ange ett filändelse i strftime-format" msgid "specify the content of the diagnostic archive" msgstr "ange vilket innehÃ¥ll diagnostikarkivet ska ha" +#, c-format +msgid "unable to parse mode: %s" +msgstr "kan inte tolka läget: %s" + +#, c-format +msgid "unable to parse object id: %s" +msgstr "kan inte tolka objekt-id: %s" + +msgid "git diff-pairs -z [<diff-options>]" +msgstr "git diff-pairs -z [<diff-flaggor>]" + +#, c-format +msgid "unrecognized argument: %s" +msgstr "okänt argument: %s" + +msgid "working without -z is not supported" +msgstr "stöder inte att arbeta utan -z" + +msgid "pathspec arguments not supported" +msgstr "sökvägsangivelser stöds inte som argument" + +msgid "revision arguments not allowed" +msgstr "revisioner tillÃ¥ts inte som argument" + +msgid "invalid raw diff input" +msgstr "ogiltig indata i rÃ¥ diff" + +msgid "tree objects not supported" +msgstr "trädobjekt stöds inte" + +msgid "got EOF while reading path" +msgstr "fick filslut vid läsning av sökväg" + +msgid "got EOF while reading destination path" +msgstr "fick filslut vid läsning av destinationssökväg" + +#, c-format +msgid "unable to parse rename/copy score: %s" +msgstr "kan inte tolka namnbyte-/kopieringspoäng: %s" + +#, c-format +msgid "unknown diff status: %c" +msgstr "okänd diff-status: %c" + msgid "--merge-base only works with two commits" msgstr "--merge-base fungerar endast med tvÃ¥ incheckningar" @@ -5725,6 +5780,9 @@ msgstr "visa förlopp efter <n> objekt" msgid "select handling of signed tags" msgstr "välj hantering av signerade taggar" +msgid "select handling of signed commits" +msgstr "välj hantering av signerade incheckningar" + msgid "select handling of tags that tag filtered objects" msgstr "välj hantering av taggar som har taggfiltrerade objekt" @@ -5895,22 +5953,6 @@ msgstr "%s sände inte alla nödvändiga objekt" msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "avvisade %s dÃ¥ grunda rötter inte tillÃ¥ts uppdateras" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"vissa lokala referenser kunde inte uppdateras; testa att köra\n" -" â€git remote prune %s†för att ta bort gamla grenar som stÃ¥r i konflikt" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s kommer bli dinglande)" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s har blivit dinglande)" - msgid "[deleted]" msgstr "[borttagen]" @@ -5951,6 +5993,18 @@ msgstr "" "varningen till fjärren ändrar HEAD till nÃ¥got annat genom att köra\n" "â€git config set remote %s.followRemoteHEAD warn-if-not-branch-%sâ€." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"vissa lokala referenser kunde inte uppdateras; testa att köra\n" +" â€git remote prune %s†för att ta bort gamla grenar som stÃ¥r i konflikt" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "misslyckades hämta referensen %s: %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "flera grenar upptäcktes, inkompatibelt med --set-upstream" @@ -6191,6 +6245,9 @@ msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "" "git for-each-ref [--contains [<incheckning>]] [--no-contains [<incheckning>]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <markör>]" + msgid "quote placeholders suitably for shells" msgstr "citera platshÃ¥llare passande för skal" @@ -6206,6 +6263,12 @@ msgstr "citera platshÃ¥llare passande för Tcl" msgid "show only <n> matched refs" msgstr "visa endast <n> träffade refs" +msgid "marker" +msgstr "markör" + +msgid "start iteration after the provided marker" +msgstr "pÃ¥börjar iterationen efter angiven markör" + msgid "respect format colors" msgstr "använd formatfärger" @@ -6230,9 +6293,15 @@ msgstr "läs referensmönster frÃ¥n standard in" msgid "also include HEAD ref and pseudorefs" msgstr "ta ocksÃ¥ med HEAD- och pseudo-referenser" +msgid "cannot use --start-after with custom sort options" +msgstr "kan inte använda --start-after med skräddarsydda sorteringsalternativ" + msgid "unknown arguments supplied with --stdin" msgstr "okända argument angavs tillsammans med --stdin" +msgid "cannot use --start-after with patterns" +msgstr "kan inte använda --start-after med mönster" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<konfig> [--] <argument>" @@ -6365,10 +6434,6 @@ msgid "%s: object corrupt or missing: %s" msgstr "%s: objektet trasigt eller saknas: %s" #, c-format -msgid "%s: object is of unknown type '%s': %s" -msgstr "%s: objektet har okänd typ â€%sâ€: %s" - -#, c-format msgid "%s: object could not be parsed: %s" msgstr "%s: objektet kunde inte tolkas: %s" @@ -6425,16 +6490,19 @@ msgstr "kan inte läsa rev-index för paketfil â€%sâ€" msgid "invalid rev-index for pack '%s'" msgstr "ogiltigt rev-index för paketet â€%sâ€" +msgid "Checking ref database" +msgstr "Kontrollerar referensdatabasen" + msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" -" [--[no-]name-objects] [<object>...]" +" [--[no-]name-objects] [--[no-]references] [<object>...]" msgstr "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" -" [--[no-]name-objects] [<objekt>...]" +" [--[no-]name-objects] [--[no-]references] [<objekt>...]" msgid "show unreachable objects" msgstr "visa onÃ¥bara objekt" @@ -6474,6 +6542,9 @@ msgstr "visa förlopp" msgid "show verbose names for reachable objects" msgstr "visa ordrika namn för nÃ¥bara objekt" +msgid "check reference database consistency" +msgstr "kontrollerar referensdatabasens konsistens" + msgid "Checking objects" msgstr "Kontrollerar objekt" @@ -6632,6 +6703,9 @@ msgstr "packa om alla paket förutom det största paketet" msgid "pack prefix to store a pack containing pruned objects" msgstr "paketprefix att lagra ett paket som innehÃ¥ller bortrensade objekt" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "hoppa över underhÃ¥llsfunktioner som vanligtvis körs i förgrunden" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "misslyckades tolka värdet %s för gc.logExpiry" @@ -6704,14 +6778,14 @@ msgstr "" "inaktiverat" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "lÃ¥sfilen â€%s†finns, hoppar över underhÃ¥ll" - -#, c-format msgid "task '%s' failed" msgstr "uppgiften â€%s†misslyckades" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "lÃ¥sfilen â€%s†finns, hoppar över underhÃ¥ll" + +#, c-format msgid "'%s' is not a valid task" msgstr "â€%s†är inte en giltig uppgift" @@ -6740,9 +6814,6 @@ msgstr "uppgift" msgid "run a specific task" msgstr "utför en specifik uppgift" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "använd som mest en av --auto och --schedule=<frekvens>" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "kan inte lägga till â€%sâ€-värdet för â€%sâ€" @@ -7608,18 +7679,10 @@ msgstr "" "spÃ¥ra utvecklingen av radintervallet <start>,<slut> eller funktionen :" "<funknamn> i <fil>" -#, c-format -msgid "unrecognized argument: %s" -msgstr "okänt argument: %s" - msgid "-L<range>:<file> cannot be used with pathspec" msgstr "-L<intervall>:<fil> kan inte användas med sökvägsspecifikation" #, c-format -msgid "Final output: %d %s\n" -msgstr "Slututdata: %d %s\n" - -#, c-format msgid "git show %s: bad file" msgstr "git show %s: felaktig fil" @@ -8250,6 +8313,9 @@ msgstr "gör endast en enkel sammanslagning" msgid "also show informational/conflict messages" msgstr "visa även informations-/konfliktmeddelanden" +msgid "suppress all output; only exit status wanted" +msgstr "undertryck all utdata; önskar endast avslutningsstatus" + msgid "list filenames without modes/oids/stages" msgstr "lista filnamn utan lägen/oid/köer" @@ -8310,6 +8376,9 @@ msgstr "visa en diffstat när sammanslagningen är färdig" msgid "(synonym to --stat)" msgstr "(synonym till --stat)" +msgid "show a compact-summary at the end of the merge" +msgstr "visa en kompakt sammanfattning när sammanslagningen är färdig" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "lägg till (som mest <n>) poster frÃ¥n shortlog till incheckningsmeddelandet" @@ -8575,10 +8644,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "fel: taggindata godkänns inte av fsck: %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) skulle aldrig utlösa detta Ã¥teranrop" - -#, c-format msgid "could not read tagged object '%s'" msgstr "kunde inte läsa det taggade objektet â€%sâ€" @@ -8651,8 +8716,11 @@ msgstr "" "vid ompackning, samla mindre paketfiler i en bunt som är större än denna " "storlek" -msgid "git mv [<options>] <source>... <destination>" -msgstr "git mv [<flaggor>] <källa>... <mÃ¥l>" +msgid "git mv [-v] [-f] [-n] [-k] <source> <destination>" +msgstr "git mv [-v] [-f] [-n] [-k] <källa> <mÃ¥l>" + +msgid "git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>" +msgstr "git mv [-v] [-f] [-n] [-k] <källa> <mÃ¥lkatalog>" #, c-format msgid "Directory %s is in index and no submodule?" @@ -8722,6 +8790,10 @@ msgid "%s, source=%s, destination=%s" msgstr "%s, källa=%s, mÃ¥l=%s" #, c-format +msgid "cannot move both '%s' and its parent directory '%s'" +msgstr "kan inte flytta bÃ¥de â€%s†och dess föräldrakatalog â€%sâ€" + +#, c-format msgid "Renaming %s to %s\n" msgstr "Byter namn pÃ¥ %s till %s\n" @@ -9086,13 +9158,26 @@ msgstr "använd anteckningar frÃ¥n <anteckningsref>" msgid "unknown subcommand: `%s'" msgstr "okänt underkommando: â€%sâ€" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "git pack-objects --stdout [<flaggor>] [< <reflista> | < <objektlista>]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" msgstr "" -"git pack-objects [<flaggor>] <basnamn> [< <reflista> | < <objektlista>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<paketnamn>]\n" +" [--cruft] [--cruft-expiration=<tid>]\n" +" [--stdout [--filter=<filterspec>] | <basnamn>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <objektlista>" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9196,6 +9281,15 @@ msgstr "kan inte packa objekt nÃ¥bara frÃ¥n taggen %s" msgid "unable to get type of object %s" msgstr "kan inte hämta typ för objektet %s" +msgid "Compressing objects by path" +msgstr "komprimerar objekt efter sökväg" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Sökvägsbaserad deltakomprimering använder upp till %d trÃ¥d" +msgstr[1] "Sökvägsbaserad deltakomprimering använder upp till %d trÃ¥dar" + msgid "Compressing objects" msgstr "Komprimerar objekt" @@ -9270,6 +9364,9 @@ msgstr "lösa objekt pÃ¥ %s kunde inte undersökas" msgid "unable to force loose object" msgstr "kan inte tvinga lösa objekt" +msgid "failed to pack objects via path-walk" +msgstr "misslyckades packa objekt genom att gÃ¥ genom sökväg" + #, c-format msgid "not a rev '%s'" msgstr "inte en referens â€%sâ€" @@ -9379,6 +9476,9 @@ msgstr "använd gles-nÃ¥barhetsalgoritmen" msgid "create thin packs" msgstr "skapa tunna paket" +msgid "use the path-walk API to walk objects when possible" +msgstr "använd â€path-walkâ€-API:et för att gÃ¥ genom objekt om möjligt" + msgid "create packs suitable for shallow fetches" msgstr "skapa packfiler lämpade för grunda hämtningar" @@ -9435,6 +9535,10 @@ msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit är för högt, pÃ¥tvingar %d" #, c-format +msgid "cannot use %s with %s" +msgstr "kan inte använda %s med %s" + +#, c-format msgid "bad pack compression level %d" msgstr "felaktig paketkomprimeringsgrad %d" @@ -9448,18 +9552,12 @@ msgstr "minsta packstorlek är 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin kan inte användas för att bygga ett indexerbart paket" -msgid "cannot use --filter with --stdin-packs" -msgstr "kan inte använda --filter med --stdin-packs" - msgid "cannot use internal rev list with --stdin-packs" msgstr "kan inte använda intern revisionslista med --stdin-packs" msgid "cannot use internal rev list with --cruft" msgstr "kan inte använda intern revisionslista med --cruft" -msgid "cannot use --stdin-packs with --cruft" -msgstr "kan inte använda --stdin-packs med --cruft" - msgid "Enumerating objects" msgstr "Räknar upp objekt" @@ -9472,22 +9570,6 @@ msgstr "" "paket-Ã¥teranvända %<PRIu32> (frÃ¥n %<PRIuMAX>)" 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 "" -"â€git pack-redundant†har nominerats för borttagning.\n" -"Om du fortfarande använder kommandot, lägg till flaggan\n" -"â€--i-still-use-this†pÃ¥ kommandoraden och berätta för\n" -"oss att du fortfarande använder det pÃ¥ e-post till\n" -"<git@vger.kernel.org>. Tack.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "vägrar köra utan --i-still-use-this" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -9639,6 +9721,10 @@ msgstr "" msgid "unable to access commit %s" msgstr "kan inte komma Ã¥t incheckningen %s" +#, c-format +msgid "invalid refspec '%s'" +msgstr "felaktig referensspecifikation: â€%sâ€" + msgid "ignoring --verify-signatures for rebase" msgstr "ignorera --verify-signatures för ombasering" @@ -10588,6 +10674,9 @@ msgstr "" msgid "git reflog exists <ref>" msgstr "git reflog exists <referens>" +msgid "git reflog drop [--all [--single-worktree] | <refs>...]" +msgstr "git reflog drop [--all [--single-worktree] | <referenser>...]" + #, c-format msgid "invalid timestamp '%s' given to '--%s'" msgstr "ogiltig tidsstämpel â€%s†given i â€--%sâ€" @@ -10636,8 +10725,8 @@ msgid "Marking reachable objects..." msgstr "Markerar nÃ¥bara objekt..." #, c-format -msgid "%s points nowhere!" -msgstr "%s pekar ingenstans!" +msgid "reflog could not be found: '%s'" +msgstr "refernsloggen hittades inte: â€%sâ€" msgid "no reflog specified to delete" msgstr "ingen referenslogg att ta bort angavs" @@ -10646,6 +10735,15 @@ msgstr "ingen referenslogg att ta bort angavs" msgid "invalid ref format: %s" msgstr "felaktigt referensformat: %s" +msgid "drop the reflogs of all references" +msgstr "kasta referensloggar för alla referenser" + +msgid "drop reflogs from the current worktree only" +msgstr "kasta referensloggar endast för aktuell arbetskatalog" + +msgid "references specified along with --all" +msgstr "referenser angivna tillsammans med --all" + msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" msgstr "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" @@ -10753,6 +10851,14 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "okänt argument till --mirror: %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "fjärrnamnet â€%s†är en delmängd av befintlig fjärr â€%sâ€" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "fjärrnamnet â€%s†är en övermängd av befintlig fjärr â€%sâ€" + msgid "fetch the remote branches" msgstr "hämta fjärrgrenarna" @@ -11052,14 +11158,6 @@ msgid "Could not set up %s" msgstr "Kunde inte ställa in %s" #, c-format -msgid " %s will become dangling!" -msgstr " %s kommer bli dinglande!" - -#, c-format -msgid " %s has become dangling!" -msgstr " %s har blivit dinglande!" - -#, c-format msgid "Pruning %s" msgstr "Rensar %s" @@ -11123,11 +11221,11 @@ msgstr "var pratsam; mÃ¥ste skrivas före ett underkommando" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<paket-namn>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11192,6 +11290,9 @@ msgstr "cirkadatum" msgid "with --cruft, expire objects older than this" msgstr "med --cruft, lÃ¥t tid gÃ¥ ut för objekt äldre än detta" +msgid "with --cruft, only repack cruft packs smaller than this" +msgstr "med --cruft, packa bara om onödiga paket mindre än detta" + msgid "remove redundant packs, and run git-prune-packed" msgstr "ta bort överflödiga paket, och kör git-prune-packed" @@ -11207,6 +11308,9 @@ msgstr "" "ange den namnhash-version som ska användas för att gruppera liknande objekt " "efter sökväg" +msgid "pass --path-walk to git-pack-objects" +msgstr "sänd --path-walk till git-pack-objects" + msgid "do not run git-update-server-info" msgstr "kör inte git-update-server-info" @@ -11666,6 +11770,9 @@ msgstr "kan inte hämta diskanvändning för %s" msgid "invalid value for '%s': '%s', the only allowed format is '%s'" msgstr "felaktigt värde för â€%sâ€: â€%sâ€, det enda tillÃ¥tna formatet är â€%sâ€" +msgid "-z option used with unsupported option" +msgstr "flaggan -z använd med en flagga som inte stöds" + msgid "rev-list does not support display of notes" msgstr "rev-list stöder inte visning av anteckningar" @@ -12351,17 +12458,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [<meddelande>]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <referens>) [<stash>...]" + +msgid "git stash import <commit>" +msgstr "git stash import <incheckning>" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "â€%s†är inte en â€stashâ€-liknande incheckning" +msgid "No stash entries found." +msgstr "Inga â€stashâ€-poster hittades." + #, c-format msgid "Too many revisions specified:%s" msgstr "För mÃ¥nga revisioner angivna:%s" -msgid "No stash entries found." -msgstr "Inga â€stashâ€-poster hittades." - #, c-format msgid "%s is not a valid reference" msgstr "%s är inte en giltig referens" @@ -12513,19 +12626,74 @@ msgstr "ta med ospÃ¥rade filer i â€stashâ€" msgid "include ignore files" msgstr "ta med ignorerade filer" -msgid "skip and remove all lines starting with comment character" -msgstr "hoppa över och ta bort alla rader som inleds med kommentarstecken" +#, c-format +msgid "cannot parse commit %s" +msgstr "kan inte tolka incheckningen %s" -msgid "prepend comment character and space to each line" -msgstr "lägg in kommentarstecken och blanksteg först pÃ¥ varje rad" +#, c-format +msgid "invalid author or committer for %s" +msgstr "ogiltig författare eller incheckare för %s" + +msgid "could not write commit" +msgstr "kunde inte skriva incheckning" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "Förväntade fullt referensnamn, fick %s" +msgid "not a valid revision: %s" +msgstr "inte en giltig revision: %s" #, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "kunde inte fÃ¥ tag i arkivhandtag för undermodulen â€%sâ€" +msgid "not a commit: %s" +msgstr "inte en incheckning: â€%sâ€" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s är inte en giltig exporterad â€stashâ€-incheckning" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "hittade rotincheckningen %s med ogiltig data" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "hittade â€stashâ€-incheckningen %s utan förväntat prefix" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "kan inte tolka föräldrar för incheckningen: %s" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s ser inte ut som en â€stashâ€-incheckning" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "kan inte läsa incheckningsbuffert för %s" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "kan inte spara â€stash†för %s" + +msgid "unable to write base commit" +msgstr "kan inte skriva basincheckning" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "kan inte hitta â€stashâ€-posten %s" + +msgid "print the object ID instead of writing it to a ref" +msgstr "skriv ut objekt-ID istället för skriva det till en referens" + +msgid "save the data to the given ref" +msgstr "spara data till given referens" + +msgid "exactly one of --print and --to-ref is required" +msgstr "exakt en av --print och --to-ref krävs" + +msgid "skip and remove all lines starting with comment character" +msgstr "hoppa över och ta bort alla rader som inleds med kommentarstecken" + +msgid "prepend comment character and space to each line" +msgstr "lägg in kommentarstecken och blanksteg först pÃ¥ varje rad" #, c-format msgid "" @@ -12536,6 +12704,10 @@ msgstr "" "officiella uppström." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "kunde inte fÃ¥ tag i arkivhandtag för undermodulen â€%sâ€" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "Hittade ingen url för undermodulsökvägen â€%s†i .gitmodules" @@ -12881,6 +13053,10 @@ msgstr "" "huvudprojektet är inte pÃ¥ nÃ¥gon gren" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "Förväntade fullt referensnamn, fick %s" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "Kan inte hitta aktuell revision i undermodulsökvägen â€%sâ€" @@ -13080,6 +13256,10 @@ msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "arkiv-URL: â€%s†mÃ¥ste vara absolut eller börja med ./|../" #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "undermodulnamnet â€%s†används redan för sökvägen â€%sâ€" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "â€%s†är inte ett giltigt namn pÃ¥ undermodul" @@ -13507,8 +13687,8 @@ msgstr "git update-ref [<flaggor>] -d <refnamn> [<gammalt-oid>]" msgid "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" msgstr "git update-ref [<flaggor>] <refnamn> <gammalt-oid> [<nytt-oid>]" -msgid "git update-ref [<options>] --stdin [-z]" -msgstr "git update-ref [<flaggor>] --stdin [-z]" +msgid "git update-ref [<options>] --stdin [-z] [--batch-updates]" +msgstr "git update-ref [<flaggor>] --stdin [-z] [--batch-updates]" msgid "delete the reference" msgstr "ta bort referensen" @@ -13522,6 +13702,9 @@ msgstr "standard in har NUL-terminerade argument" msgid "read updates from stdin" msgstr "läs uppdateringar frÃ¥n standard in" +msgid "batch reference updates" +msgstr "bunta referensuppdateringar" + msgid "update the info files from scratch" msgstr "uppdatera informationsfilerna frÃ¥n grunden" @@ -13702,10 +13885,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "Förbereder arbetskatalog (checkar ut â€%sâ€)" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "onÃ¥bar: felaktig referens: %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Förbereder arbetskatalog (frÃ¥nkopplat HEAD %s)" @@ -14201,6 +14380,9 @@ msgstr "Jämför filer i arbetskatalogen och indexet" msgid "Compare a tree to the working tree or index" msgstr "Jämför en träd med arbetskatalogen eller indexet" +msgid "Compare the content and mode of provided blob pairs" +msgstr "Jämför innehÃ¥ll och läge för det angivna blob-paret" + msgid "Compares the content and mode of blobs found via two tree objects" msgstr "Visar innehÃ¥ll och läge för blob:ar som hittats via tvÃ¥ trädobjekt" @@ -15306,14 +15488,6 @@ msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "felaktigt numeriskt konfigurationsvärde â€%s†för â€%s†i %s: %s" #, c-format -msgid "invalid value for variable %s" -msgstr "ogiltigt värde för variabeln %s" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "ignorerar okänd core.fsync-komponent â€%sâ€" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "felaktigt booleskt konfigurationsvärde â€%s†för â€%sâ€" @@ -15326,44 +15500,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "â€%s†för â€%s†är inte en giltig tidsstämpel" #, c-format -msgid "abbrev length out of range: %d" -msgstr "förkortningslängd utanför intervallet: %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "felaktigt zlib-komprimeringsgrad %d" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s kan inte innehÃ¥lla nyradstecken" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s mÃ¥ste innehÃ¥lla minst ett tecken" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "ignorerar okänt core.fsyncMethod-värde â€%sâ€" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles avrÃ¥ds frÃ¥n; använd core.fsync istället" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "felaktigt läge för skapande av objekt: %s" - -#, c-format -msgid "malformed value for %s" -msgstr "felformat värde för %s" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "felformat värde för %s: %s" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "mÃ¥ste vara en av nothing, matching, simple, upstream eller current" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "kan inte läsa konfigurerings-blobobjektet â€%sâ€" @@ -15871,8 +16007,9 @@ msgstr "kan inte jämföra standard in med en katalog" msgid "cannot compare a named pipe to a directory" msgstr "kan inte jämföra ett namngivet rör med en katalog" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<flaggor>] <sökväg> <sökväg>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "" +"git diff --no-index [<flaggor>] <sökväg> <sökväg> [<sökvägsangivelse>...]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -15881,6 +16018,13 @@ msgstr "" "Inte ett git-arkiv. Använd --no-index för att jämföra tvÃ¥ sökvägar utanför " "en arbetskatalog." +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"Det är endast möjligt att begränsa jämförelsen med sökvägsangivelser om " +"bägge sökvägarna är kataloger." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr " Misslyckades tolka dirstat-avskärningsprocentandel â€%sâ€\n" @@ -16452,6 +16596,52 @@ msgid "bad git namespace path \"%s\"" msgstr "felaktig git-namnrymdssökväg â€%sâ€" #, c-format +msgid "invalid value for variable %s" +msgstr "ogiltigt värde för variabeln %s" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "ignorerar okänd core.fsync-komponent â€%sâ€" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "förkortningslängd utanför intervallet: %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "felaktigt zlib-komprimeringsgrad %d" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s kan inte innehÃ¥lla nyradstecken" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s mÃ¥ste innehÃ¥lla minst ett tecken" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "ignorerar okänt core.fsyncMethod-värde â€%sâ€" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles avrÃ¥ds frÃ¥n; använd core.fsync istället" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "felaktigt läge för skapande av objekt: %s" + +#, c-format +msgid "malformed value for %s" +msgstr "felformat värde för %s" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "felformat värde för %s: %s" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "mÃ¥ste vara en av nothing, matching, simple, upstream eller current" + +#, c-format msgid "too many args to run %s" msgstr "för mÃ¥nga flaggor för att köra %s" @@ -17077,6 +17267,10 @@ msgid "Unknown value for http.proactiveauth" msgstr "Okänt värde för http.proactiveauth" #, c-format +msgid "failed to parse %s" +msgstr "misslyckades tolka %s" + +#, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "SSL-bakändan â€%s†stöds inte. Dessa SSL-bakändor stöds:" @@ -17157,6 +17351,29 @@ msgstr "tomt ident-namn (för <%s>) ej tillÃ¥tet" msgid "name consists only of disallowed characters: %s" msgstr "namnet bestÃ¥r enbart av ej tillÃ¥tna tecken: %s" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <mapp>] < <mbox>" + +msgid "no IMAP host specified" +msgstr "ingen IMAP-värd angavs" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"ställ in IMAP-värden med â€git config imap.host <värd>â€.\n" +"(t.ex., â€git config imap.host imaps://imap.example.comâ€)" + +msgid "no IMAP folder specified" +msgstr "ingen IMAP-mapp angavs" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"ställ in IMAP-mappen med â€git config imap.folder <mapp>â€.\n" +"(t.ex., â€git config imap.folder Utkastâ€)" + msgid "expected 'tree:<depth>'" msgstr "förväntade â€tree:<djup>â€" @@ -17263,6 +17480,10 @@ msgid "invalid marker-size '%s', expecting an integer" msgstr "felaktigt värde för marker-size â€%sâ€, förväntade ett heltal" #, c-format +msgid "Could not parse object '%s'" +msgstr "Kunde inte tolka objektet â€%sâ€" + +#, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Misslyckades slÃ¥ ihop undermodulen %s (ej utcheckad)" @@ -17504,264 +17725,6 @@ msgstr "" msgid "collecting merge info failed for trees %s, %s, %s" msgstr "samling av sammanslagningsinfo misslyckades för träden %s, %s, %s" -msgid "(bad commit)\n" -msgstr "(felaktig incheckning)\n" - -#, c-format -msgid "add_cacheinfo failed for path '%s'; merge aborting." -msgstr "" -"add_cacheinfo misslyckades för sökvägen â€%sâ€; avslutar sammanslagningen." - -#, c-format -msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." -msgstr "" -"add_cacheinfo misslyckades uppdatera för sökvägen â€%sâ€; avslutar " -"sammanslagningen." - -#, c-format -msgid "failed to create path '%s'%s" -msgstr "misslyckades skapa sökvägen â€%sâ€%s" - -#, c-format -msgid "Removing %s to make room for subdirectory\n" -msgstr "Tar bort %s för att göra plats för underkatalog\n" - -msgid ": perhaps a D/F conflict?" -msgstr ": kanske en K/F-konflikt?" - -#, c-format -msgid "refusing to lose untracked file at '%s'" -msgstr "vägrar förlora ospÃ¥rad fil vid â€%sâ€" - -#, c-format -msgid "blob expected for %s '%s'" -msgstr "blob förväntades för %s â€%sâ€" - -#, c-format -msgid "failed to open '%s': %s" -msgstr "misslyckades öppna â€%sâ€: %s" - -#, c-format -msgid "failed to symlink '%s': %s" -msgstr "misslyckades skapa symboliska länken â€%sâ€: %s" - -#, c-format -msgid "do not know what to do with %06o %s '%s'" -msgstr "vet inte hur %06o %s â€%s†ska hanteras" - -#, c-format -msgid "Failed to merge submodule %s (repository corrupt)" -msgstr "Misslyckades slÃ¥ ihop undermodulen %s (arkivet är trasigt)" - -#, c-format -msgid "Fast-forwarding submodule %s to the following commit:" -msgstr "Snabbspolar undermodulen %s till följande incheckning:" - -#, c-format -msgid "Fast-forwarding submodule %s" -msgstr "Snabbspolar undermodulen %s" - -#, c-format -msgid "Failed to merge submodule %s (merge following commits not found)" -msgstr "" -"Misslyckades slÃ¥ ihop undermodulen %s (sammanslagning efter incheckningar " -"hittades inte)" - -#, c-format -msgid "Failed to merge submodule %s (not fast-forward)" -msgstr "Misslyckades slÃ¥ ihop undermodulen %s (ej snabbspolning)" - -msgid "Found a possible merge resolution for the submodule:\n" -msgstr "Hittade en möjlig lösning av sammanslagning för undermodulen:\n" - -#, 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 "" -"Om detta är riktigt lägger du bara till det i indexet, till\n" -"exempel sÃ¥ här:\n" -"\n" -" git update-index --cacheinfo 160000 %s \"%s\"\n" -"\n" -"vilket godtar lösningen.\n" - -#, c-format -msgid "Failed to merge submodule %s (multiple merges found)" -msgstr "" -"Misslyckades slÃ¥ ihop undermodulen %s (flera sammanslagningar hittades)" - -msgid "failed to execute internal merge" -msgstr "misslyckades exekvera intern sammanslagning" - -#, c-format -msgid "unable to add %s to database" -msgstr "kan inte lägga till %s till databasen" - -#, c-format -msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." -msgstr "Fel: Vägrar förlora ospÃ¥rad fil vid %s; skriver till %s istället." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree." -msgstr "" -"KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad " -"i trädet." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree." -msgstr "" -"KONFLIKT (%s/radera): %s raderad i %s och %s till %s i %s. Versionen %s av " -"%s lämnad i trädet." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree at %s." -msgstr "" -"KONFLIKT (%s/radera): %s raderad i %s och %s i %s. Versionen %s av %s lämnad " -"i trädet vid %s." - -#, 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 "" -"KONFLIKT (%s/radera): %s raderad i %s och %s till %s i %s. Versionen %s av " -"%s lämnad i trädet vid %s." - -msgid "rename" -msgstr "namnbyte" - -msgid "renamed" -msgstr "namnbytt" - -#, c-format -msgid "Refusing to lose dirty file at %s" -msgstr "Vägrar förlora lortig fil vid â€%sâ€" - -#, c-format -msgid "Refusing to lose untracked file at %s, even though it's in the way." -msgstr "Vägrar förlora ospÃ¥rad fil vid %s, trots att den är i vägen." - -#, c-format -msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -msgstr "KONFLIKT (namnbyte/tillägg): Namnbyte %s→%s i %s. Lade till %s i %s" - -#, c-format -msgid "%s is a directory in %s adding as %s instead" -msgstr "%s är en katalog i %s lägger till som %s istället" - -#, c-format -msgid "Refusing to lose untracked file at %s; adding as %s instead" -msgstr "Vägrar förlora ospÃ¥rad fil vid %s; lägger till som %s istället" - -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " -"\"%s\"->\"%s\" in \"%s\"%s" -msgstr "" -"KONFLIKT (namnbyte/namnbyte): Namnbyte â€%sâ€â†’â€%s†pÃ¥ grenen â€%s†namnbyte " -"â€%sâ€â†’â€%s†i â€%sâ€%s" - -msgid " (left unresolved)" -msgstr " (lämnad olöst)" - -#, c-format -msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -msgstr "KONFLIKT (namnbyte/namnbyte): Namnbyte %s→%s i %s. Namnbyte %s→%s i %s" - -#, 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 "" -"KONFLIKT (namnändrad delad katalog): Osäker pÃ¥ var %s ska placeras dÃ¥ " -"katalogen %s bytte namn till flera andra kataloger, utan att nÃ¥gon " -"destination fick en majoritet av filerna." - -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" -">%s in %s" -msgstr "" -"KONFLIKT (namnbyte/namnbyte): Namnbytt katalog %s→%s i %s. Namnbytt katalog " -"%s→%s i %s" - -#, c-format -msgid "cannot read object %s" -msgstr "kan inte läsa objektet %s" - -#, c-format -msgid "object %s is not a blob" -msgstr "objektet %s är inte en blob" - -msgid "modify" -msgstr "ändra" - -msgid "modified" -msgstr "ändrad" - -#, c-format -msgid "Skipped %s (merged same as existing)" -msgstr "Hoppade över %s (sammanslagen samma som befintlig)" - -#, c-format -msgid "Adding as %s instead" -msgstr "Lägger till som %s istället" - -#, c-format -msgid "Removing %s" -msgstr "Tar bort %s" - -msgid "file/directory" -msgstr "fil/katalog" - -msgid "directory/file" -msgstr "katalog/fil" - -#, c-format -msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" -msgstr "" -"KONFLIKT (%s): Det finns en katalog med namnet %s i %s. Lägger till %s som %s" - -#, c-format -msgid "Adding %s" -msgstr "Lägger till %s" - -#, c-format -msgid "CONFLICT (add/add): Merge conflict in %s" -msgstr "KONFLIKT (tillägg/tillägg): Sammanslagningskonflikt i %s" - -#, c-format -msgid "merging of trees %s and %s failed" -msgstr "sammanslagning av träden %s och %s misslyckades" - -msgid "Merging:" -msgstr "SlÃ¥r ihop:" - -#, c-format -msgid "found %u common ancestor:" -msgid_plural "found %u common ancestors:" -msgstr[0] "hittade %u gemensam förfader:" -msgstr[1] "hittade %u gemensamma förfäder:" - -msgid "merge returned no commit" -msgstr "sammanslagningen returnerade ingen incheckning" - -#, c-format -msgid "Could not parse object '%s'" -msgstr "Kunde inte tolka objektet â€%sâ€" - msgid "failed to read the cache" msgstr "misslyckades läsa cachen" @@ -17803,12 +17766,13 @@ msgstr "kan inte länka â€%s†till â€%sâ€" msgid "failed to clear multi-pack-index at %s" msgstr "misslyckades städa multi-pack-index pÃ¥ %s" -msgid "cannot write incremental MIDX with bitmap" -msgstr "kan inte skriva inkrementell MIDX med bitkarta" - msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "ignorerar befintlig multi-pack-index; felaktig kontrollsumma" +#, c-format +msgid "could not load reverse index for MIDX %s" +msgstr "kunde inte läsa in baklängesindexet för MIDX %s" + msgid "Adding packfiles to multi-pack-index" msgstr "Lägger till paketfiler till multi-pack-index" @@ -18063,63 +18027,6 @@ msgid "Failed to convert object from %s to %s" msgstr "Misslyckades konvertera objekt frÃ¥n %s till %s" #, c-format -msgid "object directory %s does not exist; check .git/objects/info/alternates" -msgstr "objektkatalogen %s finns inte; se .git/objects/info/alternates" - -#, c-format -msgid "unable to normalize alternate object path: %s" -msgstr "kan inte normalisera supplerande objektsökväg: %s" - -#, c-format -msgid "%s: ignoring alternate object stores, nesting too deep" -msgstr "%s: ignorerar supplerande objektlager, för djup nästling" - -msgid "unable to fdopen alternates lockfile" -msgstr "kan inte utföra â€fdopen†pÃ¥ suppleantlÃ¥sfil" - -msgid "unable to read alternates file" -msgstr "kan inte läsa â€alternatesâ€-filen" - -msgid "unable to move new alternates file into place" -msgstr "kan inte flytta ny â€alternatesâ€-fil pÃ¥ plats" - -#, c-format -msgid "path '%s' does not exist" -msgstr "sökvägen â€%s†finns inte" - -#, c-format -msgid "reference repository '%s' as a linked checkout is not supported yet." -msgstr "referensarkivet â€%s†som en länkad utcheckning stöds inte ännu." - -#, c-format -msgid "reference repository '%s' is not a local repository." -msgstr "referensarkivet â€%s†är inte ett lokalt arkiv." - -#, c-format -msgid "reference repository '%s' is shallow" -msgstr "referensarkivet â€%s†är grunt" - -#, c-format -msgid "reference repository '%s' is grafted" -msgstr "referensarkivet â€%s†är ympat" - -#, c-format -msgid "could not find object directory matching %s" -msgstr "kunde inte hitta objektkatalog för %s" - -#, c-format -msgid "invalid line while parsing alternate refs: %s" -msgstr "felaktig rad vid tolkning av supplerande referenser: %s" - -#, c-format -msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" -msgstr "försök att utföra â€mmap†pÃ¥ %<PRIuMAX> över gränsen %<PRIuMAX>" - -#, c-format -msgid "mmap failed%s" -msgstr "mmap misslyckades%s" - -#, c-format msgid "object file %s is empty" msgstr "objektfilen %s är tom" @@ -18155,18 +18062,6 @@ msgid "loose object %s (stored in %s) is corrupt" msgstr "löst objekt %s (lagrat i %s) är trasigt" #, c-format -msgid "replacement %s not found for %s" -msgstr "ersättningen %s hittades inte för %s" - -#, c-format -msgid "packed object %s (stored in %s) is corrupt" -msgstr "packat objekt %s (lagrat i %s) är trasigt" - -#, c-format -msgid "missing mapping of %s to %s" -msgstr "saknar koppling av %s till %s" - -#, c-format msgid "unable to open %s" msgstr "kan inte öppna %s" @@ -18260,10 +18155,6 @@ msgid "%s: unsupported file type" msgstr "%s: filtypen stöds ej" #, c-format -msgid "%s is not a valid '%s' object" -msgstr "%s är inte ett giltigt â€%sâ€-objekt" - -#, c-format msgid "hash mismatch for %s (expected %s)" msgstr "hash stämmer inte för %s (förväntade %s)" @@ -18280,6 +18171,10 @@ msgid "unable to parse header of %s" msgstr "kan inte tolka huvud för %s" #, c-format +msgid "unable to parse type from header '%s' of %s" +msgstr "kan inte tolka typen frÃ¥n huvudet â€%s†för %s" + +#, c-format msgid "unable to unpack contents of %s" msgstr "kan inte tolka innehÃ¥ll i %s" @@ -18456,6 +18351,71 @@ msgid "hash mismatch %s" msgstr "hashvärde stämmer inte överens %s" #, c-format +msgid "object directory %s does not exist; check .git/objects/info/alternates" +msgstr "objektkatalogen %s finns inte; se .git/objects/info/alternates" + +#, c-format +msgid "unable to normalize alternate object path: %s" +msgstr "kan inte normalisera supplerande objektsökväg: %s" + +#, c-format +msgid "%s: ignoring alternate object stores, nesting too deep" +msgstr "%s: ignorerar supplerande objektlager, för djup nästling" + +msgid "unable to fdopen alternates lockfile" +msgstr "kan inte utföra â€fdopen†pÃ¥ suppleantlÃ¥sfil" + +msgid "unable to read alternates file" +msgstr "kan inte läsa â€alternatesâ€-filen" + +msgid "unable to move new alternates file into place" +msgstr "kan inte flytta ny â€alternatesâ€-fil pÃ¥ plats" + +#, c-format +msgid "path '%s' does not exist" +msgstr "sökvägen â€%s†finns inte" + +#, c-format +msgid "reference repository '%s' as a linked checkout is not supported yet." +msgstr "referensarkivet â€%s†som en länkad utcheckning stöds inte ännu." + +#, c-format +msgid "reference repository '%s' is not a local repository." +msgstr "referensarkivet â€%s†är inte ett lokalt arkiv." + +#, c-format +msgid "reference repository '%s' is shallow" +msgstr "referensarkivet â€%s†är grunt" + +#, c-format +msgid "reference repository '%s' is grafted" +msgstr "referensarkivet â€%s†är ympat" + +#, c-format +msgid "could not find object directory matching %s" +msgstr "kunde inte hitta objektkatalog för %s" + +#, c-format +msgid "invalid line while parsing alternate refs: %s" +msgstr "felaktig rad vid tolkning av supplerande referenser: %s" + +#, c-format +msgid "replacement %s not found for %s" +msgstr "ersättningen %s hittades inte för %s" + +#, c-format +msgid "packed object %s (stored in %s) is corrupt" +msgstr "packat objekt %s (lagrat i %s) är trasigt" + +#, c-format +msgid "missing mapping of %s to %s" +msgstr "saknar koppling av %s till %s" + +#, c-format +msgid "%s is not a valid '%s' object" +msgstr "%s är inte ett giltigt â€%sâ€-objekt" + +#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "duplicerad post när bitkarteindex skulle skrivas: %s" @@ -18466,9 +18426,6 @@ msgstr "försökta lagra icke-vald incheckning: â€%sâ€" msgid "too many pseudo-merges" msgstr "för mÃ¥nga pseudo-sammanslagningar" -msgid "trying to write commit not in index" -msgstr "försöker skriva incheckning som inte finns i indexet" - msgid "failed to load bitmap index (corrupted?)" msgstr "misslyckade läsa in bitkarteindex (trasigt?)" @@ -18713,6 +18670,18 @@ msgid "%s isn't available" msgstr "%s är inte tillgängligt" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "värdet för %s överstiger %<PRIdMAX>" + +#, c-format +msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" +msgstr "värdet %s för %s inte i intervallet [%<PRIdMAX>,%<PRIdMAX>]" + +#, c-format +msgid "%s expects an integer value with an optional k/m/g suffix" +msgstr "%s förväntar ett heltalsvärde, med valfritt k/m/g-suffix" + +#, c-format msgid "%s expects a non-negative integer value with an optional k/m/g suffix" msgstr "%s förväntar ett icke-negativt heltalsvärde, med valfritt k/m/g-suffix" @@ -18870,10 +18839,6 @@ msgid "bad boolean environment value '%s' for '%s'" msgstr "felaktigt booleskt miljövariabelvärde â€%s†för â€%sâ€" #, c-format -msgid "failed to parse %s" -msgstr "misslyckades tolka %s" - -#, c-format msgid "failed to walk children of tree %s: not found" msgstr "misslyckades traversera löven i trädet %s: hittades inte" @@ -19034,8 +18999,12 @@ msgid "could not fetch %s from promisor remote" msgstr "kunde inte hämta %s frÃ¥n kontraktsfjärr" #, c-format -msgid "known remote named '%s' but with url '%s' instead of '%s'" -msgstr "känd fjärr som heter â€%s†med med url:en â€%s†istället för â€%sâ€" +msgid "no or empty URL advertised for remote '%s'" +msgstr "ingen eller tom URL tillkännagavs för fjärren â€%sâ€" + +#, c-format +msgid "known remote named '%s' but with URL '%s' instead of '%s'" +msgstr "känd fjärr som heter â€%s†men med URL:en â€%s†istället för â€%sâ€" #, c-format msgid "unknown '%s' value for '%s' config option" @@ -19678,6 +19647,14 @@ msgid "%s does not point to a valid object!" msgstr "â€%s†pekar inte pÃ¥ ett giltigt objekt!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s kommer bli dinglande efter att %s tagits bort\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s har blivit dinglande efter att %s togs bort\n" + +#, 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" @@ -19805,6 +19782,10 @@ msgid "Checking references consistency" msgstr "Kontrollerar konsistens för referenser" #, c-format +msgid "unable to open '%s'" +msgstr "kan inte öppna â€%sâ€" + +#, c-format msgid "refname is dangerous: %s" msgstr "refnamnet är farligt: %s" @@ -19871,10 +19852,6 @@ msgid "refname %s is a symbolic ref, copying it is not supported" msgstr "referensnamnet %s är en symbolisk referens, kopiering stöds inte" #, c-format -msgid "invalid refspec '%s'" -msgstr "felaktig referensspecifikation: â€%sâ€" - -#, c-format msgid "pattern '%s' has no '*'" msgstr "mönstret â€%s†innehÃ¥ller ingen â€*â€" @@ -20413,8 +20390,8 @@ msgstr "kunde inte lägga till enrollering" msgid "could not set recommended config" msgstr "kan inte ange rekommenderad konfiguration" -msgid "could not turn on maintenance" -msgstr "kunde inte aktivera underhÃ¥ll" +msgid "could not toggle maintenance" +msgstr "kunde inte växla underhÃ¥ll" msgid "could not start the FSMonitor daemon" msgstr "kunde inte starta FSMonitor-server" @@ -20460,12 +20437,15 @@ msgstr "skapa arkiv inuti katalogen â€srcâ€" msgid "specify if tags should be fetched during clone" msgstr "ange om taggar ska hämtas vid kloning" +msgid "specify if background maintenance should be enabled" +msgstr "ange om bakgrundsunderhÃ¥ll ska aktiveras" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <huvudgren>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enrollering>]" +"\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enrollering>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20503,19 +20483,33 @@ msgstr "scalar diagnose [<enrollering>]" msgid "`scalar list` does not take arguments" msgstr "â€scalar list†tar inte argument" -msgid "scalar register [<enlistment>]" -msgstr "scalar register [<enrollering>]" +msgid "scalar register [--[no-]maintenance] [<enlistment>]" +msgstr "scalar register [--[no-]maintenance] [<enrollering>]" msgid "reconfigure all registered enlistments" msgstr "konfigurera alla registrerade enrolleringar pÃ¥ nytt" -msgid "scalar reconfigure [--all | <enlistment>]" -msgstr "scalar reconfigure [--all | <enrollering>]" +msgid "(enable|disable|keep)" +msgstr "(aktivera|inaktivera|behÃ¥ll)" + +msgid "signal how to adjust background maintenance" +msgstr "signallera hur bakgrundsunderhÃ¥ll ska justeras" + +msgid "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<enlistment>]" +msgstr "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<enrollering>]" msgid "--all or <enlistment>, but not both" msgstr "--all eller <enrollering>, men inte bägge" #, c-format +msgid "unknown mode for --maintenance option: %s" +msgstr "okänt läge för flaggan --maintenance: %s" + +#, c-format msgid "could not remove stale scalar.repo '%s'" msgstr "kunde inte ta bort gammal scalar.repo â€%sâ€" @@ -21946,6 +21940,9 @@ msgstr "töm cacheträdet före varje iteration" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "antal poster i cacheträdet att ogiltigförklara (förval är 0)" +msgid "the number of objects to write" +msgstr "antal objekt att skriva" + msgid "test-tool path-walk <options> -- <revision-options>" msgstr "test-tool path-walk <flaggor> -- <revision-flaggor>" @@ -21964,6 +21961,9 @@ msgstr "växla om trädobjekt ska vara med eller inte" msgid "toggle pruning of uninteresting paths" msgstr "växla bortrensning av ointressanta sökvägar" +msgid "toggle aggressive edge walk" +msgstr "växla aggressiv kantvandring" + msgid "read a pattern list over stdin" msgstr "läs en mönsterlista frÃ¥n standard in" @@ -22601,6 +22601,23 @@ msgid "warning: " msgstr "varning: " #, c-format +msgid "" +"'%s' 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 "" +"â€%s†har nominerats för borttagning.\n" +"Om du fortfarande använder kommandot, lägg till flaggan\n" +"â€--i-still-use-this†pÃ¥ kommandoraden och berätta för\n" +"oss att du fortfarande använder det pÃ¥ e-post till\n" +"<git@vger.kernel.org>. Tack.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "vägrar köra utan --i-still-use-this" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "uname() misslyckades med felet â€%s†(%d)\n" @@ -22719,6 +22736,14 @@ msgstr "kan inte hämta aktuell arbetskatalog" msgid "unable to get random bytes" msgstr "kan inte hämta slumpdata" +#, c-format +msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" +msgstr "försök att utföra â€mmap†pÃ¥ %<PRIuMAX> över gränsen %<PRIuMAX>" + +#, c-format +msgid "mmap failed%s" +msgstr "mmap misslyckades%s" + msgid "Unmerged paths:" msgstr "Ej sammanslagna sökvägar:" @@ -23450,6 +23475,13 @@ msgstr "" "smtp-debug." #, perl-format +msgid "Outlook reassigned Message-ID to: %s\n" +msgstr "Outlook gav nytt Message-ID till: %s\n" + +msgid "Warning: Could not retrieve Message-ID from server response.\n" +msgstr "Varning: Kunde inte hämta Message-ID frÃ¥n serversvaret.\n" + +#, perl-format msgid "Failed to send %s\n" msgstr "Misslyckades sända %s\n" @@ -23494,6 +23526,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(kropp) Lägger till cc: %s frÃ¥n raden â€%sâ€\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "fel: ogiltig SMTP-port â€%sâ€\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Kunde inte köra â€%sâ€" @@ -96,8 +96,8 @@ msgid "" msgstr "" "Project-Id-Version: Git Turkish Localization Project\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-05-29 11:02+0300\n" -"PO-Revision-Date: 2025-05-29 12:00+0300\n" +"POT-Creation-Date: 2025-08-14 16:38+0300\n" +"PO-Revision-Date: 2025-08-14 16:45+0300\n" "Last-Translator: Emir SARI <emir_sari@icloud.com>\n" "Language-Team: Turkish (https://github.com/bitigchi/git-po/)\n" "Language: tr\n" @@ -107,6 +107,10 @@ msgstr "" "Plural-Forms: nplurals=2; plural=(n != 1);\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s negatif olamaz" + +#, c-format msgid "Huh (%s)?" msgstr "Pardon (%s)?" @@ -2011,6 +2015,10 @@ msgid "adding files failed" msgstr "dosya ekleme baÅŸarısız" #, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' negatif olamaz" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "--chmod param '%s' ya -x ya da +x olmalıdır" @@ -5163,23 +5171,25 @@ msgstr "" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" -"git config get [<dosya-sçnÄŸi>] [<görüntü-sçnÄŸi>] [--includes] [--all] [--" -"regexp] [--value=<deÄŸer>] [--fixed-value] [--default=<öntanımlı>] <ad>" +"git config get [<dosya-seçeneÄŸi>] [<display-option>] [--includes] [--all] [--" +"regexp] [--value=<dizgi>] [--fixed-value] [--default=<öntanımlı>] [--" +"url=<url>] <ad>" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<dosya-seçeneÄŸi>] [--type=<tür>] [--all] [--value=<deÄŸer>] " +"git config set [<dosya-seçeneÄŸi>] [--type=<tür>] [--all] [--value=<dizgi>] " "[--fixed-value] <ad> <deÄŸer>" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<dosya-seçeneÄŸi>] [--all] [--value=<deÄŸer>] [--fixed-" +"git config unset [<dosya-seçeneÄŸi>] [--all] [--value=<dizgi>] [--fixed-" "value] <ad>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -5196,19 +5206,19 @@ msgstr "git config [<dosya-seçeneÄŸi>] --get-colorbool <ad> [<stdout-tty>]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" -"git config get [<dosya-seçeneÄŸi>] [<görüntüleme-seçeneÄŸi>] [--includes] [--" -"all] [--regexp=<düzenli-ifade>] [--value=<deÄŸer>] [--fixed-value] [--" +"git config get [<dosya-seçeneÄŸi>] [<görüntü-seçeneÄŸi>] [--includes] [--all] " +"[--regexp=<düzenli-ifade>] [--value=<dizgi>] [--fixed-value] [--" "default=<öntanımlı>] <ad>" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<dosya-seçeneÄŸi>] [--type=<tür>] [--comment=<ileti>] [--all] " -"[--value=<deÄŸer>] [--fixed-value] <ad> <deÄŸer>" +"[--value=<dizgi>] [--fixed-value] <ad> <deÄŸer>" msgid "Config file location" msgstr "Yapılandırma dosyası konumu" @@ -6055,22 +6065,6 @@ msgstr "%s tüm gerekli nesneleri göndermedi" msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "%s reddedildi; çünkü sığ köklerin güncellenmesine izin verilmiyor" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"bazı yerel baÅŸvurular güncellenemedi; 'git remote prune %s'\n" -"kullanarak eski ve çakışan dalları kaldırmayı deneyin" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s sarkacak)" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s sarkmaya baÅŸladı)" - msgid "[deleted]" msgstr "[silindi]" @@ -6112,6 +6106,18 @@ msgstr "" "komutunu çalıştırmak, uyarıyı HEAD'e veya baÅŸka bir ÅŸeye uzaktan\n" "deÄŸiÅŸiklik olana dek devre dışı bırakır." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"bazı yerel baÅŸvurular güncellenemedi; 'git remote prune %s'\n" +"kullanarak eski ve çakışan dalları kaldırmayı deneyin" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "%s baÅŸvurusu getirilemedi: %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "birden çok dal algılandı, --set-upstream ile uyumsuz" @@ -6355,6 +6361,9 @@ msgstr "git for-each-ref [--merged [<iÅŸleme>]] [--no-merged [<iÅŸleme>]]" msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<iÅŸleme>]] [--no-contains [<iÅŸleme>]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <imleyici>]" + msgid "quote placeholders suitably for shells" msgstr "yer tutucuları kabuÄŸun anlayabileceÄŸi biçimde tırnak içine al" @@ -6370,6 +6379,12 @@ msgstr "yer tutucuları Tcl'nin anlayabileceÄŸi biçimde tırnak içine al" msgid "show only <n> matched refs" msgstr "yalnızca <n> eÅŸleÅŸen baÅŸvuruyu göster" +msgid "marker" +msgstr "imleyici" + +msgid "start iteration after the provided marker" +msgstr "yinelemeyi belirtilen imleyiciden sonra baÅŸlat" + msgid "respect format colors" msgstr "biçim renklerine uy" @@ -6394,9 +6409,15 @@ msgstr "baÅŸvuru dizgilerini stdin'den oku" msgid "also include HEAD ref and pseudorefs" msgstr "ayrıca HEAD ve yalancı baÅŸvuruları içer" +msgid "cannot use --start-after with custom sort options" +msgstr "özel sıralama seçenekleriyle --start-after kullanılamıyor" + msgid "unknown arguments supplied with --stdin" msgstr "--stdin ile bilinmeyen argümanlar verilmiÅŸ" +msgid "cannot use --start-after with patterns" +msgstr "dizgilerle --start-after kullanılamıyor" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<yapılandırma> [--] <argümanlar>" @@ -6792,6 +6813,9 @@ msgstr "en büyük paket dışındaki diÄŸer tüm paketleri yeniden paketle" msgid "pack prefix to store a pack containing pruned objects" msgstr "budanan nesneler içeren paketi depolamak için paket öneki" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "genelde ön planda yapılan bakım görevlerini atla" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "gc.logExpiry deÄŸeri %s ayrıştırılamadı" @@ -6863,14 +6887,14 @@ msgstr "" "incremental-repack görevi atlanıyor; çünkü core.multiPackIndex devre dışı" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "kilit dosyası '%s' var, bakım atlanıyor" - -#, c-format msgid "task '%s' failed" msgstr "'%s' görevi baÅŸarısız oldu" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "kilit dosyası '%s' var, bakım atlanıyor" + +#, c-format msgid "'%s' is not a valid task" msgstr "'%s' geçerli bir görev deÄŸil" @@ -6899,9 +6923,6 @@ msgstr "görev" msgid "run a specific task" msgstr "belirli bir görevi çalıştır" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "tek kezde --auto ve --schedule=<sıklık>'tan birini kullan" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "ÅŸunun için '%s' deÄŸeri eklenemiyor: '%s'" @@ -7779,10 +7800,6 @@ msgid "-L<range>:<file> cannot be used with pathspec" msgstr "-L<erim>:<dosya>, yol belirteci ile kullanılamıyor" #, c-format -msgid "Final output: %d %s\n" -msgstr "Son çıktı: %d %s\n" - -#, c-format msgid "git show %s: bad file" msgstr "git show %s: hatalı dosya" @@ -8481,6 +8498,9 @@ msgstr "birleÅŸtirmenin sonunda bir diffstat göster" msgid "(synonym to --stat)" msgstr "(--stat eÅŸanlamlısı)" +msgid "show a compact-summary at the end of the merge" +msgstr "birleÅŸtirmenin sonunda ufak bir özet göster" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "kısa günlükten birleÅŸtirme iÅŸlemesi iletisine girdiler (en çok <n>) ekle" @@ -8744,10 +8764,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "hata: etiket girdisi fsck'den geçemiyor: %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) hiçbir zaman bu geri çağırmayı tetiklememeli" - -#, c-format msgid "could not read tagged object '%s'" msgstr "etiketlenmiÅŸ nesne '%s' okunamadı" @@ -9259,16 +9275,26 @@ msgstr "notları <not-bÅŸvr>'ndan kullan" msgid "unknown subcommand: `%s'" msgstr "bilinmeyen altkomut: '%s'" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [<sçnklr>] [< <baÅŸvuru-listesi> | < <nesne-" -"listesi>]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" msgstr "" -"git pack-objects [<sçnklr>] <temel-ad> [< <bÅŸvru-listesi> | < <nesne-" -"listesi>]" +"git pack-objects [-q | --progress | --all-progress]\n" +" [--all-progress-implied] [--no-reuse-delta]\n" +" [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<paket-adı>]\n" +" [--cruft] [--cruft-expiration=<zaman>]\n" +" [--stdout [--filter=<süzgeç-belirtimi>] | <taban-adı>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <nesne-listesi>" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9373,6 +9399,15 @@ msgstr "%s etiketinden ulaşılabilir nesneler paketlenemiyor" msgid "unable to get type of object %s" msgstr "%s nesnesinin türü alınamıyor" +msgid "Compressing objects by path" +msgstr "Nesneler yola göre sıkıştırılıyor" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Yol tabanlı delta sıkıştırması %d iÅŸ parçacığı kullanıyor" +msgstr[1] "Yol tabanlı delta sıkıştırması %d iÅŸ parçacığı kullanıyor" + msgid "Compressing objects" msgstr "Nesneler sıkıştırılıyor" @@ -9448,6 +9483,9 @@ msgstr "%s konumundaki gevÅŸek nesne incelenemedi" msgid "unable to force loose object" msgstr "gevÅŸek nesne zorlanamıyor" +msgid "failed to pack objects via path-walk" +msgstr "path-walk ile nesneler paketlenemedi" + #, c-format msgid "not a rev '%s'" msgstr "bir revizyon deÄŸil: '%s'" @@ -9557,6 +9595,9 @@ msgstr "aralıklı ulaşılabilirlik algoritmasını kullan" msgid "create thin packs" msgstr "ince paketler oluÅŸtur" +msgid "use the path-walk API to walk objects when possible" +msgstr "olursa nesneleri yürütmek için path-walk API'sini kullan" + msgid "create packs suitable for shallow fetches" msgstr "sığ getirmelere uygun paketler oluÅŸtur" @@ -9614,6 +9655,10 @@ msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit çok yüksek, %d zorlanıyor" #, c-format +msgid "cannot use %s with %s" +msgstr "%s, %s ile kullanılamıyor" + +#, c-format msgid "bad pack compression level %d" msgstr "hatalı paket sıkıştırma düzeyi %d" @@ -9626,18 +9671,12 @@ msgstr "olabilecek en küçük paket boyutu limiti 1 MiB'dır" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin bir indekslenebilir paket yapımında kullanılamaz" -msgid "cannot use --filter with --stdin-packs" -msgstr "--filter, --stdin-packs ile birlikte kullanılamıyor" - msgid "cannot use internal rev list with --stdin-packs" msgstr "iç revizyon listeleri, --stdin-packs ile birlikte kullanılamıyor" msgid "cannot use internal rev list with --cruft" msgstr "iç revizyon listeleri, --cruft ile birlikte kullanılamıyor" -msgid "cannot use --stdin-packs with --cruft" -msgstr "--stdin-packs, --cruft ile birlikte kullanılamıyor" - msgid "Enumerating objects" msgstr "Nesneler ortaya dökülüyor" @@ -9650,23 +9689,6 @@ msgstr "" "%<PRIu32>), yeniden kullanılan paket %<PRIu32> (%<PRIuMAX> konumundan)" 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 "" -"'git pack-redundant' komutu kaldırma için aday\n" -"gösterildi. Bu komutu hâlâ kullanıyorsanız lütfen\n" -"komut satırında '--i-still-use-this' ek seçeneÄŸini\n" -"kullanın ve bunu hâlâ kullandığınızı\n" -"<git@vger.kernel.org> adresine bir e-posta atarak\n" -"bize haber verin. SaÄŸ olun.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "--i-still-use-this olmadan çalıştırma reddediliyor" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -10958,6 +10980,14 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "bilinmeyen --mirror argümanı: %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "uzak konum adı '%s', var olan '%s' uzak konumunun bir alt kümesi" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "uzak konum adı '%s', var olan '%s' uzak konumunun bir üst kümesi" + msgid "fetch the remote branches" msgstr "uzak konum dallarını getir" @@ -11264,14 +11294,6 @@ msgid "Could not set up %s" msgstr "%s ayarlanamadı" #, c-format -msgid " %s will become dangling!" -msgstr " %s sarkacak!" - -#, c-format -msgid " %s has become dangling!" -msgstr " %s sarkmaya baÅŸladı!" - -#, c-format msgid "Pruning %s" msgstr "%s budanıyor" @@ -11335,11 +11357,11 @@ msgstr "ayrıntılı anlat; bir altkomuttan önce yerleÅŸtirilmelidir" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<paket-adı>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11421,6 +11443,9 @@ msgid "" msgstr "" "benzer nesneleri yola göre gruplamada kullanılacak name-hash sürümünü belirt" +msgid "pass --path-walk to git-pack-objects" +msgstr "--path-walk'ı 'git-pack-objects'e geçir" + msgid "do not run git-update-server-info" msgstr "'git-update-server-info' çalıştırma" @@ -12571,17 +12596,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [<ileti>]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <baÅŸvuru>) [<zula>...]" + +msgid "git stash import <commit>" +msgstr "git stash import [<iÅŸleme>]" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' zulaya benzer bir iÅŸleme deÄŸil" +msgid "No stash entries found." +msgstr "Zula girdisi bulunamadı." + #, c-format msgid "Too many revisions specified:%s" msgstr "Çok fazla revizyon belirtildi:%s" -msgid "No stash entries found." -msgstr "Zula girdisi bulunamadı." - #, c-format msgid "%s is not a valid reference" msgstr "%s geçerli bir baÅŸvuru deÄŸil" @@ -12733,19 +12764,74 @@ msgstr "zulada izlenmeyen dosyaları içer" msgid "include ignore files" msgstr "yok sayma dosyalarını içer" -msgid "skip and remove all lines starting with comment character" -msgstr "yorum karakteri ile baÅŸlayan tüm satırları atla ve kaldır" +#, c-format +msgid "cannot parse commit %s" +msgstr "%s iÅŸlemesi ayrıştırılamıyor" -msgid "prepend comment character and space to each line" -msgstr "her satırın başına yorum karakteri ve boÅŸluk koy" +#, c-format +msgid "invalid author or committer for %s" +msgstr "%s için geçersiz yazar veya iÅŸleyici" + +msgid "could not write commit" +msgstr "iÅŸleme yazılamadı" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "Tam bir baÅŸvuru adı bekleniyordu, %s alındı" +msgid "not a valid revision: %s" +msgstr "geçerli bir revizyon deÄŸil: %s" #, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "'%s' altmodülü için depo tutacağı alınamadı" +msgid "not a commit: %s" +msgstr "bir iÅŸleme deÄŸil: %s" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s, geçerli bir dışa aktarılmış zula iÅŸlemesi deÄŸil" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "geçersiz veriyle %s kök iÅŸlemesi bulundu" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "beklenen öneksiz %s zula iÅŸlemesi bulundu" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "iÅŸlemenin üst ögesi ayrıştırılamıyor: %s" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s, bir zula iÅŸlemesi gibi görünmüyor" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "%s için iÅŸleme arabelleÄŸi okunamıyor" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "%s için zula kaydedilemiyor" + +msgid "unable to write base commit" +msgstr "taban iÅŸleme yazılamıyor" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "zula girdisi %s bulunamıyor" + +msgid "print the object ID instead of writing it to a ref" +msgstr "baÅŸvuruya yazmak yerine nesne kimliÄŸini yazdır" + +msgid "save the data to the given ref" +msgstr "veriyi verilen baÅŸvuruya kaydet" + +msgid "exactly one of --print and --to-ref is required" +msgstr "tam olarak --print veya --to-ref arasından biri gerekiyor" + +msgid "skip and remove all lines starting with comment character" +msgstr "yorum karakteri ile baÅŸlayan tüm satırları atla ve kaldır" + +msgid "prepend comment character and space to each line" +msgstr "her satırın başına yorum karakteri ve boÅŸluk koy" #, c-format msgid "" @@ -12756,6 +12842,10 @@ msgstr "" "varsayılıyor." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "'%s' altmodülü için depo tutacağı alınamadı" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr ".gitmodules içinde '%s' altmodül yolu için url bulunamadı" @@ -13104,6 +13194,10 @@ msgstr "" "ancak üst proje, herhangi bir dalda deÄŸil" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "Tam bir baÅŸvuru adı bekleniyordu, %s alındı" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "'%s' altmodül yolunda geçerli revizyon bulunamadı" @@ -13302,6 +13396,10 @@ msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "depo URL'si: '%s' mutlak olmalı veya ./|../ ile baÅŸlamalıdır" #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "altmodül adı '%s', halihazırda '%s' yolu için kullanılıyor" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "'%s' geçerli bir altmodül adı deÄŸil" @@ -13924,10 +14022,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "Çalışma aÄŸacı hazırlanıyor ('%s' çıkış yapılıyor)" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "eriÅŸilemiyor: geçersiz baÅŸvuru: %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Çalışma aÄŸacı hazırlanıyor (ayrık HEAD %s)" @@ -15524,14 +15618,6 @@ msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "hatalı sayısal yapılandırma deÄŸeri '%s', '%s' için (%s içinde): %s" #, c-format -msgid "invalid value for variable %s" -msgstr "%s deÄŸiÅŸkeni için geçersiz deÄŸer" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "bilinmeyen core.fsync bileÅŸeni '%s' yok sayılıyor" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "hatalı Boole yapılandırma deÄŸeri '%s', '%s' için" @@ -15544,44 +15630,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "%s', '%s' için geçerli bir zaman damgası deÄŸil" #, c-format -msgid "abbrev length out of range: %d" -msgstr "kısaltma uzunluÄŸu erim dışında: %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "hatalı zlib sıkıştırma düzeyi %d" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s yenisatır içeremez" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s, en az bir karaktere iye olmalı" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "bilinmeyen core.fsyncMethod deÄŸeri '%s' yok sayılıyor" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles artık kullanılmıyor; yerine core.fsync kullanın" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "nesne oluÅŸturma için geçersiz kip: %s" - -#, c-format -msgid "malformed value for %s" -msgstr "%s için hatalı oluÅŸturulmuÅŸ deÄŸer" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "%s için hatalı oluÅŸturulmuÅŸ deÄŸer: %s" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "nothing, matching, simple, upstream veya current içinden biri olmalı" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "'%s' yapılandırma ikili nesnesi yüklenemiyor" @@ -16092,8 +16140,8 @@ msgstr "stdin, bir dizinle karşılaÅŸtırılamıyor" msgid "cannot compare a named pipe to a directory" msgstr "adlandırılmış bir veriyolu bir dizinle karşılaÅŸtırılamıyor" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<seçenekler>] <yol> <yol>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [<seçenekler>] <yol> <yol> [<yol-belirteci>...]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -16102,6 +16150,13 @@ msgstr "" "Bir git deposu deÄŸil. Bir çalışma aÄŸacının dışındaki iki yolu karşılaÅŸtırmak " "için --no-index kullanın" +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"KarşılaÅŸtırmayı yol belirteçleriyle sınırlamak yalnızca her iki yol da " +"dizinse desteklenir." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr " dirstat kesim yüzdesi '%s' ayrıştırılamadı\n" @@ -16678,6 +16733,52 @@ msgid "bad git namespace path \"%s\"" msgstr "hatalı git ad alanı yolu \"%s\"" #, c-format +msgid "invalid value for variable %s" +msgstr "%s deÄŸiÅŸkeni için geçersiz deÄŸer" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "bilinmeyen core.fsync bileÅŸeni '%s' yok sayılıyor" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "kısaltma uzunluÄŸu erim dışında: %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "hatalı zlib sıkıştırma düzeyi %d" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s yenisatır içeremez" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s, en az bir karaktere iye olmalı" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "bilinmeyen core.fsyncMethod deÄŸeri '%s' yok sayılıyor" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles artık kullanılmıyor; yerine core.fsync kullanın" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "nesne oluÅŸturma için geçersiz kip: %s" + +#, c-format +msgid "malformed value for %s" +msgstr "%s için hatalı oluÅŸturulmuÅŸ deÄŸer" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "%s için hatalı oluÅŸturulmuÅŸ deÄŸer: %s" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "nothing, matching, simple, upstream veya current içinden biri olmalı" + +#, c-format msgid "too many args to run %s" msgstr "%s çalıştırmak için pek fazla argüman" @@ -17387,6 +17488,30 @@ msgstr "boÅŸ tanımlayıcı adına (<%s> için) izin verilmiyor" msgid "name consists only of disallowed characters: %s" msgstr "ad yalnızca izin verilmeyen karakterlerden oluÅŸuyor: %s" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <klasör>] < <mbox>" + +msgid "no IMAP host specified" +msgstr "belirtilmiÅŸ IMAP makinesi yok" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"IMAP makinesini 'git config imap.host <makine>' ile ayarlayın.\n" +"ÖrneÄŸin, 'git config imap.host imaps://imap.example.com'." + +msgid "no IMAP folder specified" +msgstr "belirtilmiÅŸ IMAP klasörü yok" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"Hedef klasörü 'git config imap.folder <klasör>' ile ayarlayın.\n" +"ÖrneÄŸin, 'git config imap.folder Taslaklar'." + msgid "expected 'tree:<depth>'" msgstr "'tree:<derinlik>' bekleniyordu" @@ -18345,6 +18470,26 @@ msgid "invalid object name '%.*s'." msgstr "geçersiz nesne adı: '%.*s'." #, c-format +msgid "invalid object type \"%s\"" +msgstr "geçersiz nesne türü \"%s\"" + +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "%s nesnesi bir %s, %s deÄŸil" + +#, c-format +msgid "object %s has unknown type id %d" +msgstr "%s nesnesi %d bilinmeyen tür numarasına iye" + +#, c-format +msgid "unable to parse object: %s" +msgstr "nesne ayrıştırılamıyor: %s" + +#, c-format +msgid "hash mismatch %s" +msgstr "saÄŸlama uyuÅŸmazlığı %s" + +#, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "nesne dizini %s yok; ÅŸurayı denetleyin: .git/objects/info/alternates" @@ -18411,26 +18556,6 @@ msgid "%s is not a valid '%s' object" msgstr "%s geçerli bir '%s' nesnesi deÄŸil" #, c-format -msgid "invalid object type \"%s\"" -msgstr "geçersiz nesne türü \"%s\"" - -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "%s nesnesi bir %s, %s deÄŸil" - -#, c-format -msgid "object %s has unknown type id %d" -msgstr "%s nesnesi %d bilinmeyen tür numarasına iye" - -#, c-format -msgid "unable to parse object: %s" -msgstr "nesne ayrıştırılamıyor: %s" - -#, c-format -msgid "hash mismatch %s" -msgstr "saÄŸlama uyuÅŸmazlığı %s" - -#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "biteÅŸlem indeksi yazılırken yinelenen girdi: %s" @@ -18441,9 +18566,6 @@ msgstr "seçili olmayan iÅŸleme yazılmaya çalışıldı: '%s'" msgid "too many pseudo-merges" msgstr "pek çok yalancı birleÅŸtirme" -msgid "trying to write commit not in index" -msgstr "indekste olmayan iÅŸleme yazılmaya çalışılıyor" - msgid "failed to load bitmap index (corrupted?)" msgstr "biteÅŸlem indeksi yüklenemedi (hasarlı mı?)" @@ -18689,6 +18811,10 @@ msgid "%s isn't available" msgstr "%s kullanılabilir deÄŸil" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "%s için olan deÄŸer, %<PRIdMAX> deÄŸerini aşıyor" + +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "%s deÄŸeri, %s için, [%<PRIdMAX>, %<PRIdMAX>] eriminde deÄŸil" @@ -19654,6 +19780,14 @@ msgid "%s does not point to a valid object!" msgstr "%s geçerli bir nesneye iÅŸaret etmiyor!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s, %s silindikten sonra sarkacak\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s, %s silindikten sonra sarkmaya baÅŸladı\n" + +#, 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" @@ -21964,6 +22098,9 @@ msgstr "aÄŸaç nesnelerinin içerilmesini aç/kapat" msgid "toggle pruning of uninteresting paths" msgstr "ilgisiz yolların budanmasını aç/kapat" +msgid "toggle aggressive edge walk" +msgstr "agresif kenar yürüyüşünü aç/kapat" + msgid "read a pattern list over stdin" msgstr "stdin'den bir dizgi listesi oku" @@ -22595,6 +22732,24 @@ msgid "warning: " msgstr "uyarı: " #, c-format +msgid "" +"'%s' 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 "" +"'%s' komutu, kaldırma için aday\n" +"gösterildi. Bu komutu hâlâ kullanıyorsanız lütfen\n" +"komut satırında '--i-still-use-this' ek seçeneÄŸini\n" +"kullanın ve bunu hâlâ kullandığınızı\n" +"<git@vger.kernel.org> adresine bir e-posta atarak\n" +"bize haber verin. SaÄŸ olun.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "--i-still-use-this olmadan çalıştırma reddediliyor" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "uname() '%s' hatasını verip çıktı (%d)\n" @@ -23506,6 +23661,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(body) Cc: %s, '%s' satırından ekleniyor\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "hata: geçersiz SMTP kapısı '%s'\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) '%s' yürütülemedi" @@ -8,8 +8,8 @@ msgid "" msgstr "" "Project-Id-Version: Git v2.46\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-06-07 16:24-0700\n" -"PO-Revision-Date: 2025-06-03 18:43-0700\n" +"POT-Creation-Date: 2025-08-14 15:16-0700\n" +"PO-Revision-Date: 2025-08-14 17:33-0700\n" "Last-Translator: Kateryna Golovanova <kate@kgthreads.com>\n" "Language-Team: Ukrainian <https://github.com/arkid15r/git-uk-l10n/>\n" "Language: uk\n" @@ -21,6 +21,10 @@ msgstr "" "X-Generator: Poedit 3.6\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s не може бути відʼємним" + +#, c-format msgid "Huh (%s)?" msgstr "Га (%s)?" @@ -1957,6 +1961,10 @@ msgid "adding files failed" msgstr "Ð´Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñ–Ð² завершилоÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾" #, c-format +msgid "'%s' cannot be negative" +msgstr "\"%s\" не може бути відʼємним" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "--chmod параметр \"%s\" має бути -x або +x" @@ -5155,25 +5163,26 @@ msgstr "git config list [<опціÑ-файлу>] [<опціÑ-відображРmsgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<опціÑ-файлу>] [<опціÑ-відображеннÑ>] [--includes] [--all] " -"[--regexp] [--value=<значеннÑ>] [--fixed-value] [--default=<за " -"замовчуваннÑм>] <назва>" +"[--regexp] [--value=<шаблон>] [--fixed-value] [--default=<Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð·Ð° " +"замовчуваннÑм>] [--url=<URL-адреÑа>] <назва>" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<опціÑ-файлу>] [--type=<тип>] [--all] [--value=<значеннÑ>] " -"[--fixed-value] <назва> <значеннÑ>" +"git config set [<опціÑ-файлу>] [--type=<тип>] [--all] [--value=<шаблон>] [--" +"fixed-value] <назва> <значеннÑ>" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<опціÑ-файлу>] [--all] [--value=<значеннÑ>] [--fixed-" -"value] <назва>" +"git config unset [<опціÑ-файлу>] [--all] [--value=<шаблон>] [--fixed-value] " +"<назва>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" msgstr "git config rename-section [<опціÑ-файлу>] <Ñтара-назва> <нова-назва>" @@ -5189,19 +5198,19 @@ msgstr "git config [<опціÑ-файлу>] --get-colorbool <назва> [<stdo msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<опціÑ-файлу>] [<опціÑ-відображеннÑ>] [--includes] [--all] " -"[--regexp=<регвир>] [--value=<значеннÑ>] [--fixed-value] [--default=<за-" -"замовчуваннÑм>] <назва>" +"[--regexp=<регвир>] [--value=<шаблон>] [--fixed-value] [--default=<Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ " +"за замовчуваннÑм>] <назва>" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" -"git config set [<опціÑ-файлу>] [--type=<тип>] [--comment=<допиÑ>] [--all][--" -"value=<значеннÑ>] [--fixed-value] <назва> <значеннÑ>" +"git config set [<опціÑ-файлу>] [--type=<тип>] [--comment=<допиÑ>] [--all] [--" +"value=<шаблон>] [--fixed-value] <назва> <значеннÑ>" msgid "Config file location" msgstr "Ð Ð¾Ð·Ñ‚Ð°ÑˆÑƒÐ²Ð°Ð½Ð½Ñ Ñ„Ð°Ð¹Ð»Ñƒ конфігурації" @@ -6061,22 +6070,6 @@ msgstr "%s не надіÑлав уÑÑ– необхідні обʼєкти" msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "відхилено %s, оÑкільки неглибокі корені не можна оновлювати" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ деÑкі локальні поÑиланнÑ; Ñпробуйте виконати\n" -" \"git remote prune %s\", щоб видалити вÑÑ– Ñтарі конфліктні гілки" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s Ñтануть виÑÑчими)" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s Ñтав виÑÑчим)" - msgid "[deleted]" msgstr "[видалено]" @@ -6118,6 +6111,18 @@ msgstr "" "\"git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s\"\n" "вимкне попередженнÑ, доки віддалене Ð¿Ñ€Ð¸Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð½Ðµ змінить HEAD на щоÑÑŒ інше." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"не вдалоÑÑ Ð¾Ð½Ð¾Ð²Ð¸Ñ‚Ð¸ деÑкі локальні поÑиланнÑ; Ñпробуйте виконати\n" +" \"git remote prune %s\", щоб видалити вÑÑ– Ñтарі конфліктні гілки" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ поÑÐ¸Ð»Ð°Ð½Ð½Ñ %s: %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "виÑвлено кілька гілок, неÑуміÑних з --set-upstream" @@ -6365,6 +6370,9 @@ msgstr "git for-each-ref [--merged [<коміт>]] [--no-merged [<коміт>]]" msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<коміт>]] [--no-contains [<коміт>]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <маркер>]" + msgid "quote placeholders suitably for shells" msgstr "заповнювачі лапок Ð´Ð»Ñ shell" @@ -6380,6 +6388,12 @@ msgstr "заповнювачі лапок Ð´Ð»Ñ Tcl" msgid "show only <n> matched refs" msgstr "показати тільки <н> відповідних поÑилань" +msgid "marker" +msgstr "маркер" + +msgid "start iteration after the provided marker" +msgstr "почати ітерацію піÑÐ»Ñ Ð²ÐºÐ°Ð·Ð°Ð½Ð¾Ð³Ð¾ маркера" + msgid "respect format colors" msgstr "дотримуватиÑÑ ÐºÐ¾Ð»ÑŒÐ¾Ñ€Ñ–Ð² формату" @@ -6404,9 +6418,16 @@ msgstr "читати шаблони поÑилань з stdin" msgid "also include HEAD ref and pseudorefs" msgstr "також включити HEAD та пÑевдопоÑиланнÑ" +msgid "cannot use --start-after with custom sort options" +msgstr "" +"неможливо викориÑтовувати --start-after із влаÑними параметрами ÑортуваннÑ" + msgid "unknown arguments supplied with --stdin" msgstr "невідомі аргументи надані через --stdin" +msgid "cannot use --start-after with patterns" +msgstr "неможливо викориÑтовувати --start-after із шаблонами" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<конфіг> [--] <аргументи>" @@ -6803,6 +6824,11 @@ msgstr "перепакувати вÑÑ– пакунки, крім Ð½Ð°Ð¹Ð±Ñ–Ð»ÑŒÑ msgid "pack prefix to store a pack containing pruned objects" msgstr "Ð¿Ñ€ÐµÑ„Ñ–ÐºÑ Ð´Ð»Ñ Ð·Ð±ÐµÑ€Ñ–Ð³Ð°Ð½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° з обрізаними обʼєктами" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "" +"пропуÑтити Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ Ð¾Ð±ÑлуговуваннÑ, Ñкі зазвичай виконуютьÑÑ Ñƒ фоновому " +"режимі" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ gc.logExpiry Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s" @@ -6879,14 +6905,14 @@ msgstr "" "пропуÑк incremental-repack завданнÑ, оÑкільки core.multiPackIndex вимкнено" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "файл Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ \"%s\" Ñ–Ñнує, пропуÑк обÑлуговуваннÑ" - -#, c-format msgid "task '%s' failed" msgstr "Ð·Ð°Ð²Ð´Ð°Ð½Ð½Ñ \"%s\" завершилоÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "файл Ð±Ð»Ð¾ÐºÑƒÐ²Ð°Ð½Ð½Ñ \"%s\" Ñ–Ñнує, пропуÑк обÑлуговуваннÑ" + +#, c-format msgid "'%s' is not a valid task" msgstr "\"%s\" не Ñ” припуÑтимим завданнÑм" @@ -6915,9 +6941,6 @@ msgstr "завданнÑ" msgid "run a specific task" msgstr "запуÑтити певне завданнÑ" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "викориÑтовуйте щонайбільше одну з опцій --auto та --schedule=<чаÑтота>" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "не вдалоÑÑ Ð´Ð¾Ð´Ð°Ñ‚Ð¸ \"%s\" Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð¾ \"%s\"" @@ -7802,10 +7825,6 @@ msgid "-L<range>:<file> cannot be used with pathspec" msgstr "-L<діапазон>:<файл> не можна викориÑтовувати з визначником шлÑху" #, c-format -msgid "Final output: %d %s\n" -msgstr "Кінцевий результат: %d %s\n" - -#, c-format msgid "git show %s: bad file" msgstr "git show %s: невірний файл" @@ -8517,6 +8536,9 @@ msgstr "показувати diffstat наприкінці злиттÑ" msgid "(synonym to --stat)" msgstr "(Ñинонім до --stat)" +msgid "show a compact-summary at the end of the merge" +msgstr "показати ÑтиÑлий підÑумок наприкінці злиттÑ" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" "додати (не більше <н>) запиÑів з короткого журналу у Ð´Ð¾Ð¿Ð¸Ñ Ð´Ð¾ коміту злиттÑ" @@ -8784,10 +8806,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "помилка: вхідний тег не пройшов fsck: %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) ніколи не мав Ñпричинити цей зворотній виклик" - -#, c-format msgid "could not read tagged object '%s'" msgstr "не вдалоÑÑ Ð¿Ñ€Ð¾Ñ‡Ð¸Ñ‚Ð°Ñ‚Ð¸ тегований об’єкт \"%s\"" @@ -9304,16 +9322,27 @@ msgstr "викориÑтовувати нотатки з <поÑиланнÑ-нРmsgid "unknown subcommand: `%s'" msgstr "невідома підкоманда: \"%s\"" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [<опції>] [< <ÑпиÑок-поÑилань> | < <ÑпиÑок-" -"обʼєктів>]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects [<опції>] <базова-назва> [< <ÑпиÑок-поÑилань> | < <ÑпиÑок-" -"обʼєктів>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<н>] [--depth=<н>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<назва-" +"пакунка>]\n" +" [--cruft] [--cruft-expiration=<чаÑ>]\n" +" [--stdout [--filter=<визначник-фільтру>] | <базова-назва>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<н>] [--path-walk] < <ÑпиÑок-обʼєктів>" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9418,6 +9447,16 @@ msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð°ÐºÑƒÐ²Ð°Ñ‚Ð¸ обʼєкти, доÑÑ‚ÑƒÐ¿Ð½Ñ msgid "unable to get type of object %s" msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ тип обʼєкта %s" +msgid "Compressing objects by path" +msgstr "СтиÑÐ½ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð² за шлÑхом" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Дельта-ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð½Ð° оÑнові шлÑху з викориÑтаннÑм до %d потоку" +msgstr[1] "Дельта-ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð½Ð° оÑнові шлÑху з викориÑтаннÑм до %d потоків" +msgstr[2] "Дельта-ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð½Ð° оÑнові шлÑху з викориÑтаннÑм до %d потоків" + msgid "Compressing objects" msgstr "КомпреÑÑ–Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð²" @@ -9493,6 +9532,9 @@ msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ð³Ð»Ñнути вільний обʼєкт у msgid "unable to force loose object" msgstr "не вдалоÑÑ Ð¿Ñ€Ð¸Ð¼ÑƒÑово вивільнити обʼєкт" +msgid "failed to pack objects via path-walk" +msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð°ÐºÑƒÐ²Ð°Ñ‚Ð¸ обʼєкти за допомогою path-walk" + #, c-format msgid "not a rev '%s'" msgstr "не Ñ” ревізією \"%s\"" @@ -9603,6 +9645,10 @@ msgstr "викориÑтовувати алгоритм розрідженої Ð msgid "create thin packs" msgstr "Ñтворити тонкі пакунки" +msgid "use the path-walk API to walk objects when possible" +msgstr "" +"викориÑтовувати API path-walk Ð´Ð»Ñ Ð¿Ñ€Ð¾Ñ…Ð¾Ð´Ð¶ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð², коли це можливо" + msgid "create packs suitable for shallow fetches" msgstr "Ñтворювати пакунки, придатні Ð´Ð»Ñ Ð½ÐµÐ³Ð»Ð¸Ð±Ð¾ÐºÐ¾Ð³Ð¾ отриманнÑ" @@ -9660,6 +9706,10 @@ msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit занадто великий, примуÑове %d" #, c-format +msgid "cannot use %s with %s" +msgstr "неможливо викориÑтовувати %s з %s" + +#, c-format msgid "bad pack compression level %d" msgstr "невірний рівень ÑтиÑÐ½ÐµÐ½Ð½Ñ Ð¿Ð°ÐºÑƒÐ½ÐºÐ° %d" @@ -9673,18 +9723,12 @@ msgstr "мінімальний розмір пакунка - 1 МіБ" msgid "--thin cannot be used to build an indexable pack" msgstr "--thin не можна викориÑтовувати Ð´Ð»Ñ ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ñ–Ð½Ð´ÐµÐºÑованого пакунка" -msgid "cannot use --filter with --stdin-packs" -msgstr "неможливо викориÑтовувати --filter з --stdin-packs" - msgid "cannot use internal rev list with --stdin-packs" msgstr "неможливо викориÑтовувати внутрішній ÑпиÑок ревізій з --stdin-packs" msgid "cannot use internal rev list with --cruft" msgstr "неможливо викориÑтовувати внутрішній ÑпиÑок ревізій з --cruft" -msgid "cannot use --stdin-packs with --cruft" -msgstr "неможливо викориÑтовувати --stdin-packs з --cruft" - msgid "Enumerating objects" msgstr "ÐŸÐµÑ€ÐµÑ€Ð°Ñ…ÑƒÐ²Ð°Ð½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð²" @@ -9697,23 +9741,6 @@ msgstr "" "%<PRIu32>), повторно викориÑтано пакунків %<PRIu32> (з %<PRIuMAX>)" 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 "" -"Команду \"git pack-redundant\" номіновано на вилученнÑ.\n" -"Якщо ви вÑе ще викориÑтовуєте цю команду, будь лаÑка, додайте додатковий " -"параметр\n" -"\"--i-still-use-this\" у командному Ñ€Ñдку\n" -"Ñ– повідомте нам, що ви вÑе ще викориÑтовуєте Ñ—Ñ—, надіÑлавши лиÑта\n" -"на адреÑу <git@vger.kernel.org>. ДÑкуємо.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "відмовлено в запуÑку без --i-still-use-this" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -11032,6 +11059,14 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "невідомий --mirror аргумент: %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "віддалена назва \"%s\" Ñ” підмножиною Ñ–Ñнуючого віддаленого \"%s\"" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "віддалена назва \"%s\" Ñ” надмножиною Ñ–Ñнуючого віддаленого \"%s\"" + msgid "fetch the remote branches" msgstr "отримати віддалені гілки" @@ -11344,14 +11379,6 @@ msgid "Could not set up %s" msgstr "Ðе вдалоÑÑ Ð½Ð°Ð»Ð°ÑˆÑ‚ÑƒÐ²Ð°Ñ‚Ð¸ %s" #, c-format -msgid " %s will become dangling!" -msgstr " %s Ñтануть виÑÑчими!" - -#, c-format -msgid " %s has become dangling!" -msgstr " %s Ñтав виÑÑчим!" - -#, c-format msgid "Pruning %s" msgstr "Ð’Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %s" @@ -11415,11 +11442,11 @@ msgstr "розгорнутий вивід; має ÑтоÑти перед під msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<н>] [--depth=<н>] [--threads=<н>] [--keep-pack=<назва-пакунка>]\n" -"[--write-midx] [--name-hash-version=<н>]" +"[--write-midx] [--name-hash-version=<н>] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11486,7 +11513,8 @@ msgid "with --cruft, expire objects older than this" msgstr "з --cruft видалити обʼєкти, Ñтаріші за цей термін" msgid "with --cruft, only repack cruft packs smaller than this" -msgstr "з параметром --cruft, перепакувати лише марні пакунки, менші за цей розмір" +msgstr "" +"з параметром --cruft, перепакувати лише марні пакунки, менші за цей розмір" msgid "remove redundant packs, and run git-prune-packed" msgstr "видалити зайві пакунки Ñ– запуÑтити git-prune-packed" @@ -11501,6 +11529,9 @@ msgid "" "specify the name hash version to use for grouping similar objects by path" msgstr "вказати верÑÑ–ÑŽ назви хешу Ð´Ð»Ñ Ð³Ñ€ÑƒÐ¿ÑƒÐ²Ð°Ð½Ð½Ñ Ñхожих обʼєктів за шлÑхом" +msgid "pass --path-walk to git-pack-objects" +msgstr "передати --path-walk до git-pack-objects" + msgid "do not run git-update-server-info" msgstr "не запуÑкати git-update-server-info" @@ -12669,17 +12700,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [<допиÑ>]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <поÑиланнÑ>) [<Ñхов>...]" + +msgid "git stash import <commit>" +msgstr "git stash import <коміт>" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "\"%s\" не Ñ” Ñховоподібним комітом" +msgid "No stash entries found." +msgstr "ЗапиÑи Ñхову не знайдені." + #, c-format msgid "Too many revisions specified:%s" msgstr "Вказано забагато ревізій:%s" -msgid "No stash entries found." -msgstr "ЗапиÑи Ñхова не знайдені." - #, c-format msgid "%s is not a valid reference" msgstr "%s не Ñ” припуÑтимим поÑиланнÑм" @@ -12832,19 +12869,74 @@ msgstr "в тому чиÑлі невідÑтежувані файли ÑÑ…Ð¾Ð²Ñ msgid "include ignore files" msgstr "в тому чиÑли файли ігноруваннÑ" -msgid "skip and remove all lines starting with comment character" -msgstr "пропуÑтити та видалити вÑÑ– Ñ€Ñдки, що починаютьÑÑ Ð· Ñимволу коментарÑ" +#, c-format +msgid "cannot parse commit %s" +msgstr "неможливо розібрати коміт %s" -msgid "prepend comment character and space to each line" -msgstr "додати Ñимвол ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ Ñ‚Ð° пробіл до кожного Ñ€Ñдка" +#, c-format +msgid "invalid author or committer for %s" +msgstr "неприпуÑтимий автор або комітер Ð´Ð»Ñ %s" + +msgid "could not write commit" +msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати коміт" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "ОчікувалаÑÑŒ повна назва поÑиланнÑ, отримано %s" +msgid "not a valid revision: %s" +msgstr "неприпуÑтима редакціÑ: %s" #, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ обʼєкт Ñховища Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\"" +msgid "not a commit: %s" +msgstr "не Ñ” комітом: %s" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s не Ñ” припуÑтимим екÑпортованим комітом Ñхову" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "знайдено кореневий коміт %s з неприпуÑтими даними" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "знайдено коміт Ñхову %s без очікуваного префікÑа" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "неможливо розібрати батьків коміту: %s" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s не Ñхожий на коміт Ñхову" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "неможливо прочитати буфер комітів Ð´Ð»Ñ %s" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "неможливо зберегти Ñхов Ð´Ð»Ñ %s" + +msgid "unable to write base commit" +msgstr "не вдалоÑÑ Ð·Ð°Ð¿Ð¸Ñати базовий коміт" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "не вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ Ð·Ð°Ð¿Ð¸Ñ Ñхову %s" + +msgid "print the object ID instead of writing it to a ref" +msgstr "виводити ідентифікатор обʼєкта заміÑть запиÑÑƒÐ²Ð°Ð½Ð½Ñ Ð¹Ð¾Ð³Ð¾ в поÑиланнÑ" + +msgid "save the data to the given ref" +msgstr "зберегти дані у вказаному поÑиланні" + +msgid "exactly one of --print and --to-ref is required" +msgstr "потрібно вказати лише один з параметрів --print та --to-ref" + +msgid "skip and remove all lines starting with comment character" +msgstr "пропуÑтити та видалити вÑÑ– Ñ€Ñдки, що починаютьÑÑ Ð· Ñимволу коментарÑ" + +msgid "prepend comment character and space to each line" +msgstr "додати Ñимвол ÐºÐ¾Ð¼ÐµÐ½Ñ‚Ð°Ñ€Ñ Ñ‚Ð° пробіл до кожного Ñ€Ñдка" #, c-format msgid "" @@ -12855,6 +12947,10 @@ msgstr "" "першоджерельне Ñховище." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "не вдалоÑÑ Ð¾Ñ‚Ñ€Ð¸Ð¼Ð°Ñ‚Ð¸ обʼєкт Ñховища Ð´Ð»Ñ Ð¿Ñ–Ð´Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\"" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "Ðе знайдено URL Ð´Ð»Ñ ÑˆÐ»Ñху Ð¿Ñ–Ð´Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\" у .gitmodules" @@ -13213,6 +13309,10 @@ msgstr "" "Ñуперпроект не знаходитьÑÑ Ñƒ жодній гілці" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "ОчікувалаÑÑŒ повна назва поÑиланнÑ, отримано %s" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "Ðе вдалоÑÑ Ð·Ð½Ð°Ð¹Ñ‚Ð¸ поточну ревізію у шлÑху Ð¿Ñ–Ð´Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\"" @@ -13416,6 +13516,10 @@ msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "URL Ñховища: \"%s\" має бути абÑолютним або починатиÑÑ Ð· ./|../." #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "назва Ð¿Ñ–Ð´Ð¼Ð¾Ð´ÑƒÐ»Ñ \"%s\" вже викориÑтовуєтьÑÑ Ð´Ð»Ñ ÑˆÐ»Ñху \"%s\"" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "\"%s\" не Ñ” припуÑтимою назвою підмодулÑ" @@ -14049,10 +14153,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "Підготовка робочого дерева (перехід до \"%s\")" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "недоÑÑжне: неприпуÑтиме поÑиланнÑ: %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Підготовка робочого дерева (відокремлений HEAD %s)" @@ -15660,14 +15760,6 @@ msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "невірне чиÑлове Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ— \"%s\" Ð´Ð»Ñ \"%s\" у \"%s\": %s" #, c-format -msgid "invalid value for variable %s" -msgstr "неприпуÑтиме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— %s" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¾Ð³Ð¾ компонента core.fsync \"%s\"" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "невірне булеве Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ ÐºÐ¾Ð½Ñ„Ñ–Ð³ÑƒÑ€Ð°Ñ†Ñ–Ñ— \"%s\" Ð´Ð»Ñ \"%s\"" @@ -15680,44 +15772,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "\"%s\" Ð´Ð»Ñ \"%s\" не Ñ” припуÑтимою міткою чаÑу" #, c-format -msgid "abbrev length out of range: %d" -msgstr "довжина ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð° діапазоном: %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "невірний рівень zlib компреÑÑ–Ñ— %d" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s не може міÑтити Ñимволи нового Ñ€Ñдка" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s повинен мати принаймні один Ñимвол" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ core.fsyncMethod \"%s\"" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles заÑтаріла; натоміÑть викориÑтовуйте core.fsync" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "неприпуÑтимий режим ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ð°: %s" - -#, c-format -msgid "malformed value for %s" -msgstr "невірно Ñформоване Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "невірно Ñформоване Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s: %s" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "має бути одним з nothing, matching, simple, upstream або current" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ config blob обʼєкт \"%s\"" @@ -16238,8 +16292,8 @@ msgstr "неможливо порівнÑти stdin з директорією" msgid "cannot compare a named pipe to a directory" msgstr "неможливо порівнÑти іменований канал з директорією" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<опції>] <шлÑÑ…> <шлÑÑ…>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [<опції>] <шлÑÑ…> <шлÑÑ…> [<визначник шлÑху>...]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -16248,6 +16302,13 @@ msgstr "" "Це не git Ñховище. СкориÑтайтеÑÑŒ --no-index Ð´Ð»Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½ÑÐ½Ð½Ñ Ð´Ð²Ð¾Ñ… шлÑхів поза " "робочим деревом" +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "" +"ÐžÐ±Ð¼ÐµÐ¶ÐµÐ½Ð½Ñ Ð¿Ð¾Ñ€Ñ–Ð²Ð½ÑÐ½Ð½Ñ Ð· pathspecs підтримуєтьÑÑ Ñ‚Ñ–Ð»ÑŒÐºÐ¸ в тому випадку, Ñкщо " +"обидва шлÑхи Ñ” директоріÑми." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr " Ðе вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ відÑоток відÑÑ–ÐºÐ°Ð½Ð½Ñ dirstat \"%s\"\n" @@ -16829,6 +16890,52 @@ msgid "bad git namespace path \"%s\"" msgstr "невірний шлÑÑ… до проÑтору імен git \"%s\"" #, c-format +msgid "invalid value for variable %s" +msgstr "неприпуÑтиме Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ Ð·Ð¼Ñ–Ð½Ð½Ð¾Ñ— %s" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¾Ð³Ð¾ компонента core.fsync \"%s\"" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "довжина ÑÐºÐ¾Ñ€Ð¾Ñ‡ÐµÐ½Ð½Ñ Ð¿Ð¾Ð·Ð° діапазоном: %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "невірний рівень zlib компреÑÑ–Ñ— %d" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s не може міÑтити Ñимволи нового Ñ€Ñдка" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s повинен мати принаймні один Ñимвол" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "Ñ–Ð³Ð½Ð¾Ñ€ÑƒÐ²Ð°Ð½Ð½Ñ Ð½ÐµÐ²Ñ–Ð´Ð¾Ð¼Ð¾Ð³Ð¾ Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ core.fsyncMethod \"%s\"" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles заÑтаріла; натоміÑть викориÑтовуйте core.fsync" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "неприпуÑтимий режим ÑÑ‚Ð²Ð¾Ñ€ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ð°: %s" + +#, c-format +msgid "malformed value for %s" +msgstr "невірно Ñформоване Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "невірно Ñформоване Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s: %s" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "має бути одним з nothing, matching, simple, upstream або current" + +#, c-format msgid "too many args to run %s" msgstr "забагато аргументів Ð´Ð»Ñ Ð·Ð°Ð¿ÑƒÑку %s" @@ -17547,6 +17654,31 @@ msgstr "порожнє Ñ–Ð¼Ê¼Ñ Ð¾ÑобиÑтоÑті (Ð´Ð»Ñ <%s>) заборРmsgid "name consists only of disallowed characters: %s" msgstr "Ñ–Ð¼Ê¼Ñ ÑкладаєтьÑÑ Ð»Ð¸ÑˆÐµ з заборонених Ñимволів: %s" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <директоріÑ>] < <mbox>" + +msgid "no IMAP host specified" +msgstr "не вказано хоÑÑ‚ IMAP" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"вÑтановіть хоÑÑ‚ IMAP за допомогою команди \"git config imap.host <хоÑÑ‚>\".\n" +"(наприклад, \"git config imap.host imaps://imap.example.com\")" + +msgid "no IMAP folder specified" +msgstr "не вказано директорію IMAP" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"вÑтановіть цільову директорію за допомогою команди \"git config imap.folder " +"<директоріÑ>\".\n" +"(наприклад, \"git config imap.folder Drafts\")" + msgid "expected 'tree:<depth>'" msgstr "очікувалоÑÑŒ \"tree:<глибина>\"" @@ -18510,6 +18642,26 @@ msgid "invalid object name '%.*s'." msgstr "неприпуÑтима назва обʼєкта \"%.*s\"." #, c-format +msgid "invalid object type \"%s\"" +msgstr "неприпуÑтимий тип обʼєкту \"%s\"" + +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "обʼєкт %s Ñ” %s, а не %s" + +#, c-format +msgid "object %s has unknown type id %d" +msgstr "обʼєкт %s має невідомий тип ідентифікатора %d" + +#, c-format +msgid "unable to parse object: %s" +msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ обʼєкт: %s" + +#, c-format +msgid "hash mismatch %s" +msgstr "невідповідніÑть хешу %s" + +#, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ñ–Ñ Ð¾Ð±â€™Ñ”ÐºÑ‚Ð° %s не Ñ–Ñнує; перевірте .git/objects/info/alternates" @@ -18577,26 +18729,6 @@ msgid "%s is not a valid '%s' object" msgstr "%s не Ñ” допуÑтимим \"%s\" обʼєктом" #, c-format -msgid "invalid object type \"%s\"" -msgstr "неприпуÑтимий тип обʼєкту \"%s\"" - -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "обʼєкт %s Ñ” %s, а не %s" - -#, c-format -msgid "object %s has unknown type id %d" -msgstr "обʼєкт %s має невідомий тип ідентифікатора %d" - -#, c-format -msgid "unable to parse object: %s" -msgstr "не вдалоÑÑ Ñ€Ð¾Ð·Ñ–Ð±Ñ€Ð°Ñ‚Ð¸ обʼєкт: %s" - -#, c-format -msgid "hash mismatch %s" -msgstr "невідповідніÑть хешу %s" - -#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "дубльований елемент під Ñ‡Ð°Ñ Ð·Ð°Ð¿Ð¸Ñу bitmap індекÑу: \"%s\"" @@ -18607,9 +18739,6 @@ msgstr "Ñпроба зберегти невибраний коміт: \"%s\"" msgid "too many pseudo-merges" msgstr "занадто багато пÑевдозлиттÑ" -msgid "trying to write commit not in index" -msgstr "Ñпроба запиÑати коміт, Ñкого немає в індекÑÑ–" - msgid "failed to load bitmap index (corrupted?)" msgstr "не вдалоÑÑ Ð·Ð°Ð²Ð°Ð½Ñ‚Ð°Ð¶Ð¸Ñ‚Ð¸ bitmap Ñ–Ð½Ð´ÐµÐºÑ (пошкоджено?)" @@ -18863,6 +18992,10 @@ msgid "%s isn't available" msgstr "%s недоÑтупний" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ Ð´Ð»Ñ %s перевищує %<PRIdMAX>" + +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "Ð·Ð½Ð°Ñ‡ÐµÐ½Ð½Ñ %s Ð´Ð»Ñ %s не в діапазоні [%<PRIdMAX>,%<PRIdMAX>]" @@ -19837,6 +19970,14 @@ msgid "%s does not point to a valid object!" msgstr "%s не вказує на допуÑтимий обʼєкт!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s Ñтане виÑÑчим піÑÐ»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %s\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s Ñтав виÑÑчим піÑÐ»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ %s\n" + +#, 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" @@ -22201,6 +22342,9 @@ msgstr "перемикач Ð²ÐºÐ»ÑŽÑ‡ÐµÐ½Ð½Ñ Ð¾Ð±Ê¼Ñ”ÐºÑ‚Ñ–Ð² дерева" msgid "toggle pruning of uninteresting paths" msgstr "перемикач Ð¾Ð±Ñ€Ñ–Ð·Ð°Ð½Ð½Ñ Ð½ÐµÑ†Ñ–ÐºÐ°Ð²Ð¸Ñ… шлÑхів" +msgid "toggle aggressive edge walk" +msgstr "перемикач агреÑивного Ñ…Ð¾Ð´Ñ–Ð½Ð½Ñ Ð¿Ð¾ краю" + msgid "read a pattern list over stdin" msgstr "читати ÑпиÑок шаблонів через stdin" @@ -22845,6 +22989,24 @@ msgid "warning: " msgstr "попередженнÑ: " #, c-format +msgid "" +"'%s' 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 "" +"\"%s\" запропоновано Ð´Ð»Ñ Ð²Ð¸Ð´Ð°Ð»ÐµÐ½Ð½Ñ.\n" +"Якщо ви вÑе ще викориÑтовуєте цю команду, додайте додаткову\n" +"опцію \"--i-still-use-this\" у командний Ñ€Ñдок\n" +"Ñ– повідомте Ð½Ð°Ñ Ð¿Ñ€Ð¾ те, що ви вÑе ще Ñ—Ñ— викориÑтовуєте, надіÑлавши " +"електронного лиÑта\n" +"на адреÑу <git@vger.kernel.org>. ДÑкуємо.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "відмовлено в запуÑку без --i-still-use-this" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "uname() завершивÑÑ Ð½ÐµÐ²Ð´Ð°Ð»Ð¾ з помилкою \"%s\" (%d)\n" @@ -23087,9 +23249,9 @@ msgstr "невідÑтежуваний контент, " #, c-format msgid "Your stash currently has %d entry" msgid_plural "Your stash currently has %d entries" -msgstr[0] "У вашій Ñхованці наразі Ñ” %d запиÑ" -msgstr[1] "У вашій Ñхованці наразі Ñ” %d запиÑи" -msgstr[2] "У вашій Ñхованці наразі Ñ” %d запиÑів" +msgstr[0] "У вашому Ñхові наразі Ñ” %d запиÑ" +msgstr[1] "У вашому Ñхові наразі Ñ” %d запиÑи" +msgstr[2] "У вашому Ñхові наразі Ñ” %d запиÑів" msgid "Submodules changed but not updated:" msgstr "Підмодулі змінено, але не оновлено:" @@ -23780,6 +23942,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(тіло) Ð”Ð¾Ð´Ð°Ð²Ð°Ð½Ð½Ñ cc: %s з Ñ€Ñдка \"%s\"\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "помилка: неприпуÑтимий порт SMTP \"%s\"\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Ðе вдалоÑÑ Ð²Ð¸ÐºÐ¾Ð½Ð°Ñ‚Ð¸ \"%s\"" @@ -66,10 +66,10 @@ # +------------------------------------------------------------------+ msgid "" msgstr "" -"Project-Id-Version: git 2.49\n" +"Project-Id-Version: git 2.51\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-03-05 22:57+0000\n" -"PO-Revision-Date: 2025-03-06 08:20+0700\n" +"POT-Creation-Date: 2025-08-12 17:01+0000\n" +"PO-Revision-Date: 2025-08-14 16:16+0700\n" "Last-Translator: VÅ© Tiến Hưng <newcomerminecraft@gmail.com>\n" "Language-Team: Vietnamese <https://github.com/Nekosha/git-po>\n" "Language: vi\n" @@ -79,6 +79,10 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0\n" #, c-format +msgid "%s cannot be negative" +msgstr "%s phải không âm" + +#, c-format msgid "Huh (%s)?" msgstr "Hả (%s)?" @@ -1978,6 +1982,10 @@ msgid "adding files failed" msgstr "thêm táºp tin gặp lá»—i" #, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' phải không âm" + +#, c-format msgid "--chmod param '%s' must be either -x or +x" msgstr "--chmod tham số '%s' phải hoặc là -x hay +x" @@ -2952,7 +2960,7 @@ msgid "show hash and subject, give twice for upstream branch" msgstr "hiển thị mã băm và chá»§ Ä‘á», đưa ra hai lần cho nhánh thượng nguồn" msgid "suppress informational messages" -msgstr "không xuất các thông tin" +msgstr "không in ra các thông tin phản hồi" msgid "set branch tracking configuration" msgstr "đặt cấu hình thao dõi nhánh" @@ -3261,7 +3269,7 @@ msgid "do not show bundle details" msgstr "không hiển thị chi tiết bundle (bó)" msgid "need a repository to verify a bundle" -msgstr "cần má»™t kho chứa để thẩm tra má»™t bundle" +msgstr "cần má»™t kho chứa để xác minh má»™t bundle" #, c-format msgid "%s is okay\n" @@ -3301,11 +3309,8 @@ msgstr "chỉ má»™t tùy chá»n batch được chỉ ra" msgid "git cat-file <type> <object>" msgstr "git cat-file <kiểu> <đối tượng>" -msgid "git cat-file (-e | -p) <object>" -msgstr "git cat-file (-e | -p) <đối tượng>" - -msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" -msgstr "git cat-file (-t | -s) [--allow-unknown-type] <đối_tượng>" +msgid "git cat-file (-e | -p | -t | -s) <object>" +msgstr "git cat-file (-e | -p | -t | -s) <đối tượng>" msgid "" "git cat-file (--textconv | --filters)\n" @@ -3345,9 +3350,6 @@ msgstr "" msgid "show object size" msgstr "hiển thị kÃch thước đối tượng" -msgid "allow -s and -t to work with broken/corrupt objects" -msgstr "cho phép -s và -t để là m việc vá»›i các đối tượng sai/há»ng" - msgid "use mail map file" msgstr "sá» dụng táºp tin ánh xạ thư" @@ -3404,6 +3406,13 @@ msgid "use a <path> for (--textconv | --filters); Not with 'batch'" msgstr "" "dùng má»™t </đưá»ng/dẫn/> rõ rà ng cho (--textconv/--filters); Không vá»›i 'batch'" +msgid "objects filter only supported in batch mode" +msgstr "chỉ há»— trợ lá»c đối tượng trong chế độ batch" + +#, c-format +msgid "objects filter not supported: '%s'" +msgstr "không há»— trợ lá»c đối tượng: '%s'" + #, c-format msgid "'%s=<%s>' needs '%s' or '%s'" msgstr "'%s=<%s>' cần '%s' hoặc '%s'" @@ -4500,7 +4509,7 @@ msgid "the object directory to store the graph" msgstr "thư mục đối tượng để lưu đồ thị" msgid "if the commit-graph is split, only verify the tip file" -msgstr "nếu đồ-thị-chuyển-giao bị chia cắt, thì chỉ thẩm tra táºp tin đỉnh" +msgstr "nếu đồ-thị-chuyển-giao bị chia cắt, thì chỉ xác minh táºp tin đỉnh" #, c-format msgid "Could not open commit-graph '%s'" @@ -4932,7 +4941,7 @@ msgid "paths '%s ...' with -a does not make sense" msgstr "các đưá»ng dẫn '%s ...' vá»›i tùy chá»n -a không hợp lý" msgid "show status concisely" -msgstr "hiển thị trạng thái ở dạng súc tÃch" +msgstr "hiển thị trạng thái ở dạng tóm lược" msgid "show branch information" msgstr "hiển thị thông tin nhánh" @@ -5135,58 +5144,61 @@ msgstr "" "và sau đó \"git restore --staged :/\" để khắc phục." msgid "git config list [<file-option>] [<display-option>] [--includes]" -msgstr "git config list [<tuỳ-chá»n>] [<tuỳ-chá»n-hiển-thị>] [--includes]" +msgstr "" +"git config list [<tuỳ-chá»n-táºp-tin>] [<tuỳ-chá»n-hiển-thị>] [--includes]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" -"git config get [<tuỳ-chá»n>] [<tuỳ-chá»n-hiển-thị>] [--includes] [--all] [--" -"regexp] [--value=<giá-trị>] [--fixed-value] [--default=<giá-trị-mặc-định>] " -"<tên>" +"git config get [<tuỳ-chá»n-táºp-tin>] [<tuỳ-chá»n-hiển-thị>] [--includes] [--" +"all] [--regexp] [--value=<giá-trị>] [--fixed-value] [--default=<giá-trị-mặc-" +"định>] [--url=<url>] <tên>" msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<tuỳ-chá»n>] [--type=<kiểu>] [--all] [--value=<giá-trị>] [--" -"fixed-value] <khoá> <giá-trị>" +"git config set [<tuỳ-chá»n-táºp-tin>] [--type=<kiểu>] [--all] [--value=<giá-" +"trị>] [--fixed-value] <khoá> <giá-trị>" msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<tuỳ-chá»n>] [--all] [--value=<giá-trị>] [--fixed-value] " -"<khoá>" +"git config unset [<tuỳ-chá»n-táºp-tin>] [--all] [--value=<giá-trị>] [--fixed-" +"value] <khoá>" msgid "git config rename-section [<file-option>] <old-name> <new-name>" -msgstr "git config rename-section [<tuỳ-chá»n>] <tên-cÅ©> <tên-má»›i>" +msgstr "git config rename-section [<tuỳ-chá»n-táºp-tin>] <tên-cÅ©> <tên-má»›i>" msgid "git config remove-section [<file-option>] <name>" -msgstr "git config remove-section [<tuỳ-chá»n>] <tên>" +msgstr "git config remove-section [<tuỳ-chá»n-táºp-tin>] <tên>" msgid "git config edit [<file-option>]" -msgstr "git config edit [<tùy-chá»n>]" +msgstr "git config edit [<tùy-chá»n-táºp-tin>]" msgid "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" msgstr "" -"git config [<tuỳ-chá»n>] --get-colorbool <tên> [<stdout-là -tty-hay-không>]" +"git config [<tuỳ-chá»n-táºp-tin>] --get-colorbool <tên> [<stdout-là -tty-hay-" +"không>]" msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" -"git config get [<tuỳ-chá»n>] [<tuỳ-chá»n-hiển-thị>] [--includes] [--all] [--" -"regexp=<biểu-thức-chÃnh-quy>] [--value=<giá-trị>] [--fixed-value] [--" +"git config get [<tuỳ-chá»n-táºp-tin>] [<tuỳ-chá»n-hiển-thị>] [--includes] [--" +"all] [--regexp=<biểu-thức-chÃnh-quy>] [--value=<giá-trị>] [--fixed-value] [--" "default=<giá-trị-mặc-định>] <khoá>" msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" -"git config set [<tuỳ-chá»n>] [--type=<kiểu>] [--comment=<chú-thÃch>] [--all] " -"[--value=<giá-trị>] [--fixed-value] <khoá> <giá-trị>" +"git config set [<tuỳ-chá»n-táºp-tin>] [--type=<kiểu>] [--comment=<chú-thÃch>] " +"[--all] [--value=<giá-trị>] [--fixed-value] <khoá> <giá-trị>" msgid "Config file location" msgstr "Vị trà táºp tin cấu hình" @@ -5672,6 +5684,50 @@ msgstr "" msgid "specify the content of the diagnostic archive" msgstr "chỉ định ná»™i dung bản báo cáo" +#, c-format +msgid "unable to parse mode: %s" +msgstr "không thể Ä‘á»c chế độ: %s" + +#, c-format +msgid "unable to parse object id: %s" +msgstr "không thể Ä‘á»c đối tượng: %s" + +msgid "git diff-pairs -z [<diff-options>]" +msgstr "git diff-pairs -z [<các tùy chá»n>]" + +#, c-format +msgid "unrecognized argument: %s" +msgstr "đối số không được thừa nháºn: %s" + +msgid "working without -z is not supported" +msgstr "không há»— trợ bá» tuỳ chá»n -z" + +msgid "pathspec arguments not supported" +msgstr "đặc tả đưá»ng dẫn chưa được há»— trợ" + +msgid "revision arguments not allowed" +msgstr "không cho phép dùng tên lần cải biên" + +msgid "invalid raw diff input" +msgstr "dòng diff không hợp lệ" + +msgid "tree objects not supported" +msgstr "không há»— trợ đối tượng cây" + +msgid "got EOF while reading path" +msgstr "gặp EOF khi Ä‘á»c đưá»ng dẫn" + +msgid "got EOF while reading destination path" +msgstr "gặp EOF khi Ä‘á»c đưá»ng dẫn Ä‘Ãch" + +#, c-format +msgid "unable to parse rename/copy score: %s" +msgstr "không thể Ä‘á»c rename/copy score:%s" + +#, c-format +msgid "unknown diff status: %c" +msgstr "trạng thái diff không rõ: %c" + msgid "--merge-base only works with two commits" msgstr "--merge-base chỉ hoạt động vá»›i hai lần chuyển giao" @@ -5809,17 +5865,20 @@ msgid "show progress after <n> objects" msgstr "hiển thị tiến triển sau <n> đối tượng" msgid "select handling of signed tags" -msgstr "chá»n Ä‘iá»u khiển cá»§a thẻ đã ký" +msgstr "chá»n cách xá» lý thẻ đã ký" + +msgid "select handling of signed commits" +msgstr "chá»n cách xá» lý lần chuyển giao đã ký" msgid "select handling of tags that tag filtered objects" -msgstr "chá»n sá»± xá» lý cá»§a các thẻ, cái mà đánh thẻ các đối tượng được lá»c ra" +msgstr "chá»n cách xá» lý cá»§a các thẻ trên các đối tượng đã bị lá»c ra" msgid "select handling of commit messages in an alternate encoding" msgstr "" -"chá»n bá»™ xá» lý cho các ghi chú cá»§a lần chuyển giao theo má»™t bá»™ mã thay thế" +"chá»n cách xá» lý cho các ghi chú lần chuyển giao được mã hoá theo bá»™ mã khác" msgid "dump marks to this file" -msgstr "đổ các đánh dấu nà y và o táºp-tin" +msgstr "xuất các đánh dấu nà y và o táºp-tin" msgid "import marks from this file" msgstr "nháºp và o đánh dấu từ táºp tin nà y" @@ -5985,22 +6044,6 @@ msgstr "%s đã không gá»i tất cả các đối tượng cần thiết" msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "từ chối %s bởi vì các gốc nông thì không được phép cáºp nháºt" -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"má»™t số tham chiếu ná»™i bá»™ không thể được cáºp nháºt; hãy thá» chạy\n" -" 'git remote prune %s' để bá» Ä‘i những nhánh cÅ©, hay bị xung đột" - -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s sẽ trở thà nh không đầu (không được quản lý))" - -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s đã trở thà nh không đầu (không được quản lý))" - msgid "[deleted]" msgstr "[đã xóa]" @@ -6040,6 +6083,18 @@ msgstr "" "thông báo nà y. Cụ thể, 'git config set remote.%s.followRemoteHEAD %s'\n" "sẽ vô hiệu cảnh báo nà y tá»›i khi máy chá»§ đổi HEAD vá» chá»— khác." +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"má»™t số tham chiếu ná»™i bá»™ không thể được cáºp nháºt; hãy thá» chạy\n" +" 'git remote prune %s' để bá» Ä‘i những nhánh cÅ©, hay bị xung đột" + +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "gặp lá»—i khi tải gói %s: %s" + msgid "multiple branches detected, incompatible with --set-upstream" msgstr "phát hiện nhiá»u nhánh, không tương thÃch vá»›i --set-upstream" @@ -6284,6 +6339,9 @@ msgstr "" "git for-each-ref [--contains [<lần-chuyển-giao>]] [--no-contains [<lần-" "chuyển-giao>]]" +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <dấu>]" + msgid "quote placeholders suitably for shells" msgstr "trÃch dẫn dạng phù hợp cho shell" @@ -6299,6 +6357,12 @@ msgstr "trÃch dẫn dạng phù hợp cho Tcl" msgid "show only <n> matched refs" msgstr "hiển thị chỉ <n> tham chiếu khá»›p" +msgid "marker" +msgstr "dấu" + +msgid "start iteration after the provided marker" +msgstr "bắt đầu duyệt sau dấu chỉ định" + msgid "respect format colors" msgstr "các mà u định dạng lưu tâm" @@ -6323,9 +6387,15 @@ msgstr "Ä‘á»c các mẫu tham chiếu từ stdin" msgid "also include HEAD ref and pseudorefs" msgstr "bao gồm tham chiếu HEAD và giả tham chiếu" +msgid "cannot use --start-after with custom sort options" +msgstr "không thể dùng tùy chá»n --start-after vá»›i tuỳ chá»n sắp xếp" + msgid "unknown arguments supplied with --stdin" msgstr "đối số không rõ được chỉ định cùng vá»›i --stdin" +msgid "cannot use --start-after with patterns" +msgstr "không thể dùng tùy chá»n --start-after vá»›i mẫu" + msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<tùy chá»n> [--] <đối số>" @@ -6454,10 +6524,6 @@ msgid "%s: object corrupt or missing: %s" msgstr "%s: thiếu đối tượng hoặc há»ng: %s" #, c-format -msgid "%s: object is of unknown type '%s': %s" -msgstr "%s: đối tượng có kiểu chưa biết '%s': %s" - -#, c-format msgid "%s: object could not be parsed: %s" msgstr "%s: không thể Ä‘á»c cú đối tượng: %s" @@ -6514,11 +6580,14 @@ msgstr "không thể tải pack-index cho gói '%s'" msgid "invalid rev-index for pack '%s'" msgstr "giá trị rev-index cho gói '%s' không hợp lệ" +msgid "Checking ref database" +msgstr "Äang kiểm tra database tham chiếu" + msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" -" [--[no-]name-objects] [<object>...]" +" [--[no-]name-objects] [--[no-]references] [<object>...]" msgstr "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" @@ -6561,6 +6630,9 @@ msgstr "hiển thị quá trình" msgid "show verbose names for reachable objects" msgstr "hiển thị tên chi tiết cho các đối tượng Ä‘á»c được" +msgid "check reference database consistency" +msgstr "Äang kiểm tra tÃnh nhất quán database tham chiếu" + msgid "Checking objects" msgstr "Äang kiểm tra các đối tượng" @@ -6719,6 +6791,9 @@ msgstr "đóng gói lại tất cả các gói khác ngoại trừ gói lá»›n nh msgid "pack prefix to store a pack containing pruned objects" msgstr "tiá»n tố cá»§a gói để lưu gói gồm những đối tượng đã loại bá»" +msgid "skip maintenance tasks typically done in the foreground" +msgstr "bá» qua các tác vụ bảo trì trong ná»n" + #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "gặp lá»—i khi Ä‘á»c giá trị gc.logExpiry %s" @@ -6792,14 +6867,14 @@ msgid "" msgstr "bá» qua tác vụ incremental-repack vì core.multiPackIndex bị vô hiệu hóa" #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "đã có khóa cá»§a táºp tin '%s', bá» qua bảo trì" - -#, c-format msgid "task '%s' failed" msgstr "gặp lá»—i khi thá»±c hiện nhiệm vụ '%s'" #, c-format +msgid "lock file '%s' exists, skipping maintenance" +msgstr "đã có khóa cá»§a táºp tin '%s', bá» qua bảo trì" + +#, c-format msgid "'%s' is not a valid task" msgstr "'%s' không phải má»™t nhiệm vụ hợp lệ" @@ -6828,9 +6903,6 @@ msgstr "tác vụ" msgid "run a specific task" msgstr "chạy má»™t nhiệm vụ cụ thể" -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "dùng nhiá»u nhất là má»™t trong --auto và --schedule=<frequency>" - #, c-format msgid "unable to add '%s' value of '%s'" msgstr "không thể thêm giá trị '%s' cá»§a '%s'" @@ -7667,7 +7739,7 @@ msgid "invalid --decorate option: %s" msgstr "tùy chá»n --decorate không hợp lệ: %s" msgid "suppress diff output" -msgstr "chặn má»i đầu ra từ diff" +msgstr "không in ra kết quả diff" msgid "show source" msgstr "hiển thị mã nguồn" @@ -7691,18 +7763,10 @@ msgstr "" "theo vết sá»± tiến hóa cá»§a phạm vi dòng <start>,<end>, hoặc hà m :<tên hà m> " "trong <táºp tin>" -#, c-format -msgid "unrecognized argument: %s" -msgstr "đối số không được thừa nháºn: %s" - msgid "-L<range>:<file> cannot be used with pathspec" msgstr "-L<vùng>:<táºp tin> không thể được sá» dụng vá»›i đặc tả đưá»ng dẫn" #, c-format -msgid "Final output: %d %s\n" -msgstr "Äầu ra cuối cùng: %d %s\n" - -#, c-format msgid "git show %s: bad file" msgstr "git show %s: sai táºp tin" @@ -8085,7 +8149,7 @@ msgid "show debugging data" msgstr "hiển thị dữ liệu gỡ lá»—i" msgid "suppress duplicate entries" -msgstr "chặn các mục tin trùng lặp" +msgstr "không in ra các mục tin trùng lặp" msgid "show sparse directories in the presence of a sparse index" msgstr "hiển thị thư mục thưa trong sá»± có mặt cá»§a chỉ mục thưa" @@ -8278,7 +8342,7 @@ msgid "choose a diff algorithm" msgstr "chá»n thuáºt toán diff" msgid "for conflicts, use this marker size" -msgstr "nếu xung đột, hãy sá» dụng kÃch thước bá»™ tạo nà y" +msgstr "nếu xung đột, hãy sá» dụng kÃch thước dấu nà y" msgid "do not warn about conflicts" msgstr "không cảnh báo vá» các xung đột xảy ra" @@ -8345,6 +8409,9 @@ msgstr "chỉ hoà trá»™n đơn giản" msgid "also show informational/conflict messages" msgstr "hiển thị thông báo chú thÃch/xung đột" +msgid "suppress all output; only exit status wanted" +msgstr "không in ra kết quả; chỉ trả vá» kết quả thá»±c thi" + msgid "list filenames without modes/oids/stages" msgstr "liệt kê tên táºp tin không kèm chế độ/oid/stage" @@ -8405,6 +8472,9 @@ msgstr "hiển thị diffstat (thống kê khác biệt) phÃa dưới hòa trá» msgid "(synonym to --stat)" msgstr "(đồng nghÄ©a vá»›i --stat)" +msgid "show a compact-summary at the end of the merge" +msgstr "hiển thị compact-summary (tổng hợp tóm lược) phÃa dưới hòa trá»™n" + msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "thêm (Ãt nhất <n>) mục từ shortlog cho ghi chú chuyển giao hòa trá»™n" @@ -8424,7 +8494,7 @@ msgid "abort if fast-forward is not possible" msgstr "huá»· lệnh nếu không thể chuyển-tiếp-nhanh" msgid "verify that the named commit has a valid GPG signature" -msgstr "thẩm tra xem lần chuyển giao có tên đó có chữ ký GPG hợp lệ hay không" +msgstr "xác minh xem lần chuyển giao có tên đó có chữ ký GPG hợp lệ hay không" msgid "strategy" msgstr "chiến lược" @@ -8677,10 +8747,6 @@ msgid "error: tag input does not pass fsck: %s" msgstr "lá»—i: đầu và o thẻ không qua kiểm tra fsck: %s" #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) không bao giá» nên kÃch hoạt callback nà y" - -#, c-format msgid "could not read tagged object '%s'" msgstr "không thể Ä‘á»c đối tượng được đánh thẻ %s" @@ -8754,12 +8820,15 @@ msgstr "" "trong suốt quá trình đóng gói lại, gom các táºp tin gói có kÃch cỡ nhá» hÆ¡n " "và o má»™t bó cái mà lá»›n hÆ¡n kÃch thước nà y" -msgid "git mv [<options>] <source>... <destination>" -msgstr "git mv [<các tùy chá»n>] <nguồn>... <Ä‘Ãch>" +msgid "git mv [-v] [-f] [-n] [-k] <source> <destination>" +msgstr "git mv [-v] [-f] [-n] [-k] <nguồn> <Ä‘Ãch>" + +msgid "git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>" +msgstr "git mv [-v] [-f] [-n] [-k] <nguồn>... <thư-mục-Ä‘Ãch>" #, c-format msgid "Directory %s is in index and no submodule?" -msgstr "Thư mục '%s' có ở trong chỉ mục mà không có mô-Ä‘un con?" +msgstr "Thư mục %s có ở trong chỉ mục mà không có mô-Ä‘un con?" msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" @@ -8825,6 +8894,10 @@ msgid "%s, source=%s, destination=%s" msgstr "%s, nguồn=%s, Ä‘Ãch=%s" #, c-format +msgid "cannot move both '%s' and its parent directory '%s'" +msgstr "Không thể di chuyển cả %s và thư mục cha %s" + +#, c-format msgid "Renaming %s to %s\n" msgstr "Äổi tên %s thà nh %s\n" @@ -9189,16 +9262,26 @@ msgstr "dùng 'notes' từ <notes-ref>" msgid "unknown subcommand: `%s'" msgstr "không hiểu câu lệnh con: `%s'" -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "" -"git pack-objects --stdout [<các tùy chá»n>] [< <danh-sách-tham-chiếu> | < " -"<danh-sách-đối-tượng>]" - msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" msgstr "" -"git pack-objects [<các tùy chá»n>] <base-name> [< <danh-sách-ref> | < <danh-" -"sách-đối-tượng>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" #, c-format msgid "invalid --name-hash-version option: %d" @@ -9303,6 +9386,14 @@ msgstr "không thể đóng gói các đối tượng tiếp cáºn được từ msgid "unable to get type of object %s" msgstr "không thể lấy kiểu cá»§a đối tượng '%s'" +msgid "Compressing objects by path" +msgstr "Äang nén các đối tượng theo đưá»ng dẫn" + +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "Nén delta đưá»ng dẫn dùng tá»›i %d tuyến trình" + msgid "Compressing objects" msgstr "Äang nén các đối tượng" @@ -9378,6 +9469,9 @@ msgstr "đối tượng mất tại %s không thể đã kiểm tra" msgid "unable to force loose object" msgstr "không thể buá»™c mất đối tượng" +msgid "failed to pack objects via path-walk" +msgstr "gặp lá»—i khi nén đối tượng theo thuáºt toán duyệt cây" + #, c-format msgid "not a rev '%s'" msgstr "không phải má»™t rev '%s'" @@ -9488,6 +9582,9 @@ msgstr "sá» dụng thuáºt toán 'sparse reachability'" msgid "create thin packs" msgstr "tạo gói nhẹ" +msgid "use the path-walk API to walk objects when possible" +msgstr "dùng API path-walk để duyệt đối tượng nếu có thể" + msgid "create packs suitable for shallow fetches" msgstr "tạo gói để phù hợp cho lấy vá» nông (shallow)" @@ -9542,6 +9639,10 @@ msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit là quá cao, ép dùng %d" #, c-format +msgid "cannot use %s with %s" +msgstr "Không thể dùng %s vá»›i %s" + +#, c-format msgid "bad pack compression level %d" msgstr "mức nén gói %d không hợp lệ" @@ -9555,18 +9656,12 @@ msgstr "giá»›i hạn kÃch thước tối thiểu cá»§a gói là 1 MiB" msgid "--thin cannot be used to build an indexable pack" msgstr "không thể dùng --thin để xây dá»±ng gói đánh chỉ mục được" -msgid "cannot use --filter with --stdin-packs" -msgstr "không thể dùng tùy chá»n --filter vá»›i --stdin-packs" - msgid "cannot use internal rev list with --stdin-packs" msgstr "không thể dùng danh sách rev ná»™i bá»™ vá»›i --stdin-packs" msgid "cannot use internal rev list with --cruft" msgstr "không thể dùng danh sách rev ná»™i bá»™ vá»›i --cruft" -msgid "cannot use --stdin-packs with --cruft" -msgstr "không thể dùng tùy chá»n --stdin-packs vá»›i --cruft" - msgid "Enumerating objects" msgstr "Duyệt các đối tượng" @@ -9579,22 +9674,6 @@ msgstr "" "lại pack %<PRIu32> (trong số %<PRIuMAX>)" 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 "" -"'git pack-redundant' đã được đỠcỠđể loại bá».\n" -"Nếu bạn vẫn còn sá» dụng lệnh nà y, vui lòng bổ sung\n" -"thêm má»™t tùy chá»n, '--i-still-use-this', trên dòng lệnh\n" -"và cho chúng tôi biết bạn vẫn sá» dụng nó bằng cách gá»i e-mail\n" -"đến <git@vger.kernel.org>. Xin cảm Æ¡n.\n" - -msgid "refusing to run without --i-still-use-this" -msgstr "từ chối chạy lệnh nà y mà không có --i-still-use-this" - -msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " "<pattern>]" msgstr "" @@ -9751,6 +9830,10 @@ msgstr "" msgid "unable to access commit %s" msgstr "không thể truy cáºp lần chuyển giao '%s'" +#, c-format +msgid "invalid refspec '%s'" +msgstr "refspec không hợp lệ '%s'" + msgid "ignoring --verify-signatures for rebase" msgstr "bá» qua --verify-signatures khi cải tổ" @@ -10218,7 +10301,7 @@ msgid "debug unpack-trees" msgstr "gỡ lá»—i 'unpack-trees'" msgid "suppress feedback messages" -msgstr "không xuất các thông tin phản hồi" +msgstr "không in ra các thông tin phản hồi" msgid "You need to resolve your current index first" msgstr "Bạn cần phải giải quyết chỉ mục hiện tại cá»§a bạn trước đã" @@ -10716,6 +10799,9 @@ msgstr "" msgid "git reflog exists <ref>" msgstr "git reflog exists <tham_chiếu>" +msgid "git reflog drop [--all [--single-worktree] | <refs>...]" +msgstr "git reflog drop [--all [--single-worktree] | <tham_chiếu>...]" + #, c-format msgid "invalid timestamp '%s' given to '--%s'" msgstr "dấu vết thá»i gian không hợp lệ '%s' đưa cho '--%s'" @@ -10764,8 +10850,8 @@ msgid "Marking reachable objects..." msgstr "Äánh dấu các đối tượng tiếp cáºn được..." #, c-format -msgid "%s points nowhere!" -msgstr "%s chẳng chỉ đến đâu cả!" +msgid "reflog could not be found: '%s'" +msgstr "không tìm thấy reflog: '%s'" msgid "no reflog specified to delete" msgstr "chưa chỉ ra reflog để xóa" @@ -10774,6 +10860,15 @@ msgstr "chưa chỉ ra reflog để xóa" msgid "invalid ref format: %s" msgstr "định dạng tham chiếu không hợp lệ: %s" +msgid "drop the reflogs of all references" +msgstr "bá» các reflogs cá»§a má»i tham chiếu" + +msgid "drop reflogs from the current worktree only" +msgstr "bá» reflogs chỉ từ thư mục là m việc hiện tại" + +msgid "references specified along with --all" +msgstr "chỉ định tham chiếu vá»›i tùy chá»n --all" + msgid "git refs migrate --ref-format=<format> [--no-reflog] [--dry-run]" msgstr "git refs migrate --ref-format=<định dạng> [--no-reflog] [--dry-run]" @@ -10881,6 +10976,14 @@ msgstr "" msgid "unknown --mirror argument: %s" msgstr "không hiểu tham số --mirror: %s" +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "máy chá»§ '%s' là táºp con cá»§a máy chá»§ đã sẵn có '%s'" + +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "máy chá»§ '%s' là táºp cha cá»§a máy chá»§ đã sẵn có '%s'" + msgid "fetch the remote branches" msgstr "lấy vá» các nhánh từ máy chá»§" @@ -11175,14 +11278,6 @@ msgid "Could not set up %s" msgstr "Không thể cà i đặt %s" #, c-format -msgid " %s will become dangling!" -msgstr " %s sẽ trở thà nh không đầu (không được quản lý)!" - -#, c-format -msgid " %s has become dangling!" -msgstr " %s đã trở thà nh không đầu (không được quản lý)!" - -#, c-format msgid "Pruning %s" msgstr "Äang xén bá»›t %s" @@ -11246,11 +11341,11 @@ msgstr "chi tiết; phải được đặt trước má»™t lệnh-con" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<tên-pack>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgid "" "Incremental repacks are incompatible with bitmap indexes. Use\n" @@ -11317,6 +11412,9 @@ msgstr "ngà y ước tÃnh" msgid "with --cruft, expire objects older than this" msgstr "vá»›i --cruft, đánh dấu hết hạn các đối tượng cÅ© hÆ¡n khoảng nà y" +msgid "with --cruft, only repack cruft packs smaller than this" +msgstr "vá»›i --cruft, chỉ nén các gói nhá» hÆ¡n khoảng nà y" + msgid "remove redundant packs, and run git-prune-packed" msgstr "xóa bá» các gói dư thừa, và chạy git-prune-packed" @@ -11328,7 +11426,10 @@ msgstr "chuyển --no-reuse-object cho git-pack-objects" msgid "" "specify the name hash version to use for grouping similar objects by path" -msgstr "phiên bản hà m băm để nhóm đối tượng giống nhau theo đưá»ng dẫn" +msgstr "chá»n phiên bản hà m băm để nhóm đối tượng giống nhau theo đưá»ng dẫn" + +msgid "pass --path-walk to git-pack-objects" +msgstr "chuyển --path-walk cho git-pack-objects" msgid "do not run git-update-server-info" msgstr "không chạy git-update-server-info" @@ -11786,6 +11887,9 @@ msgstr "không thể dung lượng đĩa đã dùng cá»§a %s" msgid "invalid value for '%s': '%s', the only allowed format is '%s'" msgstr "giá trị không hợp lệ cho '%s': '%s', chỉ cho phép định dạng là '%s'" +msgid "-z option used with unsupported option" +msgstr "tuỳ chá»n -z dùng vá»›i tuỳ chá»n không há»— trợ" + msgid "rev-list does not support display of notes" msgstr "rev-list không há»— trợ hiển thị các ghi chú" @@ -12080,7 +12184,7 @@ msgid "sort output according to the number of commits per author" msgstr "sắp xếp kết quả theo số lượng chuyển giao trên má»—i tác giả" msgid "suppress commit descriptions, only provides commit count" -msgstr "chặn má»i mô tả lần chuyển giao, chỉ đưa ra số lượng lần chuyển giao" +msgstr "không in ra mô tả, chỉ đưa ra số lượng lần chuyển giao" msgid "show the email address of each author" msgstr "hiển thị thư Ä‘iện tá» cho từng tác giả" @@ -12141,7 +12245,7 @@ msgid "synonym to more=-1" msgstr "đồng nghÄ©a vá»›i more=-1" msgid "suppress naming strings" -msgstr "chặn các chuá»—i đặt tên" +msgstr "không in ra các chuá»—i đặt tên" msgid "include the current branch" msgstr "bao gồm nhánh hiện hà nh" @@ -12463,17 +12567,23 @@ msgstr "" msgid "git stash create [<message>]" msgstr "git stash create [<ghi chú>]" +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <ref>) [<stash>...]" + +msgid "git stash import <commit>" +msgstr "git stash import <lần-chuyển-giao>" + #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' không phải là lần chuyển giao kiểu-stash" +msgid "No stash entries found." +msgstr "Không tìm thấy các mục tạm cất (stash) nà o." + #, c-format msgid "Too many revisions specified:%s" msgstr "Chỉ ra quá nhiá»u lần cải biên: %s" -msgid "No stash entries found." -msgstr "Không tìm thấy các mục tạm cất (stash) nà o." - #, c-format msgid "%s is not a valid reference" msgstr "'%s' không phải má»™t tham chiếu hợp lệ" @@ -12625,19 +12735,74 @@ msgstr "bao gồm các táºp tin không được theo dõi trong stash" msgid "include ignore files" msgstr "bao gồm các táºp tin bị bá» qua" -msgid "skip and remove all lines starting with comment character" -msgstr "giữ và xóa bá» má»i dòng bắt đầu bằng ký tá»± ghi chú" +#, c-format +msgid "cannot parse commit %s" +msgstr "không thể Ä‘á»c lần chuyển giao %s" -msgid "prepend comment character and space to each line" -msgstr "treo trước ký tá»± ghi chú và ký tá»± khoảng trắng cho từng dòng" +#, c-format +msgid "invalid author or committer for %s" +msgstr "danh tÃnh tác giả/ngưá»i chuyển giao không hợp lệ cho %s" + +msgid "could not write commit" +msgstr "không thể ghi lần chuyển giao" #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "Cần tên tham chiếu dạng đầy đủ, nhưng lại có %s" +msgid "not a valid revision: %s" +msgstr "không phải revision hợp lệ: %s" #, c-format -msgid "could not get a repository handle for submodule '%s'" -msgstr "không thể lấy thẻ quản kho cho mô-Ä‘un-con '%s'" +msgid "not a commit: %s" +msgstr "không phải là lần chuyển giao: %s" + +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s không phải má»™t lần chuyển giao tạm cất hợp lệ" + +#, c-format +msgid "found root commit %s with invalid data" +msgstr "lần chuyển giao gốc %s có dữ liệu không hợp lệ" + +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "lần chuyển giao tạm cất %s không có tiá»n tố" + +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "không thể Ä‘á»c lần chuyển giao cha: %s" + +#, c-format +msgid "%s does not look like a stash commit" +msgstr "'%s' không phải lần chuyển giao tạm cất" + +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "không thể Ä‘á»c buffer chuyển giao cho %s" + +#, c-format +msgid "cannot save the stash for %s" +msgstr "không thể cất tạm cho %s" + +msgid "unable to write base commit" +msgstr "không thể ghi gốc chuyển giao" + +#, c-format +msgid "unable to find stash entry %s" +msgstr "không tìm thấy stash entry %s" + +msgid "print the object ID instead of writing it to a ref" +msgstr "in ID đối tượng thay vì ghi ra tham chiếu" + +msgid "save the data to the given ref" +msgstr "lưu dữ liệu vá» tham chiếu chỉ định" + +msgid "exactly one of --print and --to-ref is required" +msgstr "yêu cầu má»™t trong hai tuỳ chá»n --print và --to-ref" + +msgid "skip and remove all lines starting with comment character" +msgstr "giữ và xóa bá» má»i dòng bắt đầu bằng ký tá»± ghi chú" + +msgid "prepend comment character and space to each line" +msgstr "treo trước ký tá»± ghi chú và ký tá»± khoảng trắng cho từng dòng" #, c-format msgid "" @@ -12648,6 +12813,10 @@ msgstr "" "sở hữu chÃnh nó." #, c-format +msgid "could not get a repository handle for submodule '%s'" +msgstr "không thể lấy thẻ quản kho cho mô-Ä‘un-con '%s'" + +#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "Không tìm thấy url cho đưá»ng dẫn mô-Ä‘un-con '%s' trong .gitmodules" @@ -12799,7 +12968,7 @@ msgid "" "with a .git file by using absorbgitdirs." msgstr "" "Cây là m việc mô-Ä‘un-con '%s' có chứa thư mục .git. Việc nà y sẽ được thay thế " -"vá»›i má»™t táºp tin .git bằng các sá» dụng absorbgitdirs." +"vá»›i má»™t táºp tin .git bằng cách sá» dụng absorbgitdirs." #, c-format msgid "" @@ -12829,7 +12998,7 @@ msgid "remove submodule working trees even if they contain local changes" msgstr "gỡ bá» cây là m việc cá»§a mô-Ä‘un-con ngay cả khi nó có thay đổi ná»™i bá»™" msgid "unregister all submodules" -msgstr "bỠđăng ký tất cả các trong mô-Ä‘un-con" +msgstr "bỠđăng ký tất cả các mô-Ä‘un-con" msgid "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]" @@ -12887,7 +13056,7 @@ msgid "could not get submodule directory for '%s'" msgstr "không thể lấy thư mục mô-Ä‘un-con cho '%s'" msgid "alternative anchor for relative paths" -msgstr "Ä‘iểm neo thay thế cho các đưá»ng dẫn tương đối" +msgstr "Ä‘iểm gốc thay thế cho các đưá»ng dẫn tương đối" msgid "where the new submodule will be cloned to" msgstr "nhân bản mô-Ä‘un-con má»›i và o chá»— nà o" @@ -13007,6 +13176,10 @@ msgstr "" "project cha lại không trên bất kỳ nhánh nà o" #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "Cần tên tham chiếu dạng đầy đủ, nhưng lại có %s" + +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "Không tìm thấy lần cải biên hiện hà nh trong đưá»ng dẫn mô-Ä‘un-con '%s'" @@ -13130,7 +13303,7 @@ msgstr "'%s' đã tồn tại từ trước và không phải là má»™t kho git #, c-format msgid "A git directory for '%s' is found locally with remote(s):\n" -msgstr "Thư mục git cho '%s' được tìm thấy má»™t cách cục bá»™ vá»›i các máy chá»§:\n" +msgstr "Thư mục git cho '%s' được tìm thấy tại cục bá»™ vá»›i các máy chá»§:\n" #, c-format msgid "" @@ -13208,6 +13381,10 @@ msgid "repo URL: '%s' must be absolute or begin with ./|../" msgstr "repo URL: '%s' phải là đưá»ng dẫn tuyệt đối hoặc là bắt đầu bằng ./|../" #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "Mô-Ä‘un-con '%s' đã dùng cho đưá»ng dẫn '%s'" + +#, c-format msgid "'%s' is not a valid submodule name" msgstr "'%s' không phải là má»™t tên mô-Ä‘un-con hợp lệ" @@ -13338,7 +13515,7 @@ msgid "delete tags" msgstr "xóa thẻ" msgid "verify tags" -msgstr "thẩm tra thẻ" +msgstr "xác minh thẻ" msgid "Tag creation options" msgstr "Tùy chá»n tạo thẻ" @@ -13356,7 +13533,7 @@ msgid "annotated and GPG-signed tag" msgstr "thẻ chú giải và ký kiểu GPG" msgid "use another key to sign the tag" -msgstr "dùng kháo khác để ký thẻ" +msgstr "dùng khoá khác để ký thẻ" msgid "replace the tag if exists" msgstr "thay thế nếu thẻ đó đã có trước" @@ -13368,7 +13545,7 @@ msgid "Tag listing options" msgstr "Các tùy chá»n liệt kê thẻ" msgid "show tag list in columns" -msgstr "hiển thị danh sách thẻ trong các cá»™t" +msgstr "hiển thị danh sách thẻ theo cá»™t" msgid "print only tags that contain the commit" msgstr "chỉ hiển thị những nhánh mà nó chứa lần chuyển giao" @@ -13503,7 +13680,7 @@ msgid "clear assumed-unchanged bit" msgstr "xóa bÃt assumed-unchanged (giả định là không thay đổi)" msgid "mark files as \"index-only\"" -msgstr "đánh dấu các táºp tin là 'chỉ-Ä‘á»c'" +msgstr "đánh dấu các táºp tin là \"chỉ-Ä‘á»c\"" msgid "clear skip-worktree bit" msgstr "xóa bÃt skip-worktree" @@ -13529,19 +13706,19 @@ msgid "add entries from standard input to the index" msgstr "không thể Ä‘á»c các mục từ stdin và o chỉ mục" msgid "repopulate stages #2 and #3 for the listed paths" -msgstr "phục hồi các trạng thái #2 và #3 cho các đưá»ng dẫn được liệt kê" +msgstr "phục hồi giai Ä‘oạn #2 và #3 cho các đưá»ng dẫn được liệt kê" msgid "only update entries that differ from HEAD" msgstr "chỉ cáºp nháºt các mục tin mà nó khác biệt so vá»›i HEAD" msgid "ignore files missing from worktree" -msgstr "bá» qua các táºp-tin thiếu trong thư-mục là m việc" +msgstr "bá» qua các táºp tin thiếu trong thư mục là m việc" msgid "report actions to standard output" msgstr "ghi các thao tác ra stdout" msgid "(for porcelains) forget saved unresolved conflicts" -msgstr "(cho 'porcelains') quên các xung đột chưa được giải quyết đã ghi" +msgstr "(cho lệnh porcelain) quên các xung đột chưa được giải quyết đã ghi" msgid "write index in this format" msgstr "ghi chỉ mục ở định dạng nà y" @@ -13603,7 +13780,7 @@ msgstr "" "sá»± muốn tắt bá»™ đệm chưa theo dõi" msgid "Untracked cache disabled" -msgstr "Nhá»› đệm không theo vết bị tắt" +msgstr "Bá»™ đệm không theo vết bị tắt" msgid "" "core.untrackedCache is set to false; remove or change it, if you really want " @@ -13639,8 +13816,8 @@ msgstr "git update-ref [<các tùy chá»n>] -d <refname> [<oid-cÅ©>]" msgid "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" msgstr "git update-ref [<các tùy chá»n>] <refname> <oid-má»›i> [<oid-cÅ©>]" -msgid "git update-ref [<options>] --stdin [-z]" -msgstr "git update-ref [<các tùy chá»n>] --stdin [-z]" +msgid "git update-ref [<options>] --stdin [-z] [--batch-updates]" +msgstr "git update-ref [<các tùy chá»n>] --stdin [-z] [--batch-updates]" msgid "delete the reference" msgstr "xóa tham chiếu" @@ -13654,8 +13831,11 @@ msgstr "stdin có các đối số được kết thúc bởi NUL" msgid "read updates from stdin" msgstr "Ä‘á»c cáºp nháºt từ stdin" +msgid "batch reference updates" +msgstr "cáºp nháºt tham chiếu theo lô" + msgid "update the info files from scratch" -msgstr "cáºp nháºt các táºp tin thông tin từ Ä‘iểm xuất phát" +msgstr "cáºp nháºt các táºp tin thông tin lại từ đầu" msgid "" "git-upload-pack [--[no-]strict] [--timeout=<n>] [--stateless-rpc]\n" @@ -13831,10 +14011,6 @@ msgid "Preparing worktree (checking out '%s')" msgstr "Äang chuẩn bị cây là m việc (Ä‘ang checkout '%s')" #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "không tham chiếu được: tham chiếu không hợp lệ: %s" - -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "Äang chuẩn bị cây là m việc (HEAD đã tách rá»i '%s')" @@ -13903,9 +14079,7 @@ msgid "show extended annotations and reasons, if available" msgstr "hiển thị chú thÃch và lý do mở rá»™ng, nếu có" msgid "add 'prunable' annotation to worktrees older than <time>" -msgstr "" -"thêm chú thÃch kiểu 'prunable' cho các cây là m việc hết hạn cÅ© hÆ¡n khoảng " -"<thá»i gian>" +msgstr "thêm chú thÃch 'prunable' cho các cây là m việc cÅ© hÆ¡n <thá»i gian>" msgid "terminate records with a NUL character" msgstr "kết thúc các bản ghi bằng ký tá»± NULL" @@ -13960,7 +14134,7 @@ msgstr "" #, c-format msgid "validation failed, cannot move working tree: %s" -msgstr "thẩm tra gặp lá»—i, không thể di chuyển má»™t cây-là m-việc: %s" +msgstr "xác minh gặp lá»—i, không thể di chuyển má»™t cây-là m-việc: %s" #, c-format msgid "failed to move '%s' to '%s'" @@ -14000,7 +14174,7 @@ msgstr "" #, c-format msgid "validation failed, cannot remove working tree: %s" -msgstr "thẩm tra gặp lá»—i, không thể gỡ bá» má»™t cây-là m-việc: %s" +msgstr "xác minh gặp lá»—i, không thể gỡ bá» má»™t cây-là m-việc: %s" #, c-format msgid "repair: %s: %s" @@ -14282,7 +14456,7 @@ msgid "Record changes to the repository" msgstr "Ghi các thay đổi và o kho chứa" msgid "Write and verify Git commit-graph files" -msgstr "Ghi và thẩm tra các táºp tin đồ há»a các lần chuyển giao Git" +msgstr "Ghi và xác minh các táºp tin đồ há»a các lần chuyển giao Git" msgid "Create a new commit object" msgstr "Tạo má»™t đối tượng chuyển giao" @@ -14334,6 +14508,9 @@ msgstr "So sánh các táºp tin trong cây là m việc và chỉ mục" msgid "Compare a tree to the working tree or index" msgstr "So sánh các cây trong cây là m việc hoặc chỉ mục" +msgid "Compare the content and mode of provided blob pairs" +msgstr "So sánh ná»™i dung và chế độ cá»§a hai blob" + msgid "Compares the content and mode of blobs found via two tree objects" msgstr "" "So sánh ná»™i dung và chế độ cá»§a các blob tìm thấy thông qua hai đối tượng cây" @@ -14370,7 +14547,7 @@ msgstr "Chuẩn bị các bản vá để gá»i qua thư Ä‘iện tá»" msgid "Verifies the connectivity and validity of the objects in the database" msgstr "" -"Thẩm tra lại tÃnh kết nối và tÃnh hiệu lá»±c cảu các đối tượng trong cÆ¡ sở dữ " +"xác minh lại tÃnh kết nối và tÃnh hiệu lá»±c cảu các đối tượng trong cÆ¡ sở dữ " "liệu" msgid "Cleanup unnecessary files and optimize the local repository" @@ -14469,7 +14646,7 @@ msgid "Build a tree-object from ls-tree formatted text" msgstr "Xây dá»±ng má»™t tree-object từ văn bản định dạng ls-tree" msgid "Write and verify multi-pack-indexes" -msgstr "Ghi và thẩm tra các multi-pack-indexes" +msgstr "Ghi và xác minh các multi-pack-indexes" msgid "Move or rename a file, a directory, or a symlink" msgstr "Di chuyển hay đổi tên má»™t táºp tin, thư mục hoặc liên kết má»m" @@ -14627,7 +14804,7 @@ msgid "Read, modify and delete symbolic refs" msgstr "Äá»c, sá»a và xóa tham chiếu má»m" msgid "Create, list, delete or verify a tag object signed with GPG" -msgstr "Tạo, liệt kê, xóa hay xác thá»±c má»™t đối tượng thẻ được ký bằng GPG" +msgstr "Tạo, liệt kê, xóa hay xác minh má»™t đối tượng thẻ được ký bằng GPG" msgid "Creates a temporary file with a blob's contents" msgstr "Tạo má»™t táºp tin tạm vá»›i ná»™i dung cá»§a blob" @@ -15041,7 +15218,7 @@ msgstr "" "'%s' và '%s')" msgid "Verifying commits in commit graph" -msgstr "Äang thẩm tra các lần chuyển giao trong đồ thị lần chuyển giao" +msgstr "Äang xác minh các lần chuyển giao trong đồ thị lần chuyển giao" #, c-format msgid "could not parse commit %s" @@ -15447,14 +15624,6 @@ msgid "bad numeric config value '%s' for '%s' in %s: %s" msgstr "sai giá trị bằng số cá»§a cấu hình '%s' cho '%s' trong %s: %s" #, c-format -msgid "invalid value for variable %s" -msgstr "giá trị không hợp lệ cho biến %s" - -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "bá» qua thà nh phần core.fsync chưa biết '%s'" - -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "sai giá trị kiểu boolean cá»§a cấu hình '%s' cho '%s'" @@ -15467,44 +15636,6 @@ msgid "'%s' for '%s' is not a valid timestamp" msgstr "'%s' dà nh cho '%s' không phải là dấu vết thá»i gian hợp lệ" #, c-format -msgid "abbrev length out of range: %d" -msgstr "chiá»u dà i abbrev nằm ngoà i phạm vi: %d" - -#, c-format -msgid "bad zlib compression level %d" -msgstr "mức nén zlib %d là sai" - -#, c-format -msgid "%s cannot contain newline" -msgstr "%s không thể chứa ký tá»± xuống dòng" - -#, c-format -msgid "%s must have at least one character" -msgstr "%s phải có Ãt nhất má»™t ký tá»±" - -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "bá» qua giá trị core.fsyncMethod chưa biết '%s'" - -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles đã lạc háºu; hãy dùng core.fsync để thay thế" - -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "chế độ không hợp lệ đối vá»›i việc tạo đối tượng: %s" - -#, c-format -msgid "malformed value for %s" -msgstr "giá trị cho %s sai dạng" - -#, c-format -msgid "malformed value for %s: %s" -msgstr "giá trị cho %s sai dạng: %s" - -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "phải là má»™t trong số nothing, matching, simple, upstream hay current" - -#, c-format msgid "unable to load config blob object '%s'" msgstr "không thể tải đối tượng blob cấu hình '%s'" @@ -16004,8 +16135,10 @@ msgstr "không thể so sánh stdin và thư mục" msgid "cannot compare a named pipe to a directory" msgstr "không thể so sánh pipe có tên và thư mục" -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<các tùy chá»n>] </đưá»ng/dẫn> </đưá»ng/dẫn>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "" +"git diff --no-index [<các tùy chá»n>] </đưá»ng/dẫn> </đưá»ng/dẫn> [<đặc tả " +"đưá»ng dẫn>...]" msgid "" "Not a git repository. Use --no-index to compare two paths outside a working " @@ -16014,6 +16147,11 @@ msgstr "" "Không phải là má»™t thư mục git. Dùng --no-index để so sánh hai đưá»ng dẫn bên " "ngoà i cây là m việc" +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "Giá»›i hạn so sánh theo đưá»ng dẫn chỉ há»— trợ vá»›i hai thư mục." + #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr " Gặp lá»—i khi Ä‘á»c phần trăm cắt bá» dirstat '%s'\n" @@ -16193,20 +16331,19 @@ msgid "synonym for --dirstat=files,<param1>,<param2>..." msgstr "đồng nghÄ©a vá»›i --dirstat=files,<tham_số_1>,<tham_số_2>..." msgid "warn if changes introduce conflict markers or whitespace errors" -msgstr "" -"cảnh báo nếu các thay đổi đưa ra các bá»™ tạo xung đột hay lá»—i khoảng trắng" +msgstr "cảnh báo nếu các thay đổi chứa dấu xung đột hay lá»—i khoảng trắng" msgid "condensed summary such as creations, renames and mode changes" -msgstr "tổng hợp dạng xúc tÃch như là tạo, đổi tên và các thay đổi chế độ" +msgstr "tổng hợp ngắn gá»n gồm việc tạo, đổi tên và thay đổi chế độ" msgid "show only names of changed files" -msgstr "chỉ hiển thị tên cá»§a các táºp tin đổi" +msgstr "chỉ hiển thị tên cá»§a các táºp tin thay đổi" msgid "show only names and status of changed files" -msgstr "chỉ hiển thị tên táºp tin và tình trạng cá»§a các táºp tin bị thay đổi" +msgstr "chỉ hiển thị tên táºp tin và trạng thái cá»§a các táºp tin thay đổi" msgid "<width>[,<name-width>[,<count>]]" -msgstr "<rá»™ng>[,<name-width>[,<số-lượng>]]" +msgstr "<độ-rá»™ng>[,<độ-rá»™ng-tên>[,<số-lượng>]]" msgid "generate diffstat" msgstr "tạo diffstat" @@ -16589,6 +16726,52 @@ msgid "bad git namespace path \"%s\"" msgstr "đưá»ng dẫn không gian tên git \"%s\" sai" #, c-format +msgid "invalid value for variable %s" +msgstr "giá trị không hợp lệ cho biến %s" + +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "bá» qua thà nh phần core.fsync chưa biết '%s'" + +#, c-format +msgid "abbrev length out of range: %d" +msgstr "chiá»u dà i abbrev nằm ngoà i phạm vi: %d" + +#, c-format +msgid "bad zlib compression level %d" +msgstr "mức nén zlib %d là sai" + +#, c-format +msgid "%s cannot contain newline" +msgstr "%s không thể chứa ký tá»± xuống dòng" + +#, c-format +msgid "%s must have at least one character" +msgstr "%s phải có Ãt nhất má»™t ký tá»±" + +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "bá» qua giá trị core.fsyncMethod chưa biết '%s'" + +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles đã lạc háºu; hãy dùng core.fsync để thay thế" + +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "chế độ không hợp lệ đối vá»›i việc tạo đối tượng: %s" + +#, c-format +msgid "malformed value for %s" +msgstr "giá trị cho %s sai dạng" + +#, c-format +msgid "malformed value for %s: %s" +msgstr "giá trị cho %s sai dạng: %s" + +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "phải là má»™t trong số nothing, matching, simple, upstream hay current" + +#, c-format msgid "too many args to run %s" msgstr "quá nhiá»u tham số để chạy %s" @@ -17207,6 +17390,10 @@ msgid "Unknown value for http.proactiveauth" msgstr "không hiểu giá trị cho http.proactiveauth" #, c-format +msgid "failed to parse %s" +msgstr "gặp lá»—i khi Ä‘á»c cú pháp %s" + +#, c-format msgid "Unsupported SSL backend '%s'. Supported SSL backends:" msgstr "" "Không há»— trợ ứng dụng SSL chạy phÃa sau '%s'. Há»— trợ ứng dụng SSL chạy phÃa " @@ -17291,6 +17478,30 @@ msgstr "không cho phép tên định danh là rá»—ng (cho <%s>)" msgid "name consists only of disallowed characters: %s" msgstr "tên chỉ được phép bao gồm các ký tá»± sau: %s" +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" + +msgid "no IMAP host specified" +msgstr "chưa chỉ ra máy chá»§ IMAP nà o" + +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"chỉ định máy chá»§ IMAP vá»›i 'git config imap.host <host>'.\n" +"(v.d., 'git config imap.host imaps://imap.example.com')" + +msgid "no IMAP folder specified" +msgstr "chưa chỉ ra thư mục IMAP nà o" + +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"chỉ định thư mục vá»›i 'git config imap.folder <folder>'.\n" +"(v.d., 'git config imap.folder Drafts')" + msgid "expected 'tree:<depth>'" msgstr "cần 'tree:<depth>'" @@ -17396,6 +17607,10 @@ msgid "invalid marker-size '%s', expecting an integer" msgstr "marker-size không hợp lệ '%s', cần số nguyên" #, c-format +msgid "Could not parse object '%s'" +msgstr "Không thể Ä‘á»c đối tượng '%s'" + +#, c-format msgid "Failed to merge submodule %s (not checked out)" msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con %s (không checkout)" @@ -17519,7 +17734,8 @@ msgstr "" #, c-format msgid "CONFLICT (rename/rename): %s renamed to %s in %s and to %s in %s." msgstr "" -"XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên %s->%s trong %s và thà nh %s trong %s." +"XUNG ÄỘT (đổi tên/đổi tên): Äổi tên %s thà nh %s trong %s và thà nh %s trong " +"%s." #, c-format msgid "" @@ -17527,14 +17743,14 @@ msgid "" "conflicts AND collides with another path; this may result in nested conflict " "markers." msgstr "" -"XUNG ÄỘT (đổi tên liên quan đến va chạm): đổi tên %s -> %s xung đột ná»™i dung " -"VÀ va chạm vá»›i má»™t đưá»ng dẫn khác; Ä‘iá»u nà y có thể dẫn đến tạo ra các xung " -"đột lồng nhau." +"XUNG ÄỘT (đổi tên cùng va chạm): đổi tên %s -> %s xung đột ná»™i dung VÀ xung " +"đột vá»›i má»™t đưá»ng dẫn khác; Ä‘iá»u nà y có thể tạo ra các dấu xung đột lồng " +"nhau." #, c-format msgid "CONFLICT (rename/delete): %s renamed to %s in %s, but deleted in %s." msgstr "" -"XUNG ÄỘT (đổi-tên/xóa): Äổi tên %s->%s trong %s, nhưng lại bị xóa trong %s." +"XUNG ÄỘT (đổi tên/xóa): Äổi tên %s->%s trong %s, nhưng lại bị xóa trong %s." #, c-format msgid "error: cannot read object %s" @@ -17634,270 +17850,6 @@ msgstr "" msgid "collecting merge info failed for trees %s, %s, %s" msgstr "thu tháºp thông tin hòa trá»™n gặp lá»—i cho cây %s, %s, %s" -msgid "(bad commit)\n" -msgstr "(commit sai)\n" - -#, c-format -msgid "add_cacheinfo failed for path '%s'; merge aborting." -msgstr "add_cacheinfo gặp lá»—i đối vá»›i đưá»ng dẫn '%s'; huá»· bá» việc hòa trá»™n." - -#, c-format -msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." -msgstr "" -"add_cacheinfo gặp lá»—i khi là m má»›i đối vá»›i đưá»ng dẫn '%s'; huá»· bá» việc hòa " -"trá»™n." - -#, c-format -msgid "failed to create path '%s'%s" -msgstr "gặp lá»—i khi tạo đưá»ng dẫn '%s'%s" - -#, c-format -msgid "Removing %s to make room for subdirectory\n" -msgstr "Gỡ bá» %s để tạo chá»— (room) cho thư mục con\n" - -msgid ": perhaps a D/F conflict?" -msgstr ": có lẽ là xung đột D/F (táºp tin/thư mục)?" - -#, c-format -msgid "refusing to lose untracked file at '%s'" -msgstr "từ chối đóng táºp tin không được theo dõi tại '%s'" - -#, c-format -msgid "blob expected for %s '%s'" -msgstr "mong đợi đối tượng blob cho %s '%s'" - -#, c-format -msgid "failed to open '%s': %s" -msgstr "gặp lá»—i khi mở '%s': %s" - -#, c-format -msgid "failed to symlink '%s': %s" -msgstr "gặp lá»—i khi tạo liên kết má»m (symlink) '%s': %s" - -#, c-format -msgid "do not know what to do with %06o %s '%s'" -msgstr "không hiểu phải là m gì vá»›i %06o %s '%s'" - -#, c-format -msgid "Failed to merge submodule %s (repository corrupt)" -msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con %s (kho chứa há»ng)" - -#, c-format -msgid "Fast-forwarding submodule %s to the following commit:" -msgstr "Chuyển-tiếp-nhanh mô-Ä‘un-con '%s' đến lần chuyển giao sau đây:" - -#, c-format -msgid "Fast-forwarding submodule %s" -msgstr "Chuyển-tiếp-nhanh mô-Ä‘un-con '%s'" - -#, c-format -msgid "Failed to merge submodule %s (merge following commits not found)" -msgstr "" -"Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (không tìm thấy các lần chuyển giao " -"theo sau hòa trá»™n)" - -#, c-format -msgid "Failed to merge submodule %s (not fast-forward)" -msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (không chuyển tiếp nhanh được)" - -msgid "Found a possible merge resolution for the submodule:\n" -msgstr "Tìm thấy má»™t giải pháp hòa trá»™n khả thi cho mô-Ä‘un-con:\n" - -#, 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 "" -"Nếu đây là đúng đơn giản thêm nó và o chỉ mục và dụ\n" -"bằng cách dùng:\n" -"\n" -" git update-index --cacheinfo 160000 %s \"%s\"\n" -"\n" -"cái mà sẽ chấp nháºn gợi ý nà y.\n" - -#, c-format -msgid "Failed to merge submodule %s (multiple merges found)" -msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (thấy nhiá»u hòa trá»™n Ä‘a trùng)" - -msgid "failed to execute internal merge" -msgstr "Gặp lá»—i khi thá»±c hiện trá»™n ná»™i bá»™" - -#, c-format -msgid "unable to add %s to database" -msgstr "Không thể thêm %s và o cÆ¡ sở dữ liệu" - -#, c-format -msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." -msgstr "" -"Lá»—i: từ chối đóng táºp tin không được theo dõi tại '%s'; thay và o đó ghi và o " -"%s." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree." -msgstr "" -"XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s cá»§a %s " -"còn lại trong cây (tree)." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " -"left in tree." -msgstr "" -"XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s " -"cá»§a %s còn lại trong cây (tree)." - -#, c-format -msgid "" -"CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " -"in tree at %s." -msgstr "" -"XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s cá»§a %s " -"còn lại trong cây (tree) tại %s." - -#, 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 "" -"XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s " -"cá»§a %s còn lại trong cây (tree) tại %s." - -msgid "rename" -msgstr "đổi tên" - -msgid "renamed" -msgstr "đã đổi tên" - -#, c-format -msgid "Refusing to lose dirty file at %s" -msgstr "Từ chối đóng táºp tin không được theo dõi tại '%s'" - -#, c-format -msgid "Refusing to lose untracked file at %s, even though it's in the way." -msgstr "" -"Từ chối đóng táºp tin không được theo dõi tại '%s', ngay cả khi nó ở trên " -"đưá»ng." - -#, c-format -msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" -msgstr "" -"XUNG ÄỘT (đổi-tên/thêm): Äổi tên %s->%s trong %s. %s được thêm trong %s" - -#, c-format -msgid "%s is a directory in %s adding as %s instead" -msgstr "%s là má»™t thư mục trong %s thay và o đó thêm và o như là %s" - -#, c-format -msgid "Refusing to lose untracked file at %s; adding as %s instead" -msgstr "" -"Từ chối đóng táºp tin không được theo dõi tại '%s'; thay và o đó Ä‘ang thêm " -"thà nh %s" - -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " -"\"%s\"->\"%s\" in \"%s\"%s" -msgstr "" -"XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên \"%s\"->\"%s\" trong nhánh \"%s\" đổi " -"tên \"%s\"->\"%s\" trong \"%s\"%s" - -msgid " (left unresolved)" -msgstr " (cần giải quyết)" - -#, c-format -msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" -msgstr "" -"XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên %s->%s trong %s. Äổi tên %s->%s trong %s" - -#, 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 "" -"XUNG ÄỘT: (phân hoá đổi tên thư mục): Không rõ đặt %s ở đâu bởi vì thư mục " -"%s đã bị đổi tên thà nh nhiá»u thư mục khác, mà không bên nà o nháºn phần lá»›n " -"các táºp tin gốc." - -#, c-format -msgid "" -"CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" -">%s in %s" -msgstr "" -"XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên thư mục %s->%s trong %s. Äổi tên thư mục " -"%s->%s trong %s" - -#, c-format -msgid "cannot read object %s" -msgstr "không thể Ä‘á»c đối tượng %s" - -#, c-format -msgid "object %s is not a blob" -msgstr "đối tượng %s không phải là má»™t blob" - -msgid "modify" -msgstr "sá»a đổi" - -msgid "modified" -msgstr "đã sá»a" - -#, c-format -msgid "Skipped %s (merged same as existing)" -msgstr "Äã bá» qua %s (đã có sẵn lần hòa trá»™n nà y)" - -#, c-format -msgid "Adding as %s instead" -msgstr "Thay và o đó thêm và o %s" - -#, c-format -msgid "Removing %s" -msgstr "Äang xóa %s" - -msgid "file/directory" -msgstr "táºp-tin/thư-mục" - -msgid "directory/file" -msgstr "thư-mục/táºp-tin" - -#, c-format -msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" -msgstr "" -"XUNG ÄỘT (%s): Ở đây không có thư mục nà o có tên %s trong %s. Thêm %s như là " -"%s" - -#, c-format -msgid "Adding %s" -msgstr "Thêm \"%s\"" - -#, c-format -msgid "CONFLICT (add/add): Merge conflict in %s" -msgstr "XUNG ÄỘT (thêm/thêm): Xung đột hòa trá»™n trong %s" - -#, c-format -msgid "merging of trees %s and %s failed" -msgstr "hòa trá»™n các cây %s và %s gặp lá»—i" - -msgid "Merging:" -msgstr "Äang trá»™n:" - -#, c-format -msgid "found %u common ancestor:" -msgid_plural "found %u common ancestors:" -msgstr[0] "tìm thấy %u tổ tiên chung:" - -msgid "merge returned no commit" -msgstr "hòa trá»™n không trả vá» lần chuyển giao nà o" - -#, c-format -msgid "Could not parse object '%s'" -msgstr "Không thể Ä‘á»c đối tượng '%s'" - msgid "failed to read the cache" msgstr "gặp lá»—i khi Ä‘á»c bá»™ nhá»› đệm" @@ -17939,12 +17891,13 @@ msgstr "không thể liên kết '%s' và o '%s'" msgid "failed to clear multi-pack-index at %s" msgstr "gặp lá»—i khi xóa multi-pack-index tại %s" -msgid "cannot write incremental MIDX with bitmap" -msgstr "không thể ghi incremental MIDX vá»›i bitmap" - msgid "ignoring existing multi-pack-index; checksum mismatch" msgstr "bá» qua multi-pack-index sẵn có; tổng kiểm không khá»›p" +#, c-format +msgid "could not load reverse index for MIDX %s" +msgstr "không thể mở chỉ mục ngược cho MIDX %s" + msgid "Adding packfiles to multi-pack-index" msgstr "Äang thêm táºp tin gói từ multi-pack-index" @@ -18104,7 +18057,7 @@ msgid "the midx contains no oid" msgstr "midx chẳng chứa oid nà o" msgid "Verifying OID order in multi-pack-index" -msgstr "Thẩm tra thứ tá»± OID trong multi-pack-index" +msgstr "xác minh thứ tá»± OID trong multi-pack-index" #, c-format msgid "oid lookup out of order: oid[%d] = %s >= %s = oid[%d]" @@ -18114,7 +18067,7 @@ msgid "Sorting objects by packfile" msgstr "Äang sắp xếp các đối tượng theo táºp tin gói" msgid "Verifying object offsets" -msgstr "Äang thẩm tra các khoảng bù đối tượng" +msgstr "Äang xác minh các khoảng bù đối tượng" #, c-format msgid "failed to load pack entry for oid[%d] = %s" @@ -18196,64 +18149,6 @@ msgid "Failed to convert object from %s to %s" msgstr "Chuyển đổi đối tượng từ %s sang %s thất bại" #, c-format -msgid "object directory %s does not exist; check .git/objects/info/alternates" -msgstr "" -"thư mục đối tượng %s không tồn tại; kiểm tra .git/objects/info/alternates" - -#, c-format -msgid "unable to normalize alternate object path: %s" -msgstr "không thể thưá»ng hóa đưá»ng dẫn đối tượng thay thế: '%s'" - -#, c-format -msgid "%s: ignoring alternate object stores, nesting too deep" -msgstr "%s: Ä‘ang bá» qua kho đối tượng thay thế, lồng nhau quá sâu" - -msgid "unable to fdopen alternates lockfile" -msgstr "không thể fdopen táºp tin khóa thay thế" - -msgid "unable to read alternates file" -msgstr "không thể Ä‘á»c táºp tin thay thế" - -msgid "unable to move new alternates file into place" -msgstr "không thể di chuyển táºp tin thay thế và o chá»—" - -#, c-format -msgid "path '%s' does not exist" -msgstr "đưá»ng dẫn '%s' không tồn tại" - -#, c-format -msgid "reference repository '%s' as a linked checkout is not supported yet." -msgstr "kho tham chiếu '%s' như là checkout liên kết vẫn chưa được há»— trợ." - -#, c-format -msgid "reference repository '%s' is not a local repository." -msgstr "kho tham chiếu '%s' không phải là má»™t kho ná»™i bá»™." - -#, c-format -msgid "reference repository '%s' is shallow" -msgstr "kho tham chiếu '%s' là nông" - -#, c-format -msgid "reference repository '%s' is grafted" -msgstr "kho tham chiếu '%s' bị cấy ghép" - -#, c-format -msgid "could not find object directory matching %s" -msgstr "không thể tìm thấy thư mục đối tượng khá»›p vá»›i '%s'" - -#, c-format -msgid "invalid line while parsing alternate refs: %s" -msgstr "dòng không hợp lệ trong khi Ä‘á»c các tham chiếu thay thế: %s" - -#, c-format -msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" -msgstr "Ä‘ang cố để mmap %<PRIuMAX> vượt quá giá»›i hạn %<PRIuMAX>" - -#, c-format -msgid "mmap failed%s" -msgstr "mmap gặp lá»—i%s" - -#, c-format msgid "object file %s is empty" msgstr "táºp tin đối tượng %s trống rá»—ng" @@ -18289,18 +18184,6 @@ msgid "loose object %s (stored in %s) is corrupt" msgstr "đối tượng mất %s (được lưu trong %s) bị há»ng" #, c-format -msgid "replacement %s not found for %s" -msgstr "c%s thay thế không được tìm thấy cho %s" - -#, c-format -msgid "packed object %s (stored in %s) is corrupt" -msgstr "đối tượng đã đóng gói %s (được lưu trong %s) bị há»ng" - -#, c-format -msgid "missing mapping of %s to %s" -msgstr "thiếu ánh xạ %s sang %s" - -#, c-format msgid "unable to open %s" msgstr "không thể mở %s" @@ -18394,10 +18277,6 @@ msgid "%s: unsupported file type" msgstr "%s: kiểu táºp tin không được há»— trợ" #, c-format -msgid "%s is not a valid '%s' object" -msgstr "%s không phải là má»™t đối tượng '%s' hợp lệ" - -#, c-format msgid "hash mismatch for %s (expected %s)" msgstr "mã băm không khá»›p cho %s (cần %s)" @@ -18407,15 +18286,19 @@ msgstr "không thể mmap %s" #, c-format msgid "unable to unpack header of %s" -msgstr "không thể giải gói phần đầu cá»§a '%s'" +msgstr "không thể giải gói phần đầu cá»§a %s" #, c-format msgid "unable to parse header of %s" -msgstr "không thể Ä‘á»c phần đầu cá»§a '%s'" +msgstr "không thể Ä‘á»c phần đầu cá»§a %s" + +#, c-format +msgid "unable to parse type from header '%s' of %s" +msgstr "không thể Ä‘á»c phần đầu '%s' cá»§a %s" #, c-format msgid "unable to unpack contents of %s" -msgstr "không thể giải gói ná»™i dung cá»§a '%s'" +msgstr "không thể giải gói ná»™i dung cá»§a %s" #. TRANSLATORS: This is a line of ambiguous object #. output shown when we cannot look up or parse the @@ -18423,7 +18306,7 @@ msgstr "không thể giải gói ná»™i dung cá»§a '%s'" #. #, c-format msgid "%s [bad object]" -msgstr "%s [đối tượng sai.]" +msgstr "%s [đối tượng sai]" #. TRANSLATORS: This is a line of ambiguous commit #. object output. E.g.: @@ -18457,7 +18340,7 @@ msgstr "%s thẻ %s - %s" #. #, c-format msgid "%s [bad tag, could not parse it]" -msgstr "%s [thẻ sai, không hiểu cú pháp nó]" +msgstr "%s [thẻ sai, không hiểu cú pháp]" #. TRANSLATORS: This is a line of ambiguous <type> #. object output. E.g. "deadbeef tree". @@ -18591,6 +18474,72 @@ msgid "hash mismatch %s" msgstr "mã băm không khá»›p %s" #, c-format +msgid "object directory %s does not exist; check .git/objects/info/alternates" +msgstr "" +"thư mục đối tượng %s không tồn tại; kiểm tra .git/objects/info/alternates" + +#, c-format +msgid "unable to normalize alternate object path: %s" +msgstr "không thể thưá»ng hóa đưá»ng dẫn đối tượng thay thế: '%s'" + +#, c-format +msgid "%s: ignoring alternate object stores, nesting too deep" +msgstr "%s: Ä‘ang bá» qua kho đối tượng thay thế, lồng nhau quá sâu" + +msgid "unable to fdopen alternates lockfile" +msgstr "không thể fdopen táºp tin khóa thay thế" + +msgid "unable to read alternates file" +msgstr "không thể Ä‘á»c táºp tin thay thế" + +msgid "unable to move new alternates file into place" +msgstr "không thể di chuyển táºp tin thay thế và o chá»—" + +#, c-format +msgid "path '%s' does not exist" +msgstr "đưá»ng dẫn '%s' không tồn tại" + +#, c-format +msgid "reference repository '%s' as a linked checkout is not supported yet." +msgstr "kho tham chiếu '%s' như là checkout liên kết vẫn chưa được há»— trợ." + +#, c-format +msgid "reference repository '%s' is not a local repository." +msgstr "kho tham chiếu '%s' không phải là má»™t kho ná»™i bá»™." + +#, c-format +msgid "reference repository '%s' is shallow" +msgstr "kho tham chiếu '%s' là nông" + +#, c-format +msgid "reference repository '%s' is grafted" +msgstr "kho tham chiếu '%s' bị cấy ghép" + +#, c-format +msgid "could not find object directory matching %s" +msgstr "không thể tìm thấy thư mục đối tượng khá»›p vá»›i '%s'" + +#, c-format +msgid "invalid line while parsing alternate refs: %s" +msgstr "dòng không hợp lệ trong khi Ä‘á»c các tham chiếu thay thế: %s" + +#, c-format +msgid "replacement %s not found for %s" +msgstr "c%s thay thế không được tìm thấy cho %s" + +#, c-format +msgid "packed object %s (stored in %s) is corrupt" +msgstr "đối tượng đã đóng gói %s (được lưu trong %s) bị há»ng" + +#, c-format +msgid "missing mapping of %s to %s" +msgstr "thiếu ánh xạ %s sang %s" + +#, c-format +msgid "%s is not a valid '%s' object" +msgstr "%s không phải là má»™t đối tượng '%s' hợp lệ" + +#, c-format msgid "duplicate entry when writing bitmap index: %s" msgstr "đối tượng trùng lặp khi ghi chỉ mục bitmap: %s" @@ -18601,9 +18550,6 @@ msgstr "đã cố ghi lần chuyển giao không được chá»n: '%s'" msgid "too many pseudo-merges" msgstr "có quá nhiá»u lần pseudo-merge" -msgid "trying to write commit not in index" -msgstr "đã thá» ghi lần chuyển giao nằm ngoà i chỉ mục" - msgid "failed to load bitmap index (corrupted?)" msgstr "không thể Ä‘á»c chỉ mục bitmap (bị há»ng?)" @@ -18845,8 +18791,20 @@ msgid "%s isn't available" msgstr "%s không sẵn có" #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "giá trị %s vượt quá %<PRIdMAX>" + +#, c-format +msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" +msgstr "giá trị %s cho %s không nằm trong khoảng [%<PRIdMAX>, %<PRIdMAX>]" + +#, c-format +msgid "%s expects an integer value with an optional k/m/g suffix" +msgstr "%s cần má»™t giá trị dạng số nguyên vá»›i háºu tố tùy chá»n k/m/g" + +#, c-format msgid "%s expects a non-negative integer value with an optional k/m/g suffix" -msgstr "%s cần má»™t giá trị dạng số không âm vá»›i má»™t háºu tố tùy chá»n k/m/g" +msgstr "%s cần má»™t giá trị dạng số không âm vá»›i háºu tố tùy chá»n k/m/g" #, c-format msgid "ambiguous option: %s (could be --%s%s or --%s%s)" @@ -19004,10 +18962,6 @@ msgid "bad boolean environment value '%s' for '%s'" msgstr "sai giá trị kiểu boolean cá»§a cấu hình '%s' cho '%s'" #, c-format -msgid "failed to parse %s" -msgstr "gặp lá»—i khi Ä‘á»c cú pháp %s" - -#, c-format msgid "failed to walk children of tree %s: not found" msgstr "gặp lá»—i khi duyệt nhánh cá»§a cây %s: không tìm thấy" @@ -19167,12 +19121,16 @@ msgid "could not fetch %s from promisor remote" msgstr "không thể tải %s từ máy chá»§ promisor" #, c-format -msgid "known remote named '%s' but with url '%s' instead of '%s'" -msgstr "có máy chá»§ '%s' nhưng vá»›i url '%s' thay vì '%s'" +msgid "no or empty URL advertised for remote '%s'" +msgstr "URL máy chá»§ '%s' rá»—ng hoặc không có" + +#, c-format +msgid "known remote named '%s' but with URL '%s' instead of '%s'" +msgstr "có máy chá»§ '%s' nhưng vá»›i URL '%s' thay vì '%s'" #, c-format msgid "unknown '%s' value for '%s' config option" -msgstr "không hiểu giá trị '%s' cho cho cấu hình '%s'" +msgstr "không hiểu giá trị '%s' cho cấu hình '%s'" #, c-format msgid "unknown element '%s' from remote info" @@ -19805,6 +19763,14 @@ msgid "%s does not point to a valid object!" msgstr "'%s' không chỉ đến má»™t lần chuyển giao hợp lệ nà o cả!" #, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr " %s%s sẽ trở thà nh không đầu sau khi xoá %s!\n" + +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s đã trở thà nh không đầu sau khi xoá %s!\n" + +#, 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" @@ -19932,6 +19898,10 @@ msgid "Checking references consistency" msgstr "Äang kiểm tra tÃnh nhất quán các tham chiếu" #, c-format +msgid "unable to open '%s'" +msgstr "không thể mở '%s'" + +#, c-format msgid "refname is dangerous: %s" msgstr "tên tham chiếu không an toà n: %s" @@ -19999,10 +19969,6 @@ msgid "refname %s is a symbolic ref, copying it is not supported" msgstr "tên tham chiếu %s là tham chiếu biểu trưng, không há»— trợ sao chép" #, c-format -msgid "invalid refspec '%s'" -msgstr "refspec không hợp lệ '%s'" - -#, c-format msgid "pattern '%s' has no '*'" msgstr "giá trị '%s' không có '*'" @@ -20540,7 +20506,7 @@ msgstr "không thể thêm enlistment" msgid "could not set recommended config" msgstr "không thể đặt cấu hình đỠnghị" -msgid "could not turn on maintenance" +msgid "could not toggle maintenance" msgstr "không thể báºt chế độ bảo trì" msgid "could not start the FSMonitor daemon" @@ -20586,12 +20552,15 @@ msgstr "tạo kho chứa trong thư mục 'src'" msgid "specify if tags should be fetched during clone" msgstr "có nên lấy vá» thẻ khi nhân bản" +msgid "specify if background maintenance should be enabled" +msgstr "có nên báºt bảo trì ná»n" + msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]" msgstr "" "scalar clone [--single-branch] [--branch <nhánh-chÃnh>] [--full-clone]\n" -"\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" +"\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]" #, c-format msgid "cannot deduce worktree name from '%s'" @@ -20629,19 +20598,33 @@ msgstr "scalar diagnose [<enlistment>]" msgid "`scalar list` does not take arguments" msgstr "`scalar list` không nháºn các tham số" -msgid "scalar register [<enlistment>]" -msgstr "scalar register [<enlistment>]" +msgid "scalar register [--[no-]maintenance] [<enlistment>]" +msgstr "scalar register [--[no-]maintenance] [<enlistment>]" msgid "reconfigure all registered enlistments" msgstr "cấu hình má»i enlistments đã đăng ký" -msgid "scalar reconfigure [--all | <enlistment>]" -msgstr "scalar reconfigure [--all | <enlistment>]" +msgid "(enable|disable|keep)" +msgstr "(enable|disable|keep)" + +msgid "signal how to adjust background maintenance" +msgstr "Ä‘iá»u chỉnh kế hoạch bảo trì ná»n" + +msgid "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<enlistment>]" +msgstr "" +"scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " +"<enlistment>]" msgid "--all or <enlistment>, but not both" msgstr "--all hoặc <enlistment>, không thể là cả hai" #, c-format +msgid "unknown mode for --maintenance option: %s" +msgstr "không hiểu chế độ cho tuỳ chá»n --maintenance: %s" + +#, c-format msgid "could not remove stale scalar.repo '%s'" msgstr "không thể xoá scalar.repo đã cÅ© '%s'" @@ -21021,11 +21004,11 @@ msgstr "không thể cáºp nháºt %s" #, c-format msgid "could not parse parent commit %s" -msgstr "không thể Ä‘á»c lần chuyển giao mẹ '%s'" +msgstr "không thể Ä‘á»c lần chuyển giao cha %s" #, c-format msgid "unknown command: %d" -msgstr "không hiểu câu lệnh %d" +msgstr "không hiểu câu lệnh: %d" msgid "This is the 1st commit message:" msgstr "Äây là chú thÃch cho lần chuyển giao thứ nhất:" @@ -21085,7 +21068,7 @@ msgstr "không thể lấy ghi chú lần chuyển giao cho %s" #. "revert" or "pick", the second %s a SHA1. #, c-format msgid "%s: cannot parse parent commit %s" -msgstr "%s: không thể Ä‘á»c lần chuyển giao mẹ cá»§a %s" +msgstr "%s: không thể Ä‘á»c lần chuyển giao cha cá»§a %s" #, c-format msgid "could not revert %s... %s" @@ -22075,6 +22058,9 @@ msgstr "dá»n cây nhá»› tạm trước má»—i chu kỳ" msgid "number of entries in the cache tree to invalidate (default 0)" msgstr "số mục cần huá»· trong câu nhá»› tạm (mặc định 0)" +msgid "the number of objects to write" +msgstr "số đối tượng tối thiểu cần ghi" + msgid "test-tool path-walk <options> -- <revision-options>" msgstr "test-tool path-walk <tuỳ chá»n> -- <tuỳ chá»n cải biên>" @@ -22093,6 +22079,9 @@ msgstr "bao gồm các đối tượng cây" msgid "toggle pruning of uninteresting paths" msgstr "lược bá» những đưá»ng dẫn Ãt ý nghÄ©a" +msgid "toggle aggressive edge walk" +msgstr "duyệt cạnh tÃch cá»±c" + msgid "read a pattern list over stdin" msgstr "Ä‘á»c các mẫu từ stdin" @@ -22741,6 +22730,23 @@ msgid "warning: " msgstr "cảnh báo: " #, c-format +msgid "" +"'%s' 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 "" +"'%s' đã được đỠcỠđể loại bá».\n" +"Nếu bạn vẫn còn sá» dụng lệnh nà y, vui lòng bổ sung\n" +"thêm má»™t tùy chá»n, '--i-still-use-this', trên dòng lệnh\n" +"và cho chúng tôi biết bạn vẫn sá» dụng nó bằng cách gá»i e-mail\n" +"đến <git@vger.kernel.org>. Xin cảm Æ¡n.\n" + +msgid "refusing to run without --i-still-use-this" +msgstr "từ chối chạy lệnh nà y mà không có --i-still-use-this" + +#, c-format msgid "uname() failed with error '%s' (%d)\n" msgstr "uname() gặp lá»—i '%s' (%d)\n" @@ -22860,6 +22866,14 @@ msgstr "không thể lấy thư mục là m việc hiện hà nh" msgid "unable to get random bytes" msgstr "không thể lấy byte ngẫu nhiên" +#, c-format +msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" +msgstr "Ä‘ang cố để mmap %<PRIuMAX> vượt quá giá»›i hạn %<PRIuMAX>" + +#, c-format +msgid "mmap failed%s" +msgstr "mmap gặp lá»—i%s" + msgid "Unmerged paths:" msgstr "Những đưá»ng dẫn chưa được hòa trá»™n:" @@ -23606,6 +23620,13 @@ msgstr "" "Không thể khởi tạo SMTP đúng cách. Kiểm tra cấu hình và dùng --smtp-debug." #, perl-format +msgid "Outlook reassigned Message-ID to: %s\n" +msgstr "Outlook đổi Message-ID thà nh: %s\n" + +msgid "Warning: Could not retrieve Message-ID from server response.\n" +msgstr "Cảnh báo: Không thể lấy Message-ID từ máy chá»§.\n" + +#, perl-format msgid "Failed to send %s\n" msgstr "Gặp lá»—i khi gá»i %s\n" @@ -23650,6 +23671,10 @@ msgid "(body) Adding cc: %s from line '%s'\n" msgstr "(body) Thêm cc: %s từ dòng '%s'\n" #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "lá»—i: SMTP port không hợp lệ '%s'\n" + +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) Không thể thá»±c thi '%s'" @@ -23702,6 +23727,332 @@ msgstr "Bá» qua %s vá»›i háºu tố sao lưu '%s'.\n" msgid "Do you really want to send %s? [y|N]: " msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " +#~ msgid "start-after" +#~ msgstr "start-after" + +#~ msgid "compact-summary" +#~ msgstr "tổng hợp tóm lược" + +#~ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" +#~ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <đối_tượng>" + +#~ msgid "allow -s and -t to work with broken/corrupt objects" +#~ msgstr "cho phép -s và -t để là m việc vá»›i các đối tượng sai/há»ng" + +#, c-format +#~ msgid " (%s will become dangling)" +#~ msgstr " (%s sẽ trở thà nh không đầu (không được quản lý))" + +#, c-format +#~ msgid " (%s has become dangling)" +#~ msgstr " (%s đã trở thà nh không đầu (không được quản lý))" + +#, c-format +#~ msgid "%s: object is of unknown type '%s': %s" +#~ msgstr "%s: đối tượng có kiểu chưa biết '%s': %s" + +#~ msgid "use at most one of --auto and --schedule=<frequency>" +#~ msgstr "dùng nhiá»u nhất là má»™t trong --auto và --schedule=<frequency>" + +#, c-format +#~ msgid "Final output: %d %s\n" +#~ msgstr "Äầu ra cuối cùng: %d %s\n" + +#, c-format +#~ msgid "%d (FSCK_IGNORE?) should never trigger this callback" +#~ msgstr "%d (FSCK_IGNORE?) không bao giá» nên kÃch hoạt callback nà y" + +#~ msgid "" +#~ "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" +#~ msgstr "" +#~ "git pack-objects --stdout [<các tùy chá»n>] [< <danh-sách-tham-chiếu> | < " +#~ "<danh-sách-đối-tượng>]" + +#~ msgid "" +#~ "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +#~ msgstr "" +#~ "git pack-objects [<các tùy chá»n>] <base-name> [< <danh-sách-ref> | < " +#~ "<danh-sách-đối-tượng>]" + +#~ msgid "cannot use --stdin-packs with --cruft" +#~ msgstr "không thể dùng tùy chá»n --stdin-packs vá»›i --cruft" + +#, c-format +#~ msgid "%s points nowhere!" +#~ msgstr "%s chẳng chỉ đến đâu cả!" + +#, c-format +#~ msgid "unreachable: invalid reference: %s" +#~ msgstr "không tham chiếu được: tham chiếu không hợp lệ: %s" + +#~ msgid "(bad commit)\n" +#~ msgstr "(commit sai)\n" + +#, c-format +#~ msgid "add_cacheinfo failed for path '%s'; merge aborting." +#~ msgstr "add_cacheinfo gặp lá»—i đối vá»›i đưá»ng dẫn '%s'; huá»· bá» việc hòa trá»™n." + +#, c-format +#~ msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." +#~ msgstr "" +#~ "add_cacheinfo gặp lá»—i khi là m má»›i đối vá»›i đưá»ng dẫn '%s'; huá»· bá» việc hòa " +#~ "trá»™n." + +#, c-format +#~ msgid "failed to create path '%s'%s" +#~ msgstr "gặp lá»—i khi tạo đưá»ng dẫn '%s'%s" + +#, c-format +#~ msgid "Removing %s to make room for subdirectory\n" +#~ msgstr "Gỡ bá» %s để tạo chá»— (room) cho thư mục con\n" + +#~ msgid ": perhaps a D/F conflict?" +#~ msgstr ": có lẽ là xung đột D/F (táºp tin/thư mục)?" + +#, c-format +#~ msgid "refusing to lose untracked file at '%s'" +#~ msgstr "từ chối đóng táºp tin không được theo dõi tại '%s'" + +#, c-format +#~ msgid "blob expected for %s '%s'" +#~ msgstr "mong đợi đối tượng blob cho %s '%s'" + +#, c-format +#~ msgid "failed to open '%s': %s" +#~ msgstr "gặp lá»—i khi mở '%s': %s" + +#, c-format +#~ msgid "failed to symlink '%s': %s" +#~ msgstr "gặp lá»—i khi tạo liên kết má»m (symlink) '%s': %s" + +#, c-format +#~ msgid "do not know what to do with %06o %s '%s'" +#~ msgstr "không hiểu phải là m gì vá»›i %06o %s '%s'" + +#, c-format +#~ msgid "Failed to merge submodule %s (repository corrupt)" +#~ msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con %s (kho chứa há»ng)" + +#, c-format +#~ msgid "Fast-forwarding submodule %s to the following commit:" +#~ msgstr "Chuyển-tiếp-nhanh mô-Ä‘un-con '%s' đến lần chuyển giao sau đây:" + +#, c-format +#~ msgid "Fast-forwarding submodule %s" +#~ msgstr "Chuyển-tiếp-nhanh mô-Ä‘un-con '%s'" + +#, c-format +#~ msgid "Failed to merge submodule %s (merge following commits not found)" +#~ msgstr "" +#~ "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (không tìm thấy các lần chuyển giao " +#~ "theo sau hòa trá»™n)" + +#, c-format +#~ msgid "Failed to merge submodule %s (not fast-forward)" +#~ msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (không chuyển tiếp nhanh được)" + +#~ msgid "Found a possible merge resolution for the submodule:\n" +#~ msgstr "Tìm thấy má»™t giải pháp hòa trá»™n khả thi cho mô-Ä‘un-con:\n" + +#, 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 "" +#~ "Nếu đây là đúng đơn giản thêm nó và o chỉ mục và dụ\n" +#~ "bằng cách dùng:\n" +#~ "\n" +#~ " git update-index --cacheinfo 160000 %s \"%s\"\n" +#~ "\n" +#~ "cái mà sẽ chấp nháºn gợi ý nà y.\n" + +#, c-format +#~ msgid "Failed to merge submodule %s (multiple merges found)" +#~ msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con '%s' (thấy nhiá»u hòa trá»™n Ä‘a trùng)" + +#~ msgid "failed to execute internal merge" +#~ msgstr "Gặp lá»—i khi thá»±c hiện trá»™n ná»™i bá»™" + +#, c-format +#~ msgid "unable to add %s to database" +#~ msgstr "Không thể thêm %s và o cÆ¡ sở dữ liệu" + +#, c-format +#~ msgid "Error: Refusing to lose untracked file at %s; writing to %s instead." +#~ msgstr "" +#~ "Lá»—i: từ chối đóng táºp tin không được theo dõi tại '%s'; thay và o đó ghi " +#~ "và o %s." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " +#~ "left in tree." +#~ msgstr "" +#~ "XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s cá»§a %s " +#~ "còn lại trong cây (tree)." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of " +#~ "%s left in tree." +#~ msgstr "" +#~ "XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s " +#~ "cá»§a %s còn lại trong cây (tree)." + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s " +#~ "left in tree at %s." +#~ msgstr "" +#~ "XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s trong %s. Phiên bản %s cá»§a %s " +#~ "còn lại trong cây (tree) tại %s." + +#, 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 "" +#~ "XUNG ÄỘT (%s/xóa): %s bị xóa trong %s và %s đến %s trong %s. Phiên bản %s " +#~ "cá»§a %s còn lại trong cây (tree) tại %s." + +#~ msgid "rename" +#~ msgstr "đổi tên" + +#~ msgid "renamed" +#~ msgstr "đã đổi tên" + +#, c-format +#~ msgid "Refusing to lose dirty file at %s" +#~ msgstr "Từ chối đóng táºp tin không được theo dõi tại '%s'" + +#, c-format +#~ msgid "Refusing to lose untracked file at %s, even though it's in the way." +#~ msgstr "" +#~ "Từ chối đóng táºp tin không được theo dõi tại '%s', ngay cả khi nó ở trên " +#~ "đưá»ng." + +#, c-format +#~ msgid "CONFLICT (rename/add): Rename %s->%s in %s. Added %s in %s" +#~ msgstr "" +#~ "XUNG ÄỘT (đổi-tên/thêm): Äổi tên %s->%s trong %s. %s được thêm trong %s" + +#, c-format +#~ msgid "%s is a directory in %s adding as %s instead" +#~ msgstr "%s là má»™t thư mục trong %s thay và o đó thêm và o như là %s" + +#, c-format +#~ msgid "Refusing to lose untracked file at %s; adding as %s instead" +#~ msgstr "" +#~ "Từ chối đóng táºp tin không được theo dõi tại '%s'; thay và o đó Ä‘ang thêm " +#~ "thà nh %s" + +#, c-format +#~ msgid "" +#~ "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename " +#~ "\"%s\"->\"%s\" in \"%s\"%s" +#~ msgstr "" +#~ "XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên \"%s\"->\"%s\" trong nhánh \"%s\" đổi " +#~ "tên \"%s\"->\"%s\" trong \"%s\"%s" + +#~ msgid " (left unresolved)" +#~ msgstr " (cần giải quyết)" + +#, c-format +#~ msgid "CONFLICT (rename/rename): Rename %s->%s in %s. Rename %s->%s in %s" +#~ msgstr "" +#~ "XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên %s->%s trong %s. Äổi tên %s->%s trong " +#~ "%s" + +#, 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 "" +#~ "XUNG ÄỘT: (phân hoá đổi tên thư mục): Không rõ đặt %s ở đâu bởi vì thư " +#~ "mục %s đã bị đổi tên thà nh nhiá»u thư mục khác, mà không bên nà o nháºn phần " +#~ "lá»›n các táºp tin gốc." + +#, c-format +#~ msgid "" +#~ "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory " +#~ "%s->%s in %s" +#~ msgstr "" +#~ "XUNG ÄỘT (đổi-tên/đổi-tên): Äổi tên thư mục %s->%s trong %s. Äổi tên thư " +#~ "mục %s->%s trong %s" + +#, c-format +#~ msgid "cannot read object %s" +#~ msgstr "không thể Ä‘á»c đối tượng %s" + +#, c-format +#~ msgid "object %s is not a blob" +#~ msgstr "đối tượng %s không phải là má»™t blob" + +#~ msgid "modify" +#~ msgstr "sá»a đổi" + +#~ msgid "modified" +#~ msgstr "đã sá»a" + +#, c-format +#~ msgid "Skipped %s (merged same as existing)" +#~ msgstr "Äã bá» qua %s (đã có sẵn lần hòa trá»™n nà y)" + +#, c-format +#~ msgid "Adding as %s instead" +#~ msgstr "Thay và o đó thêm và o %s" + +#, c-format +#~ msgid "Removing %s" +#~ msgstr "Äang xóa %s" + +#~ msgid "file/directory" +#~ msgstr "táºp-tin/thư-mục" + +#~ msgid "directory/file" +#~ msgstr "thư-mục/táºp-tin" + +#, c-format +#~ msgid "" +#~ "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" +#~ msgstr "" +#~ "XUNG ÄỘT (%s): Ở đây không có thư mục nà o có tên %s trong %s. Thêm %s như " +#~ "là %s" + +#, c-format +#~ msgid "Adding %s" +#~ msgstr "Thêm \"%s\"" + +#, c-format +#~ msgid "CONFLICT (add/add): Merge conflict in %s" +#~ msgstr "XUNG ÄỘT (thêm/thêm): Xung đột hòa trá»™n trong %s" + +#, c-format +#~ msgid "merging of trees %s and %s failed" +#~ msgstr "hòa trá»™n các cây %s và %s gặp lá»—i" + +#~ msgid "Merging:" +#~ msgstr "Äang trá»™n:" + +#, c-format +#~ msgid "found %u common ancestor:" +#~ msgid_plural "found %u common ancestors:" +#~ msgstr[0] "tìm thấy %u tổ tiên chung:" + +#~ msgid "merge returned no commit" +#~ msgstr "hòa trá»™n không trả vá» lần chuyển giao nà o" + +#~ msgid "cannot write incremental MIDX with bitmap" +#~ msgstr "không thể ghi incremental MIDX vá»›i bitmap" + +#~ msgid "trying to write commit not in index" +#~ msgstr "đã thá» ghi lần chuyển giao nằm ngoà i chỉ mục" + #, c-format #~ msgid "Could not find remote branch %s to clone." #~ msgstr "Không tìm thấy nhánh máy chá»§ %s để nhân bản (clone)." @@ -23710,9 +24061,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "merging cannot continue; got unclean result of %d" #~ msgstr "không thể tiếp tục hoà trá»™n; kết quả không hoà n toà n %d" -#~ msgid "git repack [<options>]" -#~ msgstr "git repack [<các tùy chá»n>]" - #~ msgid "--onto and --advance are incompatible" #~ msgstr "--onto và --advance xung khắc" diff --git a/po/zh_CN.po b/po/zh_CN.po index 139ae331dc..a0d43c5333 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -155,8 +155,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-06-08 20:30+0800\n" -"PO-Revision-Date: 2025-06-12 14:50+0800\n" +"POT-Creation-Date: 2025-08-12 20:20-0400\n" +"PO-Revision-Date: 2025-08-17 08:14-0400\n" "Last-Translator: Teng Long <dyroneteng@gmail.com>\n" "Language-Team: GitHub <https://github.com/dyrone/git/>\n" "Language: zh_CN\n" @@ -168,6 +168,11 @@ msgstr "" #: add-interactive.c #, c-format +msgid "%s cannot be negative" +msgstr "%s ä¸èƒ½ä¸ºè´Ÿæ•°" + +#: add-interactive.c +#, c-format msgid "Huh (%s)?" msgstr "嗯(%s)?" @@ -1074,10 +1079,10 @@ msgstr "未能识别的空白å—符忽略选项 '%s'" #: builtin/describe.c builtin/diff-tree.c builtin/difftool.c #: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c #: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c -#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c -#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-parse.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: builtin/merge-tree.c builtin/merge.c builtin/rebase.c builtin/repack.c +#: builtin/replay.c builtin/reset.c builtin/rev-parse.c builtin/show-branch.c +#: builtin/stash.c builtin/submodule--helper.c builtin/tag.c builtin/worktree.c +#: parse-options.c range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "选项 '%s' å’Œ '%s' ä¸èƒ½åŒæ—¶ä½¿ç”¨" @@ -2459,6 +2464,12 @@ msgstr "å¦‚æžœæ‚¨ç¡®å®žæƒ³æ·»åŠ å®ƒä»¬ï¼Œè¯·ä½¿ç”¨ -f 选项。" msgid "adding files failed" msgstr "æ·»åŠ æ–‡ä»¶å¤±è´¥" +#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c +#: builtin/stash.c +#, c-format +msgid "'%s' cannot be negative" +msgstr "'%s' ä¸èƒ½ä¸ºè´Ÿæ•°" + #: builtin/add.c #, c-format msgid "--chmod param '%s' must be either -x or +x" @@ -2497,7 +2508,7 @@ msgid "bad action '%s' for '%s'" msgstr "'%2$s' 的错误动作 '%1$s'" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c +#: builtin/pull.c builtin/revert.c diff-merges.c environment.c gpg-interface.c #: ls-refs.c parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" @@ -3819,8 +3830,8 @@ msgstr "HEAD 没有ä½äºŽ /refs/heads 之下ï¼" #: builtin/branch.c msgid "" -"branch with --recurse-submodules can only be used if " -"submodule.propagateBranches is enabled" +"branch with --recurse-submodules can only be used if submodule." +"propagateBranches is enabled" msgstr "" "带有 --recurse-submodules 的分支åªèƒ½åœ¨ submodule.propagateBranches å¯ç”¨æ—¶ä½¿ç”¨" @@ -3963,8 +3974,8 @@ msgstr "" "请检查下é¢é”™è¯¯æŠ¥å‘Šä¸ä½™ä¸‹çš„内容。\n" "您å¯ä»¥åˆ é™¤ä»»ä½•æ‚¨ä¸æƒ³å…±äº«çš„内容。\n" -#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c -#: parse-options.h +#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c +#: builtin/pack-objects.c builtin/rebase.c parse-options.h msgid "mode" msgstr "模å¼" @@ -6373,25 +6384,26 @@ msgstr "git config list [<文件选项>] [<显示选项>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" "git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp] [--" -"value=<值>] [--fixed-value] [--default=<默认值>] <åç§°>" +"value=<模å¼>] [--fixed-value] [--default=<默认值>] [--url=<url>] <åç§°>" #: builtin/config.c msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<文件选项>] [--type=<类型>] [--all] [--value=<值>] [--fixed-" -"value] <åç§°> <值>" +"git config set [<文件选项>] [--type=<类型>] [--all] [--value=<模å¼>] [--" +"fixed-value] <åç§°> <值>" #: builtin/config.c msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<文件选项>] [--all] [--value=<值>] [--fixed-value] <åç§°>" +"git config unset [<文件选项>] [--all] [--value=<模å¼>] [--fixed-value] <åç§°>" #: builtin/config.c msgid "git config rename-section [<file-option>] <old-name> <new-name>" @@ -6412,19 +6424,19 @@ msgstr "git config [<文件选项>] --get-colorbool <åç§°> [<æ ‡å‡†è¾“å‡ºä¸ºtt #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" "git config get [<文件选项>] [<显示选项>] [--includes] [--all] [--regexp=<æ£åˆ™" -"表达å¼>] [--value=<值>] [--fixed-value] [--default=<默认值>] <åç§°>" +"表达å¼>] [--value=<模å¼>] [--fixed-value] [--default=<默认值>] <åç§°>" #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" "git config set [<文件选项>] [--type=<类型>] [--comment=<消æ¯>] [--all] [--" -"value=<值>] [--fixed-value] <åç§°> <值>" +"value=<模å¼>] [--fixed-value] <åç§°> <值>" #: builtin/config.c msgid "Config file location" @@ -7046,7 +7058,7 @@ msgstr "ä¸èƒ½è§£æžæ¨¡å¼ï¼š%s" #: builtin/diff-pairs.c #, c-format msgid "unable to parse object id: %s" -msgstr "ä¸èƒ½è§£æžå¯¹è±¡ID:%s" +msgstr "ä¸èƒ½è§£æžå¯¹è±¡ ID:%s" #: builtin/diff-pairs.c msgid "git diff-pairs -z [<diff-options>]" @@ -7493,27 +7505,6 @@ msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "æ‹’ç» %s å› ä¸ºæµ…å…‹éš†çš„æ ¹ä¸å…许被更新" #: builtin/fetch.c -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"一些本地引用ä¸èƒ½è¢«æ›´æ–°ï¼›å°è¯•è¿è¡Œ\n" -" 'git remote prune %s' æ¥åˆ é™¤æ—§çš„ã€æœ‰å†²çªçš„分支" - -# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/fetch.c -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s å°†æˆä¸ºæ‚¬ç©ºçжæ€ï¼‰" - -# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/fetch.c -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s å·²æˆä¸ºæ‚¬ç©ºçжæ€ï¼‰" - -#: builtin/fetch.c msgid "[deleted]" msgstr "[å·²åˆ é™¤]" @@ -7536,7 +7527,7 @@ msgstr "选项 \"%s\" 的值 \"%s\" 对于 %s æ˜¯æ— æ•ˆçš„" msgid "option \"%s\" is ignored for %s" msgstr "选项 \"%s\" 为 %s 所忽略" -#: builtin/fetch.c object-store.c +#: builtin/fetch.c odb.c #, c-format msgid "%s is not a valid object" msgstr "%s 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„对象" @@ -7561,6 +7552,20 @@ msgstr "" "以ç¦ç”¨è¯¥è¦å‘Šï¼Œç›´åˆ°è¿œç¨‹å°† HEAD 更改为其他内容。" #: builtin/fetch.c +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"一些本地引用ä¸èƒ½è¢«æ›´æ–°ï¼›å°è¯•è¿è¡Œ\n" +" 'git remote prune %s' æ¥åˆ é™¤æ—§çš„ã€æœ‰å†²çªçš„分支" + +#: builtin/fetch.c +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "获å–引用 %s 失败:%s" + +#: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "检测到多分支,和 --set-upstream ä¸å…¼å®¹" @@ -7799,8 +7804,8 @@ msgstr "åè®®ä¸æ”¯æŒ --negotiate-only,退出" #: builtin/fetch.c msgid "" -"--filter can only be used with the remote configured in " -"extensions.partialclone" +"--filter can only be used with the remote configured in extensions." +"partialclone" msgstr "åªå¯ä»¥å°† --filter 用于在 extensions.partialclone ä¸é…置的远程仓库" #: builtin/fetch.c @@ -7857,6 +7862,10 @@ msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<æäº¤>]] [--no-contains [<æäº¤>]]" #: builtin/for-each-ref.c +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <æ ‡è®°>]" + +#: builtin/for-each-ref.c msgid "quote placeholders suitably for shells" msgstr "引用å ä½ç¬¦é€‚用于 shells" @@ -7876,6 +7885,14 @@ msgstr "引用å ä½ç¬¦é€‚用于 Tcl" msgid "show only <n> matched refs" msgstr "åªæ˜¾ç¤º <n> 个匹é…的引用" +#: builtin/for-each-ref.c +msgid "marker" +msgstr "æ ‡è®°" + +#: builtin/for-each-ref.c +msgid "start iteration after the provided marker" +msgstr "ä»ŽæŒ‡å®šæ ‡è®°ä¹‹åŽå¼€å§‹è¿ä»£" + #: builtin/for-each-ref.c builtin/tag.c msgid "respect format colors" msgstr "éµç…§æ ¼å¼ä¸çš„颜色输出" @@ -7909,9 +7926,17 @@ msgid "also include HEAD ref and pseudorefs" msgstr "还包括 HEAD 引用和伪引用" #: builtin/for-each-ref.c +msgid "cannot use --start-after with custom sort options" +msgstr "ä¸èƒ½å°† --start-after 与自定义排åºé€‰é¡¹ä¸€åŒä½¿ç”¨" + +#: builtin/for-each-ref.c msgid "unknown arguments supplied with --stdin" msgstr "为 --stdin æä¾›äº†æœªçŸ¥çš„命令傿•°" +#: builtin/for-each-ref.c +msgid "cannot use --start-after with patterns" +msgstr "ä¸èƒ½å°† --start-after 与模å¼åŒ¹é…一åŒä½¿ç”¨" + #: builtin/for-each-repo.c msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<é…ç½®> [--] <命令傿•°>" @@ -8414,6 +8439,10 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "用于å˜å‚¨ä¿®å‰ªå¯¹è±¡çš„包å‰ç¼€" #: builtin/gc.c +msgid "skip maintenance tasks typically done in the foreground" +msgstr "跳过通常在å‰å°æ‰§è¡Œçš„维护任务" + +#: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "æ— æ³•è§£æž gc.logExpiry 的值 %s" @@ -8500,13 +8529,13 @@ msgstr "跳过增é‡é‡æ–°æ‰“åŒ…ä»»åŠ¡ï¼Œå› ä¸º core.multiPackIndex 被ç¦ç”¨" #: builtin/gc.c #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "锿–‡ä»¶ '%s' å·²å˜åœ¨ï¼Œè·³è¿‡ç»´æŠ¤" +msgid "task '%s' failed" +msgstr "任务 '%s' 失败" #: builtin/gc.c #, c-format -msgid "task '%s' failed" -msgstr "任务 '%s' 失败" +msgid "lock file '%s' exists, skipping maintenance" +msgstr "锿–‡ä»¶ '%s' å·²å˜åœ¨ï¼Œè·³è¿‡ç»´æŠ¤" #: builtin/gc.c #, c-format @@ -8547,10 +8576,6 @@ msgid "run a specific task" msgstr "è¿è¡Œä¸€ä¸ªç‰¹å®šçš„任务" #: builtin/gc.c -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "最多使用 --auto å’Œ --schedule=<频率> å…¶ä¸ä¹‹ä¸€" - -#: builtin/gc.c #, c-format msgid "unable to add '%s' value of '%s'" msgstr "æ— æ³•æ·»åŠ '%2$s' çš„ '%1$s' 值" @@ -9651,11 +9676,6 @@ msgstr "-L<范围>:<文件> ä¸èƒ½å’Œè·¯å¾„表达å¼å…±ç”¨" #: builtin/log.c #, c-format -msgid "Final output: %d %s\n" -msgstr "最终输出:%d %s\n" - -#: builtin/log.c -#, c-format msgid "git show %s: bad file" msgstr "git show %s: æŸå的文件" @@ -10562,6 +10582,10 @@ msgid "(synonym to --stat)" msgstr "(和 --stat åŒä¹‰ï¼‰" #: builtin/merge.c builtin/pull.c +msgid "show a compact-summary at the end of the merge" +msgstr "在åˆå¹¶ç»“æŸæ—¶æ˜¾ç¤ºç®€æ´æ‘˜è¦" + +#: builtin/merge.c builtin/pull.c msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "在åˆå¹¶æäº¤ä¿¡æ¯ä¸æ·»åŠ ï¼ˆæœ€å¤š <n> æ¡ï¼‰ç²¾ç®€æäº¤è®°å½•" @@ -10890,11 +10914,6 @@ msgstr "é”™è¯¯ï¼šæ ‡ç¾è¾“入未通过 fsck:%s" #: builtin/mktag.c #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) 永远ä¸åº”该触å‘这个回调" - -#: builtin/mktag.c -#, c-format msgid "could not read tagged object '%s'" msgstr "ä¸èƒ½è¯»å–è¢«æ ‡è®°çš„å¯¹è±¡ '%s'" @@ -11537,13 +11556,26 @@ msgid "unknown subcommand: `%s'" msgstr "未知å命令:`%s'" #: builtin/pack-objects.c -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "git pack-objects --stdout [<选项>] [< <引用列表> | < <对象列表>]" - -#: builtin/pack-objects.c msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "git pack-objects [<选项>] <å‰ç¼€åç§°> [< <引用列表> | < <对象列表>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<包å>]\n" +" [--cruft] [--cruft-expiration=<æ—¶é—´>]\n" +" [--stdout [--filter=<è¿‡æ»¤è§„æ ¼>] | <基线åç§°>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\"\n" +" [--name-hash-version=<n>] [--path-walk] < <对象列表>" #: builtin/pack-objects.c #, c-format @@ -11672,6 +11704,17 @@ msgid "unable to get type of object %s" msgstr "æ— æ³•èŽ·å¾—å¯¹è±¡ %s 类型" #: builtin/pack-objects.c +msgid "Compressing objects by path" +msgstr "按路径压缩对象" + +#: builtin/pack-objects.c +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "基于路径的差值压缩,最多使用 %d 个线程" +msgstr[1] "基于路径的差值压缩,最多使用 %d 个线程" + +#: builtin/pack-objects.c msgid "Compressing objects" msgstr "压缩对象ä¸" @@ -11762,6 +11805,10 @@ msgid "unable to force loose object" msgstr "æ— æ³•å¼ºåˆ¶æ¾æ•£å¯¹è±¡" #: builtin/pack-objects.c +msgid "failed to pack objects via path-walk" +msgstr "通过 path-walk 打包对象失败" + +#: builtin/pack-objects.c #, c-format msgid "not a rev '%s'" msgstr "䏿˜¯ä¸€ä¸ªç‰ˆæœ¬ '%s'" @@ -11906,6 +11953,10 @@ msgid "create thin packs" msgstr "创建精简包" #: builtin/pack-objects.c +msgid "use the path-walk API to walk objects when possible" +msgstr "在å¯èƒ½çš„æƒ…况下使用 path-walk API é历对象" + +#: builtin/pack-objects.c msgid "create packs suitable for shallow fetches" msgstr "åˆ›å»ºé€‚åˆæµ…克隆仓库获å–的包" @@ -11975,7 +12026,12 @@ msgstr "增é‡é“¾æ·±åº¦ %d 太深了,强制为 %d" msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "é…ç½® pack.deltaCacheLimit 太高了,强制为 %d" -#: builtin/pack-objects.c config.c +#: builtin/pack-objects.c +#, c-format +msgid "cannot use %s with %s" +msgstr "ä¸èƒ½å°† %s 与 %s 一åŒä½¿ç”¨" + +#: builtin/pack-objects.c environment.c #, c-format msgid "bad pack compression level %d" msgstr "错误的打包压缩级别 %d" @@ -11993,10 +12049,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ä¸èƒ½ç”¨äºŽåˆ›å»ºä¸€ä¸ªå¯ç´¢å¼•包" #: builtin/pack-objects.c -msgid "cannot use --filter with --stdin-packs" -msgstr "ä¸èƒ½åŒæ—¶ä½¿ç”¨ --filter å’Œ --stdin-packs" - -#: builtin/pack-objects.c msgid "cannot use internal rev list with --stdin-packs" msgstr "ä¸èƒ½åŒæ—¶ä½¿ç”¨å†…部版本列表和 --stdin-packs" @@ -12005,10 +12057,6 @@ msgid "cannot use internal rev list with --cruft" msgstr "ä¸èƒ½åŒæ—¶ä½¿ç”¨å†…部版本列表和 --cruft" #: builtin/pack-objects.c -msgid "cannot use --stdin-packs with --cruft" -msgstr "ä¸èƒ½å°† --stdin-packs å’Œ --cruft åŒæ—¶ä½¿ç”¨" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "枚举对象ä¸" @@ -12021,23 +12069,6 @@ msgstr "" "总共 %<PRIu32>(差异 %<PRIu32>),å¤ç”¨ %<PRIu32>(差异 %<PRIu32>),包å¤ç”¨ " "%<PRIu32>(æ¥è‡ª %<PRIuMAX> 个包)" -#: builtin/pack-redundant.c -msgid "" -"'git pack-redundant' is nominated for removal.\n" -"If you still use this command, please add an extra\n" -"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 "" -"准备移除 'git pack-redundant' å‘½ä»¤ã€‚å¦‚æžœæ‚¨ä»æ—§ä½¿ç”¨è¿™ä¸ª\n" -"å‘½ä»¤ï¼Œè¯·åœ¨å‘½ä»¤è¡Œä¸æ·»åŠ é¢å¤–傿•°ï¼š'--i-still-use-this',\n" -"并通过å‘é€é‚®ä»¶åˆ° <git@vger.kernel.org> è®©æˆ‘ä»¬çŸ¥é“æ‚¨ä»æ—§\n" -"使用它。 谢谢。\n" - -#: builtin/pack-redundant.c -msgid "refusing to run without --i-still-use-this" -msgstr "æ‹’ç»åœ¨æœªæŒ‡å®š --i-still-use-this 选项时è¿è¡Œ" - #: builtin/pack-refs.c msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " @@ -12395,8 +12426,8 @@ msgid "" "upstream, see 'push.autoSetupRemote' in 'git help config'.\n" msgstr "" "\n" -"为了让没有追踪上游的分支自动é…置,å‚è§ 'git help config' ä¸çš„ " -"push.autoSetupRemote。\n" +"为了让没有追踪上游的分支自动é…置,å‚è§ 'git help config' ä¸çš„ 'push." +"autoSetupRemote'。\n" #: builtin/push.c #, c-format @@ -12862,8 +12893,8 @@ msgstr "--empty=ask 已弃用;请使用 '--empty=stop'。" #: builtin/rebase.c #, c-format msgid "" -"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and " -"\"stop\"." +"unrecognized empty type '%s'; valid values are \"drop\", \"keep\", and \"stop" +"\"." msgstr "æ— æ³•è¯†åˆ«çš„ç©ºç±»åž‹ '%s';有效值有 \"drop\"ã€\"keep\" å’Œ \"stop\"。" #: builtin/rebase.c @@ -13558,6 +13589,16 @@ msgid "unknown --mirror argument: %s" msgstr "未知的 --mirror 傿•°ï¼š%s" #: builtin/remote.c +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "远程åç§° '%s' 是现有远程 '%s' çš„å集" + +#: builtin/remote.c +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "远程åç§° '%s' 是现有远程 '%s' 的超集" + +#: builtin/remote.c msgid "fetch the remote branches" msgstr "抓å–远程的分支" @@ -13920,18 +13961,6 @@ msgstr "䏿˜¯ä¸€ä¸ªæœ‰æ•ˆå¼•用:%s" msgid "Could not set up %s" msgstr "ä¸èƒ½è®¾ç½® %s" -# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/remote.c -#, c-format -msgid " %s will become dangling!" -msgstr " %s å°†æˆä¸ºæ‚¬ç©ºçжæ€ï¼" - -# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/remote.c -#, c-format -msgid " %s has become dangling!" -msgstr " %s å·²æˆä¸ºæ‚¬ç©ºçжæ€ï¼" - #: builtin/remote.c #, c-format msgid "Pruning %s" @@ -14015,11 +14044,11 @@ msgstr "冗长输出;必须置于å命令之å‰" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<包å>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" #: builtin/repack.c msgid "" @@ -14121,6 +14150,10 @@ msgid "" msgstr "指定è¦ä½¿ç”¨çš„å称哈希算法,以实现按照路径对相似对象分组" #: builtin/repack.c +msgid "pass --path-walk to git-pack-objects" +msgstr "å‘ git-pack-objects ä¼ é€’å‚æ•° --path-walk" + +#: builtin/repack.c msgid "do not run git-update-server-info" msgstr "ä¸è¿è¡Œ git-update-server-info" @@ -15537,20 +15570,28 @@ msgid "git stash create [<message>]" msgstr "git stash create [<消æ¯>]" #: builtin/stash.c +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <引用>) [<è´®è—>...]" + +#: builtin/stash.c +msgid "git stash import <commit>" +msgstr "git stash import <æäº¤>" + +#: builtin/stash.c #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' ä¸åƒæ˜¯ä¸€ä¸ªè´®è—æäº¤" #: builtin/stash.c +msgid "No stash entries found." +msgstr "未å‘çŽ°è´®è—æ¡ç›®ã€‚" + +#: builtin/stash.c #, c-format msgid "Too many revisions specified:%s" msgstr "指定了太多的版本:%s" #: builtin/stash.c -msgid "No stash entries found." -msgstr "未å‘çŽ°è´®è—æ¡ç›®ã€‚" - -#: builtin/stash.c #, c-format msgid "%s is not a valid reference" msgstr "%s 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„引用å" @@ -15745,6 +15786,86 @@ msgstr "è´®è—ä¸åŒ…嫿œªè·Ÿè¸ªæ–‡ä»¶" msgid "include ignore files" msgstr "包å«å¿½ç•¥çš„æ–‡ä»¶" +#: builtin/stash.c +#, c-format +msgid "cannot parse commit %s" +msgstr "ä¸èƒ½è§£æžæäº¤ %s" + +#: builtin/stash.c +#, c-format +msgid "invalid author or committer for %s" +msgstr "%s 的作者或æäº¤è€…ä¿¡æ¯æ— 效" + +#: builtin/stash.c +msgid "could not write commit" +msgstr "æ— æ³•å†™å…¥æäº¤" + +#: builtin/stash.c +#, c-format +msgid "not a valid revision: %s" +msgstr "䏿˜¯æœ‰æ•ˆç‰ˆæœ¬ï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "not a commit: %s" +msgstr "䏿˜¯æäº¤ï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ä¸”å·²å¯¼å‡ºçš„è´®è—æäº¤" + +#: builtin/stash.c +#, c-format +msgid "found root commit %s with invalid data" +msgstr "å‘çŽ°æ ¹æäº¤ %s åŒ…å«æ— 效数æ®" + +#: builtin/stash.c +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "å‘çŽ°è´®è—æäº¤ %s 缺少预期å‰ç¼€" + +#: builtin/stash.c +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "æ— æ³•è§£æžè¯¥æäº¤çš„父æäº¤ï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s 看起æ¥ä¸åƒæ˜¯ä¸€ä¸ªè´®è—æäº¤" + +#: builtin/stash.c +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "æ— æ³•è¯»å–æäº¤çš„ç¼“å†²åŒºï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "cannot save the stash for %s" +msgstr "æ— æ³•ä¿å˜ %s 的贮è—" + +#: builtin/stash.c +msgid "unable to write base commit" +msgstr "æ— æ³•å†™å…¥åŸºçº¿æäº¤" + +#: builtin/stash.c +#, c-format +msgid "unable to find stash entry %s" +msgstr "æ— æ³•æ‰¾åˆ°è´®è—æ¡ç›® %s" + +#: builtin/stash.c +msgid "print the object ID instead of writing it to a ref" +msgstr "打å°å¯¹è±¡ IDï¼Œè€Œä¸æ˜¯å†™å…¥å¼•用" + +#: builtin/stash.c +msgid "save the data to the given ref" +msgstr "将数æ®ä¿å˜åˆ°æŒ‡å®šå¼•用" + +#: builtin/stash.c +msgid "exactly one of --print and --to-ref is required" +msgstr "傿•° --print å’Œ --to-ref 必须二选一" + #: builtin/stripspace.c msgid "skip and remove all lines starting with comment character" msgstr "跳过和移除所有的注释行" @@ -15755,8 +15876,10 @@ msgstr "为æ¯ä¸€è¡Œçš„è¡Œé¦–æ·»åŠ æ³¨é‡Šç¬¦å’Œç©ºæ ¼" #: builtin/submodule--helper.c #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "期望一个完整的引用å称,å´å¾—到 %s" +msgid "" +"could not look up configuration '%s'. Assuming this repository is its own " +"authoritative upstream." +msgstr "æ— æ³•æ‰¾åˆ°é…ç½® '%s'。å‡å®šè¿™ä¸ªä»“库是其自身的官方上游。" #: builtin/submodule--helper.c #, c-format @@ -15765,13 +15888,6 @@ msgstr "æ— æ³•èŽ·å¾—åæ¨¡ç»„ '%s' çš„ä»“åº“å¥æŸ„" #: builtin/submodule--helper.c #, c-format -msgid "" -"could not look up configuration '%s'. Assuming this repository is its own " -"authoritative upstream." -msgstr "æ— æ³•æ‰¾åˆ°é…ç½® '%s'。å‡å®šè¿™ä¸ªä»“库是其自身的官方上游。" - -#: builtin/submodule--helper.c -#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "在 .gitmodules 䏿œªæ‰¾åˆ°å模组路径 '%s' çš„ url" @@ -16189,6 +16305,11 @@ msgstr "忍¡ç»„(%s)的分支é…置为继承上级项目的分支,但是ä #: builtin/submodule--helper.c #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "期望一个完整的引用å称,å´å¾—到 %s" + +#: builtin/submodule--helper.c +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "æ— æ³•åœ¨åæ¨¡ç»„路径 '%s' 䏿‰¾åˆ°å½“å‰ç‰ˆæœ¬" @@ -16434,6 +16555,11 @@ msgstr "仓库 URL:'%s' 必须是ç»å¯¹è·¯å¾„或以 ./|../ èµ·å§‹" #: builtin/submodule--helper.c #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "忍¡ç»„åç§° '%s' 已被用于路径 '%s'" + +#: builtin/submodule--helper.c +#, c-format msgid "'%s' is not a valid submodule name" msgstr "'%s' 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„忍¡ç»„åç§°" @@ -16988,7 +17114,7 @@ msgstr "ä»Žæ ‡å‡†è¾“å…¥è¯»å–æ›´æ–°" #: builtin/update-ref.c msgid "batch reference updates" -msgstr "批é‡å¼•用更新" +msgstr "批é‡å¤„ç†å¼•用更新" #: builtin/update-server-info.c msgid "update the info files from scratch" @@ -17207,11 +17333,6 @@ msgstr "准备工作区(检出 '%s')" #: builtin/worktree.c #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "ä¸å¯è¾¾ï¼šæ— 效引用:%s" - -#: builtin/worktree.c -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "准备工作区(分离头指针 %s)" @@ -18657,8 +18778,8 @@ msgstr "æ£å°è¯•写æäº¤å›¾ï¼Œä½†æ˜¯ 'core.commitGraph' 被ç¦ç”¨" #: commit-graph.c #, c-format msgid "" -"attempting to write a commit-graph, but 'commitGraph.changedPathsVersion' " -"(%d) is not supported" +"attempting to write a commit-graph, but 'commitGraph." +"changedPathsVersion' (%d) is not supported" msgstr "å°è¯•写入æäº¤å›¾ï¼Œä½†ä¸æ”¯æŒ 'commitGraph.changedPathsVersion' (%d)" #: commit-graph.c @@ -19081,8 +19202,8 @@ msgid "" "remote URLs cannot be configured in file directly or indirectly included by " "includeIf.hasconfig:remote.*.url" msgstr "" -"远程 URL ä¸èƒ½åœ¨æ–‡ä»¶ä¸é…置,ä¸ç®¡ç›´æŽ¥åœ°è¿˜æ˜¯é€šè¿‡ " -"includeIf.hasconfig:remote.*.url 间接地包å«ã€‚" +"远程 URL ä¸èƒ½åœ¨æ–‡ä»¶ä¸é…置,ä¸ç®¡ç›´æŽ¥åœ°è¿˜æ˜¯é€šè¿‡ includeIf.hasconfig:remote.*." +"url 间接地包å«" #: config.c #, c-format @@ -19228,16 +19349,6 @@ msgstr "在 %3$s ä¸é…ç½®å˜é‡ '%2$s' 错误的å–值 '%1$s':%4$s" #: config.c #, c-format -msgid "invalid value for variable %s" -msgstr "å˜é‡ %s çš„å€¼æ— æ•ˆ" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "忽略未知的 core.fsync 组件 '%s'" - -#: config.c -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "'%2$s' 的错误的布尔å–值 '%1$s'" @@ -19253,54 +19364,6 @@ msgstr "'%2$s' 的值 '%1$s' 䏿˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ—¶é—´æˆ³" #: config.c #, c-format -msgid "abbrev length out of range: %d" -msgstr "缩写长度超出范围:%d" - -#: config.c -#, c-format -msgid "bad zlib compression level %d" -msgstr "错误的 zlib 压缩级别 %d" - -#: config.c -#, c-format -msgid "%s cannot contain newline" -msgstr "%s ä¸èƒ½åŒ…嫿¢è¡Œç¬¦" - -#: config.c -#, c-format -msgid "%s must have at least one character" -msgstr "%s 必须至少有一个å—符" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "忽略未知的 core.fsyncMethod 值 '%s'" - -#: config.c -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles å·²ç»è¢«å¼ƒç”¨ï¼›å–而代之使用 core.fsync" - -#: config.c -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "æ— æ•ˆçš„å¯¹è±¡åˆ›å»ºæ¨¡å¼ï¼š%s" - -#: config.c -#, c-format -msgid "malformed value for %s" -msgstr "%s çš„å–å€¼æ ¼å¼é”™è¯¯" - -#: config.c -#, c-format -msgid "malformed value for %s: %s" -msgstr "%s çš„å–å€¼æ ¼å¼é”™è¯¯ï¼š%s" - -#: config.c -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "必须是其ä¸ä¹‹ä¸€ï¼šnothingã€matchingã€simpleã€upstream 或 current" - -#: config.c -#, c-format msgid "unable to load config blob object '%s'" msgstr "æ— æ³•ä»Žæ•°æ®å¯¹è±¡ '%s' åŠ è½½é…ç½®" @@ -19922,8 +19985,8 @@ msgid "cannot compare a named pipe to a directory" msgstr "æ— æ³•å°†å‘½å管é“和目录进行比较" #: diff-no-index.c -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<选项>] <路径> <路径>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [<选项>] <路径> <路径> [<è·¯å¾„è§„æ ¼>...]" #: diff-no-index.c msgid "" @@ -19931,6 +19994,12 @@ msgid "" "tree" msgstr "䏿˜¯ git 仓库。使用 --no-index 比较工作区之外的两个路径" +#: diff-no-index.c +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "仅当两个路径å‡ä¸ºç›®å½•æ—¶ï¼Œæ‰æ”¯æŒä½¿ç”¨è·¯å¾„表达å¼é™åˆ¶æ¯”较范围。" + # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ #: diff.c #, c-format @@ -20109,7 +20178,7 @@ msgstr "生æˆè¡¥ä¸" msgid "<n>" msgstr "<n>" -#: diff.c +#: diff.c parse-options.h msgid "generate diffs with <n> lines context" msgstr "生æˆå« <n> 行上下文的差异" @@ -20256,7 +20325,7 @@ msgstr "䏿˜¾ç¤ºä»»ä½•æºå’Œç›®æ ‡å‰ç¼€" msgid "use default prefixes a/ and b/" msgstr "使用 a/ å’Œ b/ 作为默认å‰ç¼€" -#: diff.c +#: diff.c parse-options.h msgid "show context between diff hunks up to the specified number of lines" msgstr "显示指定行数的差异å—间的上下文" @@ -20641,6 +20710,64 @@ msgstr "ä¸èƒ½å¯¹æ–‡ä»¶ '%s' 调用 stat" msgid "bad git namespace path \"%s\"" msgstr "错误的 git åå—空间路径 \"%s\"" +#: environment.c +#, c-format +msgid "invalid value for variable %s" +msgstr "å˜é‡ %s çš„å€¼æ— æ•ˆ" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "忽略未知的 core.fsync 组件 '%s'" + +#: environment.c +#, c-format +msgid "abbrev length out of range: %d" +msgstr "缩写长度超出范围:%d" + +#: environment.c +#, c-format +msgid "bad zlib compression level %d" +msgstr "错误的 zlib 压缩级别 %d" + +#: environment.c +#, c-format +msgid "%s cannot contain newline" +msgstr "%s ä¸èƒ½åŒ…嫿¢è¡Œç¬¦" + +#: environment.c +#, c-format +msgid "%s must have at least one character" +msgstr "%s 必须至少有一个å—符" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "忽略未知的 core.fsyncMethod 值 '%s'" + +#: environment.c +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles å·²ç»è¢«å¼ƒç”¨ï¼›å–而代之使用 core.fsync" + +#: environment.c +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "æ— æ•ˆçš„å¯¹è±¡åˆ›å»ºæ¨¡å¼ï¼š%s" + +#: environment.c +#, c-format +msgid "malformed value for %s" +msgstr "%s çš„å–å€¼æ ¼å¼é”™è¯¯" + +#: environment.c +#, c-format +msgid "malformed value for %s: %s" +msgstr "%s çš„å–å€¼æ ¼å¼é”™è¯¯ï¼š%s" + +#: environment.c +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "必须是其ä¸ä¹‹ä¸€ï¼šnothingã€matchingã€simpleã€upstream 或 current" + #: exec-cmd.c #, c-format msgid "too many args to run %s" @@ -21499,6 +21626,35 @@ msgstr "ä¸å…许空的姓å(对于 <%s>)" msgid "name consists only of disallowed characters: %s" msgstr "å§“åä¸ä»…包å«ç¦ç”¨å—符:%s" +#: imap-send.c +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <文件夹>] < <mbox>" + +#: imap-send.c +msgid "no IMAP host specified" +msgstr "未指定 IMAP 主机" + +#: imap-send.c +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"通过 'git config imap.host <主机>' 设置 IMAP 主机。\n" +"(例如:'git config imap.host imaps://imap.example.com')" + +#: imap-send.c +msgid "no IMAP folder specified" +msgstr "未指定 IMAP 文件夹" + +#: imap-send.c +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"通过 'git config imap.folder <文件夹>' è®¾ç½®ç›®æ ‡æ–‡ä»¶å¤¹ã€‚\n" +"(例如:'git config imap.folder Drafts')" + #: list-objects-filter-options.c msgid "expected 'tree:<depth>'" msgstr "期望 'tree:<深度>'" @@ -22455,7 +22611,7 @@ msgstr "æ— æ³•è§£æž %s 的头部" #: object-file.c #, c-format msgid "unable to parse type from header '%s' of %s" -msgstr "æ— æ³•ä»Ž %s 的包头 '%s' ä¸è§£æžç±»åž‹" +msgstr "æ— æ³•ä»Ž %2$s 的包头 '%1$s' ä¸è§£æžç±»åž‹" #: object-file.c #, c-format @@ -22634,113 +22790,113 @@ msgstr "éœ€è¦ <对象>:<路径>,åªç»™å‡ºäº† <对象> '%s'" msgid "invalid object name '%.*s'." msgstr "æ— æ•ˆçš„å¯¹è±¡å '%.*s'。" -#: object-store.c +#: object.c +#, c-format +msgid "invalid object type \"%s\"" +msgstr "æ— æ•ˆçš„å¯¹è±¡ç±»åž‹ \"%s\"" + +#: object.c +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "对象 %s 是一个 %sï¼Œä¸æ˜¯ä¸€ä¸ª %s" + +#: object.c +#, c-format +msgid "object %s has unknown type id %d" +msgstr "对象 %s 有未知的类型 id %d" + +#: object.c +#, c-format +msgid "unable to parse object: %s" +msgstr "ä¸èƒ½è§£æžå¯¹è±¡ï¼š%s" + +#: object.c +#, c-format +msgid "hash mismatch %s" +msgstr "哈希值与 %s ä¸åŒ¹é…" + +#: odb.c #, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "对象目录 %s ä¸å˜åœ¨ï¼Œæ£€æŸ¥ .git/objects/info/alternates" -#: object-store.c +#: odb.c #, c-format msgid "unable to normalize alternate object path: %s" msgstr "æ— æ³•è§„èŒƒåŒ–å¤‡ç”¨å¯¹è±¡è·¯å¾„ï¼š%s" -#: object-store.c +#: odb.c #, c-format msgid "%s: ignoring alternate object stores, nesting too deep" msgstr "%s:忽略备用对象库,嵌套太深" -#: object-store.c +#: odb.c msgid "unable to fdopen alternates lockfile" msgstr "æ— æ³• fdopen alternates çš„é”æ–‡ä»¶" -#: object-store.c +#: odb.c msgid "unable to read alternates file" msgstr "æ— æ³•è¯»å– alternates 文件" -#: object-store.c +#: odb.c msgid "unable to move new alternates file into place" msgstr "æ— æ³•å°†æ–°çš„ alternates 文件移动到ä½" -#: object-store.c +#: odb.c #, c-format msgid "path '%s' does not exist" msgstr "路径 '%s' ä¸å˜åœ¨" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "å°šä¸æ”¯æŒå°†å‚考仓库 '%s' 作为链接检出。" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is not a local repository." msgstr "å‚考仓库 '%s' 䏿˜¯æœ¬åœ°ä»“库。" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is shallow" msgstr "å‚考仓库 '%s' 是浅克隆" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is grafted" msgstr "å‚考仓库 '%s' 已被移æ¤" -#: object-store.c +#: odb.c #, c-format msgid "could not find object directory matching %s" msgstr "æ— æ³•æ‰¾åˆ°å’Œ %s 匹é…的对象目录" -#: object-store.c +#: odb.c #, c-format msgid "invalid line while parsing alternate refs: %s" msgstr "è§£æžå¤‡ç”¨å¼•用时é‡åˆ°æ— 效的行:%s" -#: object-store.c +#: odb.c #, c-format msgid "replacement %s not found for %s" msgstr "找ä¸åˆ° %2$s 的替代 %1$s" -#: object-store.c +#: odb.c #, c-format msgid "packed object %s (stored in %s) is corrupt" msgstr "打包对象 %s(ä¿å˜åœ¨ %s)已æŸå" -#: object-store.c +#: odb.c #, c-format msgid "missing mapping of %s to %s" msgstr "缺少 %s 到 %s çš„æ˜ å°„" -#: object-store.c +#: odb.c #, c-format msgid "%s is not a valid '%s' object" msgstr "%s 䏿˜¯æœ‰æ•ˆçš„ '%s' 对象" -#: object.c -#, c-format -msgid "invalid object type \"%s\"" -msgstr "æ— æ•ˆçš„å¯¹è±¡ç±»åž‹ \"%s\"" - -#: object.c -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "对象 %s 是一个 %sï¼Œä¸æ˜¯ä¸€ä¸ª %s" - -#: object.c -#, c-format -msgid "object %s has unknown type id %d" -msgstr "对象 %s 有未知的类型 id %d" - -#: object.c -#, c-format -msgid "unable to parse object: %s" -msgstr "ä¸èƒ½è§£æžå¯¹è±¡ï¼š%s" - -#: object.c -#, c-format -msgid "hash mismatch %s" -msgstr "哈希值与 %s ä¸åŒ¹é…" - #: pack-bitmap-write.c #, c-format msgid "duplicate entry when writing bitmap index: %s" @@ -22755,10 +22911,6 @@ msgstr "å°è¯•å˜å‚¨æœªé€‰å®šçš„æäº¤ï¼š'%s'" msgid "too many pseudo-merges" msgstr "太多伪åˆå¹¶" -#: pack-bitmap-write.c -msgid "trying to write commit not in index" -msgstr "å°è¯•写入未在索引ä¸çš„æäº¤" - #: pack-bitmap.c msgid "failed to load bitmap index (corrupted?)" msgstr "æ— æ³•è½½å…¥ä½å›¾ç´¢å¼•(已æŸå?)" @@ -23063,6 +23215,11 @@ msgstr "%s ä¸å¯ç”¨" #: parse-options.c #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "%s 的值超出了 %<PRIdMAX>" + +#: parse-options.c +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "%2$s 的值 %1$s ä¸åœ¨èŒƒå›´ [%3$<PRIdMAX>,%4$<PRIdMAX>] 内" @@ -24215,6 +24372,18 @@ msgstr "没有 '%s' 的引用日志" msgid "%s does not point to a valid object!" msgstr "%s 没有指å‘一个有效的对象ï¼" +# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ +#: refs.c +#, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "%s%s 将在 %s è¢«åˆ é™¤åŽå˜ä¸ºæ‚¬ç©ºå¼•用\n" + +# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ +#: refs.c +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "%s%s 已在 %s è¢«åˆ é™¤åŽå˜ä¸ºæ‚¬ç©ºå¼•用\n" + #: refs.c #, c-format msgid "" @@ -26992,6 +27161,10 @@ msgid "toggle pruning of uninteresting paths" msgstr "切æ¢å¯¹æ— 趣路径的修剪" #: t/helper/test-path-walk.c +msgid "toggle aggressive edge walk" +msgstr "åˆ‡æ¢æ¿€è¿›è¾¹é历模å¼" + +#: t/helper/test-path-walk.c msgid "read a pattern list over stdin" msgstr "ä»Žæ ‡å‡†è¾“å…¥è¯»å–æ¨¡å¼åˆ—表" @@ -27742,6 +27915,24 @@ msgstr "错误:" msgid "warning: " msgstr "è¦å‘Šï¼š" +#: usage.c +#, c-format +msgid "" +"'%s' 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 "" +"'%s' 命令已被æå移除。\n" +"如果您ä»åœ¨ä½¿ç”¨è¯¥å‘½ä»¤ï¼Œè¯·åœ¨å‘½ä»¤è¡Œä¸æ·»åŠ é¢å¤–选项\n" +"'--i-still-use-this',并通过å‘é€é‚®ä»¶è‡³ <git@vger.kernel.org> \n" +"通知我们您ä»åœ¨ä½¿ç”¨å®ƒã€‚谢谢。\n" + +#: usage.c +msgid "refusing to run without --i-still-use-this" +msgstr "æ‹’ç»åœ¨æœªæŒ‡å®š --i-still-use-this 选项时è¿è¡Œ" + #: version.c #, c-format msgid "uname() failed with error '%s' (%d)\n" @@ -28890,6 +29081,11 @@ msgstr "(body) æ·»åŠ cc: %s 自行 '%s'\n" #: git-send-email.perl #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "é”™è¯¯ï¼šæ— æ•ˆçš„ SMTP ç«¯å£ '%s'\n" + +#: git-send-email.perl +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) ä¸èƒ½æ‰§è¡Œ '%s'" diff --git a/po/zh_TW.po b/po/zh_TW.po index 4fcbb71f8b..6fe5dbccd2 100644 --- a/po/zh_TW.po +++ b/po/zh_TW.po @@ -19,22 +19,22 @@ # - Yichao Yu <yyc1992 AT gmail.com> # - Zhuang Ya <zhuangya AT me.com> # -# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023, 2024. +# Yi-Jyun Pan <pan93412@gmail.com>, 2021, 2022, 2023, 2024, 2025. # Kaiyang Wu <self@origincode.me>, 2022. -# Lumynous <lumynou5.tw@gmail.com>, 2023, 2024. +# Lumynous <lumynou5.tw@gmail.com>, 2023, 2024, 2025. # Kisaragi Hiu <mail@kisaragi-hiu.com>, 2024. # Ngoo Ka-iu <willy04wu69@gmail.com>, 2024. # Nightfeather Chen <slat@nightfeather.me>, 2024. -# hms5232 <hms5232@hhming.moe>, 2024. +# hms5232 <hms5232@hhming.moe>, 2024, 2025. msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2025-06-12 22:09+0800\n" -"PO-Revision-Date: 2025-06-12 22:25+0800\n" -"Last-Translator: Yi-Jyun Pan <pan93412@gmail.com>\n" -"Language-Team: Chinese (Traditional) <http://weblate.slat.org/projects/git-" -"po/git-cli/zh_Hant/>\n" +"POT-Creation-Date: 2025-08-16 12:10+0800\n" +"PO-Revision-Date: 2025-08-16 12:11+0800\n" +"Last-Translator: hms5232 <hms5232@hhming.moe>\n" +"Language-Team: Chinese (Traditional Han script) <https://weblate.slat.org/" +"projects/git-po/git-cli/zh_Hant/>\n" "Language: zh_TW\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -46,6 +46,11 @@ msgstr "" #: add-interactive.c #, c-format +msgid "%s cannot be negative" +msgstr "%s ä¸èƒ½æ˜¯è² 數" + +#: add-interactive.c +#, c-format msgid "Huh (%s)?" msgstr "嗯(%s)?" @@ -131,12 +136,12 @@ msgstr "忽略未åˆä½µé …目:%s" #: add-interactive.c #, c-format msgid "Only binary files changed.\n" -msgstr "åªæœ‰äºŒé€²ä½æª”案更動了。\n" +msgstr "åªæœ‰äºŒé€²ä½æª”案變更了。\n" #: add-interactive.c #, c-format msgid "No changes.\n" -msgstr "沒有更動。\n" +msgstr "沒有變更。\n" #: add-interactive.c msgid "Patch update" @@ -148,15 +153,15 @@ msgstr "檢閱差異" #: add-interactive.c msgid "show paths with changes" -msgstr "顯示有更動的路徑" +msgstr "顯示有變更的路徑" #: add-interactive.c msgid "add working tree state to the staged set of changes" -msgstr "將工作å€ç‹€æ…‹åŠ å…¥è‡³æš«å˜æ›´å‹•集" +msgstr "將工作å€ç‹€æ…‹åŠ å…¥è‡³æš«å˜è®Šæ›´æš«å˜é›†" #: add-interactive.c msgid "revert staged set of changes back to the HEAD version" -msgstr "將暫å˜çš„æ›´å‹•集還原回 HEAD 版本" +msgstr "將變更暫å˜é›†é‚„原至 HEAD 版本" #: add-interactive.c msgid "pick hunks and update selectively" @@ -168,7 +173,7 @@ msgstr "檢視 HEAD åŠç´¢å¼•之間的差異" #: add-interactive.c msgid "add contents of untracked files to the staged set of changes" -msgstr "å°‡æœªè¿½è¹¤æª”æ¡ˆçš„å…§å®¹åŠ å…¥è‡³æ›´å‹•æš«å˜é›†" +msgstr "å°‡æœªè¿½è¹¤æª”æ¡ˆçš„å…§å®¹åŠ å…¥è‡³è®Šæ›´æš«å˜é›†" #: add-interactive.c msgid "Prompt help:" @@ -244,7 +249,7 @@ msgstr "å†è¦‹ã€‚\n" #: add-patch.c #, c-format msgid "Stage mode change [y,n,q,a,d%s,?]? " -msgstr "æš«å˜æ¨¡å¼æ›´å‹• [y,n,q,a,d%s,?]? " +msgstr "æš«å˜æ¨¡å¼è®Šæ›´ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -284,7 +289,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Stash mode change [y,n,q,a,d%s,?]? " -msgstr "è²¯å˜æ¨¡å¼æ›´å‹• [y,n,q,a,d%s,?]? " +msgstr "è²¯å˜æ¨¡å¼è®Šæ›´ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -324,7 +329,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Unstage mode change [y,n,q,a,d%s,?]? " -msgstr "å–æ¶ˆæš«å˜æ¨¡å¼æ›´å‹• [y,n,q,a,d%s,?]? " +msgstr "å–æ¶ˆæš«å˜æ¨¡å¼è®Šæ›´ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -364,7 +369,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Apply mode change to index [y,n,q,a,d%s,?]? " -msgstr "å°‡æ¨¡å¼æ›´å‹•套用到索引 [y,n,q,a,d%s,?]? " +msgstr "將模å¼è®Šæ›´å¥—ç”¨è‡³ç´¢å¼•å€ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -404,7 +409,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Discard mode change from worktree [y,n,q,a,d%s,?]? " -msgstr "å¾žå·¥ä½œå€æ¨æ£„æ¨¡å¼æ›´å‹• [y,n,q,a,d%s,?]? " +msgstr "å¾žå·¥ä½œå€æ¨æ£„模å¼è®Šæ›´ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -444,7 +449,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Discard mode change from index and worktree [y,n,q,a,d%s,?]? " -msgstr "å¾žç´¢å¼•å’Œå·¥ä½œå€æ¨æ£„æ¨¡å¼æ›´å‹• [y,n,q,a,d%s,?]? " +msgstr "從索引å€å’Œå·¥ä½œå€æ¨æ£„模å¼è®Šæ›´ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -478,7 +483,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Apply mode change to index and worktree [y,n,q,a,d%s,?]? " -msgstr "å°‡æ¨¡å¼æ›´å‹•å¥—ç”¨åˆ°ç´¢å¼•å’Œå·¥ä½œå€ [y,n,q,a,d%s,?]? " +msgstr "將模å¼è®Šæ›´å¥—用至索引å€å’Œå·¥ä½œå€ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -512,7 +517,7 @@ msgstr "" #: add-patch.c #, c-format msgid "Apply mode change to worktree [y,n,q,a,d%s,?]? " -msgstr "å°‡æ¨¡å¼æ›´å‹•å¥—ç”¨åˆ°å·¥ä½œå€ [y,n,q,a,d%s,?]? " +msgstr "將模å¼è®Šæ›´å¥—ç”¨è‡³å·¥ä½œå€ [y,n,q,a,d%s,?]? " #: add-patch.c #, c-format @@ -608,9 +613,9 @@ msgid "" "Lines starting with %s will be removed.\n" msgstr "" "---\n" -"è¦åˆªé™¤ã€Œ%cã€é–‹é 的列,請將列首(上下文)改æˆç©ºç™½ã€‚\n" -"è¦åˆªé™¤ã€Œ%cã€é–‹é 的列,請直接刪除。\n" -"é–‹é æ˜¯ %s 的列將會被移除。\n" +"è¦ç§»é™¤ã€Œ%cã€é–‹é 的列,請將列首(上下文)改æˆç©ºç™½ã€‚\n" +"è¦ç§»é™¤ã€Œ%cã€é–‹é 的列,請直接刪除。\n" +"é–‹é æ˜¯ %s 的列會被移除。\n" #: add-patch.c msgid "" @@ -754,11 +759,11 @@ msgstr "「git applyã€å¤±æ•—" #: add-patch.c msgid "No changes." -msgstr "沒有更動。" +msgstr "沒有變更。" #: add-patch.c msgid "Only binary files changed." -msgstr "åªæœ‰äºŒé€²ä½æª”案更動了。" +msgstr "åªæœ‰äºŒé€²ä½æª”案變更了。" #: advice.c #, c-format @@ -816,7 +821,7 @@ msgstr "åˆä½µå°šæœªçµæŸï¼ˆæœ‰ MERGE_HEAD)。" #: advice.c msgid "Please, commit your changes before merging." -msgstr "請在åˆä½µå‰å…ˆæäº¤æ‚¨çš„æ›´å‹•。" +msgstr "請在åˆä½µå‰å…ˆæäº¤æ‚¨çš„變更。" #: advice.c msgid "Exiting because of unfinished merge." @@ -912,8 +917,8 @@ msgid "" "sparse-checkout definition but are not sparse due to local\n" "modifications.\n" msgstr "" -"以下路徑已經移到稀ç–簽出定義之外的地方,\n" -"ä½†å› ç‚ºæœ‰æœ¬æ©Ÿæ›´å‹•ï¼Œå› æ¤è·¯å¾‘䏿˜¯ç¨€ç–的。\n" +"以下路徑已移動至稀ç–簽出定義以外的ä½ç½®ï¼Œ\n" +"ä½†å› æœ¬æ©Ÿä¿®æ”¹è€Œä¸æ˜¯ç¨€ç–的。\n" #: advice.c msgid "" @@ -941,22 +946,22 @@ msgstr "引數éŽå¤š" #: apply.c #, c-format msgid "unrecognized whitespace option '%s'" -msgstr "空白å—å…ƒé¸é …「%sã€ä¸èªè˜" +msgstr "無法è˜åˆ¥ç©ºç™½å—å…ƒé¸é …「%sã€" #: apply.c #, c-format msgid "unrecognized whitespace ignore option '%s'" -msgstr "空白å—元忽略é¸é …「%sã€ä¸èªè˜" +msgstr "無法辨è˜ç©ºç™½å—元忽略é¸é …「%sã€" #: apply.c archive.c builtin/add.c builtin/branch.c builtin/checkout-index.c #: builtin/checkout.c builtin/clean.c builtin/clone.c builtin/commit.c #: builtin/describe.c builtin/diff-tree.c builtin/difftool.c #: builtin/fast-export.c builtin/fetch.c builtin/help.c builtin/index-pack.c #: builtin/init-db.c builtin/log.c builtin/ls-files.c builtin/merge-base.c -#: builtin/merge-tree.c builtin/merge.c builtin/pack-objects.c builtin/rebase.c -#: builtin/repack.c builtin/replay.c builtin/reset.c builtin/rev-parse.c -#: builtin/show-branch.c builtin/stash.c builtin/submodule--helper.c -#: builtin/tag.c builtin/worktree.c parse-options.c range-diff.c revision.c +#: builtin/merge-tree.c builtin/merge.c builtin/rebase.c builtin/repack.c +#: builtin/replay.c builtin/reset.c builtin/rev-parse.c builtin/show-branch.c +#: builtin/stash.c builtin/submodule--helper.c builtin/tag.c builtin/worktree.c +#: parse-options.c range-diff.c revision.c #, c-format msgid "options '%s' and '%s' cannot be used together" msgstr "ç„¡æ³•åŒæ™‚使用「%sã€å’Œã€Œ%sã€é¸é …" @@ -1080,7 +1085,7 @@ msgstr "二進ä½ä¿®è£œæª”在第 %d 列æå£žï¼š%.*s" #: apply.c #, c-format msgid "unrecognized binary patch at line %d" -msgstr "第 %d 列的二進ä½ä¿®è£œæª”ä¸èªè˜" +msgstr "無法辨è˜ç¬¬ %d 列的二進ä½ä¿®è£œæª”" #: apply.c #, c-format @@ -1294,7 +1299,7 @@ msgstr "%s 忍¡çµ„缺少 sha1 資訊或沒有幫助" #: apply.c #, c-format msgid "mode change for %s, which is not in current HEAD" -msgstr "%s çš„æ¨¡å¼æœ‰æ›´å‹•,但其ä¸åœ¨ç›®å‰ HEAD ä¸" +msgstr "有 %s 的模å¼è®Šæ›´ï¼Œä½†å…¶ä¸åœ¨ç›®å‰çš„ HEAD ä¸" #: apply.c #, c-format @@ -1428,11 +1433,11 @@ msgstr "無法寫入新索引檔案" #: apply.c msgid "don't apply changes matching the given path" -msgstr "ä¸è¦å¥—ç”¨ç¬¦åˆæä¾›è·¯å¾‘çš„æ›´å‹•" +msgstr "ä¸å¥—ç”¨ç¬¦åˆæä¾›è·¯å¾‘çš„è®Šæ›´" #: apply.c msgid "apply changes matching the given path" -msgstr "å¥—ç”¨ç¬¦åˆæä¾›è·¯å¾‘çš„æ›´å‹•" +msgstr "å¥—ç”¨ç¬¦åˆæä¾›è·¯å¾‘çš„è®Šæ›´" #: apply.c builtin/am.c msgid "num" @@ -1488,15 +1493,15 @@ msgstr "嘗試三方åˆä½µï¼Œè‹¥å¤±æ•—則回到æ£å¸¸ä¿®è£œæ¨¡å¼" #: apply.c builtin/merge-file.c msgid "for conflicts, use our version" -msgstr "如果è¡çªï¼Œä½¿ç”¨æˆ‘們的版本" +msgstr "如有è¡çªï¼Œä½¿ç”¨æˆ‘方版本" #: apply.c builtin/merge-file.c msgid "for conflicts, use their version" -msgstr "如果è¡çªï¼Œä½¿ç”¨ä»–們的版本" +msgstr "如有è¡çªï¼Œä½¿ç”¨ä»–方版本" #: apply.c builtin/merge-file.c msgid "for conflicts, use a union version" -msgstr "如果è¡çªï¼Œä½¿ç”¨è¯åˆç‰ˆæœ¬" +msgstr "如有è¡çªï¼Œä½¿ç”¨è¯é›†ç‰ˆæœ¬" #: apply.c msgid "build a temporary index based on embedded index information" @@ -1521,7 +1526,7 @@ msgstr "檢查新增和修改的列ä¸é–“ï¼Œæ˜¯å¦æœ‰ç©ºç™½å—元誤用" #: apply.c msgid "ignore changes in whitespace when finding context" -msgstr "尋找上下文時忽略空白å—元更動" +msgstr "尋找上下文時忽略空白å—元變更" #: apply.c msgid "apply the patch in reverse" @@ -1831,7 +1836,7 @@ msgstr "忽略éŽå¤§çš„ gitattributes 資料物件「%sã€" #: attr.c msgid "cannot use --attr-source or GIT_ATTR_SOURCE without repo" -msgstr "沒有版本庫無法使用 --attr-source 或 GIT_ATTR_SOURCE" +msgstr "沒有版本庫ä¸èƒ½ä½¿ç”¨ --attr-source 或 GIT_ATTR_SOURCE" #: attr.c msgid "bad --attr-source or GIT_ATTR_SOURCE" @@ -1840,7 +1845,7 @@ msgstr "無效的 --attr-source 或 GIT_ATTR_SOURCE" #: attr.c read-cache.c refs/packed-backend.c #, c-format msgid "unable to stat '%s'" -msgstr "無法統計「%sã€" +msgstr "無法 stat「%sã€" #: bisect.c builtin/cat-file.c builtin/index-pack.c builtin/notes.c #: builtin/pack-objects.c combine-diff.c object-file.c rerere.c @@ -1930,7 +1935,7 @@ msgstr "無法建立「%sã€æª”案" #: bisect.c builtin/notes.c #, c-format msgid "unable to start 'show' for object '%s'" -msgstr "無法為物件「%sã€é–‹å§‹ã€Œshowã€" +msgstr "無法å°ç‰©ä»¶ã€Œ%sã€åŸ·è¡Œã€Œshowã€" #: bisect.c builtin/merge.c #, c-format @@ -2190,7 +2195,7 @@ msgstr "無法 chmod %cx '%s'" #: builtin/add.c msgid "Unstaged changes after refreshing the index:" -msgstr "釿–°æ•´ç†ç´¢å¼•之後,尚未被暫å˜çš„æ›´å‹•:" +msgstr "釿–°æ•´ç†ç´¢å¼•之後未暫å˜çš„變更:" #: builtin/add.c msgid "could not read the index" @@ -2203,7 +2208,7 @@ msgstr "編輯修補檔失敗" #: builtin/add.c read-cache.c #, c-format msgid "could not stat '%s'" -msgstr "無法統計「%sã€" +msgstr "無法 stat「%sã€" #: builtin/add.c msgid "empty patch. aborted" @@ -2260,7 +2265,7 @@ msgstr "åªè¨˜éŒ„「路徑ç¨å¾Œæœƒå†åŠ å…¥ã€" #: builtin/add.c msgid "add changes from all tracked and untracked files" -msgstr "å¾žæ‰€æœ‰å·²è¿½è¹¤å’Œæœªè¿½è¹¤æª”æ¡ˆåŠ å…¥æ›´å‹•" +msgstr "åŠ å…¥æ‰€æœ‰å·²è¿½è¹¤å’Œæœªè¿½è¹¤æª”æ¡ˆçš„è®Šæ›´" #: builtin/add.c msgid "ignore paths removed in the working tree (same as --no-all)" @@ -2334,6 +2339,12 @@ msgstr "如果您確定想è¦åŠ å…¥å®ƒå€‘ï¼Œè«‹ä½¿ç”¨ -f。" msgid "adding files failed" msgstr "åŠ å…¥æª”æ¡ˆå¤±æ•—" +#: builtin/add.c builtin/checkout.c builtin/commit.c builtin/reset.c +#: builtin/stash.c +#, c-format +msgid "'%s' cannot be negative" +msgstr "「%sã€ä¸èƒ½æ˜¯è² 數" + #: builtin/add.c #, c-format msgid "--chmod param '%s' must be either -x or +x" @@ -2372,7 +2383,7 @@ msgid "bad action '%s' for '%s'" msgstr "「%sã€å‹•作å°ã€Œ%sã€ç„¡æ•ˆ" #: builtin/am.c builtin/blame.c builtin/fetch.c builtin/pack-objects.c -#: builtin/pull.c builtin/revert.c config.c diff-merges.c gpg-interface.c +#: builtin/pull.c builtin/revert.c diff-merges.c environment.c gpg-interface.c #: ls-refs.c parallel-checkout.c sequencer.c setup.c #, c-format msgid "invalid value for '%s': '%s'" @@ -2463,7 +2474,7 @@ msgstr "解決æ¤å•題後,請執行「%s --continueã€ã€‚\n" #: builtin/am.c #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead.\n" -msgstr "è‹¥è¦ç•¥éŽæ¤ä¿®è£œï¼Œè«‹æ”¹åŸ·è¡Œã€Œ%s --skipã€ã€‚\n" +msgstr "è‹¥è¦ç•¥éŽæ¤ä¿®è£œæª”,請改執行「%s --skipã€ã€‚\n" #: builtin/am.c #, c-format @@ -2517,7 +2528,7 @@ msgstr "æ£åœ¨å›žå¾©åˆ°ä¿®è£œåŸºç¤Žè™•,並進行三方åˆä½µâ€¦â€¦" #: builtin/am.c msgid "Failed to merge in the changes." -msgstr "無法åˆä½µæ›´å‹•。" +msgstr "åˆä½µè®Šæ›´å¤±æ•—。" #: builtin/am.c builtin/merge.c sequencer.c msgid "git write-tree failed to write a tree" @@ -2952,7 +2963,7 @@ msgstr "無法開啟檔案「%sã€" #: builtin/bisect.c #, c-format msgid "Invalid command: you're currently in a %s/%s bisect" -msgstr "命令無效:您æ£è™•於二分æœå°‹ %s/%s 的狀態" +msgstr "命令無效:您æ£è™•於採用 %s/%s 術語的二分æœå°‹" #: builtin/bisect.c #, c-format @@ -3036,7 +3047,7 @@ msgstr "「 ã€ä¸æ˜¯æœ‰æ•ˆè¡“語" #: builtin/bisect.c #, c-format msgid "unrecognized option: '%s'" -msgstr "ä¸èªè˜é¸é …:「%sã€" +msgstr "無法辨è˜é¸é …:「%sã€" #: builtin/bisect.c #, c-format @@ -3129,7 +3140,7 @@ msgstr "好的修訂版回傳å½é€ 的錯誤碼 %d" #: builtin/bisect.c #, c-format msgid "bisect run failed: exit code %d from %s is < 0 or >= 128" -msgstr "二分æœå°‹åŸ·è¡Œå¤±æ•—:%2$s å›žå‚³çš„çµæŸä»£ç¢¼ %1$d å°æ–¼ 0 或大於 128" +msgstr "二分æœå°‹åŸ·è¡Œå¤±æ•—:%2$s çš„çµæŸä»£ç¢¼ %1$d å°æ–¼ 0 或大於 128" #: builtin/bisect.c #, c-format @@ -3316,11 +3327,11 @@ msgstr "score" #: builtin/blame.c msgid "find line copies within and across files" -msgstr "找到檔案內åŠè·¨æª”案的列拷è²å‹•作" +msgstr "尋找檔案內åŠè·¨æª”案拷è²çš„列" #: builtin/blame.c msgid "find line movements within and across files" -msgstr "找到檔案內åŠè·¨æª”案的列移動動作" +msgstr "尋找檔案內åŠè·¨æª”案移動的列" #: builtin/blame.c msgid "range" @@ -3399,7 +3410,7 @@ msgid "" "deleting branch '%s' that has been merged to\n" " '%s', but not yet merged to HEAD" msgstr "" -"å°‡è¦åˆªé™¤çš„分支「%sã€å·²ç¶“被åˆä½µåˆ°\n" +"è¦åˆªé™¤çš„分支「%sã€å·²ç¶“被åˆä½µåˆ°\n" " 「%sã€ï¼Œä½†å°šæœªåˆä½µåˆ° HEAD" # è¯è€…ï¼šä¿æŒåŽŸæ›è¡Œæ ¼å¼ï¼Œåœ¨è¼¸å‡ºæ™‚ %s 的替代內容會讓å—串變長 @@ -3475,7 +3486,7 @@ msgstr "ç„¡æ³•è§£æžæ ¼å¼åŒ–å—串" #: builtin/branch.c msgid "could not resolve HEAD" -msgstr "ç„¡æ³•è§£æž HEAD" +msgstr "ç„¡æ³•è§£æž HEAD 指標" #: builtin/branch.c #, c-format @@ -3514,34 +3525,34 @@ msgstr "沒有å為「%sã€çš„分支" #: builtin/branch.c msgid "branch rename failed" -msgstr "åˆ†æ”¯é‡æ–°å‘½å失敗" +msgstr "釿–°å‘½å分支失敗" #: builtin/branch.c msgid "branch copy failed" -msgstr "分支拷è²å¤±æ•—" +msgstr "æ‹·è²åˆ†æ”¯å¤±æ•—" #: builtin/branch.c #, c-format msgid "created a copy of a misnamed branch '%s'" -msgstr "已為誤命å的分支「%sã€å»ºç«‹æ‹·è²" +msgstr "已為誤命å的分支「%sã€å»ºç«‹è¤‡æœ¬" #: builtin/branch.c #, c-format msgid "renamed a misnamed branch '%s' away" -msgstr "已更改誤命å的分支「%sã€çš„å稱" +msgstr "已將誤命å的分支「%sã€é‡æ–°å‘½å" #: builtin/branch.c #, c-format msgid "branch renamed to %s, but HEAD is not updated" -msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å為 %s,但 HEAD 指標尚未更新" +msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å為 %s,但 HEAD 指標並未更新" #: builtin/branch.c msgid "branch is renamed, but update of config-file failed" -msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å,但無法更新組態檔案" +msgstr "åˆ†æ”¯å·²é‡æ–°å‘½å,但組態檔案更新失敗" #: builtin/branch.c msgid "branch is copied, but update of config-file failed" -msgstr "分支已拷è²ï¼Œä½†ç„¡æ³•更新組態檔案" +msgstr "分支已拷è²ï¼Œä½†çµ„態檔案更新失敗" #: builtin/branch.c #, c-format @@ -3550,9 +3561,9 @@ msgid "" " %s\n" "Lines starting with '%s' will be stripped.\n" msgstr "" -"請編輯下述分支的æè¿°\n" +"請編輯以下分支的æè¿°\n" " %s\n" -"é–‹é æ˜¯ã€Œ%sã€çš„列將被刪除。\n" +"é–‹é æ˜¯ã€Œ%sã€çš„列將被濾除。\n" #: builtin/branch.c msgid "Generic options" @@ -3628,7 +3639,7 @@ msgstr "å³ä½¿ç›®æ¨™å·²å˜åœ¨ï¼Œä»ç§»å‹•æˆ–é‡æ–°å‘½å分支" #: builtin/branch.c builtin/for-each-ref.c builtin/tag.c msgid "do not output a newline after empty formatted refs" -msgstr "åœ¨æ ¼å¼åŒ–çµæžœç‚ºç©ºçš„引用之後,ä¸è¦è¼¸å‡ºæ›åˆ—符號" +msgstr "åœ¨æ ¼å¼åŒ–為空å—串的引用之後ä¸è¼¸å‡ºæ›åˆ—符號" #: builtin/branch.c msgid "copy a branch and its reflog" @@ -3724,11 +3735,11 @@ msgstr "無法編輯超éŽä¸€å€‹åˆ†æ”¯çš„æè¿°" #: builtin/branch.c msgid "cannot copy the current branch while not on any" -msgstr "ä¸åœ¨ä»»ä½•分支上,無法拷è²ç›®å‰åˆ†æ”¯" +msgstr "ä¸åœ¨ä»»ä½•分支上,ä¸èƒ½æ‹·è²ç›®å‰åˆ†æ”¯" #: builtin/branch.c msgid "cannot rename the current branch while not on any" -msgstr "ä¸åœ¨ä»»ä½•åˆ†æ”¯ä¸Šï¼Œç„¡æ³•é‡æ–°å‘½åç›®å‰åˆ†æ”¯" +msgstr "ä¸åœ¨ä»»ä½•分支上,ä¸èƒ½é‡æ–°å‘½åç›®å‰åˆ†æ”¯" #: builtin/branch.c msgid "too many branches for a copy operation" @@ -3746,7 +3757,7 @@ msgstr "è¦è¨å®šæ–°ä¸Šæ¸¸çš„引數太多" #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch" -msgstr "無法將 HEAD 的上游è¨ç‚º %s:其未指å‘任何分支" +msgstr "HEAD 䏿Œ‡å‘任何分支時無法將其上游è¨ç‚º %s" #: builtin/branch.c #, c-format @@ -3764,7 +3775,7 @@ msgstr "è¦å–消è¨å®šä¸Šæ¸¸çš„引數太多" #: builtin/branch.c msgid "could not unset upstream of HEAD when it does not point to any branch" -msgstr "ç„¡æ³•å–æ¶ˆè¨å®š HEAD 的上游:其未指å‘任何分支" +msgstr "HEAD 䏿Œ‡å‘ä»»ä½•åˆ†æ”¯æ™‚ç„¡æ³•å–æ¶ˆè¨å®šå…¶ä¸Šæ¸¸" #: builtin/branch.c #, c-format @@ -3777,7 +3788,7 @@ msgid "" "Did you mean to use: -a|-r --list <pattern>?" msgstr "" "「git branchã€çš„ -a å’Œ -r é¸é …ä¸å–分支å稱。\n" -"您是想使用:-a|-r --list <pattern> 嗎?" +"您是想使用:-a|-r --list <模å¼> 嗎?" #: builtin/branch.c msgid "" @@ -3846,8 +3857,8 @@ msgstr "" "請檢閱è‡èŸ²å ±å‘Šä¸‹æ–¹çš„剩餘部分。\n" "您å¯åˆªé™¤ä»»ä½•æ‚¨ä¸æƒ³åˆ†äº«çš„地方。\n" -#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c builtin/rebase.c -#: parse-options.h +#: builtin/bugreport.c builtin/commit.c builtin/fast-export.c +#: builtin/pack-objects.c builtin/rebase.c parse-options.h msgid "mode" msgstr "mode" @@ -4003,7 +4014,6 @@ msgid "git cat-file <type> <object>" msgstr "git cat-file <type> <object>" #: builtin/cat-file.c -#| msgid "git cat-file (-e | -p) <object>" msgid "git cat-file (-e | -p | -t | -s) <object>" msgstr "git cat-file (-e | -p | -t | -s) <object>" @@ -4124,7 +4134,7 @@ msgstr "請在 (--textconv | --filters) 使用 <path>,而éžã€Œbatchã€" #: builtin/cat-file.c msgid "objects filter only supported in batch mode" -msgstr "ç‰©ä»¶éŽæ¿¾å™¨åƒ…æ”¯æ´æ‰¹æ¬¡æ¨¡å¼" +msgstr "åƒ…æ‰¹æ¬¡æ¨¡å¼æ”¯æ´ç‰©ä»¶éŽæ¿¾å™¨" #: builtin/cat-file.c #, c-format @@ -4205,7 +4215,7 @@ msgstr "<tree-ish>" #: builtin/check-attr.c msgid "which tree-ish to check attributes at" -msgstr "è¦ç”¨å“ªä¸€å€‹æ¨¹ç‹€ç‰©ä»¶æª¢æŸ¥å±¬æ€§" +msgstr "è¦æª¢æŸ¥å±¬æ€§çš„æ¨¹ç‹€ç‰©ä»¶æŒ‡ç¤ºå…ƒ" #: builtin/check-ignore.c builtin/checkout.c builtin/gc.c builtin/worktree.c msgid "suppress progress reporting" @@ -4253,7 +4263,7 @@ msgstr "亦從 stdin 讀å–è¯çµ¡åœ°å€" #: builtin/check-mailmap.c msgid "read additional mailmap entries from file" -msgstr "從檔案讀å–å…¶ä»– mailmap é …ç›®" +msgstr "從檔案讀å–é¡å¤– mailmap é …ç›®" #: builtin/check-mailmap.c msgid "blob" @@ -4411,12 +4421,12 @@ msgstr "未指定「%2$sã€æ™‚ï¼Œå¿…é ˆä½¿ç”¨ã€Œ%1$sã€" #: builtin/checkout.c #, c-format msgid "'%s' or '%s' cannot be used with %s" -msgstr "「%sã€æˆ–「%sã€ç„¡æ³•與 %s 一起使用" +msgstr "「%sã€æˆ–「%sã€ä¸èƒ½èˆ‡ %s åŒæ™‚使用" #: builtin/checkout.c #, c-format msgid "'%s', '%s', or '%s' cannot be used when checking out of a tree" -msgstr "「%sã€ã€ã€Œ%sã€æˆ–「%sã€ç„¡æ³•在簽出樹狀物件時使用" +msgstr "「%sã€ã€ã€Œ%sã€æˆ–「%sã€ä¸èƒ½åœ¨ç°½å‡ºæ¨¹ç‹€ç‰©ä»¶æ™‚使用" #: builtin/checkout.c #, c-format @@ -4427,7 +4437,7 @@ msgstr "路徑「%sã€æœªåˆä½µ" #: merge-ort.c reset.c sequencer.c tree-walk.c #, c-format msgid "unable to read tree (%s)" -msgstr "ç„¡æ³•è®€å–æ¨¹ï¼ˆ%s)" +msgstr "ç„¡æ³•è®€å–æ¨¹ç‹€ç‰©ä»¶ï¼ˆ%s)" #: builtin/checkout.c msgid "you need to resolve your current index first" @@ -4439,7 +4449,7 @@ msgid "" "cannot continue with staged changes in the following files:\n" "%s" msgstr "" -"無法繼續,下列檔案有暫å˜çš„æ›´å‹•:\n" +"無法繼續,下列檔案有暫å˜çš„變更:\n" "%s" #: builtin/checkout.c @@ -4620,53 +4630,53 @@ msgid "" "cannot switch branch while merging\n" "Consider \"git merge --quit\" or \"git worktree add\"." msgstr "" -"無法在åˆä½µæ™‚切æ›åˆ†æ”¯\n" -"請試試「git merge --quitã€æˆ–「git worktree addã€ã€‚" +"ä¸èƒ½åœ¨åˆä½µæ™‚切æ›åˆ†æ”¯\n" +"請考慮使用「git merge --quitã€æˆ–「git worktree addã€ã€‚" #: builtin/checkout.c msgid "" "cannot switch branch in the middle of an am session\n" "Consider \"git am --quit\" or \"git worktree add\"." msgstr "" -"無法在 am 工作階段期間時切æ›åˆ†æ”¯\n" -"請試試「git am --quitã€æˆ–「git worktree addã€ã€‚" +"ä¸èƒ½åœ¨ am 工作階段ä¸åˆ‡æ›åˆ†æ”¯\n" +"請考慮使用「git am --quitã€æˆ–「git worktree addã€ã€‚" #: builtin/checkout.c msgid "" "cannot switch branch while rebasing\n" "Consider \"git rebase --quit\" or \"git worktree add\"." msgstr "" -"無法在é‡å®šåŸºåº•時切æ›åˆ†æ”¯\n" -"請試試「git rebase --quitã€æˆ–「git worktree addã€ã€‚" +"ä¸èƒ½åœ¨é‡å®šåŸºåº•時切æ›åˆ†æ”¯\n" +"請考慮使用「git rebase --quitã€æˆ–「git worktree addã€ã€‚" #: builtin/checkout.c msgid "" "cannot switch branch while cherry-picking\n" "Consider \"git cherry-pick --quit\" or \"git worktree add\"." msgstr "" -"無法在æ€é¸æ™‚切æ›åˆ†æ”¯\n" -"請試試「git cherry-pick --quitã€æˆ–「git worktree addã€ã€‚" +"ä¸èƒ½åœ¨æ€é¸æ™‚切æ›åˆ†æ”¯\n" +"請考慮使用「git cherry-pick --quitã€æˆ–「git worktree addã€ã€‚" #: builtin/checkout.c msgid "" "cannot switch branch while reverting\n" "Consider \"git revert --quit\" or \"git worktree add\"." msgstr "" -"無法在還原時切æ›åˆ†æ”¯\n" -"請試試「git revert --quitã€æˆ–「git worktree addã€ã€‚" +"ä¸èƒ½åœ¨é‚„原時切æ›åˆ†æ”¯\n" +"請考慮使用「git revert --quitã€æˆ–「git worktree addã€ã€‚" #: builtin/checkout.c msgid "you are switching branch while bisecting" -msgstr "您在進行二分æœå°‹æ™‚切æ›åˆ†æ”¯" +msgstr "在進行二分æœå°‹æ™‚切æ›åˆ†æ”¯" #: builtin/checkout.c msgid "paths cannot be used with switching branches" -msgstr "路徑ä¸èƒ½èˆ‡åˆ‡æ›åˆ†æ”¯åŒæ™‚使用" +msgstr "切æ›åˆ†æ”¯æ™‚ä¸èƒ½æŒ‡å®šè·¯å¾‘" #: builtin/checkout.c #, c-format msgid "'%s' cannot be used with switching branches" -msgstr "「%sã€ä¸èƒ½èˆ‡åˆ‡æ›åˆ†æ”¯åŒæ™‚使用" +msgstr "切æ›åˆ†æ”¯æ™‚ä¸èƒ½æŒ‡å®šã€Œ%sã€" #: builtin/checkout.c #, c-format @@ -4681,12 +4691,12 @@ msgstr "「%sã€ä¸èƒ½èˆ‡ã€Œ%sã€åŒæ™‚使用" #: builtin/checkout.c #, c-format msgid "'%s' cannot take <start-point>" -msgstr "「%sã€ä¸å– <start-point>" +msgstr "「%sã€ä¸èƒ½èˆ‡ <start-point> åŒæ™‚使用" #: builtin/checkout.c #, c-format msgid "Cannot switch branch to a non-commit '%s'" -msgstr "無法將分支切æ›è‡³éžæäº¤é …目「%sã€" +msgstr "ä¸èƒ½å°‡åˆ†æ”¯åˆ‡æ›è‡³éžæäº¤çš„「%sã€" #: builtin/checkout.c msgid "missing branch or commit argument" @@ -4711,7 +4721,7 @@ msgstr "è¡çªè¼¸å‡ºé¢¨æ ¼ï¼ˆmergeã€diff3 或 zdiff3)" #: builtin/checkout.c builtin/worktree.c msgid "detach HEAD at named commit" -msgstr "自指定æäº¤åˆ†é›¢ HEAD 指標" +msgstr "使 HEAD 指標在指定æäº¤åˆ†é›¢" #: builtin/checkout.c msgid "force checkout (throw away local modifications)" @@ -4731,24 +4741,24 @@ msgstr "更新忽略的檔案(é è¨å€¼ï¼‰" #: builtin/checkout.c msgid "do not check if another worktree is using this branch" -msgstr "䏿ª¢æŸ¥å…¶ä»–å·¥ä½œå€æ˜¯å¦æ£åœ¨ä½¿ç”¨æ¤åˆ†æ”¯" +msgstr "䏿ª¢æŸ¥æ˜¯å¦æœ‰å…¶ä»–工作å€åœ¨ä½¿ç”¨æ¤åˆ†æ”¯" #: builtin/checkout.c msgid "checkout our version for unmerged files" -msgstr "å°å°šæœªåˆä½µçš„æª”案簽出我們的版本" +msgstr "簽出未åˆä½µæª”案的我方版本" #: builtin/checkout.c msgid "checkout their version for unmerged files" -msgstr "å°å°šæœªåˆä½µçš„æª”案簽出他們的版本" +msgstr "簽出未åˆä½µæª”案的他方版本" #: builtin/checkout.c msgid "do not limit pathspecs to sparse entries only" -msgstr "å°è·¯å¾‘è¦æ ¼ä¸åšç¨€ç–簽出的é™åˆ¶" +msgstr "ä¸å°‡è·¯å¾‘è¦æ ¼é™åˆ¶ç‚ºåƒ…稀ç–é …ç›®" #: builtin/checkout.c #, c-format msgid "options '-%c', '-%c', and '%s' cannot be used together" -msgstr "「-%cã€ã€ã€Œ-%cã€å’Œã€Œ%sã€é¸é …ä¸å¾—åŒæ™‚使用" +msgstr "「-%cã€ã€ã€Œ-%cã€å’Œã€Œ%sã€é¸é …ä¸èƒ½åŒæ™‚使用" #: builtin/checkout.c msgid "--track needs a branch name" @@ -4757,7 +4767,7 @@ msgstr "--track 需è¦åˆ†æ”¯å稱" #: builtin/checkout.c #, c-format msgid "missing branch name; try -%c" -msgstr "缺少分支å稱,請嘗試 -%c" +msgstr "缺少分支å稱;請嘗試 -%c" #: builtin/checkout.c #, c-format @@ -4766,25 +4776,24 @@ msgstr "ç„¡æ³•è§£æž %s" #: builtin/checkout.c msgid "invalid path specification" -msgstr "ç„¡æ•ˆçš„è·¯å¾‘è¦æ ¼" +msgstr "è·¯å¾‘è¦æ ¼ç„¡æ•ˆ" #: builtin/checkout.c #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" -msgstr "「%sã€ä¸æ˜¯æäº¤ï¼Œå› æ¤ä¸èƒ½ä»¥é€™ç‚ºåŸºç¤Žå»ºç«‹ã€Œ%sã€åˆ†æ”¯" +msgstr "「%sã€ä¸æ˜¯æäº¤ï¼Œä¸èƒ½å»ºç«‹ä»¥å…¶ç‚ºåŸºåº•的分支「%sã€" #: builtin/checkout.c #, c-format msgid "git checkout: --detach does not take a path argument '%s'" -msgstr "git checkout:--detach ä¸å–路徑引數「%sã€" +msgstr "git checkout: --detach ä¸å–路徑引數「%sã€" #: builtin/checkout.c msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." msgstr "" -"git checkout:在從索引簽出時,--ours/--theirsã€--force\n" -"å’Œ --merge ä¸ç›¸å®¹ã€‚" +"git checkout: 從索引簽出時,--ours/--theirsã€--force å’Œ --merge ä¸ç›¸å®¹ã€‚" #: builtin/checkout.c msgid "you must specify path(s) to restore" @@ -4809,7 +4818,7 @@ msgstr "為新分支建立引用日誌" #: builtin/checkout.c msgid "second guess 'git checkout <no-such-branch>' (default)" -msgstr "二次猜測「git checkout <ç„¡æ¤åˆ†æ”¯>ã€ï¼ˆé è¨å€¼ï¼‰" +msgstr "接著猜測「git checkout <ä¸å˜åœ¨çš„分支>ã€ï¼ˆé è¨å€¼ï¼‰" #: builtin/checkout.c msgid "use overlay mode (default)" @@ -5074,7 +5083,7 @@ msgstr "建立連çµã€Œ%sã€å¤±æ•—" #: builtin/clone.c #, c-format msgid "failed to copy file to '%s'" -msgstr "複製檔案至「%sã€å¤±æ•—" +msgstr "æ‹·è²æª”案至「%sã€å¤±æ•—" #: builtin/clone.c refs/files-backend.c #, c-format @@ -6255,25 +6264,27 @@ msgstr "git config list [<檔案é¸é …>] [<顯示é¸é …>] [--includes]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp] [--value=<value>] [--fixed-value] [--default=<default>] <name>" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" msgstr "" -"git config get [<檔案é¸é …>] [<顯示é¸é …>] [--includes] [--all] [--regexp] [--" -"value=<值>] [--fixed-value] [--default=<é è¨å€¼>] <å稱>" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp] [--value=<pattern>] [--fixed-value] [--default=<default>] [--" +"url=<url>] <name>" #: builtin/config.c msgid "" -"git config set [<file-option>] [--type=<type>] [--all] [--value=<value>] [--" -"fixed-value] <name> <value>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" msgstr "" -"git config set [<檔案é¸é …>] [--type=<類型>] [--all] [--value=<值>] [--fixed-" -"value] <å稱> <值>" +"git config set [<file-option>] [--type=<type>] [--all] [--value=<pattern>] " +"[--fixed-value] <name> <value>" #: builtin/config.c msgid "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" msgstr "" -"git config unset [<file-option>] [--all] [--value=<value>] [--fixed-value] " +"git config unset [<file-option>] [--all] [--value=<pattern>] [--fixed-value] " "<name>" #: builtin/config.c @@ -6295,19 +6306,20 @@ msgstr "git config [<file-option>] --get-colorbool <name> [<stdout-is-tty>]" #: builtin/config.c msgid "" "git config get [<file-option>] [<display-option>] [--includes] [--all] [--" -"regexp=<regexp>] [--value=<value>] [--fixed-value] [--default=<default>] " +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " "<name>" msgstr "" -"git config get [<檔案é¸é …>] [<顯示é¸é …>] [--includes] [--all] [--regexp=<常è¦" -"表示å¼>] [--value=<值>] [--fixed-value] [--default=<é è¨å€¼>] <å稱>" +"git config get [<file-option>] [<display-option>] [--includes] [--all] [--" +"regexp=<regexp>] [--value=<pattern>] [--fixed-value] [--default=<default>] " +"<name>" #: builtin/config.c msgid "" "git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " -"[--value=<value>] [--fixed-value] <name> <value>" +"[--value=<pattern>] [--fixed-value] <name> <value>" msgstr "" -"git config set [<檔案é¸é …>] [--type=<類型>] [--comment=<備註>] [--all] [--" -"value=<值>] [--fixed-value] <å稱> <值>" +"git config set [<file-option>] [--type=<type>] [--comment=<message>] [--all] " +"[--value=<pattern>] [--fixed-value] <name> <value>" #: builtin/config.c msgid "Config file location" @@ -6934,7 +6946,6 @@ msgid "unable to parse object id: %s" msgstr "無法解æžç‰©ä»¶ ID:%s" #: builtin/diff-pairs.c -#| msgid "git repack [<options>]" msgid "git diff-pairs -z [<diff-options>]" msgstr "git diff-pairs -z [<diff-options>]" @@ -6975,7 +6986,7 @@ msgstr "讀å–目的地路徑時é‡åˆ° EOF" #: builtin/diff-pairs.c #, c-format msgid "unable to parse rename/copy score: %s" -msgstr "無法解æžé‡æ–°å‘½å/複製分數:%s" +msgstr "無法解æžé‡æ–°å‘½å/æ‹·è²åˆ†æ•¸ï¼š%s" #: builtin/diff-pairs.c #, c-format @@ -7068,7 +7079,7 @@ msgstr "å·¥ä½œå€æª”案被留了下來。" #: builtin/difftool.c sequencer.c #, c-format msgid "could not copy '%s' to '%s'" -msgstr "無法將「%sã€è¤‡è£½åˆ°ã€Œ%sã€" +msgstr "無法將「%sã€æ‹·è²è‡³ã€Œ%sã€" #: builtin/difftool.c #, c-format @@ -7379,27 +7390,6 @@ msgid "rejected %s because shallow roots are not allowed to be updated" msgstr "已拒絕 %s,ä¸å…許更新淺複製" #: builtin/fetch.c -#, c-format -msgid "" -"some local refs could not be updated; try running\n" -" 'git remote prune %s' to remove any old, conflicting branches" -msgstr "" -"一些本機引用ä¸èƒ½è¢«æ›´æ–°ï¼›å˜—試執行\n" -" 'git remote prune %s' ä¾†åˆªé™¤èˆŠçš„ã€æœ‰è¡çªçš„分支" - -# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ -#: builtin/fetch.c -#, c-format -msgid " (%s will become dangling)" -msgstr " (%s å°‡æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼‰" - -# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ -#: builtin/fetch.c -#, c-format -msgid " (%s has become dangling)" -msgstr " (%s å·²æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼‰" - -#: builtin/fetch.c msgid "[deleted]" msgstr "[已刪除]" @@ -7422,7 +7412,7 @@ msgstr "é¸é …「%sã€çš„值「%sã€å° %s 無效" msgid "option \"%s\" is ignored for %s" msgstr "é¸é …「%sã€è¢« %s 忽略" -#: builtin/fetch.c object-store.c +#: builtin/fetch.c odb.c #, c-format msgid "%s is not a valid object" msgstr "%s 䏿˜¯ä¸€å€‹æœ‰æ•ˆçš„物件" @@ -7441,13 +7431,27 @@ msgid "" "'git config set remote.%s.followRemoteHEAD warn-if-not-branch-%s'\n" "will disable the warning until the remote changes HEAD to something else." msgstr "" -"執行「git remote set-head %s %sã€ä¾†è·Ÿé€²æ¤å·®ç•°ï¼Œæˆ–者\n" +"執行「git remote set-head %s %sã€ä¾†è¿½è¹¤æ¤å·®ç•°ï¼Œæˆ–者\n" "å¦‚æžœæ‚¨ä¸æƒ³çœ‹åˆ°é€™å‰‡è¨Šæ¯ï¼Œè«‹å°‡ã€Œremote.%s.followRemoteHEADã€çµ„æ…‹é¸é …\n" "è¨å®šæˆåˆ¥çš„值。更具體些來說,執行\n" "「git config set remote.%s.followRemoteHEAD warn-if-not-branch-%sã€\n" "會åœç”¨é€™å€‹è¦å‘Šï¼Œç›´åˆ°é 端將 HEAD 改為指å‘å…¶ä»–æ±è¥¿ã€‚" #: builtin/fetch.c +#, c-format +msgid "" +"some local refs could not be updated; try running\n" +" 'git remote prune %s' to remove any old, conflicting branches" +msgstr "" +"一些本機引用ä¸èƒ½è¢«æ›´æ–°ï¼›å˜—試執行\n" +" 'git remote prune %s' ä¾†åˆªé™¤èˆŠçš„ã€æœ‰è¡çªçš„分支" + +#: builtin/fetch.c +#, c-format +msgid "fetching ref %s failed: %s" +msgstr "å–回 %s 引用失敗:%s" + +#: builtin/fetch.c msgid "multiple branches detected, incompatible with --set-upstream" msgstr "檢測到多分支,和 --set-upstream ä¸ç›¸å®¹" @@ -7747,6 +7751,10 @@ msgid "git for-each-ref [--contains [<commit>]] [--no-contains [<commit>]]" msgstr "git for-each-ref [--contains [<æäº¤>]] [--no-contains [<æäº¤>]]" #: builtin/for-each-ref.c +msgid "git for-each-ref [--start-after <marker>]" +msgstr "git for-each-ref [--start-after <marker>]" + +#: builtin/for-each-ref.c msgid "quote placeholders suitably for shells" msgstr "引用å ä½ç¬¦é©ç”¨æ–¼ shells" @@ -7766,6 +7774,14 @@ msgstr "引用å ä½ç¬¦é©ç”¨æ–¼ Tcl" msgid "show only <n> matched refs" msgstr "åªé¡¯ç¤º <n> 個符åˆçš„引用" +#: builtin/for-each-ref.c +msgid "marker" +msgstr "標記點" + +#: builtin/for-each-ref.c +msgid "start iteration after the provided marker" +msgstr "在指定標記點後開始è¿ä»£" + #: builtin/for-each-ref.c builtin/tag.c msgid "respect format colors" msgstr "éµç…§æ ¼å¼ä¸çš„é¡è‰²è¼¸å‡º" @@ -7799,9 +7815,17 @@ msgid "also include HEAD ref and pseudorefs" msgstr "åŒ…å« HEAD 引用和å½å¼•用" #: builtin/for-each-ref.c +msgid "cannot use --start-after with custom sort options" +msgstr "無法將 --start-after 和自訂排åºé¸é …çµåˆä½¿ç”¨" + +#: builtin/for-each-ref.c msgid "unknown arguments supplied with --stdin" msgstr "為 --stdin æä¾›çš„引數未知" +#: builtin/for-each-ref.c +msgid "cannot use --start-after with patterns" +msgstr "--start-after 無法æé… pattern 使用" + #: builtin/for-each-repo.c msgid "git for-each-repo --config=<config> [--] <arguments>" msgstr "git for-each-repo --config=<config> [--] <arguments>" @@ -8040,11 +8064,6 @@ msgid "Checking ref database" msgstr "æ£åœ¨æª¢æŸ¥å¼•用資料庫" #: builtin/fsck.c -#| msgid "" -#| "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" -#| " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" -#| " [--[no-]dangling] [--[no-]progress] [--connectivity-only]\n" -#| " [--[no-]name-objects] [<object>...]" msgid "" "git fsck [--tags] [--root] [--unreachable] [--cache] [--no-reflogs]\n" " [--[no-]full] [--strict] [--verbose] [--lost-found]\n" @@ -8309,6 +8328,10 @@ msgid "pack prefix to store a pack containing pruned objects" msgstr "å°‡å‰ç¶´æ‰“包並儲å˜ç‚ºåŒ…å«å·²å‰ªé™¤ç‰©ä»¶çš„包" #: builtin/gc.c +msgid "skip maintenance tasks typically done in the foreground" +msgstr "ç•¥éŽé€šå¸¸åœ¨å‰æ™¯å®Œæˆçš„ç¶è·ä½œæ¥" + +#: builtin/gc.c #, c-format msgid "failed to parse gc.logExpiry value %s" msgstr "ç„¡æ³•è§£æž gc.logExpiry 的值 %s" @@ -8394,13 +8417,13 @@ msgstr "ç•¥éŽå¢žé‡é‡æ–°æ‰“åŒ…å·¥ä½œï¼Œå› ç‚º core.multiPackIndex 已被åœç”¨ #: builtin/gc.c #, c-format -msgid "lock file '%s' exists, skipping maintenance" -msgstr "å·²å˜åœ¨ '%s' 鎖定檔案,略éŽç¶è·" +msgid "task '%s' failed" +msgstr "ä½œæ¥ '%s' 失敗" #: builtin/gc.c #, c-format -msgid "task '%s' failed" -msgstr "ä½œæ¥ '%s' 失敗" +msgid "lock file '%s' exists, skipping maintenance" +msgstr "å·²å˜åœ¨ '%s' 鎖定檔案,略éŽç¶è·" #: builtin/gc.c #, c-format @@ -8441,10 +8464,6 @@ msgid "run a specific task" msgstr "執行指定作æ¥" #: builtin/gc.c -msgid "use at most one of --auto and --schedule=<frequency>" -msgstr "--auto å’Œ --schedule=<é »çŽ‡> è«‹ä»»é¸ä¸€" - -#: builtin/gc.c #, c-format msgid "unable to add '%s' value of '%s'" msgstr "無法為「%2$sã€çš„å€¼åŠ ä¸Šã€Œ%1$sã€" @@ -9287,7 +9306,7 @@ msgstr "無法啟動 pack-objects 來釿–°æ‰“包本機連çµ" #: builtin/index-pack.c msgid "failed to feed local object to pack-objects" -msgstr "無法將本機物件喂給 pack-objects" +msgstr "無法將本機物件餵給 pack-objects" #: builtin/index-pack.c msgid "index-pack: Expecting full hex object ID lines only from pack-objects." @@ -9540,11 +9559,6 @@ msgstr "-L<範åœ>:<檔案> å’Œ pathspec ä¸èƒ½åŒæ™‚使用" #: builtin/log.c #, c-format -msgid "Final output: %d %s\n" -msgstr "最終輸出:%d %s\n" - -#: builtin/log.c -#, c-format msgid "git show %s: bad file" msgstr "git show %s: æå£žçš„æª”案" @@ -10155,7 +10169,7 @@ msgstr "ä¿ç•™ä¸»æ—¨ä¸ä¸æ˜¯ PATCH 的方括號" #: builtin/mailinfo.c msgid "copy Message-ID to the end of commit message" -msgstr "複製 Message-ID 至æäº¤èªªæ˜Žæœ«å°¾" +msgstr "æ‹·è² Message-ID 至æäº¤èªªæ˜Žæœ«å°¾" #: builtin/mailinfo.c msgid "re-code metadata to i18n.commitEncoding" @@ -10448,6 +10462,10 @@ msgid "(synonym to --stat)" msgstr "(和 --stat åŒç¾©ï¼‰" #: builtin/merge.c builtin/pull.c +msgid "show a compact-summary at the end of the merge" +msgstr "在åˆä½µçµå°¾é¡¯ç¤ºç²¾è¦æ‘˜è¦ (compact-summary)" + +#: builtin/merge.c builtin/pull.c msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "在åˆä½µæäº¤èªªæ˜Žä¸æ–°å¢žï¼ˆæœ€å¤š <n> æ¢ï¼‰ç²¾ç°¡æäº¤è¨˜éŒ„" @@ -10777,11 +10795,6 @@ msgstr "éŒ¯èª¤ï¼šæ¨™ç±¤è¼¸å…¥æœªé€šéŽ fsck:%s" #: builtin/mktag.c #, c-format -msgid "%d (FSCK_IGNORE?) should never trigger this callback" -msgstr "%d (FSCK_IGNORE?) 䏿‡‰è§¸ç™¼é€™å€‹å›žå‘¼å‡½å¼" - -#: builtin/mktag.c -#, c-format msgid "could not read tagged object '%s'" msgstr "ç„¡æ³•è®€å–æœ‰æ¨™ç±¤çš„物件「%sã€" @@ -10873,12 +10886,10 @@ msgid "" msgstr "在 repack 期間,將較å°å°ºå¯¸çš„包檔案收集到大於æ¤å¤§å°çš„æ‰¹æ¬¡ä¸" #: builtin/mv.c -#| msgid "git mv [<options>] <source>... <destination>" msgid "git mv [-v] [-f] [-n] [-k] <source> <destination>" msgstr "git mv [-v] [-f] [-n] [-k] <source> <destination>" #: builtin/mv.c -#| msgid "git mv [<options>] <source>... <destination>" msgid "git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>" msgstr "git mv [-v] [-f] [-n] [-k] <source>... <destination-directory>" @@ -11047,7 +11058,7 @@ msgstr "" #: builtin/notes.c msgid "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" -msgstr "git notes [--ref <註解引用>] copy [-f] <來æºç‰©ä»¶> <目標物件>" +msgstr "git notes [--ref <notes-ref>] copy [-f] <from-object> <to-object>" #: builtin/notes.c msgid "" @@ -11094,11 +11105,11 @@ msgstr "git notes add [<é¸é …>] [<物件>]" #: builtin/notes.c msgid "git notes copy [<options>] <from-object> <to-object>" -msgstr "git notes copy [<é¸é …>] <來æºç‰©ä»¶> <目標物件>" +msgstr "git notes copy [<options>] <from-object> <to-object>" #: builtin/notes.c msgid "git notes copy --stdin [<from-object> <to-object>]..." -msgstr "git notes copy --stdin [<來æºç‰©ä»¶> <目標物件>]..." +msgstr "git notes copy --stdin [<from-object> <to-object>]..." #: builtin/notes.c msgid "git notes append [<options>] [<object>]" @@ -11181,7 +11192,7 @@ msgstr "ä¸èƒ½å¾žéžè³‡æ–™ç‰©ä»¶ '%s' ä¸è®€å–註解資料。" #: builtin/notes.c #, c-format msgid "failed to copy notes from '%s' to '%s'" -msgstr "從 '%s' 複製註解到 '%s' 時失敗" +msgstr "將註解從「%sã€æ‹·è²è‡³ã€Œ%sã€å¤±æ•—" #. TRANSLATORS: the first %s will be replaced by a git #. notes command: 'add', 'merge', 'remove', etc. @@ -11270,12 +11281,12 @@ msgstr "å¤ªå°‘åƒæ•¸" msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " "existing notes" -msgstr "ä¸èƒ½è¤‡è£½è¨»è§£ã€‚發ç¾ç‰©ä»¶ %s å·²å˜åœ¨è¨»è§£ã€‚使用 '-f' 覆蓋ç¾å˜è¨»è§£" +msgstr "無法拷è²è¨»è§£ã€‚物件 %s 已有註解。使用「-fã€è¦†å¯«ç¾æœ‰çš„註解" #: builtin/notes.c #, c-format msgid "missing notes on source object %s. Cannot copy." -msgstr "來æºç‰©ä»¶ %s 缺少註解。ä¸èƒ½è¤‡è£½ã€‚" +msgstr "來æºç‰©ä»¶ %s 缺少註解。無法拷è²ã€‚" #: builtin/notes.c #, c-format @@ -11426,13 +11437,26 @@ msgid "unknown subcommand: `%s'" msgstr "æœªçŸ¥åæŒ‡ä»¤ï¼šã€Œ%sã€" #: builtin/pack-objects.c -msgid "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" -msgstr "git pack-objects --stdout [<é¸é …>] [< <引用列表> | < <物件列表>]" - -#: builtin/pack-objects.c msgid "" -"git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" -msgstr "git pack-objects [<é¸é …>] <å‰ç¶´å稱> [< <引用列表> | < <物件列表>]" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" +msgstr "" +"git pack-objects [-q | --progress | --all-progress] [--all-progress-" +"implied]\n" +" [--no-reuse-delta] [--delta-base-offset] [--non-empty]\n" +" [--local] [--incremental] [--window=<n>] [--depth=<n>]\n" +" [--revs [--unpacked | --all]] [--keep-pack=<pack-name>]\n" +" [--cruft] [--cruft-expiration=<time>]\n" +" [--stdout [--filter=<filter-spec>] | <base-name>]\n" +" [--shallow] [--keep-true-parents] [--[no-]sparse]\n" +" [--name-hash-version=<n>] [--path-walk] < <object-list>" #: builtin/pack-objects.c #, c-format @@ -11561,6 +11585,16 @@ msgid "unable to get type of object %s" msgstr "無法ç²å¾—物件 %s 類型" #: builtin/pack-objects.c +msgid "Compressing objects by path" +msgstr "æ£åœ¨æ ¹æ“šè·¯å¾‘壓縮物件" + +#: builtin/pack-objects.c +#, c-format +msgid "Path-based delta compression using up to %d thread" +msgid_plural "Path-based delta compression using up to %d threads" +msgstr[0] "使用最多 %d 個執行緒進行路徑å¼å·®ç•°å£“縮" + +#: builtin/pack-objects.c msgid "Compressing objects" msgstr "壓縮物件ä¸" @@ -11651,6 +11685,10 @@ msgid "unable to force loose object" msgstr "無法強制鬆散物件" #: builtin/pack-objects.c +msgid "failed to pack objects via path-walk" +msgstr "無法使用 path-walk å°è£ç‰©ä»¶" + +#: builtin/pack-objects.c #, c-format msgid "not a rev '%s'" msgstr "䏿˜¯ä¸€å€‹ç‰ˆæœ¬ '%s'" @@ -11795,6 +11833,10 @@ msgid "create thin packs" msgstr "建立精簡包" #: builtin/pack-objects.c +msgid "use the path-walk API to walk objects when possible" +msgstr "å¯è¡Œæ™‚使用 path-walk API 走訪物件" + +#: builtin/pack-objects.c msgid "create packs suitable for shallow fetches" msgstr "建立é©åˆæ·ºè¤‡è£½ç‰ˆæœ¬åº«å–得的包" @@ -11864,7 +11906,12 @@ msgstr "增é‡éˆæ·±åº¦ %d 太深了,強制為 %d" msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "è¨å®š pack.deltaCacheLimit 太高了,強制為 %d" -#: builtin/pack-objects.c config.c +#: builtin/pack-objects.c +#, c-format +msgid "cannot use %s with %s" +msgstr "無法將 %s 與 %s 一起使用" + +#: builtin/pack-objects.c environment.c #, c-format msgid "bad pack compression level %d" msgstr "錯誤的打包壓縮級別 %d" @@ -11882,10 +11929,6 @@ msgid "--thin cannot be used to build an indexable pack" msgstr "--thin ä¸èƒ½ç”¨æ–¼å»ºç«‹ä¸€å€‹å¯ç´¢å¼•包" #: builtin/pack-objects.c -msgid "cannot use --filter with --stdin-packs" -msgstr "無法將 --filter åŠ --stdin-packs çµåˆä½¿ç”¨" - -#: builtin/pack-objects.c msgid "cannot use internal rev list with --stdin-packs" msgstr "無法將內部版本清單與 --stdin-packs çµåˆä½¿ç”¨" @@ -11894,10 +11937,6 @@ msgid "cannot use internal rev list with --cruft" msgstr "無法é€éŽ --cruft 使用內部修訂清單" #: builtin/pack-objects.c -msgid "cannot use --stdin-packs with --cruft" -msgstr "無法將 --stdin-packs 與 --cruft 組åˆä½¿ç”¨" - -#: builtin/pack-objects.c msgid "Enumerating objects" msgstr "枚舉物件" @@ -11910,24 +11949,6 @@ msgstr "" "總共 %<PRIu32> (差異 %<PRIu32>),復用 %<PRIu32> (差異 %<PRIu32>),é‡ç”¨åŒ… " "%<PRIu32> (總共 %<PRIuMAX>)" -#: builtin/pack-redundant.c -msgid "" -"'git pack-redundant' is nominated for removal.\n" -"If you still use this command, please add an extra\n" -"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 "" -"「git pack-redundantã€å·²è¢«æå準備移除。\n" -"如果您ä»åœ¨ä½¿ç”¨é€™æ¢å‘½ä»¤ï¼Œè«‹åœ¨å‘½ä»¤åˆ—å¤šåŠ ä¸€å€‹é¸é …\n" -"「--i-still-use-thisã€ï¼Œç„¶å¾Œå¯„å°é›»å信到\n" -"<git@vger.kernel.org> è®“æˆ‘å€‘çŸ¥é“æ‚¨é‚„在使用。\n" -"感è¬ã€‚\n" - -#: builtin/pack-redundant.c -msgid "refusing to run without --i-still-use-this" -msgstr "傳入 --i-still-use-this 剿‹’絕執行" - #: builtin/pack-refs.c msgid "" "git pack-refs [--all] [--no-prune] [--auto] [--include <pattern>] [--exclude " @@ -13451,6 +13472,16 @@ msgid "unknown --mirror argument: %s" msgstr "未知的 --mirror 引數:%s" #: builtin/remote.c +#, c-format +msgid "remote name '%s' is a subset of existing remote '%s'" +msgstr "å為「%sã€çš„é 端是「%sã€ç¾æœ‰é 端的å集" + +#: builtin/remote.c +#, c-format +msgid "remote name '%s' is a superset of existing remote '%s'" +msgstr "å為「%sã€çš„é 端是「%sã€ç¾æœ‰é 端的超集" + +#: builtin/remote.c msgid "fetch the remote branches" msgstr "抓å–é 端的分支" @@ -13812,18 +13843,6 @@ msgstr "䏿˜¯ä¸€å€‹æœ‰æ•ˆå¼•用:%s" msgid "Could not set up %s" msgstr "無法é…ç½® %s" -# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ -#: builtin/remote.c -#, c-format -msgid " %s will become dangling!" -msgstr " %s å°‡æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼" - -# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ -#: builtin/remote.c -#, c-format -msgid " %s has become dangling!" -msgstr " %s å·²æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼" - #: builtin/remote.c #, c-format msgid "Pruning %s" @@ -13907,11 +13926,11 @@ msgstr "è©³ç´°è¼¸å‡ºï¼›å¿…é ˆç½®æ–¼åæŒ‡ä»¤ä¹‹å‰" msgid "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" msgstr "" "git repack [-a] [-A] [-d] [-f] [-F] [-l] [-n] [-q] [-b] [-m]\n" "[--window=<n>] [--depth=<n>] [--threads=<n>] [--keep-pack=<pack-name>]\n" -"[--write-midx] [--name-hash-version=<n>]" +"[--write-midx] [--name-hash-version=<n>] [--path-walk]" #: builtin/repack.c msgid "" @@ -14013,6 +14032,10 @@ msgid "" msgstr "指定è¦ç”¨ä¾†ä»¥è·¯å¾‘為相似物件分組的å稱雜湊版本" #: builtin/repack.c +msgid "pass --path-walk to git-pack-objects" +msgstr "å°‡ --path-walk 傳éžçµ¦ git-pack-objects" + +#: builtin/repack.c msgid "do not run git-update-server-info" msgstr "ä¸åŸ·è¡Œ git-update-server-info" @@ -15429,20 +15452,28 @@ msgid "git stash create [<message>]" msgstr "git stash create [<message>]" #: builtin/stash.c +msgid "git stash export (--print | --to-ref <ref>) [<stash>...]" +msgstr "git stash export (--print | --to-ref <ref>) [<stash>...]" + +#: builtin/stash.c +msgid "git stash import <commit>" +msgstr "git stash import <commit>" + +#: builtin/stash.c #, c-format msgid "'%s' is not a stash-like commit" msgstr "'%s' ä¸åƒæ˜¯ä¸€å€‹è²¯å˜æäº¤" #: builtin/stash.c +msgid "No stash entries found." +msgstr "未發ç¾è²¯å˜æ¢ç›®ã€‚" + +#: builtin/stash.c #, c-format msgid "Too many revisions specified:%s" msgstr "指定了太多的版本:%s" #: builtin/stash.c -msgid "No stash entries found." -msgstr "未發ç¾è²¯å˜æ¢ç›®ã€‚" - -#: builtin/stash.c #, c-format msgid "%s is not a valid reference" msgstr "%s 䏿˜¯ä¸€å€‹æœ‰æ•ˆçš„引用å" @@ -15637,6 +15668,86 @@ msgstr "貯å˜ä¸åŒ…嫿œªè¿½è¹¤æª”案" msgid "include ignore files" msgstr "包å«å¿½ç•¥çš„æª”案" +#: builtin/stash.c +#, c-format +msgid "cannot parse commit %s" +msgstr "ç„¡æ³•è§£æžæäº¤ %s" + +#: builtin/stash.c +#, c-format +msgid "invalid author or committer for %s" +msgstr "%s 的作者或æäº¤è€…無效" + +#: builtin/stash.c +msgid "could not write commit" +msgstr "無法寫入æäº¤" + +#: builtin/stash.c +#, c-format +msgid "not a valid revision: %s" +msgstr "䏿˜¯æœ‰æ•ˆçš„修訂版:%s" + +#: builtin/stash.c +#, c-format +msgid "not a commit: %s" +msgstr "䏿˜¯æäº¤ï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "%s is not a valid exported stash commit" +msgstr "%s 䏿˜¯æœ‰æ•ˆçš„åŒ¯å‡ºè²¯å˜æäº¤" + +#: builtin/stash.c +#, c-format +msgid "found root commit %s with invalid data" +msgstr "找到 %s æ ¹æäº¤ï¼Œå…§æœ‰ç„¡æ•ˆè³‡æ–™" + +#: builtin/stash.c +#, c-format +msgid "found stash commit %s without expected prefix" +msgstr "找到 %s è²¯å˜æäº¤ï¼Œè£¡é¢ç¼ºå°‘é æœŸçš„å‰ç¶´" + +#: builtin/stash.c +#, c-format +msgid "cannot parse parents of commit: %s" +msgstr "ç„¡æ³•è§£æžæäº¤çš„çˆ¶ç‰©ä»¶ï¼š%s" + +#: builtin/stash.c +#, c-format +msgid "%s does not look like a stash commit" +msgstr "%s ä¼¼ä¹Žä¸æ˜¯è²¯å˜æäº¤" + +#: builtin/stash.c +#, c-format +msgid "cannot read commit buffer for %s" +msgstr "ç„¡æ³•è®€å– %s çš„æäº¤ç·©è¡å€" + +#: builtin/stash.c +#, c-format +msgid "cannot save the stash for %s" +msgstr "ç„¡æ³•å„²å˜ %s 的貯å˜" + +#: builtin/stash.c +msgid "unable to write base commit" +msgstr "無法寫入基礎æäº¤" + +#: builtin/stash.c +#, c-format +msgid "unable to find stash entry %s" +msgstr "找ä¸åˆ°è²¯å˜é …ç›® %s" + +#: builtin/stash.c +msgid "print the object ID instead of writing it to a ref" +msgstr "輸出物件 ID 而éžå°‡å…¶å¯«å…¥å¼•用" + +#: builtin/stash.c +msgid "save the data to the given ref" +msgstr "將資料å˜å…¥æŒ‡å®šå¼•用" + +#: builtin/stash.c +msgid "exactly one of --print and --to-ref is required" +msgstr "éœ€è¦æŒ‡å®š --print 或 --to-ref å…¶ä¸ä¸€å€‹" + #: builtin/stripspace.c msgid "skip and remove all lines starting with comment character" msgstr "ç•¥éŽå’Œç§»é™¤æ‰€æœ‰çš„備註行" @@ -15647,8 +15758,10 @@ msgstr "為æ¯ä¸€è¡Œçš„è¡Œé¦–æ–°å¢žå‚™è¨»ç¬¦å’Œç©ºæ ¼" #: builtin/submodule--helper.c #, c-format -msgid "Expecting a full ref name, got %s" -msgstr "期望一個完整的引用å稱,å»å¾—到 %s" +msgid "" +"could not look up configuration '%s'. Assuming this repository is its own " +"authoritative upstream." +msgstr "找ä¸åˆ°ã€Œ%sã€çµ„æ…‹è¨å®šã€‚å‡å®šé€™å€‹ç‰ˆæœ¬åº«æ˜¯å…¶è‡ªèº«çš„官方上游。" #: builtin/submodule--helper.c #, c-format @@ -15657,13 +15770,6 @@ msgstr "無法å–得忍¡çµ„「%sã€çš„版本庫控制代碼" #: builtin/submodule--helper.c #, c-format -msgid "" -"could not look up configuration '%s'. Assuming this repository is its own " -"authoritative upstream." -msgstr "找ä¸åˆ°ã€Œ%sã€çµ„æ…‹è¨å®šã€‚å‡å®šé€™å€‹ç‰ˆæœ¬åº«æ˜¯å…¶è‡ªèº«çš„官方上游。" - -#: builtin/submodule--helper.c -#, c-format msgid "No url found for submodule path '%s' in .gitmodules" msgstr "在 .gitmodules 䏿œªæ‰¾åˆ°å模組 '%s' çš„ url" @@ -15920,7 +16026,7 @@ msgstr "ä¸èƒ½è˜åˆ¥ submodule.alternateLocation çš„å–值 '%s'" #: builtin/submodule--helper.c submodule.c #, c-format msgid "refusing to create/use '%s' in another submodule's git dir" -msgstr "æ‹’çµ•åœ¨å…¶ä»–åæ¨¡çµ„çš„ git 路徑建立ï¼ä½¿ç”¨ã€Œ%sã€" +msgstr "æ‹’çµ•åœ¨å…¶ä»–åæ¨¡çµ„çš„ git 目錄ä¸å»ºç«‹/使用「%sã€" #: builtin/submodule--helper.c #, c-format @@ -16080,6 +16186,11 @@ msgstr "忍¡çµ„(%s)的分支è¨å®šç‚ºç¹¼æ‰¿ä¸Šç´šå°ˆæ¡ˆçš„分支,但是ä #: builtin/submodule--helper.c #, c-format +msgid "Expecting a full ref name, got %s" +msgstr "期望一個完整的引用å稱,å»å¾—到 %s" + +#: builtin/submodule--helper.c +#, c-format msgid "Unable to find current revision in submodule path '%s'" msgstr "ç„¡æ³•åœ¨åæ¨¡çµ„路徑「%sã€ä¸å°‹æ‰¾ç›®å‰çš„修訂版本" @@ -16325,6 +16436,11 @@ msgstr "版本庫 URL:「%sã€å¿…é ˆæ˜¯çµ•å°è·¯å¾‘ï¼Œæˆ–é–‹é æ˜¯ ./|../" #: builtin/submodule--helper.c #, c-format +msgid "submodule name '%s' already used for path '%s'" +msgstr "「%sã€å模組å稱已被「%sã€è·¯å¾‘使用" + +#: builtin/submodule--helper.c +#, c-format msgid "'%s' is not a valid submodule name" msgstr "「%sã€ä¸æ˜¯æœ‰æ•ˆçš„忍¡çµ„å稱" @@ -16856,7 +16972,6 @@ msgid "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" msgstr "git update-ref [<options>] <refname> <new-oid> [<old-oid>]" #: builtin/update-ref.c -#| msgid "git update-ref [<options>] --stdin [-z]" msgid "git update-ref [<options>] --stdin [-z] [--batch-updates]" msgstr "git update-ref [<options>] --stdin [-z] [--batch-updates]" @@ -17054,12 +17169,12 @@ msgstr "" #: builtin/worktree.c #, c-format msgid "failed to copy '%s' to '%s'; sparse-checkout may not work correctly" -msgstr "無法將「%sã€è¤‡è£½åˆ°ã€Œ%sã€ï¼›ç¨€ç–簽出å¯èƒ½ç„¡æ³•æ£å¸¸é‹ä½œ" +msgstr "將「%sã€æ‹·è²è‡³ã€Œ%sã€å¤±æ•—;稀ç–簽出å¯èƒ½ç„¡æ³•æ£å¸¸é‹ä½œ" #: builtin/worktree.c #, c-format msgid "failed to copy worktree config from '%s' to '%s'" -msgstr "無法將工作å€çµ„態從「%sã€è¤‡è£½åˆ°ã€Œ%sã€" +msgstr "將工作å€çµ„態從「%sã€æ‹·è²è‡³ã€Œ%sã€å¤±æ•—" #: builtin/worktree.c #, c-format @@ -17097,11 +17212,6 @@ msgstr "準備工作å€ï¼ˆç°½å‡º '%s')" #: builtin/worktree.c #, c-format -msgid "unreachable: invalid reference: %s" -msgstr "ä¸å¯é”:無效引用:%s" - -#: builtin/worktree.c -#, c-format msgid "Preparing worktree (detached HEAD %s)" msgstr "準備工作å€ï¼ˆåˆ†é›¢é–‹é 指標 %s)" @@ -17629,7 +17739,7 @@ msgstr "切æ›åˆ†æ”¯æˆ–å¾©åŽŸå·¥ä½œå€æª”案" #: command-list.h msgid "Copy files from the index to the working tree" -msgstr "從索引複製檔案到工作å€" +msgstr "å¾žç´¢å¼•å€æ‹·è²æª”案至工作å€" #: command-list.h msgid "Find commits yet to be applied to upstream" @@ -18804,7 +18914,7 @@ msgstr "[GLE %ld] 無法å–得「%lsã€çš„通訊å”定資訊" #: compat/mingw.c #, c-format msgid "failed to copy SID (%ld)" -msgstr "無法複製 SID (%ld)" +msgstr "æ‹·è² SID 失敗(%ld)" #: compat/mingw.c #, c-format @@ -19113,16 +19223,6 @@ msgstr "在 %3$s ä¸è¨å®šè®Šæ•¸ '%2$s' 錯誤的å–值 '%1$s':%4$s" #: config.c #, c-format -msgid "invalid value for variable %s" -msgstr "%s 變數的值無效" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsync component '%s'" -msgstr "忽略未知的 core.fsync 元件「%sã€" - -#: config.c -#, c-format msgid "bad boolean config value '%s' for '%s'" msgstr "「%2$sã€çš„「%1$sã€å¸ƒæž—è¨å®šå€¼ç„¡æ•ˆ" @@ -19138,54 +19238,6 @@ msgstr "'%2$s' 的值 '%1$s' 䏿˜¯ä¸€å€‹æœ‰æ•ˆçš„æ™‚間戳" #: config.c #, c-format -msgid "abbrev length out of range: %d" -msgstr "縮寫長度超出範åœï¼š%d" - -#: config.c -#, c-format -msgid "bad zlib compression level %d" -msgstr "錯誤的 zlib 壓縮級別 %d" - -#: config.c -#, c-format -msgid "%s cannot contain newline" -msgstr "%s ä¸èƒ½åŒ…嫿›è¡Œç¬¦è™Ÿ" - -#: config.c -#, c-format -msgid "%s must have at least one character" -msgstr "%s 得有至少 1 個å—å…ƒ" - -#: config.c -#, c-format -msgid "ignoring unknown core.fsyncMethod value '%s'" -msgstr "忽略未知的 core.fsyncMethod 值「%sã€" - -#: config.c -msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" -msgstr "core.fsyncObjectFiles 已棄用。請改用 core.fsync" - -#: config.c -#, c-format -msgid "invalid mode for object creation: %s" -msgstr "無效的物件建立模å¼ï¼š%s" - -#: config.c -#, c-format -msgid "malformed value for %s" -msgstr "%s çš„å–å€¼æ ¼å¼éŒ¯èª¤" - -#: config.c -#, c-format -msgid "malformed value for %s: %s" -msgstr "%s çš„å–å€¼æ ¼å¼éŒ¯èª¤ï¼š%s" - -#: config.c -msgid "must be one of nothing, matching, simple, upstream or current" -msgstr "å¿…é ˆæ˜¯å…¶ä¸ä¹‹ä¸€ï¼šnothingã€matchingã€simpleã€upstream 或 current" - -#: config.c -#, c-format msgid "unable to load config blob object '%s'" msgstr "無法從資料物件 '%s' 載入è¨å®š" @@ -19509,7 +19561,7 @@ msgstr "%s ä¸çš„ CRLF 將被 LF å–代" msgid "" "in the working copy of '%s', CRLF will be replaced by LF the next time Git " "touches it" -msgstr "在「%sã€çš„工作複本ä¸ï¼Œä¸‹æ¬¡ Git 接觸到時會用 LF å–代 CRLF" +msgstr "下次 Git å˜å–「%sã€çš„工作複本時會以 LF å–代 CRLF" #: convert.c #, c-format @@ -19521,7 +19573,7 @@ msgstr "檔案 %s ä¸çš„ LF 將被 CRLF å–代" msgid "" "in the working copy of '%s', LF will be replaced by CRLF the next time Git " "touches it" -msgstr "在「%sã€çš„工作複本ä¸ï¼Œä¸‹æ¬¡ Git 接觸到時會用 CRLF å–代 LF" +msgstr "下次 Git å˜å–「%sã€çš„工作複本時會以 CRLF å–代 LF" #: convert.c #, c-format @@ -19797,8 +19849,8 @@ msgid "cannot compare a named pipe to a directory" msgstr "無法比å°å‘½å管線 (pipe) 和目錄" #: diff-no-index.c -msgid "git diff --no-index [<options>] <path> <path>" -msgstr "git diff --no-index [<é¸é …>] <路徑> <路徑>" +msgid "git diff --no-index [<options>] <path> <path> [<pathspec>...]" +msgstr "git diff --no-index [<options>] <path> <path> [<pathspec>...]" #: diff-no-index.c msgid "" @@ -19806,6 +19858,12 @@ msgid "" "tree" msgstr "䏿˜¯ä¸€å€‹ git 版本庫。使用 --no-index 比較工作å€ä¹‹å¤–的兩個路徑" +#: diff-no-index.c +msgid "" +"Limiting comparison with pathspecs is only supported if both paths are " +"directories." +msgstr "åªç•¶å…©å€‹è·¯å¾‘éƒ½æ˜¯ç›®éŒ„æ™‚ï¼Œæ‰æ”¯æ´ä½¿ç”¨è·¯å¾‘è¦æ ¼é™åˆ¶æ¯”è¼ƒé …ç›®ã€‚" + # è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ #: diff.c #, c-format @@ -19984,7 +20042,7 @@ msgstr "生æˆä¿®è£œæª”" msgid "<n>" msgstr "<n>" -#: diff.c +#: diff.c parse-options.h msgid "generate diffs with <n> lines context" msgstr "生æˆå« <n> 行上下文的差異" @@ -20131,7 +20189,7 @@ msgstr "ä¸é¡¯ç¤ºä»»ä½•來æºå’Œç›®çš„地å‰ç¶´" msgid "use default prefixes a/ and b/" msgstr "使用é è¨çš„å‰ç½®å稱 a/ å’Œ b/" -#: diff.c +#: diff.c parse-options.h msgid "show context between diff hunks up to the specified number of lines" msgstr "顯示指定行數的差異å€å¡Šé–“的上下文" @@ -20173,11 +20231,11 @@ msgstr "çœç•¥åˆªé™¤è®Šæ›´çš„差異輸出" #: diff.c msgid "detect copies" -msgstr "檢測複製" +msgstr "檢測拷è²" #: diff.c msgid "use unmodified files as source to find copies" -msgstr "使用未修改的檔案åšç‚ºç™¼ç¾æ‹·è²çš„來æº" +msgstr "使用未修改的檔案作為尋找拷è²çš„來æº" #: diff.c msgid "disable rename detection" @@ -20195,7 +20253,7 @@ msgstr "ç¹¼çºŒåˆ—å‡ºæª”æ¡ˆé‡æ–°å‘½å以外的æ·å²è¨˜éŒ„" msgid "" "prevent rename/copy detection if the number of rename/copy targets exceeds " "given limit" -msgstr "å¦‚æžœé‡æ–°å‘½å/è¤‡è£½ç›®æ¨™è¶…éŽæä¾›çš„é™åˆ¶ï¼Œç¦æ¢é‡æ–°å‘½å/複製檢測" +msgstr "å¦‚æžœé‡æ–°å‘½å/æ‹·è²çš„目標數é‡è¶…出æä¾›çš„é™åº¦ï¼Œå‰‡é˜²æ¢æª¢æ¸¬é‡æ–°å‘½å/æ‹·è²" #: diff.c msgid "Diff algorithm options" @@ -20405,7 +20463,7 @@ msgstr "å› ç‚ºæª”æ¡ˆå¤ªå¤šï¼Œå·²ç•¥éŽè©³ç´°é‡æ–°å‘½å嵿¸¬ã€‚" #: diff.c msgid "only found copies from modified paths due to too many files." -msgstr "å› ç‚ºæª”æ¡ˆå¤ªå¤šï¼Œåªåœ¨ä¿®æ”¹çš„路徑ä¸å°‹æ‰¾è¤‡è£½ã€‚" +msgstr "å› ç‚ºæª”æ¡ˆå¤ªå¤šï¼Œåªåœ¨æœ‰ä¿®æ”¹çš„路徑ä¸å°‹æ‰¾äº†è¤‡æœ¬ã€‚" #: diff.c #, c-format @@ -20516,6 +20574,64 @@ msgstr "無法 stat 檔案「%sã€" msgid "bad git namespace path \"%s\"" msgstr "錯誤的 git åå—空間路徑 \"%s\"" +#: environment.c +#, c-format +msgid "invalid value for variable %s" +msgstr "%s 變數的值無效" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsync component '%s'" +msgstr "忽略未知的 core.fsync 元件「%sã€" + +#: environment.c +#, c-format +msgid "abbrev length out of range: %d" +msgstr "縮寫長度超出範åœï¼š%d" + +#: environment.c +#, c-format +msgid "bad zlib compression level %d" +msgstr "錯誤的 zlib 壓縮級別 %d" + +#: environment.c +#, c-format +msgid "%s cannot contain newline" +msgstr "%s ä¸èƒ½åŒ…嫿›è¡Œç¬¦è™Ÿ" + +#: environment.c +#, c-format +msgid "%s must have at least one character" +msgstr "%s 得有至少 1 個å—å…ƒ" + +#: environment.c +#, c-format +msgid "ignoring unknown core.fsyncMethod value '%s'" +msgstr "忽略未知的 core.fsyncMethod 值「%sã€" + +#: environment.c +msgid "core.fsyncObjectFiles is deprecated; use core.fsync instead" +msgstr "core.fsyncObjectFiles 已棄用。請改用 core.fsync" + +#: environment.c +#, c-format +msgid "invalid mode for object creation: %s" +msgstr "無效的物件建立模å¼ï¼š%s" + +#: environment.c +#, c-format +msgid "malformed value for %s" +msgstr "%s çš„å–å€¼æ ¼å¼éŒ¯èª¤" + +#: environment.c +#, c-format +msgid "malformed value for %s: %s" +msgstr "%s çš„å–å€¼æ ¼å¼éŒ¯èª¤ï¼š%s" + +#: environment.c +msgid "must be one of nothing, matching, simple, upstream or current" +msgstr "å¿…é ˆæ˜¯å…¶ä¸ä¹‹ä¸€ï¼šnothingã€matchingã€simpleã€upstream 或 current" + #: exec-cmd.c #, c-format msgid "too many args to run %s" @@ -21372,6 +21488,35 @@ msgstr "ä¸å…許空的姓åï¼ˆå°æ–¼ <%s>)" msgid "name consists only of disallowed characters: %s" msgstr "å§“åä¸åƒ…包å«åœç”¨å—元:%s" +#: imap-send.c +msgid "git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" +msgstr "" +"git imap-send [-v] [-q] [--[no-]curl] [(--folder|-f) <folder>] < <mbox>" + +#: imap-send.c +msgid "no IMAP host specified" +msgstr "沒有指定 IMAP 主機" + +#: imap-send.c +msgid "" +"set the IMAP host with 'git config imap.host <host>'.\n" +"(e.g., 'git config imap.host imaps://imap.example.com')" +msgstr "" +"使用「git config imap.host <主機>ã€ä¾†è¨å®š IMAP 主機。\n" +"(比如「git config imap.host imaps://imap.example.comã€ï¼‰" + +#: imap-send.c +msgid "no IMAP folder specified" +msgstr "沒有指定 IMAP 資料夾" + +#: imap-send.c +msgid "" +"set the target folder with 'git config imap.folder <folder>'.\n" +"(e.g., 'git config imap.folder Drafts')" +msgstr "" +"使用「git config imap.folder <資料夾>ã€æŒ‡å®šç›®çš„地資料夾。\n" +"(比如「git config imap.folder Draftsã€ï¼‰" + #: list-objects-filter-options.c msgid "expected 'tree:<depth>'" msgstr "期望 'tree:<深度>'" @@ -22511,113 +22656,113 @@ msgstr "éœ€è¦æŒ‡å®š <object>:<path>,å»åªæŒ‡å®š <object>「%sã€" msgid "invalid object name '%.*s'." msgstr "'%.*s' 物件å稱無效。" -#: object-store.c +#: object.c +#, c-format +msgid "invalid object type \"%s\"" +msgstr "無效的物件類型 \"%s\"" + +#: object.c +#, c-format +msgid "object %s is a %s, not a %s" +msgstr "物件 %s 是一個 %sï¼Œä¸æ˜¯ä¸€å€‹ %s" + +#: object.c +#, c-format +msgid "object %s has unknown type id %d" +msgstr "物件 %s 有未知的類型 id %d" + +#: object.c +#, c-format +msgid "unable to parse object: %s" +msgstr "ä¸èƒ½è§£æžç‰©ä»¶ï¼š%s" + +#: object.c +#, c-format +msgid "hash mismatch %s" +msgstr "雜湊值與 %s ä¸ç¬¦åˆ" + +#: odb.c #, c-format msgid "object directory %s does not exist; check .git/objects/info/alternates" msgstr "物件目錄 %s ä¸å˜åœ¨ï¼Œæª¢æŸ¥ .git/objects/info/alternates" -#: object-store.c +#: odb.c #, c-format msgid "unable to normalize alternate object path: %s" msgstr "無法è¦ç¯„化備用物件路徑:%s" -#: object-store.c +#: odb.c #, c-format msgid "%s: ignoring alternate object stores, nesting too deep" msgstr "%s:忽略備用物件庫,嵌套太深" -#: object-store.c +#: odb.c msgid "unable to fdopen alternates lockfile" msgstr "無法 fdopen å–代鎖檔案" -#: object-store.c +#: odb.c msgid "unable to read alternates file" msgstr "ç„¡æ³•è®€å–æ›¿ä»£æª”案" -#: object-store.c +#: odb.c msgid "unable to move new alternates file into place" msgstr "無法將新的替代檔案移動到ä½" -#: object-store.c +#: odb.c #, c-format msgid "path '%s' does not exist" msgstr "路徑 '%s' ä¸å˜åœ¨" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "å°šä¸æ”¯æ´å°‡å¼•用版本庫 '%s' 作為一個連çµç°½å‡ºã€‚" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is not a local repository." msgstr "引用版本庫 '%s' 䏿˜¯ä¸€å€‹æœ¬æ©Ÿç‰ˆæœ¬åº«ã€‚" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is shallow" msgstr "引用版本庫 '%s' 是一個淺複製" -#: object-store.c +#: odb.c #, c-format msgid "reference repository '%s' is grafted" msgstr "引用版本庫 '%s' 已被移æ¤" -#: object-store.c +#: odb.c #, c-format msgid "could not find object directory matching %s" msgstr "找ä¸åˆ°ç¬¦åˆ %s 的物件目錄" -#: object-store.c +#: odb.c #, c-format msgid "invalid line while parsing alternate refs: %s" msgstr "è§£æžå‚™ç”¨å¼•用時無效的行:%s" -#: object-store.c +#: odb.c #, c-format msgid "replacement %s not found for %s" msgstr "找ä¸åˆ° %2$s 的替代 %1$s" -#: object-store.c +#: odb.c #, c-format msgid "packed object %s (stored in %s) is corrupt" msgstr "打包物件 %s(儲å˜åœ¨ %s)已æå£ž" -#: object-store.c +#: odb.c #, c-format msgid "missing mapping of %s to %s" msgstr "缺少 %s 到 %s çš„æ˜ å°„" -#: object-store.c +#: odb.c #, c-format msgid "%s is not a valid '%s' object" msgstr "%s 䏿˜¯ä¸€å€‹æœ‰æ•ˆçš„ '%s' 物件" -#: object.c -#, c-format -msgid "invalid object type \"%s\"" -msgstr "無效的物件類型 \"%s\"" - -#: object.c -#, c-format -msgid "object %s is a %s, not a %s" -msgstr "物件 %s 是一個 %sï¼Œä¸æ˜¯ä¸€å€‹ %s" - -#: object.c -#, c-format -msgid "object %s has unknown type id %d" -msgstr "物件 %s 有未知的類型 id %d" - -#: object.c -#, c-format -msgid "unable to parse object: %s" -msgstr "ä¸èƒ½è§£æžç‰©ä»¶ï¼š%s" - -#: object.c -#, c-format -msgid "hash mismatch %s" -msgstr "雜湊值與 %s ä¸ç¬¦åˆ" - #: pack-bitmap-write.c #, c-format msgid "duplicate entry when writing bitmap index: %s" @@ -22632,10 +22777,6 @@ msgstr "å˜—è©¦å„²å˜æœªé¸å–çš„æäº¤ï¼šã€Œ%sã€" msgid "too many pseudo-merges" msgstr "å½åˆä½µéŽå¤š" -#: pack-bitmap-write.c -msgid "trying to write commit not in index" -msgstr "嘗試寫入ä¸åœ¨ç´¢å¼•çš„æäº¤" - #: pack-bitmap.c msgid "failed to load bitmap index (corrupted?)" msgstr "無法載入ä½åœ–索引(æå£žï¼Ÿï¼‰" @@ -22940,6 +23081,11 @@ msgstr "%s ä¸å¯ç”¨" #: parse-options.c #, c-format +msgid "value for %s exceeds %<PRIdMAX>" +msgstr "%s çš„å€¼è¶…éŽ %<PRIdMAX>" + +#: parse-options.c +#, c-format msgid "value %s for %s not in range [%<PRIdMAX>,%<PRIdMAX>]" msgstr "%2$s 的數值 %1$s ä¸åœ¨ [%3$<PRIdMAX>,%4$<PRIdMAX>] 範åœå…§" @@ -24091,6 +24237,18 @@ msgstr "沒有 '%s' 的引用日誌" msgid "%s does not point to a valid object!" msgstr "%s 沒有指å‘一個有效的物件ï¼" +# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ +#: refs.c +#, c-format +msgid "%s%s will become dangling after %s is deleted\n" +msgstr "在刪除 %3$s 之後,%1$s%2$s 將進入懸空狀態\n" + +# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ +#: refs.c +#, c-format +msgid "%s%s has become dangling after %s was deleted\n" +msgstr "在刪除 %3$s 後,%1$s%2$s 已經是懸空狀態\n" + #: refs.c #, c-format msgid "" @@ -24324,7 +24482,7 @@ msgstr "找ä¸åˆ°å¼•用å稱 %s" #: refs/reftable-backend.c #, c-format msgid "refname %s is a symbolic ref, copying it is not supported" -msgstr "引用å稱 %s æ˜¯ç¬¦è™Ÿå¼•ç”¨ï¼Œä¸æ”¯æ´è¤‡è£½" +msgstr "引用å稱 %s 是象徵å¼å¼•ç”¨ï¼Œä¸æ”¯æ´æ‹·è²" #: refspec.c #, c-format @@ -25047,9 +25205,6 @@ msgid "specify if background maintenance should be enabled" msgstr "指定是å¦è¦å•Ÿç”¨èƒŒæ™¯ç¶è·æ¨¡å¼" #: scalar.c -#| msgid "" -#| "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" -#| "\t[--[no-]src] [--[no-]tags] <url> [<enlistment>]" msgid "" "scalar clone [--single-branch] [--branch <main-branch>] [--full-clone]\n" "\t[--[no-]src] [--[no-]tags] [--[no-]maintenance] <url> [<enlistment>]" @@ -25104,7 +25259,6 @@ msgid "`scalar list` does not take arguments" msgstr "`scalar list` 未å–引數" #: scalar.c -#| msgid "scalar register [<enlistment>]" msgid "scalar register [--[no-]maintenance] [<enlistment>]" msgstr "scalar register [--[no-]maintenance] [<enlistment>]" @@ -25113,7 +25267,6 @@ msgid "reconfigure all registered enlistments" msgstr "釿–°è¨å®šæ‰€æœ‰è¨»å†Šçš„編列åå–®" #: scalar.c -#| msgid "enable/disable untracked cache" msgid "(enable|disable|keep)" msgstr "(enable|disable|keep)" @@ -25122,7 +25275,6 @@ msgid "signal how to adjust background maintenance" msgstr "指示調整背景ç¶è·æ¨¡å¼çš„æ–¹å¼" #: scalar.c -#| msgid "scalar reconfigure [--all | <enlistment>]" msgid "" "scalar reconfigure [--maintenance=(enable|disable|keep)] [--all | " "<enlistment>]" @@ -25137,7 +25289,7 @@ msgstr "--all 或 <enlistment> 但ä¸èƒ½å‚³å…¥å…©è€…" #: scalar.c #, c-format msgid "unknown mode for --maintenance option: %s" -msgstr "--maintenance é¸é …的值無效:%s" +msgstr "æä¾›çš„ --maintenance 模å¼ç„¡æ•ˆï¼š%s" #: scalar.c #, c-format @@ -25534,7 +25686,7 @@ msgstr "建立æäº¤å¾Œï¼Œä¸èƒ½è§£æž HEAD" #: sequencer.c msgid "detached HEAD" -msgstr "分離 HEAD" +msgstr "分離 HEAD 指標" # è¯è€…ï¼šä¸æ–‡å—串拼接,å¯åˆªé™¤å‰å°Žç©ºæ ¼ #: sequencer.c @@ -26460,7 +26612,7 @@ msgstr "ä¸èƒ½è‡ª '%s' 到 '%s' 建立符號連çµ" #: setup.c #, c-format msgid "cannot copy '%s' to '%s'" -msgstr "ä¸èƒ½è¤‡è£½ '%s' 至 '%s'" +msgstr "無法將「%sã€æ‹·è²è‡³ã€Œ%sã€" #: setup.c #, c-format @@ -26475,7 +26627,7 @@ msgstr "沒有在 %s 䏿‰¾åˆ°ç¯„本" #: setup.c #, c-format msgid "not copying templates from '%s': %s" -msgstr "沒有從 '%s' 複製範本:%s" +msgstr "未從「%sã€æ‹·è²ç¯„本:%s" #: setup.c #, c-format @@ -26877,8 +27029,12 @@ msgid "toggle pruning of uninteresting paths" msgstr "åˆ‡æ›æ˜¯å¦å‰ªé™¤ä¸é‡è¦è·¯å¾‘" #: t/helper/test-path-walk.c +msgid "toggle aggressive edge walk" +msgstr "åˆ‡æ›æ˜¯å¦æ›´æ¿€é€²åœ°èµ°è¨ªé‚Š" + +#: t/helper/test-path-walk.c msgid "read a pattern list over stdin" -msgstr "å¾žæ¨™æº–è¼¸å…¥è®€å–æ¨¡å¼æ¸…å–®" +msgstr "從 stdin è®€å–æ¨¡å¼æ¸…å–®" #: t/helper/test-reach.c #, c-format @@ -27184,7 +27340,7 @@ msgstr "%s 執行緒ç‰å¾…失敗:%s" #: transport-helper.c #, c-format msgid "can't start thread for copying data: %s" -msgstr "ä¸èƒ½å•Ÿå‹•執行緒來複製資料:%s" +msgstr "無法啟動執行緒來拷è²è³‡æ–™: %s" #: transport-helper.c #, c-format @@ -27198,7 +27354,7 @@ msgstr "%s 進程失敗" #: transport-helper.c msgid "can't start thread for copying data" -msgstr "ä¸èƒ½å•Ÿå‹•執行緒來複製資料" +msgstr "無法啟動執行緒來拷è²è³‡æ–™" #: transport.c #, c-format @@ -27627,6 +27783,24 @@ msgstr "錯誤: " msgid "warning: " msgstr "è¦å‘Š: " +#: usage.c +#, c-format +msgid "" +"'%s' 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 "" +"「%sã€å‘½ä»¤å·²è¢«æå移除。\n" +"如果您ä»åœ¨ä½¿ç”¨è©²å‘½ä»¤ï¼Œè«‹å¤šåŠ ä¸Šã€Œ--i-still-use-thisã€\n" +"é¸é …,然後寄å°é›»å郵件到 <git@vger.kernel.org>,\n" +"è®“æˆ‘å€‘çŸ¥é“æ‚¨é‚„在使用,è¬è¬ã€‚\n" + +#: usage.c +msgid "refusing to run without --i-still-use-this" +msgstr "傳入 --i-still-use-this 剿‹’絕執行" + #: version.c #, c-format msgid "uname() failed with error '%s' (%d)\n" @@ -27674,7 +27848,7 @@ msgstr ".git æª”æ¡ˆä¸æ£ç¢º" #: worktree.c msgid ".git file absolute/relative path mismatch" -msgstr ".git æª”æ¡ˆçš„çµ•å°æˆ–相å°è·¯å¾‘ä¸ä¸€è‡´" +msgstr ".git 檔案的絕å°/相å°è·¯å¾‘ä¸ä¸€è‡´" #: worktree.c msgid "not a valid path" @@ -27698,7 +27872,7 @@ msgstr "ç„¡æ³•è®€å– gitdir" #: worktree.c msgid "gitdir absolute/relative path mismatch" -msgstr "gitdir çš„çµ•å°æˆ–相å°è·¯å¾‘ä¸ä¸€è‡´" +msgstr "gitdir 的絕å°/相å°è·¯å¾‘ä¸ä¸€è‡´" #: worktree.c msgid "gitdir incorrect" @@ -28307,7 +28481,7 @@ msgstr "æäº¤ç‚ºç©ºï¼Œä½†æ˜¯å˜åœ¨å°šæœªè¿½è¹¤çš„æª”案\n" #: wt-status.c #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" -msgstr "ç„¡æª”æ¡ˆè¦æäº¤ï¼ˆå»ºç«‹/複製檔案並使用 \"git add\" 建立追蹤)\n" +msgstr "沒有æ±è¥¿æäº¤ï¼ˆå»ºç«‹/æ‹·è²æª”案並使用「git addã€è¿½è¹¤ä¹‹ï¼‰\n" #: wt-status.c #, c-format @@ -28688,7 +28862,7 @@ msgstr "傳é€é€™å°ä¿¡ä»¶ï¼Ÿ([y]es|[n]o|[e]dit|[q]uit|[a]ll): " #: git-send-email.perl msgid "Send this email reply required" -msgstr "傳é€è¦æ±‚的信件回復" +msgstr "傳é€è¦æ±‚的信件回覆" #: git-send-email.perl msgid "The required SMTP server is not properly defined." @@ -28775,6 +28949,11 @@ msgstr "(body) 新增 cc: %s 自行 '%s'\n" #: git-send-email.perl #, perl-format +msgid "error: invalid SMTP port '%s'\n" +msgstr "錯誤:SMTP é€£ç·šåŸ ã€Œ%sã€ç„¡æ•ˆ\n" + +#: git-send-email.perl +#, perl-format msgid "(%s) Could not execute '%s'" msgstr "(%s) ä¸èƒ½åŸ·è¡Œ '%s'" @@ -28815,7 +28994,7 @@ msgstr "" #: git-send-email.perl #, perl-format msgid "unable to open %s: %s\n" -msgstr "ä¸èƒ½é–‹å•Ÿ %s:%s\n" +msgstr "無法開啟 %s: %s\n" #: git-send-email.perl #, perl-format @@ -28829,7 +29008,7 @@ msgstr "" #: git-send-email.perl #, perl-format msgid "Skipping %s with backup suffix '%s'.\n" -msgstr "ç•¥éŽ %s å«å‚™ä»½å¾Œç¶´ '%s'。\n" +msgstr "ç•¥éŽå…·æœ‰å‚™ä»½å¾Œç¶´ã€Œ%2$sã€çš„ %1$s。\n" #. TRANSLATORS: please keep "[y|N]" as is. #: git-send-email.perl @@ -28837,6 +29016,51 @@ msgstr "ç•¥éŽ %s å«å‚™ä»½å¾Œç¶´ '%s'。\n" msgid "Do you really want to send %s? [y|N]: " msgstr "您真的è¦å‚³é€ %s?[y|N]: " +#~ msgid "start-after" +#~ msgstr "start-after" + +#~ msgid "compact-summary" +#~ msgstr "ç²¾è¦æ‘˜è¦ (compact-summary)" + +# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ +#, c-format +#~ msgid " (%s will become dangling)" +#~ msgstr " (%s å°‡æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼‰" + +# è¯è€…ï¼šè«‹ç¶æŒå‰å°Žç©ºæ ¼ +#, c-format +#~ msgid " (%s has become dangling)" +#~ msgstr " (%s å·²æˆç‚ºæ‡¸ç©ºç‹€æ…‹ï¼‰" + +#~ msgid "use at most one of --auto and --schedule=<frequency>" +#~ msgstr "--auto å’Œ --schedule=<é »çŽ‡> è«‹ä»»é¸ä¸€" + +#, c-format +#~ msgid "Final output: %d %s\n" +#~ msgstr "最終輸出:%d %s\n" + +#, c-format +#~ msgid "%d (FSCK_IGNORE?) should never trigger this callback" +#~ msgstr "%d (FSCK_IGNORE?) 䏿‡‰è§¸ç™¼é€™å€‹å›žå‘¼å‡½å¼" + +#~ msgid "" +#~ "git pack-objects --stdout [<options>] [< <ref-list> | < <object-list>]" +#~ msgstr "git pack-objects --stdout [<é¸é …>] [< <引用列表> | < <物件列表>]" + +#~ msgid "" +#~ "git pack-objects [<options>] <base-name> [< <ref-list> | < <object-list>]" +#~ msgstr "git pack-objects [<é¸é …>] <å‰ç¶´å稱> [< <引用列表> | < <物件列表>]" + +#~ msgid "cannot use --stdin-packs with --cruft" +#~ msgstr "無法將 --stdin-packs 與 --cruft 組åˆä½¿ç”¨" + +#, c-format +#~ msgid "unreachable: invalid reference: %s" +#~ msgstr "ä¸å¯é”:無效引用:%s" + +#~ msgid "trying to write commit not in index" +#~ msgstr "嘗試寫入ä¸åœ¨ç´¢å¼•çš„æäº¤" + #~ msgid "git cat-file (-t | -s) [--allow-unknown-type] <object>" #~ msgstr "git cat-file (-t | -s) [--allow-unknown-type] <object>" @@ -141,7 +141,7 @@ static void setup_commit_formats(void) COPY_ARRAY(commit_formats, builtin_formats, ARRAY_SIZE(builtin_formats)); - git_config(git_pretty_formats_config, NULL); + repo_config(the_repository, git_pretty_formats_config, NULL); } static struct cmt_fmt_map *find_commit_format_recursive(const char *sought, diff --git a/progress.c b/progress.c index 8d5ae70f3a..8315bdc3d4 100644 --- a/progress.c +++ b/progress.c @@ -114,16 +114,19 @@ static void display(struct progress *progress, uint64_t n, const char *done) const char *tp; struct strbuf *counters_sb = &progress->counters_sb; int show_update = 0; + int update = !!progress_update; int last_count_len = counters_sb->len; - if (progress->delay && (!progress_update || --progress->delay)) + progress_update = 0; + + if (progress->delay && (!update || --progress->delay)) return; progress->last_value = n; tp = (progress->throughput) ? progress->throughput->display.buf : ""; if (progress->total) { unsigned percent = n * 100 / progress->total; - if (percent != progress->last_percent || progress_update) { + if (percent != progress->last_percent || update) { progress->last_percent = percent; strbuf_reset(counters_sb); @@ -133,7 +136,7 @@ static void display(struct progress *progress, uint64_t n, const char *done) tp); show_update = 1; } - } else if (progress_update) { + } else if (update) { strbuf_reset(counters_sb); strbuf_addf(counters_sb, "%"PRIuMAX"%s", (uintmax_t)n, tp); show_update = 1; @@ -166,7 +169,6 @@ static void display(struct progress *progress, uint64_t n, const char *done) } fflush(stderr); } - progress_update = 0; } } @@ -281,7 +283,7 @@ static int get_default_delay(void) static int delay_in_secs = -1; if (delay_in_secs < 0) - delay_in_secs = git_env_ulong("GIT_PROGRESS_DELAY", 2); + delay_in_secs = git_env_ulong("GIT_PROGRESS_DELAY", 1); return delay_in_secs; } diff --git a/promisor-remote.c b/promisor-remote.c index be6f82d12f..08b0da8962 100644 --- a/promisor-remote.c +++ b/promisor-remote.c @@ -46,7 +46,7 @@ static int fetch_objects(struct repository *repo, "fetch", remote_name, "--no-tags", "--no-write-fetch-head", "--recurse-submodules=no", "--filter=blob:none", "--stdin", NULL); - if (!git_config_get_bool("promisor.quiet", &quiet) && quiet) + if (!repo_config_get_bool(the_repository, "promisor.quiet", &quiet) && quiet) strvec_push(&child.args, "--quiet"); if (start_command(&child)) die(_("promisor-remote: unable to fork off fetch subprocess")); @@ -327,7 +327,7 @@ static void promisor_info_vecs(struct repository *repo, char *url_key = xstrfmt("remote.%s.url", r->name); /* Only add remotes with a non empty URL */ - if (!git_config_get_string_tmp(url_key, &url) && *url) { + if (!repo_config_get_string_tmp(the_repository, url_key, &url) && *url) { strvec_push(names, r->name); strvec_push(urls, url); } @@ -343,7 +343,7 @@ char *promisor_remote_info(struct repository *repo) struct strvec names = STRVEC_INIT; struct strvec urls = STRVEC_INIT; - git_config_get_bool("promisor.advertise", &advertise_promisors); + repo_config_get_bool(the_repository, "promisor.advertise", &advertise_promisors); if (!advertise_promisors) return NULL; @@ -433,7 +433,7 @@ static void filter_promisor_remote(struct repository *repo, struct strvec names = STRVEC_INIT; struct strvec urls = STRVEC_INIT; - if (!git_config_get_string_tmp("promisor.acceptfromserver", &accept_str)) { + if (!repo_config_get_string_tmp(the_repository, "promisor.acceptfromserver", &accept_str)) { if (!*accept_str || !strcasecmp("None", accept_str)) accept = ACCEPT_NONE; else if (!strcasecmp("KnownUrl", accept_str)) @@ -77,12 +77,6 @@ char *git_prompt(const char *prompt, int flags) int git_read_line_interactively(struct strbuf *line) { - int ret; - fflush(stdout); - ret = strbuf_getline_lf(line, stdin); - if (ret != EOF) - strbuf_trim_trailing_newline(line); - - return ret; + return strbuf_getline(line, stdin); } diff --git a/protocol.c b/protocol.c index bae7226ff4..a3e26a8dd3 100644 --- a/protocol.c +++ b/protocol.c @@ -24,7 +24,7 @@ enum protocol_version get_protocol_version_config(void) const char *git_test_k = "GIT_TEST_PROTOCOL_VERSION"; const char *git_test_v; - if (!git_config_get_string_tmp("protocol.version", &value)) { + if (!repo_config_get_string_tmp(the_repository, "protocol.version", &value)) { enum protocol_version version = parse_protocol_version(value); if (version == protocol_unknown_version) @@ -61,7 +61,7 @@ enum protocol_version determine_protocol_version_server(void) if (git_protocol) { struct string_list list = STRING_LIST_INIT_DUP; const struct string_list_item *item; - string_list_split(&list, git_protocol, ':', -1); + string_list_split(&list, git_protocol, ":", -1); for_each_string_list_item(item, &list) { const char *value; diff --git a/prune-packed.c b/prune-packed.c index 92fb4fbb0e..d49dc11957 100644 --- a/prune-packed.c +++ b/prune-packed.c @@ -40,7 +40,7 @@ void prune_packed_objects(int opts) progress = start_delayed_progress(the_repository, _("Removing duplicate objects"), 256); - for_each_loose_file_in_objdir(repo_get_object_directory(the_repository), + for_each_loose_file_in_source(the_repository->objects->sources, prune_object, NULL, prune_subdir, &opts); /* Ensure we show 100% before finishing progress */ diff --git a/reachable.c b/reachable.c index e984b68a0c..22266db523 100644 --- a/reachable.c +++ b/reachable.c @@ -170,7 +170,7 @@ static void load_gc_recent_objects(struct recent_data *data) data->extra_recent_oids_loaded = 1; - if (git_config_get_string_multi("gc.recentobjectshook", &programs)) + if (repo_config_get_string_multi(the_repository, "gc.recentobjectshook", &programs)) return; for (i = 0; i < programs->nr; i++) { @@ -319,7 +319,7 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, oidset_init(&data.extra_recent_oids, 0); data.extra_recent_oids_loaded = 0; - r = for_each_loose_object(add_recent_loose, &data, + r = for_each_loose_object(the_repository->objects, add_recent_loose, &data, FOR_EACH_OBJECT_LOCAL_ONLY); if (r) goto done; diff --git a/read-cache.c b/read-cache.c index 5cf41b81f1..06ad74db22 100644 --- a/read-cache.c +++ b/read-cache.c @@ -690,7 +690,7 @@ static struct cache_entry *create_alias_ce(struct index_state *istate, void set_object_name_for_intent_to_add_entry(struct cache_entry *ce) { struct object_id oid; - if (write_object_file("", 0, OBJ_BLOB, &oid)) + if (odb_write_object(the_repository->objects, "", 0, OBJ_BLOB, &oid)) die(_("cannot create an empty blob in the object database")); oidcpy(&ce->oid, &oid); } @@ -2755,7 +2755,7 @@ static int record_eoie(void) { int val; - if (!git_config_get_bool("index.recordendofindexentries", &val)) + if (!repo_config_get_bool(the_repository, "index.recordendofindexentries", &val)) return val; /* @@ -2770,7 +2770,7 @@ static int record_ieot(void) { int val; - if (!git_config_get_bool("index.recordoffsettable", &val)) + if (!repo_config_get_bool(the_repository, "index.recordoffsettable", &val)) return val; /* diff --git a/rebase-interactive.c b/rebase-interactive.c index cbeb864147..809f76a87b 100644 --- a/rebase-interactive.c +++ b/rebase-interactive.c @@ -30,7 +30,7 @@ static enum missing_commit_check_level get_missing_commit_check_level(void) { const char *value; - if (git_config_get_value("rebase.missingcommitscheck", &value) || + if (repo_config_get_value(the_repository, "rebase.missingcommitscheck", &value) || !strcasecmp("ignore", value)) return MISSING_COMMIT_CHECK_IGNORE; if (!strcasecmp("warn", value)) diff --git a/ref-filter.c b/ref-filter.c index f9f2c512a8..520d2539c9 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -435,7 +435,7 @@ static int remote_ref_atom_parser(struct ref_format *format UNUSED, } atom->u.remote_ref.nobracket = 0; - string_list_split(¶ms, arg, ',', -1); + string_list_split(¶ms, arg, ",", -1); for (i = 0; i < params.nr; i++) { const char *s = params.items[i].string; @@ -831,7 +831,7 @@ static int align_atom_parser(struct ref_format *format UNUSED, align->position = ALIGN_LEFT; - string_list_split(¶ms, arg, ',', -1); + string_list_split(¶ms, arg, ",", -1); for (i = 0; i < params.nr; i++) { const char *s = params.items[i].string; int position; @@ -2684,6 +2684,41 @@ static int filter_exclude_match(struct ref_filter *filter, const char *refname) } /* + * We need to seek to the reference right after a given marker but excluding any + * matching references. So we seek to the lexicographically next reference. + */ +static int start_ref_iterator_after(struct ref_iterator *iter, const char *marker) +{ + struct strbuf sb = STRBUF_INIT; + int ret; + + strbuf_addstr(&sb, marker); + strbuf_addch(&sb, 1); + + ret = ref_iterator_seek(iter, sb.buf, 0); + + strbuf_release(&sb); + return ret; +} + +static int for_each_fullref_with_seek(struct ref_filter *filter, each_ref_fn cb, + void *cb_data, unsigned int flags) +{ + struct ref_iterator *iter; + int ret = 0; + + iter = refs_ref_iterator_begin(get_main_ref_store(the_repository), "", + NULL, 0, flags); + if (filter->start_after) + ret = start_ref_iterator_after(iter, filter->start_after); + + if (ret) + return ret; + + return do_for_each_ref_iterator(iter, cb, cb_data); +} + +/* * This is the same as for_each_fullref_in(), but it tries to iterate * only over the patterns we'll care about. Note that it _doesn't_ do a full * pattern match, so the callback still has to match each ref individually. @@ -2694,8 +2729,8 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, { if (filter->kind & FILTER_REFS_ROOT_REFS) { /* In this case, we want to print all refs including root refs. */ - return refs_for_each_include_root_refs(get_main_ref_store(the_repository), - cb, cb_data); + return for_each_fullref_with_seek(filter, cb, cb_data, + DO_FOR_EACH_INCLUDE_ROOT_REFS); } if (!filter->match_as_path) { @@ -2704,8 +2739,7 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, * prefixes like "refs/heads/" etc. are stripped off, * so we have to look at everything: */ - return refs_for_each_fullref_in(get_main_ref_store(the_repository), - "", NULL, cb, cb_data); + return for_each_fullref_with_seek(filter, cb, cb_data, 0); } if (filter->ignore_case) { @@ -2714,14 +2748,12 @@ static int for_each_fullref_in_pattern(struct ref_filter *filter, * so just return everything and let the caller * sort it out. */ - return refs_for_each_fullref_in(get_main_ref_store(the_repository), - "", NULL, cb, cb_data); + return for_each_fullref_with_seek(filter, cb, cb_data, 0); } if (!filter->name_patterns[0]) { /* no patterns; we have to look at everything */ - return refs_for_each_fullref_in(get_main_ref_store(the_repository), - "", filter->exclude.v, cb, cb_data); + return for_each_fullref_with_seek(filter, cb, cb_data, 0); } return refs_for_each_fullref_in_prefixes(get_main_ref_store(the_repository), @@ -3189,6 +3221,7 @@ void filter_is_base(struct repository *r, static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref_fn fn, void *cb_data) { + const char *prefix = NULL; int ret = 0; filter->kind = type & FILTER_REFS_KIND_MASK; @@ -3199,38 +3232,48 @@ static int do_filter_refs(struct ref_filter *filter, unsigned int type, each_ref /* Simple per-ref filtering */ if (!filter->kind) die("filter_refs: invalid type"); - else { - /* - * For common cases where we need only branches or remotes or tags, - * we only iterate through those refs. If a mix of refs is needed, - * we iterate over all refs and filter out required refs with the help - * of filter_ref_kind(). - */ - if (filter->kind == FILTER_REFS_BRANCHES) - ret = refs_for_each_fullref_in(get_main_ref_store(the_repository), - "refs/heads/", NULL, - fn, cb_data); - else if (filter->kind == FILTER_REFS_REMOTES) - ret = refs_for_each_fullref_in(get_main_ref_store(the_repository), - "refs/remotes/", NULL, - fn, cb_data); - else if (filter->kind == FILTER_REFS_TAGS) - ret = refs_for_each_fullref_in(get_main_ref_store(the_repository), - "refs/tags/", NULL, fn, - cb_data); - else if (filter->kind & FILTER_REFS_REGULAR) - ret = for_each_fullref_in_pattern(filter, fn, cb_data); - /* - * When printing all ref types, HEAD is already included, - * so we don't want to print HEAD again. - */ - if (!ret && !(filter->kind & FILTER_REFS_ROOT_REFS) && - (filter->kind & FILTER_REFS_DETACHED_HEAD)) - refs_head_ref(get_main_ref_store(the_repository), fn, - cb_data); + /* + * For common cases where we need only branches or remotes or tags, + * we only iterate through those refs. If a mix of refs is needed, + * we iterate over all refs and filter out required refs with the help + * of filter_ref_kind(). + */ + if (filter->kind == FILTER_REFS_BRANCHES) + prefix = "refs/heads/"; + else if (filter->kind == FILTER_REFS_REMOTES) + prefix = "refs/remotes/"; + else if (filter->kind == FILTER_REFS_TAGS) + prefix = "refs/tags/"; + + if (prefix) { + struct ref_iterator *iter; + + iter = refs_ref_iterator_begin(get_main_ref_store(the_repository), + "", NULL, 0, 0); + + if (filter->start_after) + ret = start_ref_iterator_after(iter, filter->start_after); + else + ret = ref_iterator_seek(iter, prefix, + REF_ITERATOR_SEEK_SET_PREFIX); + + if (!ret) + ret = do_for_each_ref_iterator(iter, fn, cb_data); + } else if (filter->kind & FILTER_REFS_REGULAR) { + ret = for_each_fullref_in_pattern(filter, fn, cb_data); } + /* + * When printing all ref types, HEAD is already included, + * so we don't want to print HEAD again. + */ + if (!ret && !(filter->kind & FILTER_REFS_ROOT_REFS) && + (filter->kind & FILTER_REFS_DETACHED_HEAD)) + refs_head_ref(get_main_ref_store(the_repository), fn, + cb_data); + + clear_contains_cache(&filter->internal.contains_cache); clear_contains_cache(&filter->internal.no_contains_cache); diff --git a/ref-filter.h b/ref-filter.h index c98c4fbd4c..f22ca94b49 100644 --- a/ref-filter.h +++ b/ref-filter.h @@ -64,6 +64,7 @@ struct ref_array { struct ref_filter { const char **name_patterns; + const char *start_after; struct strvec exclude; struct oid_array points_at; struct commit_list *with_commit; diff --git a/reflog-walk.c b/reflog-walk.c index c7070b13b0..4f1ce04749 100644 --- a/reflog-walk.c +++ b/reflog-walk.c @@ -22,9 +22,10 @@ struct complete_reflogs { int nr, alloc; }; -static int read_one_reflog(struct object_id *ooid, struct object_id *noid, - const char *email, timestamp_t timestamp, int tz, - const char *message, void *cb_data) +static int read_one_reflog(const char *refname UNUSED, + struct object_id *ooid, struct object_id *noid, + const char *email, timestamp_t timestamp, int tz, + const char *message, void *cb_data) { struct complete_reflogs *array = cb_data; struct reflog_info *item; @@ -3,6 +3,7 @@ #include "git-compat-util.h" #include "config.h" +#include "environment.h" #include "gettext.h" #include "parse-options.h" #include "odb.h" @@ -81,6 +82,20 @@ int reflog_expire_config(const char *var, const char *value, return 0; } +void reflog_clear_expire_config(struct reflog_expire_options *opts) +{ + struct reflog_expire_entry_option *ent = opts->entries, *tmp; + + while (ent) { + tmp = ent; + ent = ent->next; + free(tmp); + } + + opts->entries = NULL; + opts->entries_tail = NULL; +} + void reflog_expire_options_set_refname(struct reflog_expire_options *cb, const char *ref) { @@ -492,7 +507,8 @@ void reflog_expiry_cleanup(void *cb_data) free_commit_list(cb->mark_list); } -int count_reflog_ent(struct object_id *ooid UNUSED, +int count_reflog_ent(const char *refname UNUSED, + struct object_id *ooid UNUSED, struct object_id *noid UNUSED, const char *email UNUSED, timestamp_t timestamp, int tz UNUSED, @@ -34,6 +34,8 @@ struct reflog_expire_options { int reflog_expire_config(const char *var, const char *value, const struct config_context *ctx, void *cb); +void reflog_clear_expire_config(struct reflog_expire_options *opts); + /* * Adapt the options so that they apply to the given refname. This applies any * per-reference reflog expiry configuration that may exist to the options. @@ -63,7 +65,8 @@ void reflog_expiry_prepare(const char *refname, const struct object_id *oid, int should_expire_reflog_ent(struct object_id *ooid, struct object_id *noid, const char *email, timestamp_t timestamp, int tz, const char *message, void *cb_data); -int count_reflog_ent(struct object_id *ooid, struct object_id *noid, +int count_reflog_ent(const char *refname, + struct object_id *ooid, struct object_id *noid, const char *email, timestamp_t timestamp, int tz, const char *message, void *cb_data); int should_expire_reflog_ent_verbose(struct object_id *ooid, @@ -945,7 +945,7 @@ long get_files_ref_lock_timeout_ms(void) static int timeout_ms = 100; if (!configured) { - git_config_get_int("core.filesreflocktimeout", &timeout_ms); + repo_config_get_int(the_repository, "core.filesreflocktimeout", &timeout_ms); configured = 1; } @@ -1022,7 +1022,6 @@ int is_branch(const char *refname) } struct read_ref_at_cb { - const char *refname; timestamp_t at_time; int cnt; int reccnt; @@ -1052,7 +1051,8 @@ static void set_read_ref_cutoffs(struct read_ref_at_cb *cb, *cb->cutoff_cnt = cb->reccnt; } -static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid, +static int read_ref_at_ent(const char *refname, + struct object_id *ooid, struct object_id *noid, const char *email UNUSED, timestamp_t timestamp, int tz, const char *message, void *cb_data) @@ -1072,14 +1072,13 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid, oidcpy(cb->oid, noid); if (!oideq(&cb->ooid, noid)) warning(_("log for ref %s has gap after %s"), - cb->refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); + refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); } else if (cb->date == cb->at_time) oidcpy(cb->oid, noid); else if (!oideq(noid, cb->oid)) warning(_("log for ref %s unexpectedly ended on %s"), - cb->refname, show_date(cb->date, cb->tz, - DATE_MODE(RFC2822))); + refname, show_date(cb->date, cb->tz, DATE_MODE(RFC2822))); cb->reccnt++; oidcpy(&cb->ooid, ooid); oidcpy(&cb->noid, noid); @@ -1094,7 +1093,8 @@ static int read_ref_at_ent(struct object_id *ooid, struct object_id *noid, return 0; } -static int read_ref_at_ent_oldest(struct object_id *ooid, struct object_id *noid, +static int read_ref_at_ent_oldest(const char *refname UNUSED, + struct object_id *ooid, struct object_id *noid, const char *email UNUSED, timestamp_t timestamp, int tz, const char *message, void *cb_data) @@ -1117,7 +1117,6 @@ int read_ref_at(struct ref_store *refs, const char *refname, struct read_ref_at_cb cb; memset(&cb, 0, sizeof(cb)); - cb.refname = refname; cb.at_time = at_time; cb.cnt = cnt; cb.msg = msg; @@ -1362,27 +1361,22 @@ int ref_transaction_update(struct ref_transaction *transaction, return 0; } -/* - * Similar to`ref_transaction_update`, but this function is only for adding - * a reflog update. Supports providing custom committer information. The index - * field can be utiltized to order updates as desired. When not used, the - * updates default to being ordered by refname. - */ -static int ref_transaction_update_reflog(struct ref_transaction *transaction, - const char *refname, - const struct object_id *new_oid, - const struct object_id *old_oid, - const char *committer_info, - unsigned int flags, - const char *msg, - uint64_t index, - struct strbuf *err) +int ref_transaction_update_reflog(struct ref_transaction *transaction, + const char *refname, + const struct object_id *new_oid, + const struct object_id *old_oid, + const char *committer_info, + const char *msg, + uint64_t index, + struct strbuf *err) { struct ref_update *update; + unsigned int flags; assert(err); - flags |= REF_LOG_ONLY | REF_FORCE_CREATE_REFLOG | REF_NO_DEREF; + flags = REF_HAVE_OLD | REF_HAVE_NEW | REF_LOG_ONLY | REF_FORCE_CREATE_REFLOG | REF_NO_DEREF | + REF_LOG_USE_PROVIDED_OIDS; if (!transaction_refname_valid(refname, new_oid, flags, err)) return -1; @@ -1390,11 +1384,6 @@ static int ref_transaction_update_reflog(struct ref_transaction *transaction, update = ref_transaction_add_update(transaction, refname, flags, new_oid, old_oid, NULL, NULL, committer_info, msg); - /* - * While we do set the old_oid value, we unset the flag to skip - * old_oid verification which only makes sense for refs. - */ - update->flags &= ~REF_HAVE_OLD; update->index = index; /* @@ -1850,7 +1839,13 @@ int refs_for_each_namespaced_ref(struct ref_store *refs, int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data) { - return do_for_each_ref(refs, "", NULL, fn, 0, + return refs_for_each_rawref_in(refs, "", fn, cb_data); +} + +int refs_for_each_rawref_in(struct ref_store *refs, const char *prefix, + each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(refs, prefix, NULL, fn, 0, DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } @@ -2657,12 +2652,12 @@ enum ref_transaction_error refs_verify_refnames_available(struct ref_store *refs if (!initial_transaction) { int ok; - if (!iter) { + if (!iter) iter = refs_ref_iterator_begin(refs, dirname.buf, NULL, 0, DO_FOR_EACH_INCLUDE_BROKEN); - } else if (ref_iterator_seek(iter, dirname.buf) < 0) { + else if (ref_iterator_seek(iter, dirname.buf, + REF_ITERATOR_SEEK_SET_PREFIX) < 0) goto cleanup; - } while ((ok = ref_iterator_advance(iter)) == ITER_OK) { if (skip && @@ -2951,7 +2946,8 @@ struct migration_data { struct ref_store *old_refs; struct ref_transaction *transaction; struct strbuf *errbuf; - struct strbuf sb; + struct strbuf sb, name, mail; + uint64_t index; }; static int migrate_one_ref(const char *refname, const char *referent UNUSED, const struct object_id *oid, @@ -2984,50 +2980,41 @@ done: return ret; } -struct reflog_migration_data { - uint64_t index; - const char *refname; - struct ref_store *old_refs; - struct ref_transaction *transaction; - struct strbuf *errbuf; - struct strbuf *sb; -}; - -static int migrate_one_reflog_entry(struct object_id *old_oid, +static int migrate_one_reflog_entry(const char *refname, + struct object_id *old_oid, struct object_id *new_oid, const char *committer, timestamp_t timestamp, int tz, const char *msg, void *cb_data) { - struct reflog_migration_data *data = cb_data; + struct migration_data *data = cb_data; + struct ident_split ident; const char *date; int ret; + if (split_ident_line(&ident, committer, strlen(committer)) < 0) + return -1; + + strbuf_reset(&data->name); + strbuf_add(&data->name, ident.name_begin, ident.name_end - ident.name_begin); + strbuf_reset(&data->mail); + strbuf_add(&data->mail, ident.mail_begin, ident.mail_end - ident.mail_begin); + date = show_date(timestamp, tz, DATE_MODE(NORMAL)); - strbuf_reset(data->sb); - /* committer contains name and email */ - strbuf_addstr(data->sb, fmt_ident("", committer, WANT_BLANK_IDENT, date, 0)); - - ret = ref_transaction_update_reflog(data->transaction, data->refname, - new_oid, old_oid, data->sb->buf, - REF_HAVE_NEW | REF_HAVE_OLD, msg, - data->index++, data->errbuf); + strbuf_reset(&data->sb); + strbuf_addstr(&data->sb, fmt_ident(data->name.buf, data->mail.buf, WANT_BLANK_IDENT, date, 0)); + + ret = ref_transaction_update_reflog(data->transaction, refname, + new_oid, old_oid, data->sb.buf, + msg, data->index++, data->errbuf); return ret; } static int migrate_one_reflog(const char *refname, void *cb_data) { struct migration_data *migration_data = cb_data; - struct reflog_migration_data data = { - .refname = refname, - .old_refs = migration_data->old_refs, - .transaction = migration_data->transaction, - .errbuf = migration_data->errbuf, - .sb = &migration_data->sb, - }; - return refs_for_each_reflog_ent(migration_data->old_refs, refname, - migrate_one_reflog_entry, &data); + migrate_one_reflog_entry, migration_data); } static int move_files(const char *from_path, const char *to_path, struct strbuf *errbuf) @@ -3122,6 +3109,8 @@ int repo_migrate_ref_storage_format(struct repository *repo, struct strbuf new_gitdir = STRBUF_INIT; struct migration_data data = { .sb = STRBUF_INIT, + .name = STRBUF_INIT, + .mail = STRBUF_INIT, }; int did_migrate_refs = 0; int ret; @@ -3297,11 +3286,16 @@ done: ref_transaction_free(transaction); strbuf_release(&new_gitdir); strbuf_release(&data.sb); + strbuf_release(&data.name); + strbuf_release(&data.mail); return ret; } int ref_update_expects_existing_old_ref(struct ref_update *update) { + if (update->flags & REF_LOG_ONLY) + return 0; + return (update->flags & REF_HAVE_OLD) && (!is_null_oid(&update->old_oid) || update->old_target); } @@ -428,6 +428,8 @@ int refs_for_each_namespaced_ref(struct ref_store *refs, /* can be used to learn about broken ref and symref */ int refs_for_each_rawref(struct ref_store *refs, each_ref_fn fn, void *cb_data); +int refs_for_each_rawref_in(struct ref_store *refs, const char *prefix, + each_ref_fn fn, void *cb_data); /* * Iterates over all refs including root refs, i.e. pseudorefs and HEAD. @@ -558,10 +560,13 @@ int refs_delete_reflog(struct ref_store *refs, const char *refname); * The cb_data is a caller-supplied pointer given to the iterator * functions. */ -typedef int each_reflog_ent_fn( - struct object_id *old_oid, struct object_id *new_oid, - const char *committer, timestamp_t timestamp, - int tz, const char *msg, void *cb_data); +typedef int each_reflog_ent_fn(const char *refname, + struct object_id *old_oid, + struct object_id *new_oid, + const char *committer, + timestamp_t timestamp, + int tz, const char *msg, + void *cb_data); /* Iterate over reflog entries in the log for `refname`. */ @@ -760,12 +765,19 @@ struct ref_transaction *ref_store_transaction_begin(struct ref_store *refs, #define REF_SKIP_CREATE_REFLOG (1 << 12) /* + * When writing a REF_LOG_ONLY record, use the old and new object IDs provided + * in the update instead of resolving the old object ID. The caller must also + * set both REF_HAVE_OLD and REF_HAVE_NEW. + */ +#define REF_LOG_USE_PROVIDED_OIDS (1 << 13) + +/* * Bitmask of all of the flags that are allowed to be passed in to * ref_transaction_update() and friends: */ #define REF_TRANSACTION_UPDATE_ALLOWED_FLAGS \ (REF_NO_DEREF | REF_FORCE_CREATE_REFLOG | REF_SKIP_OID_VERIFICATION | \ - REF_SKIP_REFNAME_VERIFICATION | REF_SKIP_CREATE_REFLOG) + REF_SKIP_REFNAME_VERIFICATION | REF_SKIP_CREATE_REFLOG | REF_LOG_USE_PROVIDED_OIDS) /* * Add a reference update to transaction. `new_oid` is the value that @@ -795,6 +807,21 @@ int ref_transaction_update(struct ref_transaction *transaction, struct strbuf *err); /* + * Similar to `ref_transaction_update`, but this function is only for adding + * a reflog update. Supports providing custom committer information. The index + * field can be utiltized to order updates as desired. When set to zero, the + * updates default to being ordered by refname. + */ +int ref_transaction_update_reflog(struct ref_transaction *transaction, + const char *refname, + const struct object_id *new_oid, + const struct object_id *old_oid, + const char *committer_info, + const char *msg, + uint64_t index, + struct strbuf *err); + +/* * Add a reference creation to transaction. new_oid is the value that * the reference should have after the update; it must not be * null_oid. It is verified that the reference does not exist @@ -1194,4 +1221,159 @@ int repo_migrate_ref_storage_format(struct repository *repo, unsigned int flags, struct strbuf *err); +/* + * Reference iterators + * + * A reference iterator encapsulates the state of an in-progress + * iteration over references. Create an instance of `struct + * ref_iterator` via one of the functions in this module. + * + * A freshly-created ref_iterator doesn't yet point at a reference. To + * advance the iterator, call ref_iterator_advance(). If successful, + * this sets the iterator's refname, oid, and flags fields to describe + * the next reference and returns ITER_OK. The data pointed at by + * refname and oid belong to the iterator; if you want to retain them + * after calling ref_iterator_advance() again or calling + * ref_iterator_free(), you must make a copy. When the iteration has + * been exhausted, ref_iterator_advance() releases any resources + * associated with the iteration, frees the ref_iterator object, and + * returns ITER_DONE. If you want to abort the iteration early, call + * ref_iterator_free(), which also frees the ref_iterator object and + * any associated resources. If there was an internal error advancing + * to the next entry, ref_iterator_advance() aborts the iteration, + * frees the ref_iterator, and returns ITER_ERROR. + * + * The reference currently being looked at can be peeled by calling + * ref_iterator_peel(). This function is often faster than peel_ref(), + * so it should be preferred when iterating over references. + * + * Putting it all together, a typical iteration looks like this: + * + * int ok; + * struct ref_iterator *iter = ...; + * + * while ((ok = ref_iterator_advance(iter)) == ITER_OK) { + * if (want_to_stop_iteration()) { + * ok = ITER_DONE; + * break; + * } + * + * // Access information about the current reference: + * if (!(iter->flags & REF_ISSYMREF)) + * printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid)); + * + * // If you need to peel the reference: + * ref_iterator_peel(iter, &oid); + * } + * + * if (ok != ITER_DONE) + * handle_error(); + * ref_iterator_free(iter); + */ +struct ref_iterator; + +/* + * These flags are passed to refs_ref_iterator_begin() (and do_for_each_ref(), + * which feeds it). + */ +enum do_for_each_ref_flags { + /* + * Include broken references in a do_for_each_ref*() iteration, which + * would normally be omitted. This includes both refs that point to + * missing objects (a true repository corruption), ones with illegal + * names (which we prefer not to expose to callers), as well as + * dangling symbolic refs (i.e., those that point to a non-existent + * ref; this is not a corruption, but as they have no valid oid, we + * omit them from normal iteration results). + */ + DO_FOR_EACH_INCLUDE_BROKEN = (1 << 0), + + /* + * Only include per-worktree refs in a do_for_each_ref*() iteration. + * Normally this will be used with a files ref_store, since that's + * where all reference backends will presumably store their + * per-worktree refs. + */ + DO_FOR_EACH_PER_WORKTREE_ONLY = (1 << 1), + + /* + * Omit dangling symrefs from output; this only has an effect with + * INCLUDE_BROKEN, since they are otherwise not included at all. + */ + DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2), + + /* + * Include root refs i.e. HEAD and pseudorefs along with the regular + * refs. + */ + DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3), +}; + +/* + * Return an iterator that goes over each reference in `refs` for + * which the refname begins with prefix. If trim is non-zero, then + * trim that many characters off the beginning of each refname. + * The output is ordered by refname. + */ +struct ref_iterator *refs_ref_iterator_begin( + struct ref_store *refs, + const char *prefix, const char **exclude_patterns, + int trim, enum do_for_each_ref_flags flags); + +/* + * Advance the iterator to the first or next item and return ITER_OK. + * If the iteration is exhausted, free the resources associated with + * the ref_iterator and return ITER_DONE. On errors, free the iterator + * resources and return ITER_ERROR. It is a bug to use ref_iterator or + * call this function again after it has returned ITER_DONE or + * ITER_ERROR. + */ +int ref_iterator_advance(struct ref_iterator *ref_iterator); + +enum ref_iterator_seek_flag { + /* + * When the REF_ITERATOR_SEEK_SET_PREFIX flag is set, the iterator's prefix is + * updated to match the provided string, affecting all subsequent iterations. If + * not, the iterator seeks to the specified reference and clears any previously + * set prefix. + */ + REF_ITERATOR_SEEK_SET_PREFIX = (1 << 0), +}; + +/* + * Seek the iterator to the first reference matching the given seek string. + * The seek string is matched as a literal string, without regard for path + * separators. If seek is NULL or the empty string, seek the iterator to the + * first reference again. + * + * This function is expected to behave as if a new ref iterator has been + * created, but allows reuse of existing iterators for optimization. + * + * Returns 0 on success, a negative error code otherwise. + */ +int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname, + unsigned int flags); + +/* + * If possible, peel the reference currently being viewed by the + * iterator. Return 0 on success. + */ +int ref_iterator_peel(struct ref_iterator *ref_iterator, + struct object_id *peeled); + +/* Free the reference iterator and any associated resources. */ +void ref_iterator_free(struct ref_iterator *ref_iterator); + +/* + * The common backend for the for_each_*ref* functions. Call fn for + * each reference in iter. If the iterator itself ever returns + * ITER_ERROR, return -1. If fn ever returns a non-zero value, stop + * the iteration and return that value. Otherwise, return 0. In any + * case, free the iterator when done. This function is basically an + * adapter between the callback style of reference iteration and the + * iterator style. + */ +int do_for_each_ref_iterator(struct ref_iterator *iter, + each_ref_fn fn, void *cb_data); + #endif /* REFS_H */ diff --git a/refs/debug.c b/refs/debug.c index 485e3079d7..1cb955961e 100644 --- a/refs/debug.c +++ b/refs/debug.c @@ -170,12 +170,13 @@ static int debug_ref_iterator_advance(struct ref_iterator *ref_iterator) } static int debug_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct debug_ref_iterator *diter = (struct debug_ref_iterator *)ref_iterator; - int res = diter->iter->vtable->seek(diter->iter, prefix); - trace_printf_key(&trace_refs, "iterator_seek: %s: %d\n", prefix ? prefix : "", res); + int res = diter->iter->vtable->seek(diter->iter, refname, flags); + trace_printf_key(&trace_refs, "iterator_seek: %s flags: %d: %d\n", + refname ? refname : "", flags, res); return res; } @@ -276,7 +277,8 @@ struct debug_reflog { void *cb_data; }; -static int debug_print_reflog_ent(struct object_id *old_oid, +static int debug_print_reflog_ent(const char *refname, + struct object_id *old_oid, struct object_id *new_oid, const char *committer, timestamp_t timestamp, int tz, const char *msg, void *cb_data) @@ -291,7 +293,7 @@ static int debug_print_reflog_ent(struct object_id *old_oid, if (new_oid) oid_to_hex_r(n, new_oid); - ret = dbg->fn(old_oid, new_oid, committer, timestamp, tz, msg, + ret = dbg->fn(refname, old_oid, new_oid, committer, timestamp, tz, msg, dbg->cb_data); trace_printf_key(&trace_refs, "reflog_ent %s (ret %d): %s -> %s, %s %ld \"%.*s\"\n", diff --git a/refs/files-backend.c b/refs/files-backend.c index 89ae4517a9..1b3bf26add 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -68,6 +68,12 @@ */ #define REF_DELETED_RMDIR (1 << 9) +/* + * Used to indicate that the reflog-only update has been created via + * `split_head_update()`. + */ +#define REF_LOG_VIA_SPLIT (1 << 14) + struct ref_lock { char *ref_name; struct lock_file lk; @@ -929,11 +935,11 @@ static int files_ref_iterator_advance(struct ref_iterator *ref_iterator) } static int files_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct files_ref_iterator *iter = (struct files_ref_iterator *)ref_iterator; - return ref_iterator_seek(iter->iter0, prefix); + return ref_iterator_seek(iter->iter0, refname, flags); } static int files_ref_iterator_peel(struct ref_iterator *ref_iterator, @@ -2109,7 +2115,9 @@ static int files_delete_reflog(struct ref_store *ref_store, return ret; } -static int show_one_reflog_ent(struct files_ref_store *refs, struct strbuf *sb, +static int show_one_reflog_ent(struct files_ref_store *refs, + const char *refname, + struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data) { struct object_id ooid, noid; @@ -2136,7 +2144,7 @@ static int show_one_reflog_ent(struct files_ref_store *refs, struct strbuf *sb, message += 6; else message += 7; - return fn(&ooid, &noid, p, timestamp, tz, message, cb_data); + return fn(refname, &ooid, &noid, p, timestamp, tz, message, cb_data); } static char *find_beginning_of_line(char *bob, char *scan) @@ -2220,7 +2228,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store, strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1)); scanp = bp; endp = bp + 1; - ret = show_one_reflog_ent(refs, &sb, fn, cb_data); + ret = show_one_reflog_ent(refs, refname, &sb, fn, cb_data); strbuf_reset(&sb); if (ret) break; @@ -2232,7 +2240,7 @@ static int files_for_each_reflog_ent_reverse(struct ref_store *ref_store, * Process it, and we can end the loop. */ strbuf_splice(&sb, 0, 0, buf, endp - buf); - ret = show_one_reflog_ent(refs, &sb, fn, cb_data); + ret = show_one_reflog_ent(refs, refname, &sb, fn, cb_data); strbuf_reset(&sb); break; } @@ -2282,7 +2290,7 @@ static int files_for_each_reflog_ent(struct ref_store *ref_store, return -1; while (!ret && !strbuf_getwholeline(&sb, logfp, '\n')) - ret = show_one_reflog_ent(refs, &sb, fn, cb_data); + ret = show_one_reflog_ent(refs, refname, &sb, fn, cb_data); fclose(logfp); strbuf_release(&sb); return ret; @@ -2316,7 +2324,8 @@ static int files_reflog_iterator_advance(struct ref_iterator *ref_iterator) } static int files_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED, - const char *prefix UNUSED) + const char *refname UNUSED, + unsigned int flags UNUSED) { BUG("ref_iterator_seek() called for reflog_iterator"); } @@ -2420,9 +2429,10 @@ static enum ref_transaction_error split_head_update(struct ref_update *update, new_update = ref_transaction_add_update( transaction, "HEAD", - update->flags | REF_LOG_ONLY | REF_NO_DEREF, + update->flags | REF_LOG_ONLY | REF_NO_DEREF | REF_LOG_VIA_SPLIT, &update->new_oid, &update->old_oid, NULL, NULL, update->committer_info, update->msg); + new_update->parent_update = update; /* * Add "HEAD". This insertion is O(N) in the transaction @@ -2493,7 +2503,6 @@ static enum ref_transaction_error split_symref_update(struct ref_update *update, * done when new_update is processed. */ update->flags |= REF_LOG_ONLY | REF_NO_DEREF; - update->flags &= ~REF_HAVE_OLD; return 0; } @@ -2506,11 +2515,36 @@ static enum ref_transaction_error split_symref_update(struct ref_update *update, */ static enum ref_transaction_error check_old_oid(struct ref_update *update, struct object_id *oid, + struct strbuf *referent, struct strbuf *err) { - if (!(update->flags & REF_HAVE_OLD) || - oideq(oid, &update->old_oid)) + if (update->flags & REF_LOG_ONLY || + !(update->flags & REF_HAVE_OLD)) + return 0; + + if (oideq(oid, &update->old_oid)) { + /* + * Normally matching the expected old oid is enough. Either we + * found the ref at the expected state, or we are creating and + * expect the null oid (and likewise found nothing). + * + * But there is one exception for the null oid: if we found a + * symref pointing to nothing we'll also get the null oid. In + * regular recursive mode, that's good (we'll write to what the + * symref points to, which doesn't exist). But in no-deref + * mode, it means we'll clobber the symref, even though the + * caller asked for this to be a creation event. So flag + * that case to preserve the dangling symref. + */ + if ((update->flags & REF_NO_DEREF) && referent->len && + is_null_oid(oid)) { + strbuf_addf(err, "cannot lock ref '%s': " + "dangling symref already exists", + ref_update_original_update_refname(update)); + return REF_TRANSACTION_ERROR_CREATE_EXISTS; + } return 0; + } if (is_null_oid(&update->old_oid)) { strbuf_addf(err, "cannot lock ref '%s': " @@ -2600,7 +2634,36 @@ static enum ref_transaction_error lock_ref_for_update(struct files_ref_store *re update->backend_data = lock; - if (update->type & REF_ISSYMREF) { + if (update->flags & REF_LOG_VIA_SPLIT) { + struct ref_lock *parent_lock; + + if (!update->parent_update) + BUG("split update without a parent"); + + parent_lock = update->parent_update->backend_data; + + /* + * Check that "HEAD" didn't racily change since we have looked + * it up. If it did we must refuse to write the reflog entry. + * + * Note that this does not catch all races: if "HEAD" was + * racily changed to point to one of the refs part of the + * transaction then we would miss writing the split reflog + * entry for "HEAD". + */ + if (!(update->type & REF_ISSYMREF) || + strcmp(update->parent_update->refname, referent.buf)) { + strbuf_addstr(err, "HEAD has been racily updated"); + ret = REF_TRANSACTION_ERROR_GENERIC; + goto out; + } + + if (update->flags & REF_HAVE_OLD) { + oidcpy(&lock->old_oid, &update->old_oid); + } else { + oidcpy(&lock->old_oid, &parent_lock->old_oid); + } + } else if (update->type & REF_ISSYMREF) { if (update->flags & REF_NO_DEREF) { /* * We won't be reading the referent as part of @@ -2622,7 +2685,8 @@ static enum ref_transaction_error lock_ref_for_update(struct files_ref_store *re if (update->old_target) ret = ref_update_check_old_target(referent.buf, update, err); else - ret = check_old_oid(update, &lock->old_oid, err); + ret = check_old_oid(update, &lock->old_oid, + &referent, err); if (ret) goto out; } else { @@ -2654,7 +2718,8 @@ static enum ref_transaction_error lock_ref_for_update(struct files_ref_store *re ret = REF_TRANSACTION_ERROR_EXPECTED_SYMREF; goto out; } else { - ret = check_old_oid(update, &lock->old_oid, err); + ret = check_old_oid(update, &lock->old_oid, + &referent, err); if (ret) { goto out; } @@ -2976,6 +3041,20 @@ static int parse_and_write_reflog(struct files_ref_store *refs, struct ref_lock *lock, struct strbuf *err) { + struct object_id *old_oid = &lock->old_oid; + + if (update->flags & REF_LOG_USE_PROVIDED_OIDS) { + if (!(update->flags & REF_HAVE_OLD) || + !(update->flags & REF_HAVE_NEW) || + !(update->flags & REF_LOG_ONLY)) { + strbuf_addf(err, _("trying to write reflog for '%s'" + "with incomplete values"), update->refname); + return REF_TRANSACTION_ERROR_GENERIC; + } + + old_oid = &update->old_oid; + } + if (update->new_target) { /* * We want to get the resolved OID for the target, to ensure @@ -2993,7 +3072,7 @@ static int parse_and_write_reflog(struct files_ref_store *refs, } } - if (files_log_ref_write(refs, lock->ref_name, &lock->old_oid, + if (files_log_ref_write(refs, lock->ref_name, old_oid, &update->new_oid, update->committer_info, update->msg, update->flags, err)) { char *old_msg = strbuf_detach(err, NULL); @@ -3061,7 +3140,8 @@ static int files_transaction_finish_initial(struct files_ref_store *refs, for (i = 0; i < transaction->nr; i++) { struct ref_update *update = transaction->updates[i]; - if ((update->flags & REF_HAVE_OLD) && + if (!(update->flags & REF_LOG_ONLY) && + (update->flags & REF_HAVE_OLD) && !is_null_oid(&update->old_oid)) BUG("initial ref transaction with old_sha1 set"); @@ -3308,7 +3388,8 @@ struct expire_reflog_cb { dry_run:1; }; -static int expire_reflog_ent(struct object_id *ooid, struct object_id *noid, +static int expire_reflog_ent(const char *refname UNUSED, + struct object_id *ooid, struct object_id *noid, const char *email, timestamp_t timestamp, int tz, const char *message, void *cb_data) { diff --git a/refs/iterator.c b/refs/iterator.c index 766d96e795..17ef841d8a 100644 --- a/refs/iterator.c +++ b/refs/iterator.c @@ -15,10 +15,10 @@ int ref_iterator_advance(struct ref_iterator *ref_iterator) return ref_iterator->vtable->advance(ref_iterator); } -int ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) +int ref_iterator_seek(struct ref_iterator *ref_iterator, const char *refname, + unsigned int flags) { - return ref_iterator->vtable->seek(ref_iterator, prefix); + return ref_iterator->vtable->seek(ref_iterator, refname, flags); } int ref_iterator_peel(struct ref_iterator *ref_iterator, @@ -57,7 +57,8 @@ static int empty_ref_iterator_advance(struct ref_iterator *ref_iterator UNUSED) } static int empty_ref_iterator_seek(struct ref_iterator *ref_iterator UNUSED, - const char *prefix UNUSED) + const char *refname UNUSED, + unsigned int flags UNUSED) { return 0; } @@ -224,7 +225,7 @@ error: } static int merge_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct merge_ref_iterator *iter = (struct merge_ref_iterator *)ref_iterator; @@ -234,11 +235,11 @@ static int merge_ref_iterator_seek(struct ref_iterator *ref_iterator, iter->iter0 = iter->iter0_owned; iter->iter1 = iter->iter1_owned; - ret = ref_iterator_seek(iter->iter0, prefix); + ret = ref_iterator_seek(iter->iter0, refname, flags); if (ret < 0) return ret; - ret = ref_iterator_seek(iter->iter1, prefix); + ret = ref_iterator_seek(iter->iter1, refname, flags); if (ret < 0) return ret; @@ -407,13 +408,16 @@ static int prefix_ref_iterator_advance(struct ref_iterator *ref_iterator) } static int prefix_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct prefix_ref_iterator *iter = (struct prefix_ref_iterator *)ref_iterator; - free(iter->prefix); - iter->prefix = xstrdup_or_null(prefix); - return ref_iterator_seek(iter->iter0, prefix); + + if (flags & REF_ITERATOR_SEEK_SET_PREFIX) { + free(iter->prefix); + iter->prefix = xstrdup_or_null(refname); + } + return ref_iterator_seek(iter->iter0, refname, flags); } static int prefix_ref_iterator_peel(struct ref_iterator *ref_iterator, diff --git a/refs/packed-backend.c b/refs/packed-backend.c index 7fd73a0e6d..a8c22a0a7f 100644 --- a/refs/packed-backend.c +++ b/refs/packed-backend.c @@ -1004,19 +1004,23 @@ static int packed_ref_iterator_advance(struct ref_iterator *ref_iterator) } static int packed_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct packed_ref_iterator *iter = (struct packed_ref_iterator *)ref_iterator; const char *start; - if (prefix && *prefix) - start = find_reference_location(iter->snapshot, prefix, 0); + if (refname && *refname) + start = find_reference_location(iter->snapshot, refname, 0); else start = iter->snapshot->start; - free(iter->prefix); - iter->prefix = xstrdup_or_null(prefix); + /* Unset any previously set prefix */ + FREE_AND_NULL(iter->prefix); + + if (flags & REF_ITERATOR_SEEK_SET_PREFIX) + iter->prefix = xstrdup_or_null(refname); + iter->pos = start; iter->eof = iter->snapshot->eof; @@ -1194,7 +1198,8 @@ static struct ref_iterator *packed_ref_iterator_begin( iter->repo = ref_store->repo; iter->flags = flags; - if (packed_ref_iterator_seek(&iter->base, prefix) < 0) { + if (packed_ref_iterator_seek(&iter->base, prefix, + REF_ITERATOR_SEEK_SET_PREFIX) < 0) { ref_iterator_free(&iter->base); return NULL; } @@ -1228,7 +1233,7 @@ int packed_refs_lock(struct ref_store *ref_store, int flags, struct strbuf *err) static int timeout_value = 1000; if (!timeout_configured) { - git_config_get_int("core.packedrefstimeout", &timeout_value); + repo_config_get_int(the_repository, "core.packedrefstimeout", &timeout_value); timeout_configured = 1; } diff --git a/refs/ref-cache.c b/refs/ref-cache.c index c1f1bab1d5..c180e0aad7 100644 --- a/refs/ref-cache.c +++ b/refs/ref-cache.c @@ -194,20 +194,6 @@ static struct ref_dir *find_containing_dir(struct ref_dir *dir, return dir; } -struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname) -{ - int entry_index; - struct ref_entry *entry; - dir = find_containing_dir(dir, refname); - if (!dir) - return NULL; - entry_index = search_ref_dir(dir, refname, strlen(refname)); - if (entry_index == -1) - return NULL; - entry = dir->entries[entry_index]; - return (entry->flag & REF_DIR) ? NULL : entry; -} - /* * Emit a warning and return true iff ref1 and ref2 have the same name * and the same oid. Die if they have the same name but different @@ -448,11 +434,9 @@ static int cache_ref_iterator_advance(struct ref_iterator *ref_iterator) } } -static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) +static int cache_ref_iterator_set_prefix(struct cache_ref_iterator *iter, + const char *prefix) { - struct cache_ref_iterator *iter = - (struct cache_ref_iterator *)ref_iterator; struct cache_ref_iterator_level *level; struct ref_dir *dir; @@ -483,6 +467,84 @@ static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator, return 0; } +static int cache_ref_iterator_seek(struct ref_iterator *ref_iterator, + const char *refname, unsigned int flags) +{ + struct cache_ref_iterator *iter = + (struct cache_ref_iterator *)ref_iterator; + + if (flags & REF_ITERATOR_SEEK_SET_PREFIX) { + return cache_ref_iterator_set_prefix(iter, refname); + } else if (refname && *refname) { + struct cache_ref_iterator_level *level; + const char *slash = refname; + struct ref_dir *dir; + + dir = get_ref_dir(iter->cache->root); + + if (iter->prime_dir) + prime_ref_dir(dir, refname); + + iter->levels_nr = 1; + level = &iter->levels[0]; + level->index = -1; + level->dir = dir; + + /* Unset any previously set prefix */ + FREE_AND_NULL(iter->prefix); + + /* + * Breakdown the provided seek path and assign the correct + * indexing to each level as needed. + */ + do { + int idx; + size_t len; + int cmp = 0; + + sort_ref_dir(dir); + + slash = strchr(slash, '/'); + len = slash ? (size_t)(slash - refname) : strlen(refname); + + for (idx = 0; idx < dir->nr; idx++) { + cmp = strncmp(refname, dir->entries[idx]->name, len); + if (cmp <= 0) + break; + } + /* don't overflow the index */ + idx = idx >= dir->nr ? dir->nr - 1 : idx; + + if (slash) + slash = slash + 1; + + level->index = idx; + if (dir->entries[idx]->flag & REF_DIR) { + /* push down a level */ + dir = get_ref_dir(dir->entries[idx]); + + ALLOC_GROW(iter->levels, iter->levels_nr + 1, + iter->levels_alloc); + level = &iter->levels[iter->levels_nr++]; + level->dir = dir; + level->index = -1; + level->prefix_state = PREFIX_CONTAINS_DIR; + } else { + /* reduce the index so the leaf node is iterated over */ + if (cmp <= 0 && !slash) + level->index = idx - 1; + /* + * while the seek path may not be exhausted, our + * match is exhausted at a leaf node. + */ + break; + } + } while (slash); + } + + return 0; +} + static int cache_ref_iterator_peel(struct ref_iterator *ref_iterator, struct object_id *peeled) { @@ -523,7 +585,8 @@ struct ref_iterator *cache_ref_iterator_begin(struct ref_cache *cache, iter->cache = cache; iter->prime_dir = prime_dir; - if (cache_ref_iterator_seek(&iter->base, prefix) < 0) { + if (cache_ref_iterator_seek(&iter->base, prefix, + REF_ITERATOR_SEEK_SET_PREFIX) < 0) { ref_iterator_free(&iter->base); return NULL; } diff --git a/refs/ref-cache.h b/refs/ref-cache.h index 5f04e518c3..f635d2d824 100644 --- a/refs/ref-cache.h +++ b/refs/ref-cache.h @@ -202,13 +202,6 @@ void free_ref_cache(struct ref_cache *cache); void add_entry_to_dir(struct ref_dir *dir, struct ref_entry *entry); /* - * Find the value entry with the given name in dir, sorting ref_dirs - * and recursing into subdirectories as necessary. If the name is not - * found or it corresponds to a directory entry, return NULL. - */ -struct ref_entry *find_ref_entry(struct ref_dir *dir, const char *refname); - -/* * Start iterating over references in `cache`. If `prefix` is * specified, only include references whose names start with that * prefix. If `prime_dir` is true, then fill any incomplete diff --git a/refs/refs-internal.h b/refs/refs-internal.h index f868870851..54c2079c12 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -244,90 +244,8 @@ const char *find_descendant_ref(const char *dirname, #define SYMREF_MAXDEPTH 5 /* - * These flags are passed to refs_ref_iterator_begin() (and do_for_each_ref(), - * which feeds it). - */ -enum do_for_each_ref_flags { - /* - * Include broken references in a do_for_each_ref*() iteration, which - * would normally be omitted. This includes both refs that point to - * missing objects (a true repository corruption), ones with illegal - * names (which we prefer not to expose to callers), as well as - * dangling symbolic refs (i.e., those that point to a non-existent - * ref; this is not a corruption, but as they have no valid oid, we - * omit them from normal iteration results). - */ - DO_FOR_EACH_INCLUDE_BROKEN = (1 << 0), - - /* - * Only include per-worktree refs in a do_for_each_ref*() iteration. - * Normally this will be used with a files ref_store, since that's - * where all reference backends will presumably store their - * per-worktree refs. - */ - DO_FOR_EACH_PER_WORKTREE_ONLY = (1 << 1), - - /* - * Omit dangling symrefs from output; this only has an effect with - * INCLUDE_BROKEN, since they are otherwise not included at all. - */ - DO_FOR_EACH_OMIT_DANGLING_SYMREFS = (1 << 2), - - /* - * Include root refs i.e. HEAD and pseudorefs along with the regular - * refs. - */ - DO_FOR_EACH_INCLUDE_ROOT_REFS = (1 << 3), -}; - -/* - * Reference iterators - * - * A reference iterator encapsulates the state of an in-progress - * iteration over references. Create an instance of `struct - * ref_iterator` via one of the functions in this module. - * - * A freshly-created ref_iterator doesn't yet point at a reference. To - * advance the iterator, call ref_iterator_advance(). If successful, - * this sets the iterator's refname, oid, and flags fields to describe - * the next reference and returns ITER_OK. The data pointed at by - * refname and oid belong to the iterator; if you want to retain them - * after calling ref_iterator_advance() again or calling - * ref_iterator_free(), you must make a copy. When the iteration has - * been exhausted, ref_iterator_advance() releases any resources - * associated with the iteration, frees the ref_iterator object, and - * returns ITER_DONE. If you want to abort the iteration early, call - * ref_iterator_free(), which also frees the ref_iterator object and - * any associated resources. If there was an internal error advancing - * to the next entry, ref_iterator_advance() aborts the iteration, - * frees the ref_iterator, and returns ITER_ERROR. - * - * The reference currently being looked at can be peeled by calling - * ref_iterator_peel(). This function is often faster than peel_ref(), - * so it should be preferred when iterating over references. - * - * Putting it all together, a typical iteration looks like this: - * - * int ok; - * struct ref_iterator *iter = ...; - * - * while ((ok = ref_iterator_advance(iter)) == ITER_OK) { - * if (want_to_stop_iteration()) { - * ok = ITER_DONE; - * break; - * } - * - * // Access information about the current reference: - * if (!(iter->flags & REF_ISSYMREF)) - * printf("%s is %s\n", iter->refname, oid_to_hex(iter->oid)); - * - * // If you need to peel the reference: - * ref_iterator_peel(iter, &oid); - * } - * - * if (ok != ITER_DONE) - * handle_error(); - * ref_iterator_free(iter); + * Data structure for holding a reference iterator. See refs.h for + * more details and usage instructions. */ struct ref_iterator { struct ref_iterator_vtable *vtable; @@ -338,42 +256,6 @@ struct ref_iterator { }; /* - * Advance the iterator to the first or next item and return ITER_OK. - * If the iteration is exhausted, free the resources associated with - * the ref_iterator and return ITER_DONE. On errors, free the iterator - * resources and return ITER_ERROR. It is a bug to use ref_iterator or - * call this function again after it has returned ITER_DONE or - * ITER_ERROR. - */ -int ref_iterator_advance(struct ref_iterator *ref_iterator); - -/* - * Seek the iterator to the first reference with the given prefix. - * The prefix is matched as a literal string, without regard for path - * separators. If prefix is NULL or the empty string, seek the iterator to the - * first reference again. - * - * This function is expected to behave as if a new ref iterator with the same - * prefix had been created, but allows reuse of iterators and thus may allow - * the backend to optimize. Parameters other than the prefix that have been - * passed when creating the iterator will remain unchanged. - * - * Returns 0 on success, a negative error code otherwise. - */ -int ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix); - -/* - * If possible, peel the reference currently being viewed by the - * iterator. Return 0 on success. - */ -int ref_iterator_peel(struct ref_iterator *ref_iterator, - struct object_id *peeled); - -/* Free the reference iterator and any associated resources. */ -void ref_iterator_free(struct ref_iterator *ref_iterator); - -/* * An iterator over nothing (its first ref_iterator_advance() call * returns ITER_DONE). */ @@ -385,17 +267,6 @@ struct ref_iterator *empty_ref_iterator_begin(void); int is_empty_ref_iterator(struct ref_iterator *ref_iterator); /* - * Return an iterator that goes over each reference in `refs` for - * which the refname begins with prefix. If trim is non-zero, then - * trim that many characters off the beginning of each refname. - * The output is ordered by refname. - */ -struct ref_iterator *refs_ref_iterator_begin( - struct ref_store *refs, - const char *prefix, const char **exclude_patterns, - int trim, enum do_for_each_ref_flags flags); - -/* * A callback function used to instruct merge_ref_iterator how to * interleave the entries from iter0 and iter1. The function should * return one of the constants defined in enum iterator_selection. It @@ -482,11 +353,12 @@ void base_ref_iterator_init(struct ref_iterator *iter, typedef int ref_iterator_advance_fn(struct ref_iterator *ref_iterator); /* - * Seek the iterator to the first reference matching the given prefix. Should - * behave the same as if a new iterator was created with the same prefix. + * Seek the iterator to the first matching reference. If the + * REF_ITERATOR_SEEK_SET_PREFIX flag is set, it would behave the same as if a + * new iterator was created with the provided refname as prefix. */ typedef int ref_iterator_seek_fn(struct ref_iterator *ref_iterator, - const char *prefix); + const char *refname, unsigned int flags); /* * Peels the current ref, returning 0 for success or -1 for failure. @@ -520,18 +392,6 @@ struct ref_iterator_vtable { */ extern struct ref_iterator *current_ref_iter; -/* - * The common backend for the for_each_*ref* functions. Call fn for - * each reference in iter. If the iterator itself ever returns - * ITER_ERROR, return -1. If fn ever returns a non-zero value, stop - * the iteration and return that value. Otherwise, return 0. In any - * case, free the iterator when done. This function is basically an - * adapter between the callback style of reference iteration and the - * iterator style. - */ -int do_for_each_ref_iterator(struct ref_iterator *iter, - each_ref_fn fn, void *cb_data); - struct ref_store; /* refs backends */ @@ -802,7 +662,8 @@ enum ref_transaction_error ref_update_check_old_target(const char *referent, /* * Check if the ref must exist, this means that the old_oid or - * old_target is non NULL. + * old_target is non NULL. Log-only updates never require the old state to + * match. */ int ref_update_expects_existing_old_ref(struct ref_update *update); diff --git a/refs/reftable-backend.c b/refs/reftable-backend.c index 4c3817f4ec..9e889da2ff 100644 --- a/refs/reftable-backend.c +++ b/refs/reftable-backend.c @@ -386,7 +386,7 @@ static struct ref_store *reftable_be_init(struct repository *repo, refs->write_options.lock_timeout_ms = 100; refs->write_options.fsync = reftable_be_fsync; - git_config(reftable_be_config, &refs->write_options); + repo_config(the_repository, reftable_be_config, &refs->write_options); /* * It is somewhat unfortunate that we have to mirror the default block @@ -719,15 +719,20 @@ static int reftable_ref_iterator_advance(struct ref_iterator *ref_iterator) } static int reftable_ref_iterator_seek(struct ref_iterator *ref_iterator, - const char *prefix) + const char *refname, unsigned int flags) { struct reftable_ref_iterator *iter = (struct reftable_ref_iterator *)ref_iterator; - free(iter->prefix); - iter->prefix = xstrdup_or_null(prefix); - iter->prefix_len = prefix ? strlen(prefix) : 0; - iter->err = reftable_iterator_seek_ref(&iter->iter, prefix); + /* Unset any previously set prefix */ + FREE_AND_NULL(iter->prefix); + iter->prefix_len = 0; + + if (flags & REF_ITERATOR_SEEK_SET_PREFIX) { + iter->prefix = xstrdup_or_null(refname); + iter->prefix_len = refname ? strlen(refname) : 0; + } + iter->err = reftable_iterator_seek_ref(&iter->iter, refname); return iter->err; } @@ -839,7 +844,8 @@ static struct reftable_ref_iterator *ref_iterator_for_stack(struct reftable_ref_ if (ret) goto done; - ret = reftable_ref_iterator_seek(&iter->base, prefix); + ret = reftable_ref_iterator_seek(&iter->base, prefix, + REF_ITERATOR_SEEK_SET_PREFIX); if (ret) goto done; @@ -1006,10 +1012,6 @@ static int prepare_transaction_update(struct write_transaction_table_arg **out, if (!arg) { struct reftable_addition *addition; - ret = reftable_stack_reload(be->stack); - if (ret) - return ret; - ret = reftable_stack_new_addition(&addition, be->stack, REFTABLE_STACK_NEW_ADDITION_RELOAD); if (ret) { @@ -1096,6 +1098,20 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor if (ret) return REF_TRANSACTION_ERROR_GENERIC; + if (u->flags & REF_LOG_USE_PROVIDED_OIDS) { + if (!(u->flags & REF_HAVE_OLD) || + !(u->flags & REF_HAVE_NEW) || + !(u->flags & REF_LOG_ONLY)) { + strbuf_addf(err, _("trying to write reflog for '%s'" + "with incomplete values"), u->refname); + return REF_TRANSACTION_ERROR_GENERIC; + } + + if (queue_transaction_update(refs, tx_data, u, &u->old_oid, err)) + return REF_TRANSACTION_ERROR_GENERIC; + return 0; + } + /* Verify that the new object ID is valid. */ if ((u->flags & REF_HAVE_NEW) && !is_null_oid(&u->new_oid) && !(u->flags & REF_SKIP_OID_VERIFICATION) && @@ -1180,8 +1196,6 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor if (ret > 0) { /* The reference does not exist, but we expected it to. */ strbuf_addf(err, _("cannot lock ref '%s': " - - "unable to resolve reference '%s'"), ref_update_original_update_refname(u), u->refname); return REF_TRANSACTION_ERROR_NONEXISTENT_REF; @@ -1235,13 +1249,8 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor new_update->parent_update = u; - /* - * Change the symbolic ref update to log only. Also, it - * doesn't need to check its old OID value, as that will be - * done when new_update is processed. - */ + /* Change the symbolic ref update to log only. */ u->flags |= REF_LOG_ONLY | REF_NO_DEREF; - u->flags &= ~REF_HAVE_OLD; } } @@ -1265,8 +1274,33 @@ static enum ref_transaction_error prepare_single_update(struct reftable_ref_stor ret = ref_update_check_old_target(referent->buf, u, err); if (ret) return ret; - } else if ((u->flags & REF_HAVE_OLD) && !oideq(¤t_oid, &u->old_oid)) { - if (is_null_oid(&u->old_oid)) { + } else if ((u->flags & (REF_LOG_ONLY | REF_HAVE_OLD)) == REF_HAVE_OLD) { + if (oideq(¤t_oid, &u->old_oid)) { + /* + * Normally matching the expected old oid is enough. Either we + * found the ref at the expected state, or we are creating and + * expect the null oid (and likewise found nothing). + * + * But there is one exception for the null oid: if we found a + * symref pointing to nothing we'll also get the null oid. In + * regular recursive mode, that's good (we'll write to what the + * symref points to, which doesn't exist). But in no-deref + * mode, it means we'll clobber the symref, even though the + * caller asked for this to be a creation event. So flag + * that case to preserve the dangling symref. + * + * Everything else is OK and we can fall through to the + * end of the conditional chain. + */ + if ((u->flags & REF_NO_DEREF) && + referent->len && + is_null_oid(&u->old_oid)) { + strbuf_addf(err, _("cannot lock ref '%s': " + "dangling symref already exists"), + ref_update_original_update_refname(u)); + return REF_TRANSACTION_ERROR_CREATE_EXISTS; + } + } else if (is_null_oid(&u->old_oid)) { strbuf_addf(err, _("cannot lock ref '%s': " "reference already exists"), ref_update_original_update_refname(u)); @@ -1960,7 +1994,8 @@ static int reftable_be_rename_ref(struct ref_store *ref_store, ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, + REFTABLE_STACK_NEW_ADDITION_RELOAD); done: assert(ret != REFTABLE_API_ERROR); @@ -1989,7 +2024,8 @@ static int reftable_be_copy_ref(struct ref_store *ref_store, ret = backend_for(&arg.be, refs, newrefname, &newrefname, 1); if (ret) goto done; - ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg); + ret = reftable_stack_add(arg.be->stack, &write_copy_table, &arg, + REFTABLE_STACK_NEW_ADDITION_RELOAD); done: assert(ret != REFTABLE_API_ERROR); @@ -2042,7 +2078,8 @@ static int reftable_reflog_iterator_advance(struct ref_iterator *ref_iterator) } static int reftable_reflog_iterator_seek(struct ref_iterator *ref_iterator UNUSED, - const char *prefix UNUSED) + const char *refname UNUSED, + unsigned int flags UNUSED) { BUG("reftable reflog iterator cannot be seeked"); return -1; @@ -2140,7 +2177,7 @@ static int yield_log_record(struct reftable_ref_store *refs, full_committer = fmt_ident(log->value.update.name, log->value.update.email, WANT_COMMITTER_IDENT, NULL, IDENT_NO_DATE); - return fn(&old_oid, &new_oid, full_committer, + return fn(log->refname, &old_oid, &new_oid, full_committer, log->value.update.time, log->value.update.tz_offset, log->value.update.message, cb_data); } @@ -2360,7 +2397,8 @@ static int reftable_be_create_reflog(struct ref_store *ref_store, goto done; arg.stack = be->stack; - ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg); + ret = reftable_stack_add(be->stack, &write_reflog_existence_table, &arg, + REFTABLE_STACK_NEW_ADDITION_RELOAD); done: return ret; @@ -2431,7 +2469,8 @@ static int reftable_be_delete_reflog(struct ref_store *ref_store, return ret; arg.stack = be->stack; - ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg); + ret = reftable_stack_add(be->stack, &write_reflog_delete_table, &arg, + REFTABLE_STACK_NEW_ADDITION_RELOAD); assert(ret != REFTABLE_API_ERROR); return ret; @@ -2552,15 +2591,16 @@ static int reftable_be_reflog_expire(struct ref_store *ref_store, if (ret < 0) goto done; - ret = reftable_stack_init_log_iterator(be->stack, &it); + ret = reftable_stack_new_addition(&add, be->stack, + REFTABLE_STACK_NEW_ADDITION_RELOAD); if (ret < 0) goto done; - ret = reftable_iterator_seek_log(&it, refname); + ret = reftable_stack_init_log_iterator(be->stack, &it); if (ret < 0) goto done; - ret = reftable_stack_new_addition(&add, be->stack, 0); + ret = reftable_iterator_seek_log(&it, refname); if (ret < 0) goto done; diff --git a/reftable/reftable-stack.h b/reftable/reftable-stack.h index 910ec6ef3a..d70fcb705d 100644 --- a/reftable/reftable-stack.h +++ b/reftable/reftable-stack.h @@ -68,12 +68,15 @@ int reftable_addition_commit(struct reftable_addition *add); * transaction. Releases the lock if held. */ void reftable_addition_destroy(struct reftable_addition *add); -/* add a new table to the stack. The write_table function must call - * reftable_writer_set_limits, add refs and return an error value. */ +/* + * Add a new table to the stack. The write_table function must call + * reftable_writer_set_limits, add refs and return an error value. + * The flags are passed through to `reftable_stack_new_addition()`. + */ int reftable_stack_add(struct reftable_stack *st, int (*write_table)(struct reftable_writer *wr, void *write_arg), - void *write_arg); + void *write_arg, unsigned flags); struct reftable_iterator; diff --git a/reftable/reftable-writer.h b/reftable/reftable-writer.h index 0fbeff17f4..1e7003cd69 100644 --- a/reftable/reftable-writer.h +++ b/reftable/reftable-writer.h @@ -156,7 +156,7 @@ int reftable_writer_add_ref(struct reftable_writer *w, the records before adding them, reordering the records array passed in. */ int reftable_writer_add_refs(struct reftable_writer *w, - struct reftable_ref_record *refs, int n); + struct reftable_ref_record *refs, size_t n); /* adds reftable_log_records. Log records are keyed by (refname, decreasing @@ -171,7 +171,7 @@ int reftable_writer_add_log(struct reftable_writer *w, the records before adding them, reordering records array passed in. */ int reftable_writer_add_logs(struct reftable_writer *w, - struct reftable_log_record *logs, int n); + struct reftable_log_record *logs, size_t n); /* reftable_writer_close finalizes the reftable. The writer is retained so * statistics can be inspected. */ diff --git a/reftable/stack.c b/reftable/stack.c index 4caf96aa1d..f91ce50bcd 100644 --- a/reftable/stack.c +++ b/reftable/stack.c @@ -17,18 +17,6 @@ #include "table.h" #include "writer.h" -static int stack_try_add(struct reftable_stack *st, - int (*write_table)(struct reftable_writer *wr, - void *arg), - void *arg); -static int stack_write_compact(struct reftable_stack *st, - struct reftable_writer *wr, - size_t first, size_t last, - struct reftable_log_expiry_config *config); -static void reftable_addition_close(struct reftable_addition *add); -static int reftable_stack_reload_maybe_reuse(struct reftable_stack *st, - int reuse_open); - static int stack_filename(struct reftable_buf *dest, struct reftable_stack *st, const char *name) { @@ -84,54 +72,6 @@ static int fd_writer_flush(void *arg) return stack_fsync(writer->opts, writer->fd); } -int reftable_new_stack(struct reftable_stack **dest, const char *dir, - const struct reftable_write_options *_opts) -{ - struct reftable_buf list_file_name = REFTABLE_BUF_INIT; - struct reftable_write_options opts = { 0 }; - struct reftable_stack *p; - int err; - - p = reftable_calloc(1, sizeof(*p)); - if (!p) { - err = REFTABLE_OUT_OF_MEMORY_ERROR; - goto out; - } - - if (_opts) - opts = *_opts; - if (opts.hash_id == 0) - opts.hash_id = REFTABLE_HASH_SHA1; - - *dest = NULL; - - reftable_buf_reset(&list_file_name); - if ((err = reftable_buf_addstr(&list_file_name, dir)) < 0 || - (err = reftable_buf_addstr(&list_file_name, "/tables.list")) < 0) - goto out; - - p->list_file = reftable_buf_detach(&list_file_name); - p->list_fd = -1; - p->opts = opts; - p->reftable_dir = reftable_strdup(dir); - if (!p->reftable_dir) { - err = REFTABLE_OUT_OF_MEMORY_ERROR; - goto out; - } - - err = reftable_stack_reload_maybe_reuse(p, 1); - if (err < 0) - goto out; - - *dest = p; - err = 0; - -out: - if (err < 0) - reftable_stack_destroy(p); - return err; -} - static int fd_read_lines(int fd, char ***namesp) { char *buf = NULL; @@ -591,9 +531,59 @@ out: return err; } -/* -1 = error - 0 = up to date - 1 = changed. */ +int reftable_new_stack(struct reftable_stack **dest, const char *dir, + const struct reftable_write_options *_opts) +{ + struct reftable_buf list_file_name = REFTABLE_BUF_INIT; + struct reftable_write_options opts = { 0 }; + struct reftable_stack *p; + int err; + + p = reftable_calloc(1, sizeof(*p)); + if (!p) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + + if (_opts) + opts = *_opts; + if (opts.hash_id == 0) + opts.hash_id = REFTABLE_HASH_SHA1; + + *dest = NULL; + + reftable_buf_reset(&list_file_name); + if ((err = reftable_buf_addstr(&list_file_name, dir)) < 0 || + (err = reftable_buf_addstr(&list_file_name, "/tables.list")) < 0) + goto out; + + p->list_file = reftable_buf_detach(&list_file_name); + p->list_fd = -1; + p->opts = opts; + p->reftable_dir = reftable_strdup(dir); + if (!p->reftable_dir) { + err = REFTABLE_OUT_OF_MEMORY_ERROR; + goto out; + } + + err = reftable_stack_reload_maybe_reuse(p, 1); + if (err < 0) + goto out; + + *dest = p; + err = 0; + +out: + if (err < 0) + reftable_stack_destroy(p); + return err; +} + +/* + * Check whether the given stack is up-to-date with what we have in memory. + * Returns 0 if so, 1 if the stack is out-of-date or a negative error code + * otherwise. + */ static int stack_uptodate(struct reftable_stack *st) { char **names = NULL; @@ -667,34 +657,6 @@ int reftable_stack_reload(struct reftable_stack *st) return err; } -int reftable_stack_add(struct reftable_stack *st, - int (*write)(struct reftable_writer *wr, void *arg), - void *arg) -{ - int err = stack_try_add(st, write, arg); - if (err < 0) { - if (err == REFTABLE_OUTDATED_ERROR) { - /* Ignore error return, we want to propagate - REFTABLE_OUTDATED_ERROR. - */ - reftable_stack_reload(st); - } - return err; - } - - return 0; -} - -static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max) -{ - char buf[100]; - uint32_t rnd = reftable_rand(); - snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x", - min, max, rnd); - reftable_buf_reset(dest); - return reftable_buf_addstr(dest, buf); -} - struct reftable_addition { struct reftable_flock tables_list_lock; struct reftable_stack *stack; @@ -704,7 +666,25 @@ struct reftable_addition { uint64_t next_update_index; }; -#define REFTABLE_ADDITION_INIT {0} +static void reftable_addition_close(struct reftable_addition *add) +{ + struct reftable_buf nm = REFTABLE_BUF_INIT; + size_t i; + + for (i = 0; i < add->new_tables_len; i++) { + if (!stack_filename(&nm, add->stack, add->new_tables[i])) + unlink(nm.buf); + reftable_free(add->new_tables[i]); + add->new_tables[i] = NULL; + } + reftable_free(add->new_tables); + add->new_tables = NULL; + add->new_tables_len = 0; + add->new_tables_cap = 0; + + flock_release(&add->tables_list_lock); + reftable_buf_release(&nm); +} static int reftable_stack_init_addition(struct reftable_addition *add, struct reftable_stack *st, @@ -713,18 +693,14 @@ static int reftable_stack_init_addition(struct reftable_addition *add, struct reftable_buf lock_file_name = REFTABLE_BUF_INIT; int err; + memset(add, 0, sizeof(*add)); add->stack = st; err = flock_acquire(&add->tables_list_lock, st->list_file, st->opts.lock_timeout_ms); - if (err < 0) { - if (errno == EEXIST) { - err = REFTABLE_LOCK_ERROR; - } else { - err = REFTABLE_IO_ERROR; - } + if (err < 0) goto done; - } + if (st->opts.default_permissions) { if (chmod(add->tables_list_lock.path, st->opts.default_permissions) < 0) { @@ -754,24 +730,54 @@ done: return err; } -static void reftable_addition_close(struct reftable_addition *add) +static int stack_try_add(struct reftable_stack *st, + int (*write_table)(struct reftable_writer *wr, + void *arg), + void *arg, unsigned flags) { - struct reftable_buf nm = REFTABLE_BUF_INIT; - size_t i; + struct reftable_addition add; + int err; - for (i = 0; i < add->new_tables_len; i++) { - if (!stack_filename(&nm, add->stack, add->new_tables[i])) - unlink(nm.buf); - reftable_free(add->new_tables[i]); - add->new_tables[i] = NULL; + err = reftable_stack_init_addition(&add, st, flags); + if (err < 0) + goto done; + + err = reftable_addition_add(&add, write_table, arg); + if (err < 0) + goto done; + + err = reftable_addition_commit(&add); +done: + reftable_addition_close(&add); + return err; +} + +int reftable_stack_add(struct reftable_stack *st, + int (*write)(struct reftable_writer *wr, void *arg), + void *arg, unsigned flags) +{ + int err = stack_try_add(st, write, arg, flags); + if (err < 0) { + if (err == REFTABLE_OUTDATED_ERROR) { + /* Ignore error return, we want to propagate + REFTABLE_OUTDATED_ERROR. + */ + reftable_stack_reload(st); + } + return err; } - reftable_free(add->new_tables); - add->new_tables = NULL; - add->new_tables_len = 0; - add->new_tables_cap = 0; - flock_release(&add->tables_list_lock); - reftable_buf_release(&nm); + return 0; +} + +static int format_name(struct reftable_buf *dest, uint64_t min, uint64_t max) +{ + char buf[100]; + uint32_t rnd = reftable_rand(); + snprintf(buf, sizeof(buf), "0x%012" PRIx64 "-0x%012" PRIx64 "-%08x", + min, max, rnd); + reftable_buf_reset(dest); + return reftable_buf_addstr(dest, buf); } void reftable_addition_destroy(struct reftable_addition *add) @@ -841,10 +847,13 @@ int reftable_addition_commit(struct reftable_addition *add) * control. It is possible that a concurrent writer is already * trying to compact parts of the stack, which would lead to a * `REFTABLE_LOCK_ERROR` because parts of the stack are locked - * already. This is a benign error though, so we ignore it. + * already. Similarly, the stack may have been rewritten by a + * concurrent writer, which causes `REFTABLE_OUTDATED_ERROR`. + * Both of these errors are benign, so we simply ignore them. */ err = reftable_stack_auto_compact(add->stack); - if (err < 0 && err != REFTABLE_LOCK_ERROR) + if (err < 0 && err != REFTABLE_LOCK_ERROR && + err != REFTABLE_OUTDATED_ERROR) goto done; err = 0; } @@ -858,39 +867,18 @@ int reftable_stack_new_addition(struct reftable_addition **dest, struct reftable_stack *st, unsigned int flags) { - int err = 0; - struct reftable_addition empty = REFTABLE_ADDITION_INIT; + int err; REFTABLE_CALLOC_ARRAY(*dest, 1); if (!*dest) return REFTABLE_OUT_OF_MEMORY_ERROR; - **dest = empty; err = reftable_stack_init_addition(*dest, st, flags); if (err) { reftable_free(*dest); *dest = NULL; } - return err; -} -static int stack_try_add(struct reftable_stack *st, - int (*write_table)(struct reftable_writer *wr, - void *arg), - void *arg) -{ - struct reftable_addition add = REFTABLE_ADDITION_INIT; - int err = reftable_stack_init_addition(&add, st, 0); - if (err < 0) - goto done; - - err = reftable_addition_add(&add, write_table, arg); - if (err < 0) - goto done; - - err = reftable_addition_commit(&add); -done: - reftable_addition_close(&add); return err; } @@ -1007,72 +995,6 @@ uint64_t reftable_stack_next_update_index(struct reftable_stack *st) return 1; } -static int stack_compact_locked(struct reftable_stack *st, - size_t first, size_t last, - struct reftable_log_expiry_config *config, - struct reftable_tmpfile *tab_file_out) -{ - struct reftable_buf next_name = REFTABLE_BUF_INIT; - struct reftable_buf tab_file_path = REFTABLE_BUF_INIT; - struct reftable_writer *wr = NULL; - struct fd_writer writer= { - .opts = &st->opts, - }; - struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; - int err = 0; - - err = format_name(&next_name, reftable_table_min_update_index(st->tables[first]), - reftable_table_max_update_index(st->tables[last])); - if (err < 0) - goto done; - - err = stack_filename(&tab_file_path, st, next_name.buf); - if (err < 0) - goto done; - - err = reftable_buf_addstr(&tab_file_path, ".temp.XXXXXX"); - if (err < 0) - goto done; - - err = tmpfile_from_pattern(&tab_file, tab_file_path.buf); - if (err < 0) - goto done; - - if (st->opts.default_permissions && - chmod(tab_file.path, st->opts.default_permissions) < 0) { - err = REFTABLE_IO_ERROR; - goto done; - } - - writer.fd = tab_file.fd; - err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, - &writer, &st->opts); - if (err < 0) - goto done; - - err = stack_write_compact(st, wr, first, last, config); - if (err < 0) - goto done; - - err = reftable_writer_close(wr); - if (err < 0) - goto done; - - err = tmpfile_close(&tab_file); - if (err < 0) - goto done; - - *tab_file_out = tab_file; - tab_file = REFTABLE_TMPFILE_INIT; - -done: - tmpfile_delete(&tab_file); - reftable_writer_free(wr); - reftable_buf_release(&next_name); - reftable_buf_release(&tab_file_path); - return err; -} - static int stack_write_compact(struct reftable_stack *st, struct reftable_writer *wr, size_t first, size_t last, @@ -1172,6 +1094,72 @@ done: return err; } +static int stack_compact_locked(struct reftable_stack *st, + size_t first, size_t last, + struct reftable_log_expiry_config *config, + struct reftable_tmpfile *tab_file_out) +{ + struct reftable_buf next_name = REFTABLE_BUF_INIT; + struct reftable_buf tab_file_path = REFTABLE_BUF_INIT; + struct reftable_writer *wr = NULL; + struct fd_writer writer= { + .opts = &st->opts, + }; + struct reftable_tmpfile tab_file = REFTABLE_TMPFILE_INIT; + int err = 0; + + err = format_name(&next_name, reftable_table_min_update_index(st->tables[first]), + reftable_table_max_update_index(st->tables[last])); + if (err < 0) + goto done; + + err = stack_filename(&tab_file_path, st, next_name.buf); + if (err < 0) + goto done; + + err = reftable_buf_addstr(&tab_file_path, ".temp.XXXXXX"); + if (err < 0) + goto done; + + err = tmpfile_from_pattern(&tab_file, tab_file_path.buf); + if (err < 0) + goto done; + + if (st->opts.default_permissions && + chmod(tab_file.path, st->opts.default_permissions) < 0) { + err = REFTABLE_IO_ERROR; + goto done; + } + + writer.fd = tab_file.fd; + err = reftable_writer_new(&wr, fd_writer_write, fd_writer_flush, + &writer, &st->opts); + if (err < 0) + goto done; + + err = stack_write_compact(st, wr, first, last, config); + if (err < 0) + goto done; + + err = reftable_writer_close(wr); + if (err < 0) + goto done; + + err = tmpfile_close(&tab_file); + if (err < 0) + goto done; + + *tab_file_out = tab_file; + tab_file = REFTABLE_TMPFILE_INIT; + +done: + tmpfile_delete(&tab_file); + reftable_writer_free(wr); + reftable_buf_release(&next_name); + reftable_buf_release(&tab_file_path); + return err; +} + enum stack_compact_range_flags { /* * Perform a best-effort compaction. That is, even if we cannot lock @@ -1219,17 +1207,27 @@ static int stack_compact_range(struct reftable_stack *st, * which are part of the user-specified range. */ err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); - if (err < 0) { - if (errno == EEXIST) - err = REFTABLE_LOCK_ERROR; - else - err = REFTABLE_IO_ERROR; + if (err < 0) goto done; - } + /* + * Check whether the stack is up-to-date. We unfortunately cannot + * handle the situation gracefully in case it's _not_ up-to-date + * because the range of tables that the user has requested us to + * compact may have been changed. So instead we abort. + * + * We could in theory improve the situation by having the caller not + * pass in a range, but instead the list of tables to compact. If so, + * we could check that relevant tables still exist. But for now it's + * good enough to just abort. + */ err = stack_uptodate(st); - if (err) + if (err < 0) + goto done; + if (err > 0) { + err = REFTABLE_OUTDATED_ERROR; goto done; + } /* * Lock all tables in the user-provided range. This is the slice of our @@ -1264,7 +1262,7 @@ static int stack_compact_range(struct reftable_stack *st, * tables, otherwise there would be nothing to compact. * In that case, we return a lock error to our caller. */ - if (errno == EEXIST && last - (i - 1) >= 2 && + if (err == REFTABLE_LOCK_ERROR && last - (i - 1) >= 2 && flags & STACK_COMPACT_RANGE_BEST_EFFORT) { err = 0; /* @@ -1276,13 +1274,9 @@ static int stack_compact_range(struct reftable_stack *st, */ first = (i - 1) + 1; break; - } else if (errno == EEXIST) { - err = REFTABLE_LOCK_ERROR; - goto done; - } else { - err = REFTABLE_IO_ERROR; - goto done; } + + goto done; } /* @@ -1291,10 +1285,8 @@ static int stack_compact_range(struct reftable_stack *st, * of tables. */ err = flock_close(&table_locks[nlocks++]); - if (err < 0) { - err = REFTABLE_IO_ERROR; + if (err < 0) goto done; - } } /* @@ -1326,13 +1318,8 @@ static int stack_compact_range(struct reftable_stack *st, * the new table. */ err = flock_acquire(&tables_list_lock, st->list_file, st->opts.lock_timeout_ms); - if (err < 0) { - if (errno == EEXIST) - err = REFTABLE_LOCK_ERROR; - else - err = REFTABLE_IO_ERROR; + if (err < 0) goto done; - } if (st->opts.default_permissions) { if (chmod(tables_list_lock.path, diff --git a/reftable/system.c b/reftable/system.c index 1ee268b125..725a25844e 100644 --- a/reftable/system.c +++ b/reftable/system.c @@ -72,7 +72,7 @@ int flock_acquire(struct reftable_flock *l, const char *target_path, reftable_free(lockfile); if (errno == EEXIST) return REFTABLE_LOCK_ERROR; - return -1; + return REFTABLE_IO_ERROR; } l->fd = get_lock_file_fd(lockfile); diff --git a/reftable/system.h b/reftable/system.h index beb9d2431f..c54ed4cad6 100644 --- a/reftable/system.h +++ b/reftable/system.h @@ -81,7 +81,9 @@ struct reftable_flock { * to acquire the lock. If `timeout_ms` is 0 we don't wait, if it is negative * we block indefinitely. * - * Retrun 0 on success, a reftable error code on error. + * Retrun 0 on success, a reftable error code on error. Specifically, + * `REFTABLE_LOCK_ERROR` should be returned in case the target path is already + * locked. */ int flock_acquire(struct reftable_flock *l, const char *target_path, long timeout_ms); diff --git a/reftable/writer.c b/reftable/writer.c index 3b4ebdd6dc..0133b64975 100644 --- a/reftable/writer.c +++ b/reftable/writer.c @@ -395,14 +395,16 @@ out: } int reftable_writer_add_refs(struct reftable_writer *w, - struct reftable_ref_record *refs, int n) + struct reftable_ref_record *refs, size_t n) { int err = 0; - int i = 0; - QSORT(refs, n, reftable_ref_record_compare_name); - for (i = 0; err == 0 && i < n; i++) { + + if (n) + qsort(refs, n, sizeof(*refs), reftable_ref_record_compare_name); + + for (size_t i = 0; err == 0 && i < n; i++) err = reftable_writer_add_ref(w, &refs[i]); - } + return err; } @@ -486,15 +488,16 @@ done: } int reftable_writer_add_logs(struct reftable_writer *w, - struct reftable_log_record *logs, int n) + struct reftable_log_record *logs, size_t n) { int err = 0; - int i = 0; - QSORT(logs, n, reftable_log_record_compare_key); - for (i = 0; err == 0 && i < n; i++) { + if (n) + qsort(logs, n, sizeof(*logs), reftable_log_record_compare_key); + + for (size_t i = 0; err == 0 && i < n; i++) err = reftable_writer_add_log(w, &logs[i]); - } + return err; } @@ -734,7 +734,7 @@ static void validate_remote_url(struct remote *remote) struct strbuf redacted = STRBUF_INIT; int warn_not_die; - if (git_config_get_string_tmp("transfer.credentialsinurl", &value)) + if (repo_config_get_string_tmp(the_repository, "transfer.credentialsinurl", &value)) return; if (!strcmp("warn", value)) @@ -1171,7 +1171,6 @@ static void show_push_unqualified_ref_name_error(const char *dst_value, const char *matched_src_name) { struct object_id oid; - enum object_type type; /* * TRANSLATORS: "matches '%s'%" is the <dst> part of "git push @@ -1196,30 +1195,37 @@ static void show_push_unqualified_ref_name_error(const char *dst_value, BUG("'%s' is not a valid object, " "match_explicit_lhs() should catch this!", matched_src_name); - type = odb_read_object_info(the_repository->objects, &oid, NULL); - if (type == OBJ_COMMIT) { + + switch (odb_read_object_info(the_repository->objects, &oid, NULL)) { + case OBJ_COMMIT: advise(_("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'?"), matched_src_name, dst_value); - } else if (type == OBJ_TAG) { + break; + case OBJ_TAG: advise(_("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'?"), matched_src_name, dst_value); - } else if (type == OBJ_TREE) { + break; + case OBJ_TREE: advise(_("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'?"), matched_src_name, dst_value); - } else if (type == OBJ_BLOB) { + break; + case OBJ_BLOB: advise(_("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'?"), matched_src_name, dst_value); - } else { - BUG("'%s' should be commit/tag/tree/blob, is '%d'", - matched_src_name, type); + break; + default: + advise(_("The <src> part of the refspec ('%s') " + "is an object ID that doesn't exist.\n"), + matched_src_name); + break; } } @@ -2578,7 +2584,8 @@ struct check_and_collect_until_cb_data { }; /* Get the timestamp of the latest entry. */ -static int peek_reflog(struct object_id *o_oid UNUSED, +static int peek_reflog(const char *refname UNUSED, + struct object_id *o_oid UNUSED, struct object_id *n_oid UNUSED, const char *ident UNUSED, timestamp_t timestamp, int tz UNUSED, @@ -2589,7 +2596,8 @@ static int peek_reflog(struct object_id *o_oid UNUSED, return 1; } -static int check_and_collect_until(struct object_id *o_oid UNUSED, +static int check_and_collect_until(const char *refname UNUSED, + struct object_id *o_oid UNUSED, struct object_id *n_oid, const char *ident UNUSED, timestamp_t timestamp, int tz UNUSED, @@ -5,6 +5,7 @@ #include "abspath.h" #include "config.h" #include "copy.h" +#include "environment.h" #include "gettext.h" #include "hex.h" #include "lockfile.h" @@ -877,9 +878,9 @@ static int do_plain_rerere(struct repository *r, static void git_rerere_config(void) { - git_config_get_bool("rerere.enabled", &rerere_enabled); - git_config_get_bool("rerere.autoupdate", &rerere_autoupdate); - git_config(git_default_config, NULL); + repo_config_get_bool(the_repository, "rerere.enabled", &rerere_enabled); + repo_config_get_bool(the_repository, "rerere.autoupdate", &rerere_autoupdate); + repo_config(the_repository, git_default_config, NULL); } static GIT_PATH_FUNC(git_path_rr_cache, "rr-cache") @@ -1247,7 +1248,7 @@ void rerere_gc(struct repository *r, struct string_list *rr) &cutoff_resolve, now); repo_config_get_expiry_in_days(the_repository, "gc.rerereunresolved", &cutoff_noresolve, now); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); dir = opendir(repo_git_path_replace(the_repository, &buf, "rr-cache")); if (!dir) die_errno(_("unable to open rr-cache directory")); diff --git a/revision.c b/revision.c index 212ca0de27..6ba8f67054 100644 --- a/revision.c +++ b/revision.c @@ -50,8 +50,6 @@ #include "parse-options.h" #include "wildmatch.h" -volatile show_early_output_fn_t show_early_output; - static char *term_bad; static char *term_good; @@ -673,12 +671,17 @@ static void trace2_bloom_filter_statistics_atexit(void) static int forbid_bloom_filters(struct pathspec *spec) { - if (spec->has_wildcard) - return 1; - if (spec->magic & ~PATHSPEC_LITERAL) + unsigned int allowed_magic = + PATHSPEC_FROMTOP | + PATHSPEC_MAXDEPTH | + PATHSPEC_LITERAL | + PATHSPEC_GLOB | + PATHSPEC_ATTR; + + if (spec->magic & ~allowed_magic) return 1; for (size_t nr = 0; nr < spec->nr; nr++) - if (spec->items[nr].magic & ~PATHSPEC_LITERAL) + if (spec->items[nr].magic & ~allowed_magic) return 1; return 0; @@ -693,23 +696,34 @@ static int convert_pathspec_to_bloom_keyvec(struct bloom_keyvec **out, char *path_alloc = NULL; const char *path; size_t len; - int res = 0; + int res = -1; + len = pi->nowildcard_len; + if (len != pi->len) { + /* + * for path like "dir/file*", nowildcard part would be + * "dir/file", but only "dir" should be used for the + * bloom filter. + */ + while (len > 0 && pi->match[len - 1] != '/') + len--; + } /* remove single trailing slash from path, if needed */ - if (pi->len > 0 && pi->match[pi->len - 1] == '/') { - path_alloc = xmemdupz(pi->match, pi->len - 1); + if (len > 0 && pi->match[len - 1] == '/') + len--; + + if (!len) + goto cleanup; + + if (len != pi->len) { + path_alloc = xmemdupz(pi->match, len); path = path_alloc; } else path = pi->match; - len = strlen(path); - if (!len) { - res = -1; - goto cleanup; - } - *out = bloom_keyvec_new(path, len, settings); + res = 0; cleanup: free(path_alloc); return res; @@ -1473,7 +1487,6 @@ static int limit_list(struct rev_info *revs) while (original_list) { struct commit *commit = pop_commit(&original_list); struct object *obj = &commit->object; - show_early_output_fn_t show; if (commit == interesting_cache) interesting_cache = NULL; @@ -1497,13 +1510,6 @@ static int limit_list(struct rev_info *revs) continue; date = commit->date; p = &commit_list_insert(commit, p)->next; - - show = show_early_output; - if (!show) - continue; - - show(revs, newlist); - show_early_output = NULL; } if (revs->cherry_pick || revs->cherry_mark) cherry_pick_list(newlist, revs); @@ -1630,7 +1636,7 @@ void exclude_hidden_refs(struct ref_exclusions *exclusions, const char *section) cb.exclusions = exclusions; cb.section = section; - git_config(hide_refs_config, &cb); + repo_config(the_repository, hide_refs_config, &cb); } struct all_refs_cb { @@ -1699,7 +1705,8 @@ static void handle_one_reflog_commit(struct object_id *oid, void *cb_data) } } -static int handle_one_reflog_ent(struct object_id *ooid, struct object_id *noid, +static int handle_one_reflog_ent(const char *refname UNUSED, + struct object_id *ooid, struct object_id *noid, const char *email UNUSED, timestamp_t timestamp UNUSED, int tz UNUSED, @@ -2437,13 +2444,6 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg } else if (!strcmp(arg, "--author-date-order")) { revs->sort_order = REV_SORT_BY_AUTHOR_DATE; revs->topo_order = 1; - } else if (!strcmp(arg, "--early-output")) { - revs->early_output = 100; - revs->topo_order = 1; - } else if (skip_prefix(arg, "--early-output=", &optarg)) { - if (strtoul_ui(optarg, 10, &revs->early_output) < 0) - die("'%s': not a non-negative integer", optarg); - revs->topo_order = 1; } else if (!strcmp(arg, "--parents")) { revs->rewrite_parents = 1; revs->print_parents = 1; diff --git a/revision.h b/revision.h index ac843f58d0..21e288c5ba 100644 --- a/revision.h +++ b/revision.h @@ -160,8 +160,6 @@ struct rev_info { /* topo-sort */ enum rev_sort_order sort_order; - unsigned int early_output; - unsigned int ignore_missing:1, ignore_missing_links:1; @@ -553,10 +551,4 @@ 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 8833b23367..ed9575bd6a 100644 --- a/run-command.c +++ b/run-command.c @@ -1817,7 +1817,7 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) { int enabled, auto_detach; - if (!git_config_get_bool("maintenance.auto", &enabled) && + if (!repo_config_get_bool(the_repository, "maintenance.auto", &enabled) && !enabled) return 0; @@ -1826,8 +1826,8 @@ int prepare_auto_maintenance(int quiet, struct child_process *maint) * honoring `gc.autoDetach`. This is somewhat weird, but required to * retain behaviour from when we used to run git-gc(1) here. */ - if (git_config_get_bool("maintenance.autodetach", &auto_detach) && - git_config_get_bool("gc.autodetach", &auto_detach)) + if (repo_config_get_bool(the_repository, "maintenance.autodetach", &auto_detach) && + repo_config_get_bool(the_repository, "gc.autodetach", &auto_detach)) auto_detach = 1; maint->git_cmd = 1; @@ -101,9 +101,9 @@ static int set_scalar_config(const struct scalar_config *config, int reconfigure int res; if ((reconfigure && config->overwrite_on_reconfigure) || - git_config_get_string(config->key, &value)) { + repo_config_get_string(the_repository, config->key, &value)) { trace2_data_string("scalar", the_repository, config->key, "created"); - res = git_config_set_gently(config->key, config->value); + res = repo_config_set_gently(the_repository, config->key, config->value); } else { trace2_data_string("scalar", the_repository, config->key, "exists"); res = 0; @@ -193,12 +193,12 @@ static int set_recommended_config(int reconfigure) * The `log.excludeDecoration` setting is special because it allows * for multiple values. */ - if (git_config_get_string("log.excludeDecoration", &value)) { + if (repo_config_get_string(the_repository, "log.excludeDecoration", &value)) { trace2_data_string("scalar", the_repository, "log.excludeDecoration", "created"); - if (git_config_set_multivar_gently("log.excludeDecoration", - "refs/prefetch/*", - CONFIG_REGEX_NONE, 0)) + if (repo_config_set_multivar_gently(the_repository, "log.excludeDecoration", + "refs/prefetch/*", + CONFIG_REGEX_NONE, 0)) return error(_("could not configure " "log.excludeDecoration")); } else { @@ -322,7 +322,7 @@ static int set_config(const char *fmt, ...) value = strchr(buf.buf, '='); if (value) *(value++) = '\0'; - res = git_config_set_gently(buf.buf, value); + res = repo_config_set_gently(the_repository, buf.buf, value); strbuf_release(&buf); return res; @@ -713,7 +713,7 @@ static int cmd_reconfigure(int argc, const char **argv) maintenance_str); } - git_config(get_scalar_repos, &scalar_repos); + repo_config(the_repository, get_scalar_repos, &scalar_repos); for (size_t i = 0; i < scalar_repos.nr; i++) { int succeeded = 0; @@ -763,7 +763,7 @@ static int cmd_reconfigure(int argc, const char **argv) break; } - git_config_clear(); + repo_config_clear(the_repository); if (repo_init(&r, gitdir.buf, commondir.buf)) goto loop_end; diff --git a/sequencer.c b/sequencer.c index 67e4310edc..9ae40a91b2 100644 --- a/sequencer.c +++ b/sequencer.c @@ -327,7 +327,7 @@ static int git_sequencer_config(const char *k, const char *v, void sequencer_init_config(struct replay_opts *opts) { opts->default_msg_cleanup = COMMIT_MSG_CLEANUP_NONE; - git_config(git_sequencer_config, opts); + repo_config(the_repository, git_sequencer_config, opts); } static inline int is_rebase_i(const struct replay_opts *opts) @@ -2721,6 +2721,7 @@ static int check_merge_commit_insn(enum todo_command command) return error(_("cannot squash merge commit into another commit")); case TODO_MERGE: + case TODO_DROP: return 0; default: @@ -3650,57 +3651,57 @@ static int save_opts(struct replay_opts *opts) int res = 0; if (opts->no_commit) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.no-commit", NULL, "true"); if (opts->edit >= 0) - res |= git_config_set_in_file_gently(opts_file, "options.edit", NULL, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.edit", NULL, opts->edit ? "true" : "false"); if (opts->allow_empty) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-empty", NULL, "true"); if (opts->allow_empty_message) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-empty-message", NULL, "true"); if (opts->drop_redundant_commits) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.drop-redundant-commits", NULL, "true"); if (opts->keep_redundant_commits) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.keep-redundant-commits", NULL, "true"); if (opts->signoff) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.signoff", NULL, "true"); if (opts->record_origin) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.record-origin", NULL, "true"); if (opts->allow_ff) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-ff", NULL, "true"); if (opts->mainline) { struct strbuf buf = STRBUF_INIT; strbuf_addf(&buf, "%d", opts->mainline); - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.mainline", NULL, buf.buf); strbuf_release(&buf); } if (opts->strategy) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.strategy", NULL, opts->strategy); if (opts->gpg_sign) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.gpg-sign", NULL, opts->gpg_sign); for (size_t i = 0; i < opts->xopts.nr; i++) - res |= git_config_set_multivar_in_file_gently(opts_file, + res |= repo_config_set_multivar_in_file_gently(the_repository, opts_file, "options.strategy-option", opts->xopts.v[i], "^$", NULL, 0); if (opts->allow_rerere_auto) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.allow-rerere-auto", NULL, opts->allow_rerere_auto == RERERE_AUTOUPDATE ? "true" : "false"); if (opts->explicit_cleanup) - res |= git_config_set_in_file_gently(opts_file, + res |= repo_config_set_in_file_gently(the_repository, opts_file, "options.default-msg-cleanup", NULL, describe_cleanup_mode(opts->default_msg_cleanup)); return res; @@ -5834,7 +5835,7 @@ static int make_script_with_merges(struct pretty_print_context *pp, *cmd_reset = abbr ? "t" : "reset", *cmd_merge = abbr ? "m" : "merge"; - git_config_get_int("rebase.maxlabellength", &state.max_label_length); + repo_config_get_int(the_repository, "rebase.maxlabellength", &state.max_label_length); oidmap_init(&commit2todo, 0); oidmap_init(&state.commit2label, 0); @@ -6089,7 +6090,7 @@ int sequencer_make_script(struct repository *r, struct strbuf *out, int argc, revs.topo_order = 1; revs.pretty_given = 1; - git_config_get_string("rebase.instructionFormat", &format); + repo_config_get_string(the_repository, "rebase.instructionFormat", &format); if (!format || !*format) { free(format); format = xstrdup("# %s"); @@ -815,7 +815,7 @@ int upgrade_repository_format(int target_version) } strbuf_addf(&repo_version, "%d", target_version); - git_config_set("core.repositoryformatversion", repo_version.buf); + repo_config_set(the_repository, "core.repositoryformatversion", repo_version.buf); ret = 1; @@ -1460,8 +1460,9 @@ static enum discovery_result setup_git_directory_gently_1(struct strbuf *dir, if (env_ceiling_dirs) { int empty_entry_found = 0; + static const char path_sep[] = { PATH_SEP, '\0' }; - string_list_split(&ceiling_dirs, env_ceiling_dirs, PATH_SEP, -1); + string_list_split(&ceiling_dirs, env_ceiling_dirs, path_sep, -1); filter_string_list(&ceiling_dirs, 0, canonicalize_ceiling_entry, &empty_entry_found); ceil_offset = longest_ancestor_length(dir->buf, &ceiling_dirs); @@ -1741,7 +1742,7 @@ const char *setup_git_directory_gently(int *nongit_ok) * configuration (including the per-repo config file that we * ignored previously). */ - git_config_clear(); + repo_config_clear(the_repository); /* * Let's assume that we are in a git repository. @@ -1877,7 +1878,7 @@ const char *setup_git_directory_gently(int *nongit_ok) * the core.precomposeunicode configuration, this * has to happen after the above block that finds * out where the repository is, i.e. a preparation - * for calling git_config_get_bool(). + * for calling repo_config_get_bool(). */ if (prefix) { prefix = precompose_string_if_needed(prefix); @@ -2233,16 +2234,16 @@ void initialize_repository_version(int hash_algo, target_version = GIT_REPO_VERSION_READ; if (hash_algo != GIT_HASH_SHA1_LEGACY && hash_algo != GIT_HASH_UNKNOWN) - git_config_set("extensions.objectformat", - hash_algos[hash_algo].name); + repo_config_set(the_repository, "extensions.objectformat", + hash_algos[hash_algo].name); else if (reinit) - git_config_set_gently("extensions.objectformat", NULL); + repo_config_set_gently(the_repository, "extensions.objectformat", NULL); if (ref_storage_format != REF_STORAGE_FORMAT_FILES) - git_config_set("extensions.refstorage", - ref_storage_format_to_name(ref_storage_format)); + repo_config_set(the_repository, "extensions.refstorage", + ref_storage_format_to_name(ref_storage_format)); else if (reinit) - git_config_set_gently("extensions.refstorage", NULL); + repo_config_set_gently(the_repository, "extensions.refstorage", NULL); if (reinit) { struct strbuf config = STRBUF_INIT; @@ -2259,7 +2260,7 @@ void initialize_repository_version(int hash_algo, } strbuf_addf(&repo_version, "%d", target_version); - git_config_set("core.repositoryformatversion", repo_version.buf); + repo_config_set(the_repository, "core.repositoryformatversion", repo_version.buf); strbuf_release(&repo_version); } @@ -2337,9 +2338,9 @@ static int create_default_files(const char *template_path, * disk). */ copy_templates(template_path); - git_config_clear(); + repo_config_clear(the_repository); repo_settings_reset_shared_repository(the_repository); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); reinit = is_reinit(); @@ -2375,17 +2376,17 @@ static int create_default_files(const char *template_path, if (filemode && !reinit && (st1.st_mode & S_IXUSR)) filemode = 0; } - git_config_set("core.filemode", filemode ? "true" : "false"); + repo_config_set(the_repository, "core.filemode", filemode ? "true" : "false"); if (is_bare_repository()) - git_config_set("core.bare", "true"); + repo_config_set(the_repository, "core.bare", "true"); else { - git_config_set("core.bare", "false"); + repo_config_set(the_repository, "core.bare", "false"); /* allow template config file to override the default */ if (repo_settings_get_log_all_ref_updates(the_repository) == LOG_REFS_UNSET) - git_config_set("core.logallrefupdates", "true"); + repo_config_set(the_repository, "core.logallrefupdates", "true"); if (needs_work_tree_config(original_git_dir, work_tree)) - git_config_set("core.worktree", work_tree); + repo_config_set(the_repository, "core.worktree", work_tree); } if (!reinit) { @@ -2398,12 +2399,12 @@ static int create_default_files(const char *template_path, S_ISLNK(st1.st_mode)) unlink(path.buf); /* good */ else - git_config_set("core.symlinks", "false"); + repo_config_set(the_repository, "core.symlinks", "false"); /* Check if the filesystem is case-insensitive */ repo_git_path_replace(the_repository, &path, "CoNfIg"); if (!access(path.buf, F_OK)) - git_config_set("core.ignorecase", "true"); + repo_config_set(the_repository, "core.ignorecase", "true"); probe_utf8_pathname_composition(); } @@ -2610,7 +2611,7 @@ int init_db(const char *git_dir, const char *real_git_dir, * have set up the repository format such that we can evaluate * includeIf conditions correctly in the case of re-initialization. */ - git_config(platform_core_config, NULL); + repo_config(the_repository, platform_core_config, NULL); safe_create_dir(the_repository, git_dir, 0); @@ -2639,8 +2640,8 @@ int init_db(const char *git_dir, const char *real_git_dir, xsnprintf(buf, sizeof(buf), "%d", OLD_PERM_EVERYBODY); else BUG("invalid value for shared_repository"); - git_config_set("core.sharedrepository", buf); - git_config_set("receive.denyNonFastforwards", "true"); + repo_config_set(the_repository, "core.sharedrepository", buf); + repo_config_set(the_repository, "receive.denyNonFastforwards", "true"); } if (!(flags & INIT_DB_QUIET)) { diff --git a/shared.mak b/shared.mak index 1a99848a95..5c7bc94785 100644 --- a/shared.mak +++ b/shared.mak @@ -88,6 +88,8 @@ ifndef V QUIET_LINT_GITLINK = @echo ' ' LINT GITLINK $<; QUIET_LINT_MANSEC = @echo ' ' LINT MAN SEC $<; + QUIET_LINT_DELIMSEC = @echo ' ' LINT DEL SEC $<; + QUIET_LINT_DOCSTYLE = @echo ' ' LINT DOCSTYLE $<; QUIET_LINT_MANEND = @echo ' ' LINT MAN END $<; export V diff --git a/sideband.c b/sideband.c index 251e9615ed..8f15b98a65 100644 --- a/sideband.c +++ b/sideband.c @@ -39,9 +39,9 @@ static int use_sideband_colors(void) if (use_sideband_colors_cached >= 0) return use_sideband_colors_cached; - if (!git_config_get_string_tmp(key, &value)) + if (!repo_config_get_string_tmp(the_repository, key, &value)) use_sideband_colors_cached = git_config_colorbool(key, value); - else if (!git_config_get_string_tmp("color.ui", &value)) + else if (!repo_config_get_string_tmp(the_repository, "color.ui", &value)) use_sideband_colors_cached = git_config_colorbool("color.ui", value); else use_sideband_colors_cached = GIT_COLOR_AUTO; @@ -49,7 +49,7 @@ static int use_sideband_colors(void) for (i = 0; i < ARRAY_SIZE(keywords); i++) { strbuf_reset(&sb); strbuf_addf(&sb, "%s.%s", key, keywords[i].keyword); - if (git_config_get_string_tmp(sb.buf, &value)) + if (repo_config_get_string_tmp(the_repository, sb.buf, &value)) continue; color_parse(value, keywords[i].color); } diff --git a/string-list.c b/string-list.c index 53faaa8420..343cf1ca90 100644 --- a/string-list.c +++ b/string-list.c @@ -276,55 +276,99 @@ void unsorted_string_list_delete_item(struct string_list *list, int i, int free_ list->nr--; } -int string_list_split(struct string_list *list, const char *string, - int delim, int maxsplit) +/* + * append a substring [p..end] to list; return number of things it + * appended to the list. + */ +static int append_one(struct string_list *list, + const char *p, const char *end, + int in_place, unsigned flags) +{ + if (!end) + end = p + strlen(p); + + if ((flags & STRING_LIST_SPLIT_TRIM)) { + /* rtrim */ + for (; p < end; end--) + if (!isspace(end[-1])) + break; + } + + if ((flags & STRING_LIST_SPLIT_NONEMPTY) && (end <= p)) + return 0; + + if (in_place) { + *((char *)end) = '\0'; + string_list_append(list, p); + } else { + string_list_append_nodup(list, xmemdupz(p, end - p)); + } + return 1; +} + +/* + * Unfortunately this cannot become a public interface, as _in_place() + * wants to have "const char *string" while the other variant wants to + * have "char *string" for type safety. + * + * This accepts "const char *string" to allow both wrappers to use it; + * it internally casts away the constness when in_place is true by + * taking advantage of strpbrk() that takes a "const char *" arg and + * returns "char *" pointer into that const string. Yucky but works ;-). + */ +static int split_string(struct string_list *list, const char *string, const char *delim, + int maxsplit, int in_place, unsigned flags) { int count = 0; - const char *p = string, *end; + const char *p = string; + + if (in_place && list->strdup_strings) + BUG("string_list_split_in_place() called with strdup_strings"); + else if (!in_place && !list->strdup_strings) + BUG("string_list_split() called without strdup_strings"); - if (!list->strdup_strings) - die("internal error in string_list_split(): " - "list->strdup_strings must be set"); for (;;) { - count++; - if (maxsplit >= 0 && count > maxsplit) { - string_list_append(list, p); - return count; + char *end; + + if (flags & STRING_LIST_SPLIT_TRIM) { + /* ltrim */ + while (*p && isspace(*p)) + p++; } - end = strchr(p, delim); - if (end) { - string_list_append_nodup(list, xmemdupz(p, end - p)); - p = end + 1; - } else { - string_list_append(list, p); + + if (0 <= maxsplit && maxsplit <= count) + end = NULL; + else + end = strpbrk(p, delim); + + count += append_one(list, p, end, in_place, flags); + + if (!end) return count; - } + p = end + 1; } } +int string_list_split(struct string_list *list, const char *string, + const char *delim, int maxsplit) +{ + return split_string(list, string, delim, maxsplit, 0, 0); +} + int string_list_split_in_place(struct string_list *list, char *string, const char *delim, int maxsplit) { - int count = 0; - char *p = string, *end; + return split_string(list, string, delim, maxsplit, 1, 0); +} - if (list->strdup_strings) - die("internal error in string_list_split_in_place(): " - "list->strdup_strings must not be set"); - for (;;) { - count++; - if (maxsplit >= 0 && count > maxsplit) { - string_list_append(list, p); - return count; - } - end = strpbrk(p, delim); - if (end) { - *end = '\0'; - string_list_append(list, p); - p = end + 1; - } else { - string_list_append(list, p); - return count; - } - } +int string_list_split_f(struct string_list *list, const char *string, + const char *delim, int maxsplit, unsigned flags) +{ + return split_string(list, string, delim, maxsplit, 0, flags); +} + +int string_list_split_in_place_f(struct string_list *list, char *string, + const char *delim, int maxsplit, unsigned flags) +{ + return split_string(list, string, delim, maxsplit, 1, flags); } diff --git a/string-list.h b/string-list.h index 122b318641..2b438c7733 100644 --- a/string-list.h +++ b/string-list.h @@ -254,7 +254,7 @@ struct string_list_item *unsorted_string_list_lookup(struct string_list *list, void unsorted_string_list_delete_item(struct string_list *list, int i, int free_util); /** - * Split string into substrings on character `delim` and append the + * Split string into substrings on characters in `delim` and append the * substrings to `list`. The input string is not modified. * list->strdup_strings must be set, as new memory needs to be * allocated to hold the substrings. If maxsplit is non-negative, @@ -262,15 +262,15 @@ void unsorted_string_list_delete_item(struct string_list *list, int i, int free_ * appended to list. * * Examples: - * string_list_split(l, "foo:bar:baz", ':', -1) -> ["foo", "bar", "baz"] - * string_list_split(l, "foo:bar:baz", ':', 0) -> ["foo:bar:baz"] - * string_list_split(l, "foo:bar:baz", ':', 1) -> ["foo", "bar:baz"] - * string_list_split(l, "foo:bar:", ':', -1) -> ["foo", "bar", ""] - * string_list_split(l, "", ':', -1) -> [""] - * string_list_split(l, ":", ':', -1) -> ["", ""] + * string_list_split(l, "foo:bar:baz", ":", -1) -> ["foo", "bar", "baz"] + * string_list_split(l, "foo:bar:baz", ":", 0) -> ["foo:bar:baz"] + * string_list_split(l, "foo:bar:baz", ":", 1) -> ["foo", "bar:baz"] + * string_list_split(l, "foo:bar:", ":", -1) -> ["foo", "bar", ""] + * string_list_split(l, "", ":", -1) -> [""] + * string_list_split(l, ":", ":", -1) -> ["", ""] */ int string_list_split(struct string_list *list, const char *string, - int delim, int maxsplit); + const char *delim, int maxsplit); /* * Like string_list_split(), except that string is split in-place: the @@ -281,4 +281,21 @@ int string_list_split(struct string_list *list, const char *string, */ int string_list_split_in_place(struct string_list *list, char *string, const char *delim, int maxsplit); + +/* Flag bits for split_f and split_in_place_f functions */ +enum { + /* + * trim whitespaces around resulting string piece before adding + * it to the list + */ + STRING_LIST_SPLIT_TRIM = (1 << 0), + /* omit adding empty string piece to the resulting list */ + STRING_LIST_SPLIT_NONEMPTY = (1 << 1), +}; + +int string_list_split_f(struct string_list *, const char *string, + const char *delim, int maxsplit, unsigned flags); + +int string_list_split_in_place_f(struct string_list *, char *string, + const char *delim, int maxsplit, unsigned flags); #endif /* STRING_LIST_H */ diff --git a/sub-process.c b/sub-process.c index 1daf5a9752..83bf0a0e82 100644 --- a/sub-process.c +++ b/sub-process.c @@ -30,23 +30,20 @@ struct subprocess_entry *subprocess_find_entry(struct hashmap *hashmap, const ch int subprocess_read_status(int fd, struct strbuf *status) { - struct strbuf **pair; - char *line; int len; for (;;) { + char *line; + const char *value; + len = packet_read_line_gently(fd, NULL, &line); if ((len < 0) || !line) break; - pair = strbuf_split_str(line, '=', 2); - if (pair[0] && pair[0]->len && pair[1]) { + if (skip_prefix(line, "status=", &value)) { /* the last "status=<foo>" line wins */ - if (!strcmp(pair[0]->buf, "status=")) { - strbuf_reset(status); - strbuf_addbuf(status, pair[1]); - } + strbuf_reset(status); + strbuf_addstr(status, value); } - strbuf_list_free(pair); } return (len < 0) ? len : 0; diff --git a/submodule-config.c b/submodule-config.c index 70324da383..1f19fe2077 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -983,7 +983,7 @@ int config_set_in_gitmodules_file_gently(const char *key, const char *value) { int ret; - ret = git_config_set_in_file_gently(GITMODULES_FILE, key, NULL, value); + ret = repo_config_set_in_file_gently(the_repository, GITMODULES_FILE, key, NULL, value); if (ret < 0) /* Maybe the user already did that, don't error out here */ warning(_("Could not update .gitmodules entry %s"), key); diff --git a/submodule.c b/submodule.c index f8373a9ea7..fff3c75570 100644 --- a/submodule.c +++ b/submodule.c @@ -2058,7 +2058,7 @@ void submodule_unset_core_worktree(const struct submodule *sub) submodule_name_to_gitdir(&config_path, the_repository, sub->name); strbuf_addstr(&config_path, "/config"); - if (git_config_set_in_file_gently(config_path.buf, "core.worktree", NULL, NULL)) + if (repo_config_set_in_file_gently(the_repository, config_path.buf, "core.worktree", NULL, NULL)) warning(_("Could not unset core.worktree setting in submodule '%s'"), sub->path); diff --git a/t/Makefile b/t/Makefile index 791e0a0978..ab8a5b54aa 100644 --- a/t/Makefile +++ b/t/Makefile @@ -125,7 +125,6 @@ check-meson: @mkdir -p mesontmp && \ printf "%s\n" \ "integration_tests t[0-9][0-9][0-9][0-9]-*.sh" \ - "unit_test_programs unit-tests/t-*.c" \ "clar_test_suites unit-tests/u-*.c" | \ while read -r variable pattern; do \ awk "/^$$variable = \[\$$/ {flag=1 ; next } /^]$$/ { flag=0 } flag { gsub(/^ \047/, \"\"); gsub(/\047,\$$/, \"\"); print }" meson.build >mesontmp/meson.txt && \ @@ -190,15 +189,9 @@ perf: .PHONY: libgit-sys-test libgit-rs-test libgit-sys-test: - $(QUIET)(\ - cd ../contrib/libgit-sys && \ - cargo test \ - ) -libgit-rs-test: - $(QUIET)(\ - cd ../contrib/libgit-rs && \ - cargo test \ - ) + $(QUIET)cargo test --manifest-path ../contrib/libgit-sys/Cargo.toml +libgit-rs-test: libgit-sys-test + $(QUIET)cargo test --manifest-path ../contrib/libgit-rs/Cargo.toml ifdef INCLUDE_LIBGIT_RS -all:: libgit-sys-test libgit-rs-test +all:: libgit-rs-test endif diff --git a/t/for-each-ref-tests.sh b/t/for-each-ref-tests.sh new file mode 100644 index 0000000000..e3ad19298a --- /dev/null +++ b/t/for-each-ref-tests.sh @@ -0,0 +1,2141 @@ +git_for_each_ref=${git_for_each_ref:-git for-each-ref} +GNUPGHOME_NOT_USED=$GNUPGHOME +. "$TEST_DIRECTORY"/lib-gpg.sh +. "$TEST_DIRECTORY"/lib-terminal.sh + +# Mon Jul 3 23:18:43 2006 +0000 +datestamp=1151968723 +setdate_and_increment () { + GIT_COMMITTER_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + GIT_AUTHOR_DATE="$datestamp +0200" + datestamp=$(expr "$datestamp" + 1) + export GIT_COMMITTER_DATE GIT_AUTHOR_DATE +} + +test_object_file_size () { + oid=$(git rev-parse "$1") + path=".git/objects/$(test_oid_to_path $oid)" + test_file_size "$path" +} + +test_expect_success setup ' + # setup .mailmap + cat >.mailmap <<-EOF && + A Thor <athor@example.com> A U Thor <author@example.com> + C Mitter <cmitter@example.com> C O Mitter <committer@example.com> + EOF + + setdate_and_increment && + echo "Using $datestamp" > one && + git add one && + git commit -m "Initial" && + git branch -M main && + setdate_and_increment && + git tag -a -m "Tagging at $datestamp" testtag && + git update-ref refs/remotes/origin/main main && + git remote add origin nowhere && + git config branch.main.remote origin && + git config branch.main.merge refs/heads/main && + git remote add myfork elsewhere && + git config remote.pushdefault myfork && + git config push.default current +' + +test_atom () { + case "$1" in + head) ref=refs/heads/main ;; + tag) ref=refs/tags/testtag ;; + sym) ref=refs/heads/sym ;; + *) ref=$1 ;; + esac + format=$2 + test_do=test_expect_${4:-success} + + printf '%s\n' "$3" >expected + $test_do $PREREQ "basic atom: $ref $format" ' + ${git_for_each_ref} --format="%($format)" "$ref" >actual && + sanitize_pgp <actual >actual.clean && + test_cmp expected actual.clean + ' + + # Automatically test "contents:size" atom after testing "contents" + if test "$format" = "contents" + then + # for commit leg, $3 is changed there + expect=$(printf '%s' "$3" | wc -c) + $test_do $PREREQ "basic atom: $ref contents:size" ' + type=$(git cat-file -t "$ref") && + case $type in + tag) + # We cannot use $3 as it expects sanitize_pgp to run + git cat-file tag $ref >out && + expect=$(tail -n +6 out | wc -c) && + rm -f out ;; + tree | blob) + expect="" ;; + commit) + : "use the calculated expect" ;; + *) + BUG "unknown object type" ;; + esac && + # Leave $expect unquoted to lose possible leading whitespaces + echo $expect >expected && + ${git_for_each_ref} --format="%(contents:size)" "$ref" >actual && + test_cmp expected actual + ' + fi +} + +hexlen=$(test_oid hexsz) + +test_atom head refname refs/heads/main +test_atom head refname: refs/heads/main +test_atom head refname:short main +test_atom head refname:lstrip=1 heads/main +test_atom head refname:lstrip=2 main +test_atom head refname:lstrip=-1 main +test_atom head refname:lstrip=-2 heads/main +test_atom head refname:rstrip=1 refs/heads +test_atom head refname:rstrip=2 refs +test_atom head refname:rstrip=-1 refs +test_atom head refname:rstrip=-2 refs/heads +test_atom head refname:strip=1 heads/main +test_atom head refname:strip=2 main +test_atom head refname:strip=-1 main +test_atom head refname:strip=-2 heads/main +test_atom head upstream refs/remotes/origin/main +test_atom head upstream:short origin/main +test_atom head upstream:lstrip=2 origin/main +test_atom head upstream:lstrip=-2 origin/main +test_atom head upstream:rstrip=2 refs/remotes +test_atom head upstream:rstrip=-2 refs/remotes +test_atom head upstream:strip=2 origin/main +test_atom head upstream:strip=-2 origin/main +test_atom head push refs/remotes/myfork/main +test_atom head push:short myfork/main +test_atom head push:lstrip=1 remotes/myfork/main +test_atom head push:lstrip=-1 main +test_atom head push:rstrip=1 refs/remotes/myfork +test_atom head push:rstrip=-1 refs +test_atom head push:strip=1 remotes/myfork/main +test_atom head push:strip=-1 main +test_atom head objecttype commit +test_atom head objectsize $((131 + hexlen)) +test_atom head objectsize:disk $(test_object_file_size refs/heads/main) +test_atom head deltabase $ZERO_OID +test_atom head objectname $(git rev-parse refs/heads/main) +test_atom head objectname:short $(git rev-parse --short refs/heads/main) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) +test_atom head tree $(git rev-parse refs/heads/main^{tree}) +test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) +test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) +test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) +test_atom head parent '' +test_atom head parent:short '' +test_atom head parent:short=1 '' +test_atom head parent:short=10 '' +test_atom head numparent 0 +test_atom head object '' +test_atom head type '' +test_atom head raw "$(git cat-file commit refs/heads/main) +" +test_atom head '*objectname' '' +test_atom head '*objecttype' '' +test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' +test_atom head authorname 'A U Thor' +test_atom head authorname:mailmap 'A Thor' +test_atom head authoremail '<author@example.com>' +test_atom head authoremail:trim 'author@example.com' +test_atom head authoremail:localpart 'author' +test_atom head authoremail:trim,localpart 'author' +test_atom head authoremail:mailmap '<athor@example.com>' +test_atom head authoremail:mailmap,trim 'athor@example.com' +test_atom head authoremail:trim,mailmap 'athor@example.com' +test_atom head authoremail:mailmap,localpart 'athor' +test_atom head authoremail:localpart,mailmap 'athor' +test_atom head authoremail:mailmap,trim,localpart,mailmap,trim 'athor' +test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' +test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' +test_atom head committername 'C O Mitter' +test_atom head committername:mailmap 'C Mitter' +test_atom head committeremail '<committer@example.com>' +test_atom head committeremail:trim 'committer@example.com' +test_atom head committeremail:localpart 'committer' +test_atom head committeremail:localpart,trim 'committer' +test_atom head committeremail:mailmap '<cmitter@example.com>' +test_atom head committeremail:mailmap,trim 'cmitter@example.com' +test_atom head committeremail:trim,mailmap 'cmitter@example.com' +test_atom head committeremail:mailmap,localpart 'cmitter' +test_atom head committeremail:localpart,mailmap 'cmitter' +test_atom head committeremail:trim,mailmap,trim,trim,localpart 'cmitter' +test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' +test_atom head tag '' +test_atom head tagger '' +test_atom head taggername '' +test_atom head taggeremail '' +test_atom head taggeremail:trim '' +test_atom head taggeremail:localpart '' +test_atom head taggerdate '' +test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' +test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' +test_atom head subject 'Initial' +test_atom head subject:sanitize 'Initial' +test_atom head contents:subject 'Initial' +test_atom head body '' +test_atom head contents:body '' +test_atom head contents:signature '' +test_atom head contents 'Initial +' +test_atom head HEAD '*' + +test_atom tag refname refs/tags/testtag +test_atom tag refname:short testtag +test_atom tag upstream '' +test_atom tag push '' +test_atom tag objecttype tag +test_atom tag objectsize $((114 + hexlen)) +test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) +test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) +test_atom tag deltabase $ZERO_OID +test_atom tag '*deltabase' $ZERO_OID +test_atom tag objectname $(git rev-parse refs/tags/testtag) +test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) +test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) +test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) +test_atom tag tree '' +test_atom tag tree:short '' +test_atom tag tree:short=1 '' +test_atom tag tree:short=10 '' +test_atom tag parent '' +test_atom tag parent:short '' +test_atom tag parent:short=1 '' +test_atom tag parent:short=10 '' +test_atom tag numparent '' +test_atom tag object $(git rev-parse refs/tags/testtag^0) +test_atom tag type 'commit' +test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{}) +test_atom tag '*objecttype' 'commit' +test_atom tag author '' +test_atom tag authorname '' +test_atom tag authorname:mailmap '' +test_atom tag authoremail '' +test_atom tag authoremail:trim '' +test_atom tag authoremail:localpart '' +test_atom tag authoremail:trim,localpart '' +test_atom tag authoremail:mailmap '' +test_atom tag authoremail:mailmap,trim '' +test_atom tag authoremail:trim,mailmap '' +test_atom tag authoremail:mailmap,localpart '' +test_atom tag authoremail:localpart,mailmap '' +test_atom tag authoremail:mailmap,trim,localpart,mailmap,trim '' +test_atom tag authordate '' +test_atom tag committer '' +test_atom tag committername '' +test_atom tag committername:mailmap '' +test_atom tag committeremail '' +test_atom tag committeremail:trim '' +test_atom tag committeremail:localpart '' +test_atom tag committeremail:localpart,trim '' +test_atom tag committeremail:mailmap '' +test_atom tag committeremail:mailmap,trim '' +test_atom tag committeremail:trim,mailmap '' +test_atom tag committeremail:mailmap,localpart '' +test_atom tag committeremail:localpart,mailmap '' +test_atom tag committeremail:trim,mailmap,trim,trim,localpart '' +test_atom tag committerdate '' +test_atom tag tag 'testtag' +test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' +test_atom tag taggername 'C O Mitter' +test_atom tag taggername:mailmap 'C Mitter' +test_atom tag taggeremail '<committer@example.com>' +test_atom tag taggeremail:trim 'committer@example.com' +test_atom tag taggeremail:localpart 'committer' +test_atom tag taggeremail:trim,localpart 'committer' +test_atom tag taggeremail:mailmap '<cmitter@example.com>' +test_atom tag taggeremail:mailmap,trim 'cmitter@example.com' +test_atom tag taggeremail:trim,mailmap 'cmitter@example.com' +test_atom tag taggeremail:mailmap,localpart 'cmitter' +test_atom tag taggeremail:localpart,mailmap 'cmitter' +test_atom tag taggeremail:trim,mailmap,trim,localpart,localpart 'cmitter' +test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' +test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' +test_atom tag subject 'Tagging at 1151968727' +test_atom tag subject:sanitize 'Tagging-at-1151968727' +test_atom tag contents:subject 'Tagging at 1151968727' +test_atom tag body '' +test_atom tag contents:body '' +test_atom tag contents:signature '' +test_atom tag contents 'Tagging at 1151968727 +' +test_atom tag HEAD ' ' + +test_expect_success 'basic atom: refs/tags/testtag *raw' ' + git cat-file commit refs/tags/testtag^{} >expected && + ${git_for_each_ref} --format="%(*raw)" refs/tags/testtag >actual && + sanitize_pgp <expected >expected.clean && + echo >>expected.clean && + sanitize_pgp <actual >actual.clean && + test_cmp expected.clean actual.clean +' + +test_expect_success 'Check invalid atoms names are errors' ' + test_must_fail ${git_for_each_ref} --format="%(INVALID)" refs/heads +' + +test_expect_success 'Check format specifiers are ignored in naming date atoms' ' + ${git_for_each_ref} --format="%(authordate)" refs/heads && + ${git_for_each_ref} --format="%(authordate:default) %(authordate)" refs/heads && + ${git_for_each_ref} --format="%(authordate) %(authordate:default)" refs/heads && + ${git_for_each_ref} --format="%(authordate:default) %(authordate:default)" refs/heads +' + +test_expect_success 'Check valid format specifiers for date fields' ' + ${git_for_each_ref} --format="%(authordate:default)" refs/heads && + ${git_for_each_ref} --format="%(authordate:relative)" refs/heads && + ${git_for_each_ref} --format="%(authordate:short)" refs/heads && + ${git_for_each_ref} --format="%(authordate:local)" refs/heads && + ${git_for_each_ref} --format="%(authordate:iso8601)" refs/heads && + ${git_for_each_ref} --format="%(authordate:rfc2822)" refs/heads +' + +test_expect_success 'Check invalid format specifiers are errors' ' + test_must_fail ${git_for_each_ref} --format="%(authordate:INVALID)" refs/heads +' + +test_expect_success 'arguments to %(objectname:short=) must be positive integers' ' + test_must_fail ${git_for_each_ref} --format="%(objectname:short=0)" && + test_must_fail ${git_for_each_ref} --format="%(objectname:short=-1)" && + test_must_fail ${git_for_each_ref} --format="%(objectname:short=foo)" +' + +test_bad_atom () { + case "$1" in + head) ref=refs/heads/main ;; + tag) ref=refs/tags/testtag ;; + sym) ref=refs/heads/sym ;; + *) ref=$1 ;; + esac + format=$2 + test_do=test_expect_${4:-success} + + printf '%s\n' "$3" >expect + $test_do $PREREQ "err basic atom: $ref $format" ' + test_must_fail ${git_for_each_ref} \ + --format="%($format)" "$ref" 2>error && + test_cmp expect error + ' +} + +test_bad_atom head 'authoremail:foo' \ + 'fatal: unrecognized %(authoremail) argument: foo' + +test_bad_atom head 'authoremail:mailmap,trim,bar' \ + 'fatal: unrecognized %(authoremail) argument: bar' + +test_bad_atom head 'authoremail:trim,' \ + 'fatal: unrecognized %(authoremail) argument: ' + +test_bad_atom head 'authoremail:mailmaptrim' \ + 'fatal: unrecognized %(authoremail) argument: trim' + +test_bad_atom head 'committeremail: ' \ + 'fatal: unrecognized %(committeremail) argument: ' + +test_bad_atom head 'committeremail: trim,foo' \ + 'fatal: unrecognized %(committeremail) argument: trim,foo' + +test_bad_atom head 'committeremail:mailmap,localpart ' \ + 'fatal: unrecognized %(committeremail) argument: ' + +test_bad_atom head 'committeremail:trim_localpart' \ + 'fatal: unrecognized %(committeremail) argument: _localpart' + +test_bad_atom head 'committeremail:localpart,,,trim' \ + 'fatal: unrecognized %(committeremail) argument: ,,trim' + +test_bad_atom tag 'taggeremail:mailmap,trim, foo ' \ + 'fatal: unrecognized %(taggeremail) argument: foo ' + +test_bad_atom tag 'taggeremail:trim,localpart,' \ + 'fatal: unrecognized %(taggeremail) argument: ' + +test_bad_atom tag 'taggeremail:mailmap;localpart trim' \ + 'fatal: unrecognized %(taggeremail) argument: ;localpart trim' + +test_bad_atom tag 'taggeremail:localpart trim' \ + 'fatal: unrecognized %(taggeremail) argument: trim' + +test_bad_atom tag 'taggeremail:mailmap,mailmap,trim,qux,localpart,trim' \ + 'fatal: unrecognized %(taggeremail) argument: qux,localpart,trim' + +test_date () { + f=$1 && + committer_date=$2 && + author_date=$3 && + tagger_date=$4 && + cat >expected <<-EOF && + 'refs/heads/main' '$committer_date' '$author_date' + 'refs/tags/testtag' '$tagger_date' + EOF + ( + ${git_for_each_ref} --shell \ + --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ + refs/heads && + ${git_for_each_ref} --shell \ + --format="%(refname) %(taggerdate${f:+:$f})" \ + refs/tags + ) >actual && + test_cmp expected actual +} + +test_expect_success 'Check unformatted date fields output' ' + test_date "" \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" +' + +test_expect_success 'Check format "default" formatted date fields output' ' + test_date default \ + "Tue Jul 4 01:18:43 2006 +0200" \ + "Tue Jul 4 01:18:44 2006 +0200" \ + "Tue Jul 4 01:18:45 2006 +0200" +' + +test_expect_success 'Check format "default-local" date fields output' ' + test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" +' + +# Don't know how to do relative check because I can't know when this script +# is going to be run and can't fake the current time to git, and hence can't +# provide expected output. Instead, I'll just make sure that "relative" +# doesn't exit in error +test_expect_success 'Check format "relative" date fields output' ' + f=relative && + (${git_for_each_ref} --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && + ${git_for_each_ref} --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual +' + +# We just check that this is the same as "relative" for now. +test_expect_success 'Check format "relative-local" date fields output' ' + test_date relative-local \ + "$(${git_for_each_ref} --format="%(committerdate:relative)" refs/heads)" \ + "$(${git_for_each_ref} --format="%(authordate:relative)" refs/heads)" \ + "$(${git_for_each_ref} --format="%(taggerdate:relative)" refs/tags)" +' + +test_expect_success 'Check format "short" date fields output' ' + test_date short 2006-07-04 2006-07-04 2006-07-04 +' + +test_expect_success 'Check format "short-local" date fields output' ' + test_date short-local 2006-07-03 2006-07-03 2006-07-03 +' + +test_expect_success 'Check format "local" date fields output' ' + test_date local \ + "Mon Jul 3 23:18:43 2006" \ + "Mon Jul 3 23:18:44 2006" \ + "Mon Jul 3 23:18:45 2006" +' + +test_expect_success 'Check format "iso8601" date fields output' ' + test_date iso8601 \ + "2006-07-04 01:18:43 +0200" \ + "2006-07-04 01:18:44 +0200" \ + "2006-07-04 01:18:45 +0200" +' + +test_expect_success 'Check format "iso8601-local" date fields output' ' + test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" +' + +test_expect_success 'Check format "rfc2822" date fields output' ' + test_date rfc2822 \ + "Tue, 4 Jul 2006 01:18:43 +0200" \ + "Tue, 4 Jul 2006 01:18:44 +0200" \ + "Tue, 4 Jul 2006 01:18:45 +0200" +' + +test_expect_success 'Check format "rfc2822-local" date fields output' ' + test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" +' + +test_expect_success 'Check format "raw" date fields output' ' + test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" +' + +test_expect_success 'Check format "raw-local" date fields output' ' + test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" +' + +test_expect_success 'Check format of strftime date fields' ' + echo "my date is 2006-07-04" >expected && + ${git_for_each_ref} \ + --format="%(authordate:format:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'Check format of strftime-local date fields' ' + echo "my date is 2006-07-03" >expected && + ${git_for_each_ref} \ + --format="%(authordate:format-local:my date is %Y-%m-%d)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'exercise strftime with odd fields' ' + echo >expected && + ${git_for_each_ref} --format="%(authordate:format:)" refs/heads >actual && + test_cmp expected actual && + long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" && + echo $long >expected && + ${git_for_each_ref} --format="%(authordate:format:$long)" refs/heads >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/heads/main +refs/remotes/origin/main +refs/tags/testtag +EOF + +test_expect_success 'Verify ascending sort' ' + ${git_for_each_ref} --format="%(refname)" --sort=refname >actual && + test_cmp expected actual +' + + +cat >expected <<\EOF +refs/tags/testtag +refs/remotes/origin/main +refs/heads/main +EOF + +test_expect_success 'Verify descending sort' ' + ${git_for_each_ref} --format="%(refname)" --sort=-refname >actual && + test_cmp expected actual +' + +test_expect_success 'Give help even with invalid sort atoms' ' + test_expect_code 129 ${git_for_each_ref} --sort=bogus -h >actual 2>&1 && + grep "^usage: ${git_for_each_ref}" actual +' + +cat >expected <<\EOF +refs/tags/testtag +refs/tags/testtag-2 +EOF + +test_expect_success 'exercise patterns with prefixes' ' + git tag testtag-2 && + test_when_finished "git tag -d testtag-2" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/testtag refs/tags/testtag-2 >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/testtag +refs/tags/testtag-2 +EOF + +test_expect_success 'exercise glob patterns with prefixes' ' + git tag testtag-2 && + test_when_finished "git tag -d testtag-2" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/testtag "refs/tags/testtag-*" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with prefix exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/ --exclude=refs/tags/foo >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +refs/tags/bar +refs/tags/baz +refs/tags/foo/one +refs/tags/testtag +EOF + +test_expect_success 'exercise patterns with pattern exclusions' ' + for tag in foo/one foo/two foo/three bar baz + do + git tag "$tag" || return 1 + done && + test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && + ${git_for_each_ref} --format="%(refname)" \ + refs/tags/ --exclude="refs/tags/foo/t*" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +'refs/heads/main' +'refs/remotes/origin/main' +'refs/tags/testtag' +EOF + +test_expect_success 'Quoting style: shell' ' + ${git_for_each_ref} --shell --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: perl' ' + ${git_for_each_ref} --perl --format="%(refname)" >actual && + test_cmp expected actual +' + +test_expect_success 'Quoting style: python' ' + ${git_for_each_ref} --python --format="%(refname)" >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +"refs/heads/main" +"refs/remotes/origin/main" +"refs/tags/testtag" +EOF + +test_expect_success 'Quoting style: tcl' ' + ${git_for_each_ref} --tcl --format="%(refname)" >actual && + test_cmp expected actual +' + +for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do + test_expect_success "more than one quoting style: $i" " + test_must_fail ${git_for_each_ref} $i 2>err && + grep '^error: more than one quoting style' err + " +done + +test_expect_success 'setup for upstream:track[short]' ' + test_commit two +' + +test_atom head upstream:track '[ahead 1]' +test_atom head upstream:trackshort '>' +test_atom head upstream:track,nobracket 'ahead 1' +test_atom head upstream:nobracket,track 'ahead 1' + +test_expect_success 'setup for push:track[short]' ' + test_commit third && + git update-ref refs/remotes/myfork/main main && + git reset main~1 +' + +test_atom head push:track '[behind 1]' +test_atom head push:trackshort '<' + +test_expect_success 'Check that :track[short] cannot be used with other atoms' ' + test_must_fail ${git_for_each_ref} --format="%(refname:track)" 2>/dev/null && + test_must_fail ${git_for_each_ref} --format="%(refname:trackshort)" 2>/dev/null +' + +test_expect_success 'Check that :track[short] works when upstream is invalid' ' + cat >expected <<-\EOF && + [gone] + + EOF + test_when_finished "git config branch.main.merge refs/heads/main" && + git config branch.main.merge refs/heads/does-not-exist && + ${git_for_each_ref} \ + --format="%(upstream:track)$LF%(upstream:trackshort)" \ + refs/heads >actual && + test_cmp expected actual +' + +test_expect_success 'Check for invalid refname format' ' + test_must_fail ${git_for_each_ref} --format="%(refname:INVALID)" +' + +test_expect_success 'set up color tests' ' + cat >expected.color <<-EOF && + $(git rev-parse --short refs/heads/main) <GREEN>main<RESET> + $(git rev-parse --short refs/remotes/myfork/main) <GREEN>myfork/main<RESET> + $(git rev-parse --short refs/remotes/origin/main) <GREEN>origin/main<RESET> + $(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET> + $(git rev-parse --short refs/tags/third) <GREEN>third<RESET> + $(git rev-parse --short refs/tags/two) <GREEN>two<RESET> + EOF + sed "s/<[^>]*>//g" <expected.color >expected.bare && + color_format="%(objectname:short) %(color:green)%(refname:short)" +' + +test_expect_success TTY '%(color) shows color with a tty' ' + test_terminal ${git_for_each_ref} --format="$color_format" >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expected.color actual +' + +test_expect_success '%(color) does not show color without tty' ' + TERM=vt100 ${git_for_each_ref} --format="$color_format" >actual && + test_cmp expected.bare actual +' + +test_expect_success '--color can override tty check' ' + ${git_for_each_ref} --color --format="$color_format" >actual.raw && + test_decode_color <actual.raw >actual && + test_cmp expected.color actual +' + +test_expect_success 'color.ui=always does not override tty check' ' + git -c color.ui=always ${git_for_each_ref#git} --format="$color_format" >actual && + test_cmp expected.bare actual +' + +test_expect_success 'setup for describe atom tests' ' + git init -b master describe-repo && + ( + cd describe-repo && + + test_commit --no-tag one && + git tag tagone && + + test_commit --no-tag two && + git tag -a -m "tag two" tagtwo + ) +' + +test_expect_success 'describe atom vs git describe' ' + ( + cd describe-repo && + + ${git_for_each_ref} --format="%(objectname)" \ + refs/tags/ >obj && + while read hash + do + if desc=$(git describe $hash) + then + : >expect-contains-good + else + : >expect-contains-bad + fi && + echo "$hash $desc" || return 1 + done <obj >expect && + test_path_exists expect-contains-good && + test_path_exists expect-contains-bad && + + ${git_for_each_ref} --format="%(objectname) %(describe)" \ + refs/tags/ >actual 2>err && + test_cmp expect actual && + test_must_be_empty err + ) +' + +test_expect_success 'describe:tags vs describe --tags' ' + ( + cd describe-repo && + git describe --tags >expect && + ${git_for_each_ref} --format="%(describe:tags)" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' + ( + cd describe-repo && + + # Case 1: We have commits between HEAD and the most + # recent tag reachable from it + test_commit --no-tag file && + git describe --abbrev=14 >expect && + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + + # Make sure the hash used is at least 14 digits long + sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && + test 15 -le $(wc -c <hexpart) && + + # Case 2: We have a tag at HEAD, describe directly gives + # the name of the tag + git tag -a -m tagged tagname && + git describe --abbrev=14 >expect && + ${git_for_each_ref} --format="%(describe:abbrev=14)" \ + refs/heads/master >actual && + test_cmp expect actual && + test tagname = $(cat actual) + ) +' + +test_expect_success 'describe:match=... vs describe --match ...' ' + ( + cd describe-repo && + git tag -a -m "tag foo" tag-foo && + git describe --match "*-foo" >expect && + ${git_for_each_ref} --format="%(describe:match="*-foo")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'describe:exclude:... vs describe --exclude ...' ' + ( + cd describe-repo && + git tag -a -m "tag bar" tag-bar && + git describe --exclude "*-bar" >expect && + ${git_for_each_ref} --format="%(describe:exclude="*-bar")" \ + refs/heads/master >actual && + test_cmp expect actual + ) +' + +test_expect_success 'deref with describe atom' ' + ( + cd describe-repo && + cat >expect <<-\EOF && + + tagname + tagname + tagname + + tagtwo + EOF + ${git_for_each_ref} --format="%(*describe)" >actual && + test_cmp expect actual + ) +' + +test_expect_success 'err on bad describe atom arg' ' + ( + cd describe-repo && + + # The bad arg is the only arg passed to describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: baz + EOF + test_must_fail ${git_for_each_ref} --format="%(describe:baz)" \ + refs/heads/master 2>actual && + test_cmp expect actual && + + # The bad arg is in the middle of the option string + # passed to the describe atom + cat >expect <<-\EOF && + fatal: unrecognized %(describe) argument: qux=1,abbrev=14 + EOF + test_must_fail ${git_for_each_ref} \ + --format="%(describe:tags,qux=1,abbrev=14)" \ + ref/heads/master 2>actual && + test_cmp expect actual + ) +' + +cat >expected <<\EOF +heads/main +tags/main +EOF + +test_expect_success 'Check ambiguous head and tag refs (strict)' ' + git config --bool core.warnambiguousrefs true && + git checkout -b newtag && + echo "Using $datestamp" > one && + git add one && + git commit -m "Branch" && + setdate_and_increment && + git tag -m "Tagging at $datestamp" main && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +heads/main +main +EOF + +test_expect_success 'Check ambiguous head and tag refs (loose)' ' + git config --bool core.warnambiguousrefs false && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/main refs/tags/main >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +heads/ambiguous +ambiguous +EOF + +test_expect_success 'Check ambiguous head and tag refs II (loose)' ' + git checkout main && + git tag ambiguous testtag^0 && + git branch ambiguous testtag^0 && + ${git_for_each_ref} --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && + test_cmp expected actual +' + +test_expect_success 'create tag without tagger' ' + git tag -a -m "Broken tag" taggerless && + git tag -f taggerless $(git cat-file tag taggerless | + sed -e "/^tagger /d" | + git hash-object --literally --stdin -w -t tag) +' + +test_atom refs/tags/taggerless type 'commit' +test_atom refs/tags/taggerless tag 'taggerless' +test_atom refs/tags/taggerless tagger '' +test_atom refs/tags/taggerless taggername '' +test_atom refs/tags/taggerless taggeremail '' +test_atom refs/tags/taggerless taggeremail:trim '' +test_atom refs/tags/taggerless taggeremail:localpart '' +test_atom refs/tags/taggerless taggerdate '' +test_atom refs/tags/taggerless committer '' +test_atom refs/tags/taggerless committername '' +test_atom refs/tags/taggerless committeremail '' +test_atom refs/tags/taggerless committeremail:trim '' +test_atom refs/tags/taggerless committeremail:localpart '' +test_atom refs/tags/taggerless committerdate '' +test_atom refs/tags/taggerless subject 'Broken tag' + +test_expect_success 'an unusual tag with an incomplete line' ' + + git tag -m "bogo" bogo && + bogo=$(git cat-file tag bogo) && + bogo=$(printf "%s" "$bogo" | git mktag) && + git tag -f bogo "$bogo" && + ${git_for_each_ref} --format "%(body)" refs/tags/bogo + +' + +test_expect_success 'create tag with subject and body content' ' + cat >>msg <<-\EOF && + the subject line + + first body line + second body line + EOF + git tag -F msg subject-body +' +test_atom refs/tags/subject-body subject 'the subject line' +test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' +test_atom refs/tags/subject-body body 'first body line +second body line +' +test_atom refs/tags/subject-body contents 'the subject line + +first body line +second body line +' + +test_expect_success 'create tag with multiline subject' ' + cat >msg <<-\EOF && + first subject line + second subject line + + first body line + second body line + EOF + git tag -F msg multiline +' +test_atom refs/tags/multiline subject 'first subject line second subject line' +test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' +test_atom refs/tags/multiline contents:subject 'first subject line second subject line' +test_atom refs/tags/multiline body 'first body line +second body line +' +test_atom refs/tags/multiline contents:body 'first body line +second body line +' +test_atom refs/tags/multiline contents:signature '' +test_atom refs/tags/multiline contents 'first subject line +second subject line + +first body line +second body line +' + +test_expect_success GPG 'create signed tags' ' + git tag -s -m "" signed-empty && + git tag -s -m "subject line" signed-short && + cat >msg <<-\EOF && + subject line + + body contents + EOF + git tag -s -F msg signed-long +' + +sig='-----BEGIN PGP SIGNATURE----- +-----END PGP SIGNATURE----- +' + +PREREQ=GPG +test_atom refs/tags/signed-empty subject '' +test_atom refs/tags/signed-empty subject:sanitize '' +test_atom refs/tags/signed-empty contents:subject '' +test_atom refs/tags/signed-empty body "$sig" +test_atom refs/tags/signed-empty contents:body '' +test_atom refs/tags/signed-empty contents:signature "$sig" +test_atom refs/tags/signed-empty contents "$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' + git cat-file tag refs/tags/signed-empty >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-empty >actual && + sanitize_pgp <expected >expected.clean && + echo >>expected.clean && + sanitize_pgp <actual >actual.clean && + test_cmp expected.clean actual.clean +' + +test_atom refs/tags/signed-short subject 'subject line' +test_atom refs/tags/signed-short subject:sanitize 'subject-line' +test_atom refs/tags/signed-short contents:subject 'subject line' +test_atom refs/tags/signed-short body "$sig" +test_atom refs/tags/signed-short contents:body '' +test_atom refs/tags/signed-short contents:signature "$sig" +test_atom refs/tags/signed-short contents "subject line +$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' + git cat-file tag refs/tags/signed-short >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-short >actual && + sanitize_pgp <expected >expected.clean && + echo >>expected.clean && + sanitize_pgp <actual >actual.clean && + test_cmp expected.clean actual.clean +' + +test_atom refs/tags/signed-long subject 'subject line' +test_atom refs/tags/signed-long subject:sanitize 'subject-line' +test_atom refs/tags/signed-long contents:subject 'subject line' +test_atom refs/tags/signed-long body "body contents +$sig" +test_atom refs/tags/signed-long contents:body 'body contents +' +test_atom refs/tags/signed-long contents:signature "$sig" +test_atom refs/tags/signed-long contents "subject line + +body contents +$sig" + +test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' + git cat-file tag refs/tags/signed-long >expected && + ${git_for_each_ref} --format="%(raw)" refs/tags/signed-long >actual && + sanitize_pgp <expected >expected.clean && + echo >>expected.clean && + sanitize_pgp <actual >actual.clean && + test_cmp expected.clean actual.clean +' + +test_expect_success 'set up refs pointing to tree and blob' ' + git update-ref refs/mytrees/first refs/heads/main^{tree} && + git update-ref refs/myblobs/first refs/heads/main:one +' + +test_atom refs/mytrees/first subject "" +test_atom refs/mytrees/first contents:subject "" +test_atom refs/mytrees/first body "" +test_atom refs/mytrees/first contents:body "" +test_atom refs/mytrees/first contents:signature "" +test_atom refs/mytrees/first contents "" + +test_expect_success 'basic atom: refs/mytrees/first raw' ' + git cat-file tree refs/mytrees/first >expected && + echo >>expected && + ${git_for_each_ref} --format="%(raw)" refs/mytrees/first >actual && + test_cmp expected actual && + git cat-file -s refs/mytrees/first >expected && + ${git_for_each_ref} --format="%(raw:size)" refs/mytrees/first >actual && + test_cmp expected actual +' + +test_atom refs/myblobs/first subject "" +test_atom refs/myblobs/first contents:subject "" +test_atom refs/myblobs/first body "" +test_atom refs/myblobs/first contents:body "" +test_atom refs/myblobs/first contents:signature "" +test_atom refs/myblobs/first contents "" + +test_expect_success 'basic atom: refs/myblobs/first raw' ' + git cat-file blob refs/myblobs/first >expected && + echo >>expected && + ${git_for_each_ref} --format="%(raw)" refs/myblobs/first >actual && + test_cmp expected actual && + git cat-file -s refs/myblobs/first >expected && + ${git_for_each_ref} --format="%(raw:size)" refs/myblobs/first >actual && + test_cmp expected actual +' + +test_expect_success 'set up refs pointing to binary blob' ' + printf "a\0b\0c" >blob1 && + printf "a\0c\0b" >blob2 && + printf "\0a\0b\0c" >blob3 && + printf "abc" >blob4 && + printf "\0 \0 \0 " >blob5 && + printf "\0 \0a\0 " >blob6 && + printf " " >blob7 && + >blob8 && + obj=$(git hash-object -w blob1) && + git update-ref refs/myblobs/blob1 "$obj" && + obj=$(git hash-object -w blob2) && + git update-ref refs/myblobs/blob2 "$obj" && + obj=$(git hash-object -w blob3) && + git update-ref refs/myblobs/blob3 "$obj" && + obj=$(git hash-object -w blob4) && + git update-ref refs/myblobs/blob4 "$obj" && + obj=$(git hash-object -w blob5) && + git update-ref refs/myblobs/blob5 "$obj" && + obj=$(git hash-object -w blob6) && + git update-ref refs/myblobs/blob6 "$obj" && + obj=$(git hash-object -w blob7) && + git update-ref refs/myblobs/blob7 "$obj" && + obj=$(git hash-object -w blob8) && + git update-ref refs/myblobs/blob8 "$obj" +' + +test_expect_success 'Verify sorts with raw' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob3 + refs/myblobs/blob7 + refs/mytrees/first + refs/myblobs/first + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob4 + refs/heads/main + EOF + ${git_for_each_ref} --format="%(refname)" --sort=raw \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'Verify sorts with raw:size' ' + cat >expected <<-EOF && + refs/myblobs/blob8 + refs/myblobs/blob7 + refs/myblobs/blob4 + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/first + refs/mytrees/first + refs/heads/main + EOF + ${git_for_each_ref} --format="%(refname)" --sort=raw:size \ + refs/heads/main refs/myblobs/ refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:equals)' ' + cat >expected <<-EOF && + not equals + not equals + not equals + not equals + not equals + not equals + refs/myblobs/blob4 + not equals + not equals + not equals + not equals + not equals + EOF + ${git_for_each_ref} --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'validate raw atom with %(if:notequals)' ' + cat >expected <<-EOF && + refs/heads/ambiguous + refs/heads/main + refs/heads/newtag + refs/myblobs/blob1 + refs/myblobs/blob2 + refs/myblobs/blob3 + equals + refs/myblobs/blob5 + refs/myblobs/blob6 + refs/myblobs/blob7 + refs/myblobs/blob8 + refs/myblobs/first + EOF + ${git_for_each_ref} --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ + refs/myblobs/ refs/heads/ >actual && + test_cmp expected actual +' + +test_expect_success 'empty raw refs with %(if)' ' + cat >expected <<-EOF && + refs/myblobs/blob1 not empty + refs/myblobs/blob2 not empty + refs/myblobs/blob3 not empty + refs/myblobs/blob4 not empty + refs/myblobs/blob5 not empty + refs/myblobs/blob6 not empty + refs/myblobs/blob7 empty + refs/myblobs/blob8 empty + refs/myblobs/first not empty + EOF + ${git_for_each_ref} --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ + refs/myblobs/ >actual && + test_cmp expected actual +' + +test_expect_success '%(raw) with --python must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --python +' + +test_expect_success '%(raw) with --tcl must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --tcl +' + +test_expect_success PERL_TEST_HELPERS '%(raw) with --perl' ' + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && + cmp blob1 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && + cmp blob3 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && + cmp blob8 actual && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/myblobs/first --perl | perl >actual && + cmp one actual && + git cat-file tree refs/mytrees/first > expected && + ${git_for_each_ref} --format="\$name= %(raw); +print \"\$name\"" refs/mytrees/first --perl | perl >actual && + cmp expected actual +' + +test_expect_success '%(raw) with --shell must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --shell +' + +test_expect_success '%(raw) with --shell and --sort=raw must fail' ' + test_must_fail ${git_for_each_ref} --format="%(raw)" --sort=raw --shell +' + +test_expect_success '%(raw:size) with --shell' ' + ${git_for_each_ref} --format="%(raw:size)" | sed "s/^/$SQ/;s/$/$SQ/" >expect && + ${git_for_each_ref} --format="%(raw:size)" --shell >actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --format compare with cat-file --batch" ' + git rev-parse refs/mytrees/first | git cat-file --batch >expected && + ${git_for_each_ref} --format="%(objectname) %(objecttype) %(objectsize) +%(raw)" refs/mytrees/first >actual && + test_cmp expected actual +' + +test_expect_success 'verify sorts with contents:size' ' + cat >expect <<-\EOF && + refs/heads/main + refs/heads/newtag + refs/heads/ambiguous + EOF + ${git_for_each_ref} --format="%(refname)" \ + --sort=contents:size refs/heads/ >actual && + test_cmp expect actual +' + +test_expect_success 'set up multiple-sort tags' ' + for when in 100000 200000 + do + for email in user1 user2 + do + for ref in ref1 ref2 + do + GIT_COMMITTER_DATE="@$when +0000" \ + GIT_COMMITTER_EMAIL="$email@example.com" \ + git tag -m "tag $ref-$when-$email" \ + multi-$ref-$when-$email || return 1 + done + done + done +' + +test_expect_success 'Verify sort with multiple keys' ' + cat >expected <<-\EOF && + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=-refname \ + --sort=taggeremail \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success 'equivalent sorts fall back on refname' ' + cat >expected <<-\EOF && + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success '--no-sort cancels the previous sort keys' ' + cat >expected <<-\EOF && + 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 + 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 + 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 + 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 + 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 + 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 + EOF + ${git_for_each_ref} \ + --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ + --sort=-refname \ + --sort=taggeremail \ + --no-sort \ + --sort=taggerdate \ + "refs/tags/multi-*" >actual && + test_cmp expected actual +' + +test_expect_success '--no-sort without subsequent --sort prints expected refs' ' + cat >expected <<-\EOF && + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + EOF + + # Sort the results with `sort` for a consistent comparison against + # expected + ${git_for_each_ref} \ + --format="%(refname)" \ + --no-sort \ + "refs/tags/multi-*" | sort >actual && + test_cmp expected actual +' + +test_expect_success 'set up custom date sorting' ' + # Dates: + # - Wed Feb 07 2024 21:34:20 +0000 + # - Tue Dec 14 1999 00:05:22 +0000 + # - Fri Jun 04 2021 11:26:51 +0000 + # - Mon Jan 22 2007 16:44:01 GMT+0000 + i=1 && + for when in 1707341660 945129922 1622806011 1169484241 + do + GIT_COMMITTER_DATE="@$when +0000" \ + GIT_COMMITTER_EMAIL="user@example.com" \ + git tag -m "tag $when" custom-dates-$i && + i=$(($i+1)) || return 1 + done +' + +test_expect_success 'sort by date defaults to full timestamp' ' + cat >expected <<-\EOF && + 945129922 refs/tags/custom-dates-2 + 1169484241 refs/tags/custom-dates-4 + 1622806011 refs/tags/custom-dates-3 + 1707341660 refs/tags/custom-dates-1 + EOF + + ${git_for_each_ref} \ + --format="%(creatordate:unix) %(refname)" \ + --sort=creatordate \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + +test_expect_success 'sort by custom date format' ' + cat >expected <<-\EOF && + 00:05:22 refs/tags/custom-dates-2 + 11:26:51 refs/tags/custom-dates-3 + 16:44:01 refs/tags/custom-dates-4 + 21:34:20 refs/tags/custom-dates-1 + EOF + + ${git_for_each_ref} \ + --format="%(creatordate:format:%H:%M:%S) %(refname)" \ + --sort="creatordate:format:%H:%M:%S" \ + "refs/tags/custom-dates-*" >actual && + test_cmp expected actual +' + +test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' + test_when_finished "git checkout main" && + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && + sed -e "s/^\* / /" actual >expect && + git checkout --orphan orphaned-branch && + ${git_for_each_ref} --format="%(HEAD) %(refname:short)" refs/heads/ >actual && + test_cmp expect actual +' + +cat >trailers <<EOF +Reviewed-by: A U Thor <author@example.com> +Signed-off-by: A U Thor <author@example.com> +[ v2 updated patch description ] +Acked-by: A U Thor + <author@example.com> +EOF + +unfold () { + perl -0pe 's/\n\s+/ /g' +} + +test_expect_success 'set up trailers for next test' ' + echo "Some contents" > two && + git add two && + git commit -F - <<-EOF + trailers: this commit message has trailers + + Some message contents + + $(cat trailers) + EOF +' + +test_trailer_option () { + if test "$#" -eq 3 + then + prereq="$1" + shift + fi && + title=$1 option=$2 + cat >expect + test_expect_success $prereq "$title" ' + ${git_for_each_ref} --format="%($option)" refs/heads/main >actual && + test_cmp expect actual && + ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main >actual && + test_cmp expect actual + ' +} + +test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) unfolds trailers' \ + 'trailers:unfold' <<-EOF + $(unfold <trailers) + + EOF + +test_trailer_option '%(trailers:only) shows only "key: value" trailers' \ + 'trailers:only' <<-EOF + $(grep -v patch.description <trailers) + + EOF + +test_trailer_option '%(trailers:only=no,only=true) shows only "key: value" trailers' \ + 'trailers:only=no,only=true' <<-EOF + $(grep -v patch.description <trailers) + + EOF + +test_trailer_option '%(trailers:only=yes) shows only "key: value" trailers' \ + 'trailers:only=yes' <<-EOF + $(grep -v patch.description <trailers) + + EOF + +test_trailer_option '%(trailers:only=no) shows all trailers' \ + 'trailers:only=no' <<-EOF + $(cat trailers) + + EOF + +test_trailer_option PERL_TEST_HELPERS '%(trailers:only) and %(trailers:unfold) work together' \ + 'trailers:only,unfold' <<-EOF + $(grep -v patch.description <trailers | unfold) + + EOF + +test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) and %(trailers:only) work together' \ + 'trailers:unfold,only' <<-EOF + $(grep -v patch.description <trailers | unfold) + + EOF + +test_trailer_option '%(trailers:key=foo) shows that trailer' \ + 'trailers:key=Signed-off-by' <<-EOF + Signed-off-by: A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:key=foo) is case insensitive' \ + 'trailers:key=SiGned-oFf-bY' <<-EOF + Signed-off-by: A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ + 'trailers:key=Signed-off-by:' <<-EOF + Signed-off-by: A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:key=foo) multiple keys' \ + 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF + Reviewed-by: A U Thor <author@example.com> + Signed-off-by: A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ + 'trailers:key=Shined-off-by:' <<-EOF + + EOF + +test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \ + 'trailers:key=Acked-by' <<-EOF + $(grep -v patch.description <trailers | grep -v Signed-off-by | grep -v Reviewed-by) + + EOF + +test_trailer_option '%(trailers:key=foo,unfold) properly unfolds' \ + 'trailers:key=Signed-Off-by,unfold' <<-EOF + $(unfold <trailers | grep Signed-off-by) + + EOF + +test_trailer_option '%(trailers:key=foo,only=no) also includes nontrailer lines' \ + 'trailers:key=Signed-off-by,only=no' <<-EOF + Signed-off-by: A U Thor <author@example.com> + $(grep patch.description <trailers) + + EOF + +test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \ + 'trailers:key=Signed-off-by,valueonly' <<-EOF + A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:separator) changes separator' \ + 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by: A U Thor <author@example.com>,Signed-off-by: A U Thor <author@example.com> + EOF + +test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \ + 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by,A U Thor <author@example.com> + Signed-off-by,A U Thor <author@example.com> + + EOF + +test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \ + 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF + Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com> + EOF + +test_expect_success 'multiple %(trailers) use their own options' ' + git tag -F - tag-with-trailers <<-\EOF && + body + + one: foo + one: bar + two: baz + two: qux + EOF + t1="%(trailers:key=one,key_value_separator=W,separator=X)" && + t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && + ${git_for_each_ref} --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && + cat >expect <<-\EOF && + oneWfooXoneWbar + twoYbazZtwoYqux + EOF + test_cmp expect actual +' + +test_failing_trailer_option () { + title=$1 option=$2 + cat >expect + test_expect_success "$title" ' + # error message cannot be checked under i18n + test_must_fail ${git_for_each_ref} --format="%($option)" refs/heads/main 2>actual && + test_cmp expect actual && + test_must_fail ${git_for_each_ref} --format="%(contents:$option)" refs/heads/main 2>actual && + test_cmp expect actual + ' +} + +test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ + 'trailers:unsupported' <<-\EOF + fatal: unknown %(trailers) argument: unsupported + EOF + +test_failing_trailer_option '%(trailers:key) without value is error' \ + 'trailers:key' <<-\EOF + fatal: expected %(trailers:key=<value>) + EOF + +test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' + cat >expect <<-EOF && + fatal: unrecognized %(contents) argument: trailersonly + EOF + test_must_fail ${git_for_each_ref} --format="%(contents:trailersonly)" 2>actual && + test_cmp expect actual +' + +test_expect_success 'basic atom: head contents:trailers' ' + ${git_for_each_ref} --format="%(contents:trailers)" refs/heads/main >actual && + sanitize_pgp <actual >actual.clean && + # ${git_for_each_ref} ends with a blank line + cat >expect <<-EOF && + $(cat trailers) + + EOF + test_cmp expect actual.clean +' + +test_expect_success 'basic atom: rest must fail' ' + test_must_fail ${git_for_each_ref} --format="%(rest)" refs/heads/main +' + +test_expect_success 'HEAD atom does not take arguments' ' + test_must_fail ${git_for_each_ref} --format="%(HEAD:foo)" 2>err && + echo "fatal: %(HEAD) does not take arguments" >expect && + test_cmp expect err +' + +test_expect_success 'subject atom rejects unknown arguments' ' + test_must_fail ${git_for_each_ref} --format="%(subject:foo)" 2>err && + echo "fatal: unrecognized %(subject) argument: foo" >expect && + test_cmp expect err +' + +test_expect_success 'refname atom rejects unknown arguments' ' + test_must_fail ${git_for_each_ref} --format="%(refname:foo)" 2>err && + echo "fatal: unrecognized %(refname) argument: foo" >expect && + test_cmp expect err +' + +test_expect_success 'trailer parsing not fooled by --- line' ' + git commit --allow-empty -F - <<-\EOF && + this is the subject + + This is the body. The message has a "---" line which would confuse a + message+patch parser. But here we know we have only a commit message, + so we get it right. + + trailer: wrong + --- + This is more body. + + trailer: right + EOF + + { + echo "trailer: right" && + echo + } >expect && + ${git_for_each_ref} --format="%(trailers)" refs/heads/main >actual && + test_cmp expect actual +' + +test_expect_success 'Add symbolic ref for the following tests' ' + git symbolic-ref refs/heads/sym refs/heads/main +' + +cat >expected <<EOF +refs/heads/main +EOF + +test_expect_success 'Verify usage of %(symref) atom' ' + ${git_for_each_ref} --format="%(symref)" refs/heads/sym >actual && + test_cmp expected actual +' + +cat >expected <<EOF +heads/main +EOF + +test_expect_success 'Verify usage of %(symref:short) atom' ' + ${git_for_each_ref} --format="%(symref:short)" refs/heads/sym >actual && + test_cmp expected actual +' + +cat >expected <<EOF +main +heads/main +EOF + +test_expect_success 'Verify usage of %(symref:lstrip) atom' ' + ${git_for_each_ref} --format="%(symref:lstrip=2)" refs/heads/sym > actual && + ${git_for_each_ref} --format="%(symref:lstrip=-2)" refs/heads/sym >> actual && + test_cmp expected actual && + + ${git_for_each_ref} --format="%(symref:strip=2)" refs/heads/sym > actual && + ${git_for_each_ref} --format="%(symref:strip=-2)" refs/heads/sym >> actual && + test_cmp expected actual +' + +cat >expected <<EOF +refs +refs/heads +EOF + +test_expect_success 'Verify usage of %(symref:rstrip) atom' ' + ${git_for_each_ref} --format="%(symref:rstrip=2)" refs/heads/sym > actual && + ${git_for_each_ref} --format="%(symref:rstrip=-2)" refs/heads/sym >> actual && + test_cmp expected actual +' + +test_expect_success ':remotename and :remoteref' ' + git init remote-tests && + ( + cd remote-tests && + test_commit initial && + git branch -M main && + git remote add from fifth.coffee:blub && + git config branch.main.remote from && + git config branch.main.merge refs/heads/stable && + git remote add to southridge.audio:repo && + git config remote.to.push "refs/heads/*:refs/heads/pushed/*" && + git config branch.main.pushRemote to && + for pair in "%(upstream)=refs/remotes/from/stable" \ + "%(upstream:remotename)=from" \ + "%(upstream:remoteref)=refs/heads/stable" \ + "%(push)=refs/remotes/to/pushed/main" \ + "%(push:remotename)=to" \ + "%(push:remoteref)=refs/heads/pushed/main" + do + echo "${pair#*=}" >expect && + ${git_for_each_ref} --format="${pair%=*}" \ + refs/heads/main >actual && + test_cmp expect actual || exit 1 + done && + git branch push-simple && + git config branch.push-simple.pushRemote from && + actual="$(${git_for_each_ref} \ + --format="%(push:remotename),%(push:remoteref)" \ + refs/heads/push-simple)" && + test from, = "$actual" + ) +' + +test_expect_success "${git_for_each_ref} --ignore-case ignores case" ' + ${git_for_each_ref} --format="%(refname)" refs/heads/MAIN >actual && + test_must_be_empty actual && + + echo refs/heads/main >expect && + ${git_for_each_ref} --format="%(refname)" --ignore-case \ + refs/heads/MAIN >actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --omit-empty works" ' + ${git_for_each_ref} --format="%(refname)" >actual && + test_line_count -gt 1 actual && + ${git_for_each_ref} --format="%(if:equals=refs/heads/main)%(refname)%(then)%(refname)%(end)" --omit-empty >actual && + echo refs/heads/main >expect && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --ignore-case works on multiple sort keys" ' + # name refs numerically to avoid case-insensitive filesystem conflicts + nr=0 && + for email in a A b B + do + for subject in a A b B + do + GIT_COMMITTER_EMAIL="$email@example.com" \ + git tag -m "tag $subject" icase-$(printf %02d $nr) && + nr=$((nr+1))|| + return 1 + done + done && + ${git_for_each_ref} --ignore-case \ + --format="%(taggeremail) %(subject) %(refname)" \ + --sort=refname \ + --sort=subject \ + --sort=taggeremail \ + refs/tags/icase-* >actual && + cat >expect <<-\EOF && + <a@example.com> tag a refs/tags/icase-00 + <a@example.com> tag A refs/tags/icase-01 + <A@example.com> tag a refs/tags/icase-04 + <A@example.com> tag A refs/tags/icase-05 + <a@example.com> tag b refs/tags/icase-02 + <a@example.com> tag B refs/tags/icase-03 + <A@example.com> tag b refs/tags/icase-06 + <A@example.com> tag B refs/tags/icase-07 + <b@example.com> tag a refs/tags/icase-08 + <b@example.com> tag A refs/tags/icase-09 + <B@example.com> tag a refs/tags/icase-12 + <B@example.com> tag A refs/tags/icase-13 + <b@example.com> tag b refs/tags/icase-10 + <b@example.com> tag B refs/tags/icase-11 + <B@example.com> tag b refs/tags/icase-14 + <B@example.com> tag B refs/tags/icase-15 + EOF + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} reports broken tags" ' + git tag -m "good tag" broken-tag-good HEAD && + git cat-file tag broken-tag-good >good && + sed s/commit/blob/ <good >bad && + bad=$(git hash-object -w -t tag bad) && + git update-ref refs/tags/broken-tag-bad $bad && + test_must_fail ${git_for_each_ref} --format="%(*objectname)" \ + refs/tags/broken-tag-* +' + +test_expect_success 'set up tag with signature and no blank lines' ' + git tag -F - fake-sig-no-blanks <<-\EOF + this is the subject + -----BEGIN PGP SIGNATURE----- + not a real signature, but we just care about the + subject/body parsing. It is important here that + there are no blank lines in the signature. + -----END PGP SIGNATURE----- + EOF +' + +test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject' +test_atom refs/tags/fake-sig-no-blanks contents:body '' +test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig" + +test_expect_success 'set up tag with CRLF signature' ' + append_cr <<-\EOF | + this is the subject + -----BEGIN PGP SIGNATURE----- + + not a real signature, but we just care about + the subject/body parsing. It is important here + that there is a blank line separating this + from the signature header. + -----END PGP SIGNATURE----- + EOF + git tag -F - --cleanup=verbatim fake-sig-crlf +' + +test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject' +test_atom refs/tags/fake-sig-crlf contents:body '' + +# CRLF is retained in the signature, so we have to pass our expected value +# through append_cr. But test_atom requires a shell string, which means command +# substitution, and the shell will strip trailing newlines from the output of +# the substitution. Hack around it by adding and then removing a dummy line. +sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" +sig_crlf=${sig_crlf%dummy} +test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" + +test_expect_success 'set up tag with signature and trailers' ' + git tag -F - fake-sig-trailer <<-\EOF + this is the subject + + this is the body + + My-Trailer: foo + -----BEGIN PGP SIGNATURE----- + + not a real signature, but we just care about the + subject/body/trailer parsing. + -----END PGP SIGNATURE----- + EOF +' + +# use "separator=" here to suppress the terminating newline +test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' + +test_expect_success "${git_for_each_ref} --stdin: empty" ' + >in && + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && + ${git_for_each_ref} --format="%(refname)" >expect && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} --stdin: fails if extra args" ' + >in && + test_must_fail ${git_for_each_ref} --format="%(refname)" \ + --stdin refs/heads/extra <in 2>err && + grep "unknown arguments supplied with --stdin" err +' + +test_expect_success "${git_for_each_ref} --stdin: matches" ' + cat >in <<-EOF && + refs/tags/multi* + refs/heads/amb* + EOF + + cat >expect <<-EOF && + refs/heads/ambiguous + refs/tags/multi-ref1-100000-user1 + refs/tags/multi-ref1-100000-user2 + refs/tags/multi-ref1-200000-user1 + refs/tags/multi-ref1-200000-user2 + refs/tags/multi-ref2-100000-user1 + refs/tags/multi-ref2-100000-user2 + refs/tags/multi-ref2-200000-user1 + refs/tags/multi-ref2-200000-user2 + refs/tags/multiline + EOF + + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && + test_cmp expect actual +' + +test_expect_success "${git_for_each_ref} with non-existing refs" ' + cat >in <<-EOF && + refs/heads/this-ref-does-not-exist + refs/tags/bogus + EOF + + ${git_for_each_ref} --format="%(refname)" --stdin <in >actual && + test_must_be_empty actual && + + xargs ${git_for_each_ref} --format="%(refname)" <in >actual && + test_must_be_empty actual +' + +test_expect_success "${git_for_each_ref} with nested tags" ' + git tag -am "Normal tag" nested/base HEAD && + git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && + git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && + + head_oid="$(git rev-parse HEAD)" && + base_tag_oid="$(git rev-parse refs/tags/nested/base)" && + nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && + nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && + + cat >expect <<-EOF && + refs/tags/nested/base $base_tag_oid tag $head_oid commit + refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit + refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit + EOF + + ${git_for_each_ref} \ + --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ + refs/tags/nested/ >actual && + test_cmp expect actual +' + +test_expect_success 'is-base atom with non-commits' ' + ${git_for_each_ref} --format="%(is-base:HEAD) %(refname)" >out 2>err && + grep "(HEAD) refs/heads/main" out && + + test_line_count = 2 err && + grep "error: object .* is a commit, not a blob" err && + grep "error: bad tag pointer to" err +' + +GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" +TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" + +test_expect_success GPG 'setup for signature atom using gpg' ' + git checkout -b signed && + + test_when_finished "test_unconfig commit.gpgSign" && + + echo "1" >file && + git add file && + test_tick && + git commit -S -m "file: 1" && + git tag first-signed && + + echo "2" >file && + test_tick && + git commit -a -m "file: 2" && + git tag second-unsigned && + + git config commit.gpgSign 1 && + echo "3" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 3" && + git tag third-unsigned && + + test_tick && + git rebase -f HEAD^^ && git tag second-signed HEAD^ && + git tag third-signed && + + echo "4" >file && + test_tick && + git commit -a -SB7227189 -m "file: 4" && + git tag fourth-signed && + + echo "5" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 5" && + git tag fifth-unsigned && + + echo "6" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 6" && + + test_tick && + git rebase -f HEAD^^ && + git tag fifth-signed HEAD^ && + git tag sixth-signed && + + echo "7" >file && + test_tick && + git commit -a --no-gpg-sign -m "file: 7" && + git tag seventh-unsigned +' + +test_expect_success GPGSSH 'setup for signature atom using ssh' ' + test_when_finished "test_unconfig gpg.format user.signingkey" && + + test_config gpg.format ssh && + test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && + echo "8" >file && + test_tick && + git add file && + git commit -S -m "file: 8" && + git tag eighth-signed-ssh +' + +test_expect_success GPG2 'bare signature atom' ' + git verify-commit first-signed 2>expect && + echo >>expect && + ${git_for_each_ref} refs/tags/first-signed \ + --format="%(signature)" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show good signature with custom format' ' + git verify-commit first-signed && + cat >expect <<-\EOF && + G + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + ${git_for_each_ref} refs/tags/first-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' +test_expect_success GPGSSH 'show good signature with custom format with ssh' ' + test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && + FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && + cat >expect.tmpl <<-\EOF && + G + FINGERPRINT + principal with number 1 + FINGERPRINT + + EOF + sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && + ${git_for_each_ref} refs/tags/eighth-signed-ssh \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'signature atom with grade option and bad signature' ' + git cat-file commit third-signed >raw && + sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && + FORGED1=$(git hash-object -w -t commit forged1) && + git update-ref refs/tags/third-signed "$FORGED1" && + test_must_fail git verify-commit "$FORGED1" && + + cat >expect <<-\EOF && + B + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + + + EOF + ${git_for_each_ref} refs/tags/third-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with custom format' ' + cat >expect <<-\EOF && + U + 65A0EEA02E30CAD7 + Eris Discordia <discord@example.net> + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + ${git_for_each_ref} refs/tags/fourth-signed \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with undefined trust level' ' + cat >expect <<-\EOF && + undefined + 65A0EEA02E30CAD7 + Eris Discordia <discord@example.net> + F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 + D4BE22311AD3131E5EDA29A461092E85B7227189 + EOF + ${git_for_each_ref} refs/tags/fourth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show untrusted signature with ultimate trust level' ' + cat >expect <<-\EOF && + ultimate + 13B6F51ECDDE430D + C O Mitter <committer@example.com> + 73D758744BE721698EC54E8713B6F51ECDDE430D + 73D758744BE721698EC54E8713B6F51ECDDE430D + EOF + ${git_for_each_ref} refs/tags/sixth-signed \ + --format="$TRUSTLEVEL_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show unknown signature with custom format' ' + cat >expect <<-\EOF && + E + 13B6F51ECDDE430D + + + + EOF + GNUPGHOME="$GNUPGHOME_NOT_USED" ${git_for_each_ref} \ + refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_expect_success GPG 'show lack of signature with custom format' ' + cat >expect <<-\EOF && + N + + + + + EOF + ${git_for_each_ref} refs/tags/seventh-unsigned \ + --format="$GRADE_FORMAT" >actual && + test_cmp expect actual +' + +test_done diff --git a/t/helper/test-advise.c b/t/helper/test-advise.c index 6967c8e25c..81ed93a05c 100644 --- a/t/helper/test-advise.c +++ b/t/helper/test-advise.c @@ -3,6 +3,7 @@ #include "test-tool.h" #include "advice.h" #include "config.h" +#include "environment.h" #include "setup.h" int cmd__advise_if_enabled(int argc, const char **argv) @@ -11,7 +12,7 @@ int cmd__advise_if_enabled(int argc, const char **argv) die("usage: %s <advice>", argv[0]); setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); /* * Any advice type can be used for testing, but NESTED_TAG was diff --git a/t/helper/test-config.c b/t/helper/test-config.c index 75e028ab2a..9f8cca7c48 100644 --- a/t/helper/test-config.c +++ b/t/helper/test-config.c @@ -32,10 +32,10 @@ * ascending order of priority from a config_set * constructed from files entered as arguments. * - * iterate -> iterate over all values using git_config(), and print some + * iterate -> iterate over all values using repo_config(), and print some * data for each * - * git_config_int -> iterate over all values using git_config() and print the + * git_config_int -> iterate over all values using repo_config() and print the * integer value for the entered key or die * * Examples: @@ -110,7 +110,7 @@ int cmd__config(int argc, const char **argv) fprintf(stderr, "Please, provide a command name on the command-line\n"); goto exit1; } else if (argc == 3 && !strcmp(argv[1], "get_value")) { - if (!git_config_get_value(argv[2], &v)) { + if (!repo_config_get_value(the_repository, argv[2], &v)) { if (!v) printf("(NULL)\n"); else @@ -121,7 +121,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_value_multi")) { - if (!git_config_get_value_multi(argv[2], &strptr)) { + if (!repo_config_get_value_multi(the_repository, argv[2], &strptr)) { for (i = 0; i < strptr->nr; i++) { v = strptr->items[i].string; if (!v) @@ -137,7 +137,7 @@ int cmd__config(int argc, const char **argv) } else if (argc == 3 && !strcmp(argv[1], "get")) { int ret; - if (!(ret = git_config_get(argv[2]))) + if (!(ret = repo_config_get(the_repository, argv[2]))) goto exit0; else if (ret == 1) printf("Value not found for \"%s\"\n", argv[2]); @@ -155,7 +155,7 @@ int cmd__config(int argc, const char **argv) BUG("Key \"%s\" has unknown return %d", argv[2], ret); goto exit1; } else if (argc == 3 && !strcmp(argv[1], "get_int")) { - if (!git_config_get_int(argv[2], &val)) { + if (!repo_config_get_int(the_repository, argv[2], &val)) { printf("%d\n", val); goto exit0; } else { @@ -163,7 +163,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_bool")) { - if (!git_config_get_bool(argv[2], &val)) { + if (!repo_config_get_bool(the_repository, argv[2], &val)) { printf("%d\n", val); goto exit0; } else { @@ -171,7 +171,7 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (argc == 3 && !strcmp(argv[1], "get_string")) { - if (!git_config_get_string_tmp(argv[2], &v)) { + if (!repo_config_get_string_tmp(the_repository, argv[2], &v)) { printf("%s\n", v); goto exit0; } else { @@ -218,10 +218,10 @@ int cmd__config(int argc, const char **argv) goto exit1; } } else if (!strcmp(argv[1], "iterate")) { - git_config(iterate_cb, NULL); + repo_config(the_repository, iterate_cb, NULL); goto exit0; } else if (argc == 3 && !strcmp(argv[1], "git_config_int")) { - git_config(parse_int_cb, (void *) argv[2]); + repo_config(the_repository, parse_int_cb, (void *) argv[2]); goto exit0; } diff --git a/t/helper/test-delta.c b/t/helper/test-delta.c index 6bc787a474..52ea00c937 100644 --- a/t/helper/test-delta.c +++ b/t/helper/test-delta.c @@ -11,6 +11,7 @@ #include "test-tool.h" #include "git-compat-util.h" #include "delta.h" +#include "strbuf.h" static const char usage_str[] = "test-tool delta (-d|-p) <from_file> <data_file> <out_file>"; @@ -18,68 +19,38 @@ static const char usage_str[] = int cmd__delta(int argc, const char **argv) { int fd; - struct stat st; - void *from_buf = NULL, *data_buf = NULL, *out_buf = NULL; - unsigned long from_size, data_size, out_size; - int ret = 1; + struct strbuf from = STRBUF_INIT, data = STRBUF_INIT; + char *out_buf; + unsigned long out_size; - if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) { - fprintf(stderr, "usage: %s\n", usage_str); - return 1; - } + if (argc != 5 || (strcmp(argv[1], "-d") && strcmp(argv[1], "-p"))) + usage(usage_str); - fd = open(argv[2], O_RDONLY); - if (fd < 0 || fstat(fd, &st)) { - perror(argv[2]); - return 1; - } - from_size = st.st_size; - from_buf = xmalloc(from_size); - if (read_in_full(fd, from_buf, from_size) < 0) { - perror(argv[2]); - close(fd); - goto cleanup; - } - close(fd); - - fd = open(argv[3], O_RDONLY); - if (fd < 0 || fstat(fd, &st)) { - perror(argv[3]); - goto cleanup; - } - data_size = st.st_size; - data_buf = xmalloc(data_size); - if (read_in_full(fd, data_buf, data_size) < 0) { - perror(argv[3]); - close(fd); - goto cleanup; - } - close(fd); + if (strbuf_read_file(&from, argv[2], 0) < 0) + die_errno("unable to read '%s'", argv[2]); + if (strbuf_read_file(&data, argv[3], 0) < 0) + die_errno("unable to read '%s'", argv[3]); if (argv[1][1] == 'd') - out_buf = diff_delta(from_buf, from_size, - data_buf, data_size, + out_buf = diff_delta(from.buf, from.len, + data.buf, data.len, &out_size, 0); else - out_buf = patch_delta(from_buf, from_size, - data_buf, data_size, + out_buf = patch_delta(from.buf, from.len, + data.buf, data.len, &out_size); - if (!out_buf) { - fprintf(stderr, "delta operation failed (returned NULL)\n"); - goto cleanup; - } + if (!out_buf) + die("delta operation failed (returned NULL)"); - fd = open (argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666); - if (fd < 0 || write_in_full(fd, out_buf, out_size) < 0) { - perror(argv[4]); - goto cleanup; - } + fd = xopen(argv[4], O_WRONLY|O_CREAT|O_TRUNC, 0666); + if (write_in_full(fd, out_buf, out_size) < 0) + die_errno("write(%s)", argv[4]); + if (close(fd) < 0) + die_errno("close(%s)", argv[4]); - ret = 0; -cleanup: - free(from_buf); - free(data_buf); + strbuf_release(&from); + strbuf_release(&data); free(out_buf); - return ret; + return 0; } diff --git a/t/helper/test-hashmap.c b/t/helper/test-hashmap.c index 7782ae585e..56d223a283 100644 --- a/t/helper/test-hashmap.c +++ b/t/helper/test-hashmap.c @@ -137,6 +137,11 @@ static void perf_hashmap(unsigned int method, unsigned int rounds) * Read stdin line by line and print result of commands to stdout: * * perfhashmap method rounds -> test hashmap.[ch] performance + * + * NOTE: this is not used by any of our mechanized build & test + * procedure, after 3469a236 (t: port helper/test-hashmap.c to + * unit-tests/t-hashmap.c, 2024-08-03). See the log message of that + * commit for the reason why this is still here. */ int cmd__hashmap(int argc UNUSED, const char **argv UNUSED) { @@ -149,8 +154,8 @@ int cmd__hashmap(int argc UNUSED, const char **argv UNUSED) /* break line into command and up to two parameters */ string_list_setlen(&parts, 0); - string_list_split_in_place(&parts, line.buf, DELIM, 2); - string_list_remove_empty_items(&parts, 0); + string_list_split_in_place_f(&parts, line.buf, DELIM, 2, + STRING_LIST_SPLIT_NONEMPTY); /* ignore empty lines */ if (!parts.nr) diff --git a/t/helper/test-json-writer.c b/t/helper/test-json-writer.c index a288069b04..f8316a7d29 100644 --- a/t/helper/test-json-writer.c +++ b/t/helper/test-json-writer.c @@ -492,8 +492,8 @@ static int scripted(void) /* break line into command and zero or more tokens */ string_list_setlen(&parts, 0); - string_list_split_in_place(&parts, line, " ", -1); - string_list_remove_empty_items(&parts, 0); + string_list_split_in_place_f(&parts, line, " ", -1, + STRING_LIST_SPLIT_NONEMPTY); /* ignore empty lines */ if (!parts.nr || !*parts.items[0].string) diff --git a/t/helper/test-path-utils.c b/t/helper/test-path-utils.c index 086238c826..f5f33751da 100644 --- a/t/helper/test-path-utils.c +++ b/t/helper/test-path-utils.c @@ -348,6 +348,7 @@ int cmd__path_utils(int argc, const char **argv) if (argc == 4 && !strcmp(argv[1], "longest_ancestor_length")) { int len; struct string_list ceiling_dirs = STRING_LIST_INIT_DUP; + const char path_sep[] = { PATH_SEP, '\0' }; char *path = xstrdup(argv[2]); /* @@ -362,7 +363,7 @@ int cmd__path_utils(int argc, const char **argv) */ if (normalize_path_copy(path, path)) die("Path \"%s\" could not be normalized", argv[2]); - string_list_split(&ceiling_dirs, argv[3], PATH_SEP, -1); + string_list_split(&ceiling_dirs, argv[3], path_sep, -1); filter_string_list(&ceiling_dirs, 0, normalize_ceiling_entry, NULL); len = longest_ancestor_length(path, &ceiling_dirs); diff --git a/t/helper/test-read-cache.c b/t/helper/test-read-cache.c index e277dde8e7..9ae71cefb3 100644 --- a/t/helper/test-read-cache.c +++ b/t/helper/test-read-cache.c @@ -2,6 +2,7 @@ #include "test-tool.h" #include "config.h" +#include "environment.h" #include "read-cache-ll.h" #include "repository.h" #include "setup.h" @@ -19,7 +20,7 @@ int cmd__read_cache(int argc, const char **argv) if (argc == 2) cnt = strtol(argv[1], NULL, 0); setup_git_directory(); - git_config(git_default_config, NULL); + repo_config(the_repository, git_default_config, NULL); for (i = 0; i < cnt; i++) { repo_read_index(the_repository); diff --git a/t/helper/test-read-graph.c b/t/helper/test-read-graph.c index ef5339bbee..6a5f64e473 100644 --- a/t/helper/test-read-graph.c +++ b/t/helper/test-read-graph.c @@ -81,7 +81,7 @@ int cmd__read_graph(int argc, const char **argv) prepare_repo_settings(the_repository); - graph = read_commit_graph_one(the_repository, source); + graph = read_commit_graph_one(source); if (!graph) { ret = 1; goto done; diff --git a/t/helper/test-ref-store.c b/t/helper/test-ref-store.c index 8d9a271845..83b06d39a3 100644 --- a/t/helper/test-ref-store.c +++ b/t/helper/test-ref-store.c @@ -29,7 +29,7 @@ static unsigned int parse_flags(const char *str, struct flag_definition *defs) if (!strcmp(str, "0")) return 0; - string_list_split(&masks, str, ',', 64); + string_list_split(&masks, str, ",", 64); for (size_t i = 0; i < masks.nr; i++) { const char *name = masks.items[i].string; struct flag_definition *def = defs; @@ -215,7 +215,8 @@ static int cmd_for_each_reflog(struct ref_store *refs, return refs_for_each_reflog(refs, each_reflog, NULL); } -static int each_reflog_ent(struct object_id *old_oid, struct object_id *new_oid, +static int each_reflog_ent(const char *refname UNUSED, + struct object_id *old_oid, struct object_id *new_oid, const char *committer, timestamp_t timestamp, int tz, const char *msg, void *cb_data UNUSED) { diff --git a/t/helper/test-truncate.c b/t/helper/test-truncate.c index 3931deaec7..2820cc7ed7 100644 --- a/t/helper/test-truncate.c +++ b/t/helper/test-truncate.c @@ -21,5 +21,8 @@ int cmd__truncate(int argc, const char **argv) if (ftruncate(fd, (off_t) sz) < 0) die_errno("failed to truncate file"); + + close(fd); + return 0; } diff --git a/t/helper/test-userdiff.c b/t/helper/test-userdiff.c index 94c48ababb..aa3a9894d2 100644 --- a/t/helper/test-userdiff.c +++ b/t/helper/test-userdiff.c @@ -41,7 +41,7 @@ int cmd__userdiff(int argc, const char **argv) if (want & USERDIFF_DRIVER_TYPE_CUSTOM) { setup_git_directory(); - git_config(cmd__userdiff_config, NULL); + repo_config(the_repository, cmd__userdiff_config, NULL); } for_each_userdiff_driver(driver_cb, &want); diff --git a/t/meson.build b/t/meson.build index b74125b047..82af229be3 100644 --- a/t/meson.build +++ b/t/meson.build @@ -1,5 +1,6 @@ clar_test_suites = [ 'unit-tests/u-ctype.c', + 'unit-tests/u-dir.c', 'unit-tests/u-example-decorate.c', 'unit-tests/u-hash.c', 'unit-tests/u-hashmap.c', @@ -8,6 +9,14 @@ clar_test_suites = [ 'unit-tests/u-oidmap.c', 'unit-tests/u-oidtree.c', 'unit-tests/u-prio-queue.c', + 'unit-tests/u-reftable-basics.c', + 'unit-tests/u-reftable-block.c', + 'unit-tests/u-reftable-merged.c', + 'unit-tests/u-reftable-pq.c', + 'unit-tests/u-reftable-readwrite.c', + 'unit-tests/u-reftable-record.c', + 'unit-tests/u-reftable-stack.c', + 'unit-tests/u-reftable-table.c', 'unit-tests/u-reftable-tree.c', 'unit-tests/u-strbuf.c', 'unit-tests/u-strcmp-offset.c', @@ -20,7 +29,8 @@ clar_test_suites = [ clar_sources = [ 'unit-tests/clar/clar.c', 'unit-tests/unit-test.c', - 'unit-tests/lib-oid.c' + 'unit-tests/lib-oid.c', + 'unit-tests/lib-reftable.c' ] clar_decls_h = custom_target( @@ -50,37 +60,13 @@ clar_sources += custom_target( clar_unit_tests = executable('unit-tests', sources: clar_sources + clar_test_suites, + c_args: [ + '-DGIT_CLAR_DECLS_H="' + clar_decls_h.full_path() + '"', + ], dependencies: [libgit_commonmain], ) test('unit-tests', clar_unit_tests, kwargs: test_kwargs) -unit_test_programs = [ - 'unit-tests/t-reftable-basics.c', - 'unit-tests/t-reftable-block.c', - 'unit-tests/t-reftable-merged.c', - 'unit-tests/t-reftable-pq.c', - 'unit-tests/t-reftable-readwrite.c', - 'unit-tests/t-reftable-record.c', - 'unit-tests/t-reftable-stack.c', - 'unit-tests/t-reftable-table.c', -] - -foreach unit_test_program : unit_test_programs - unit_test_name = fs.stem(unit_test_program) - unit_test = executable(unit_test_name, - sources: [ - 'unit-tests/test-lib.c', - 'unit-tests/lib-reftable.c', - unit_test_program, - ], - dependencies: [libgit_commonmain], - ) - test(unit_test_name, unit_test, - workdir: meson.current_source_dir(), - kwargs: test_kwargs, - ) -endforeach - subdir('helper') integration_tests = [ @@ -219,10 +205,12 @@ integration_tests = [ 't1418-reflog-exists.sh', 't1419-exclude-refs.sh', 't1420-lost-found.sh', + 't1421-reflog-write.sh', 't1430-bad-ref-name.sh', 't1450-fsck.sh', 't1451-fsck-buffer.sh', 't1460-refs-migrate.sh', + 't1461-refs-list.sh', 't1500-rev-parse.sh', 't1501-work-tree.sh', 't1502-rev-parse-parseopt.sh', @@ -245,6 +233,7 @@ integration_tests = [ 't1700-split-index.sh', 't1701-racy-split-index.sh', 't1800-hook.sh', + 't1900-repo.sh', 't2000-conflict-when-checking-files-out.sh', 't2002-checkout-cache-u.sh', 't2003-checkout-cache-mkdir.sh', @@ -501,6 +490,7 @@ integration_tests = [ 't4069-remerge-diff.sh', 't4070-diff-pairs.sh', 't4071-diff-minimal.sh', + 't4072-diff-max-depth.sh', 't4100-apply-stat.sh', 't4101-apply-nonl.sh', 't4102-apply-rename.sh', @@ -1165,8 +1155,6 @@ benchmarks = [ # sufficient to catch missing test suites in our CI though. foreach glob, tests : { 't[0-9][0-9][0-9][0-9]-*.sh': integration_tests, - 'perf/p[0-9][0-9][0-9][0-9]-*.sh': benchmarks, - 'unit-tests/t-*.c': unit_test_programs, 'unit-tests/u-*.c': clar_test_suites, } actual_tests = run_command(shell, '-c', 'ls ' + glob, @@ -1233,4 +1221,4 @@ if perl.found() and time.found() timeout: 0, ) endforeach -endif +endif
\ No newline at end of file diff --git a/t/t0450/adoc-help-mismatches b/t/t0450/adoc-help-mismatches index 06b469bdee..2c6ecd5fc8 100644 --- a/t/t0450/adoc-help-mismatches +++ b/t/t0450/adoc-help-mismatches @@ -17,7 +17,6 @@ fast-export fast-import fetch-pack fmt-merge-msg -for-each-ref format-patch fsck-objects fsmonitor--daemon diff --git a/t/t1092-sparse-checkout-compatibility.sh b/t/t1092-sparse-checkout-compatibility.sh index d8101139b4..b0f691c151 100755 --- a/t/t1092-sparse-checkout-compatibility.sh +++ b/t/t1092-sparse-checkout-compatibility.sh @@ -1506,6 +1506,8 @@ test_expect_success 'sparse-index is not expanded' ' ensure_not_expanded reset --hard && ensure_not_expanded restore -s rename-out-to-out -- deep/deeper1 && + ensure_not_expanded ls-files deep/deeper1 && + echo >>sparse-index/README.md && ensure_not_expanded add -A && echo >>sparse-index/extra.txt && @@ -1607,6 +1609,17 @@ test_expect_success 'describe tested on all' ' test_all_match git describe --dirty ' +test_expect_success 'ls-files filtering and expansion' ' + init_repos && + + # This filtering will hit a sparse directory midway + # through the iteration. + test_all_match git ls-files deep && + + # This pathspec will filter the index to only a sparse + # directory. + test_all_match git ls-files folder1 +' test_expect_success 'sparse-index is not expanded: describe' ' init_repos && diff --git a/t/t1400-update-ref.sh b/t/t1400-update-ref.sh index 96648a6e5d..b7415ec9d5 100755 --- a/t/t1400-update-ref.sh +++ b/t/t1400-update-ref.sh @@ -2368,4 +2368,25 @@ test_expect_success REFFILES 'empty directories are pruned when not committing' test_path_is_missing .git/refs/heads/nested ' +test_expect_success 'dangling symref not overwritten by creation' ' + test_when_finished "git update-ref -d refs/heads/dangling" && + git symbolic-ref refs/heads/dangling refs/heads/does-not-exist && + test_must_fail git update-ref --no-deref --stdin 2>err <<-\EOF && + create refs/heads/dangling HEAD + EOF + test_grep "cannot lock.*dangling symref already exists" err && + test_must_fail git rev-parse --verify refs/heads/dangling && + test_must_fail git rev-parse --verify refs/heads/does-not-exist +' + +test_expect_success 'dangling symref overwritten without old oid' ' + test_when_finished "git update-ref -d refs/heads/dangling" && + git symbolic-ref refs/heads/dangling refs/heads/does-not-exist && + git update-ref --no-deref --stdin <<-\EOF && + update refs/heads/dangling HEAD + EOF + git rev-parse --verify refs/heads/dangling && + test_must_fail git rev-parse --verify refs/heads/does-not-exist +' + test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index 42b501f163..e30f87a358 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -673,4 +673,32 @@ test_expect_success 'reflog drop --all with reference' ' ) ' +test_expect_success 'expire with pattern config' ' + # Split refs/heads/ into two roots so we can apply config to each. Make + # two branches per root to verify that config is applied correctly + # multiple times. + git branch root1/branch1 && + git branch root1/branch2 && + git branch root2/branch1 && + git branch root2/branch2 && + + test_config "gc.reflogexpire" "never" && + test_config "gc.refs/heads/root2/*.reflogExpire" "now" && + git reflog expire \ + root1/branch1 root1/branch2 \ + root2/branch1 root2/branch2 && + + cat >expect <<-\EOF && + root1/branch1@{0} + root1/branch2@{0} + EOF + git log -g --branches="root*" --format=%gD >actual.raw && + # The sole reflog entry of each branch points to the same commit, so + # the order in which they are shown is nondeterministic. We just care + # about the what was expired (and what was not), so sort to get a known + # order. + sort <actual.raw >actual.sorted && + test_cmp expect actual.sorted +' + test_done diff --git a/t/t1421-reflog-write.sh b/t/t1421-reflog-write.sh new file mode 100755 index 0000000000..46df64c176 --- /dev/null +++ b/t/t1421-reflog-write.sh @@ -0,0 +1,126 @@ +#!/bin/sh + +test_description='Manually write reflog entries' + +. ./test-lib.sh + +SIGNATURE="C O Mitter <committer@example.com> 1112911993 -0700" + +test_reflog_matches () { + repo="$1" && + refname="$2" && + cat >actual && + test-tool -C "$repo" ref-store main for-each-reflog-ent "$refname" >expected && + test_cmp expected actual +} + +test_expect_success 'invalid number of arguments' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + for args in "" "1" "1 2" "1 2 3" "1 2 3 4 5" + do + test_must_fail git reflog write $args 2>err && + test_grep "usage: git reflog write" err || return 1 + done + ) +' + +test_expect_success 'invalid refname' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write "refs/heads/ invalid" $ZERO_OID $ZERO_OID first 2>err && + test_grep "invalid reference name: " err + ) +' + +test_expect_success 'unqualified refname is rejected' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write unqualified $ZERO_OID $ZERO_OID first 2>err && + test_grep "invalid reference name: " err + ) +' + +test_expect_success 'nonexistent object IDs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_must_fail git reflog write refs/heads/something $(test_oid deadbeef) $ZERO_OID old-object-id 2>err && + test_grep "old object .* does not exist" err && + test_must_fail git reflog write refs/heads/something $ZERO_OID $(test_oid deadbeef) new-object-id 2>err && + test_grep "new object .* does not exist" err + ) +' + +test_expect_success 'abbreviated object IDs' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + abbreviated_oid=$(git rev-parse HEAD | test_copy_bytes 8) && + test_must_fail git reflog write refs/heads/something $abbreviated_oid $ZERO_OID old-object-id 2>err && + test_grep "invalid old object ID" err && + test_must_fail git reflog write refs/heads/something $ZERO_OID $abbreviated_oid new-object-id 2>err && + test_grep "invalid new object ID" err + ) +' + +test_expect_success 'reflog message gets normalized' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + git reflog write HEAD $COMMIT_OID $COMMIT_OID "$(printf "message\nwith\nnewlines")" && + git reflog show -1 --format=%gs HEAD >actual && + echo "message with newlines" >expected && + test_cmp expected actual + ) +' + +test_expect_success 'simple writes' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + git reflog write refs/heads/something $ZERO_OID $COMMIT_OID first && + test_reflog_matches . refs/heads/something <<-EOF && + $ZERO_OID $COMMIT_OID $SIGNATURE first + EOF + + git reflog write refs/heads/something $COMMIT_OID $COMMIT_OID second && + test_reflog_matches . refs/heads/something <<-EOF + $ZERO_OID $COMMIT_OID $SIGNATURE first + $COMMIT_OID $COMMIT_OID $SIGNATURE second + EOF + ) +' + +test_expect_success 'can write to root ref' ' + test_when_finished "rm -rf repo" && + git init repo && + ( + cd repo && + test_commit initial && + COMMIT_OID=$(git rev-parse HEAD) && + + git reflog write ROOT_REF_HEAD $ZERO_OID $COMMIT_OID first && + test_reflog_matches . ROOT_REF_HEAD <<-EOF + $ZERO_OID $COMMIT_OID $SIGNATURE first + EOF + ) +' + +test_done diff --git a/t/t1460-refs-migrate.sh b/t/t1460-refs-migrate.sh index 2ab97e1b7d..0e1116a319 100755 --- a/t/t1460-refs-migrate.sh +++ b/t/t1460-refs-migrate.sh @@ -7,6 +7,17 @@ export GIT_TEST_DEFAULT_INITIAL_BRANCH_NAME . ./test-lib.sh +print_all_reflog_entries () { + repo=$1 && + test-tool -C "$repo" ref-store main for-each-reflog >reflogs && + while read reflog + do + echo "REFLOG: $reflog" && + test-tool -C "$repo" ref-store main for-each-reflog-ent "$reflog" || + return 1 + done <reflogs +} + # Migrate the provided repository from one format to the other and # verify that the references and logs are migrated over correctly. # Usage: test_migration <repo> <format> [<skip_reflog_verify> [<options...>]] @@ -28,8 +39,7 @@ test_migration () { --format='%(refname) %(objectname) %(symref)' >expect && if ! $skip_reflog_verify then - git -C "$repo" reflog --all >expect_logs && - git -C "$repo" reflog list >expect_log_list + print_all_reflog_entries "$repo" >expect_logs fi && git -C "$repo" refs migrate --ref-format="$format" "$@" && @@ -39,10 +49,8 @@ test_migration () { test_cmp expect actual && if ! $skip_reflog_verify then - git -C "$repo" reflog --all >actual_logs && - git -C "$repo" reflog list >actual_log_list && - test_cmp expect_logs actual_logs && - test_cmp expect_log_list actual_log_list + print_all_reflog_entries "$repo" >actual_logs && + test_cmp expect_logs actual_logs fi && git -C "$repo" rev-parse --show-ref-format >actual && @@ -273,7 +281,7 @@ test_expect_success 'multiple reftable blocks with multiple entries' ' test_commit -C repo second && printf "update refs/heads/ref-%d HEAD\n" $(test_seq 3000) >stdin && git -C repo update-ref --stdin <stdin && - test_migration repo reftable + test_migration repo reftable true ' test_expect_success 'migrating from files format deletes backend files' ' diff --git a/t/t1461-refs-list.sh b/t/t1461-refs-list.sh new file mode 100755 index 0000000000..36e3d81e59 --- /dev/null +++ b/t/t1461-refs-list.sh @@ -0,0 +1,8 @@ +#!/bin/sh + +test_description='git refs list tests' + +. ./test-lib.sh + +git_for_each_ref='git refs list' +. "$TEST_DIRECTORY"/for-each-ref-tests.sh diff --git a/t/t1517-outside-repo.sh b/t/t1517-outside-repo.sh index 8f59b867f2..c824c1a25c 100755 --- a/t/t1517-outside-repo.sh +++ b/t/t1517-outside-repo.sh @@ -107,18 +107,46 @@ test_expect_success LIBCURL 'remote-http outside repository' ' test_grep "^error: remote-curl" actual ' -test_expect_success 'update-server-info does not crash with -h' ' - test_expect_code 129 git update-server-info -h >usage && - test_grep "[Uu]sage: git update-server-info " usage && - test_expect_code 129 nongit git update-server-info -h >usage && - test_grep "[Uu]sage: git update-server-info " usage -' - -test_expect_success 'prune does not crash with -h' ' - test_expect_code 129 git prune -h >usage && - test_grep "[Uu]sage: git prune " usage && - test_expect_code 129 nongit git prune -h >usage && - test_grep "[Uu]sage: git prune " usage +for cmd in $(git --list-cmds=main) +do + cmd=${cmd%.*} # strip .sh, .perl, etc. + case "$cmd" in + archimport | citool | credential-netrc | credential-libsecret | \ + credential-osxkeychain | cvsexportcommit | cvsimport | cvsserver | \ + daemon | \ + difftool--helper | filter-branch | fsck-objects | get-tar-commit-id | \ + gui | gui--askpass | \ + http-backend | http-fetch | http-push | init-db | \ + merge-octopus | merge-one-file | merge-resolve | mergetool | \ + mktag | p4 | p4.py | pickaxe | remote-ftp | remote-ftps | \ + remote-http | remote-https | replay | send-email | \ + sh-i18n--envsubst | shell | show | stage | submodule | svn | \ + upload-archive--writer | upload-pack | web--browse | whatchanged) + expect_outcome=expect_failure ;; + *) + expect_outcome=expect_success ;; + esac + case "$cmd" in + instaweb) + prereq=PERL ;; + *) + prereq= ;; + esac + test_$expect_outcome $prereq "'git $cmd -h' outside a repository" ' + test_expect_code 129 nongit git $cmd -h >usage && + test_grep "[Uu]sage: git $cmd " usage + ' + test_$expect_outcome $prereq "'git $cmd --help-all' outside a repository" ' + test_expect_code 129 nongit git $cmd --help-all >usage && + test_grep "[Uu]sage: git $cmd " usage + ' +done + +test_expect_success 'fmt-merge-msg does not crash with -h' ' + test_expect_code 129 git fmt-merge-msg -h >usage && + test_grep "[Uu]sage: git fmt-merge-msg " usage && + test_expect_code 129 nongit git fmt-merge-msg -h >usage && + test_grep "[Uu]sage: git fmt-merge-msg " usage ' test_done diff --git a/t/t1900-repo.sh b/t/t1900-repo.sh new file mode 100755 index 0000000000..a69c715357 --- /dev/null +++ b/t/t1900-repo.sh @@ -0,0 +1,95 @@ +#!/bin/sh + +test_description='test git repo-info' + +. ./test-lib.sh + +# Test whether a key-value pair is correctly returned +# +# Usage: test_repo_info <label> <init command> <repo_name> <key> <expected value> +# +# Arguments: +# label: the label of the test +# init_command: a command which creates a repository +# repo_name: the name of the repository that will be created in init_command +# key: the key of the field that is being tested +# expected_value: the value that the field should contain +test_repo_info () { + label=$1 + init_command=$2 + repo_name=$3 + key=$4 + expected_value=$5 + + test_expect_success "setup: $label" ' + eval "$init_command $repo_name" + ' + + test_expect_success "keyvalue: $label" ' + echo "$key=$expected_value" > expect && + git -C "$repo_name" repo info "$key" >actual && + test_cmp expect actual + ' + + test_expect_success "nul: $label" ' + printf "%s\n%s\0" "$key" "$expected_value" >expect && + git -C "$repo_name" repo info --format=nul "$key" >actual && + test_cmp_bin expect actual + ' +} + +test_repo_info 'ref format files is retrieved correctly' \ + 'git init --ref-format=files' 'format-files' 'references.format' 'files' + +test_repo_info 'ref format reftable is retrieved correctly' \ + 'git init --ref-format=reftable' 'format-reftable' 'references.format' 'reftable' + +test_repo_info 'bare repository = false is retrieved correctly' \ + 'git init' 'nonbare' 'layout.bare' 'false' + +test_repo_info 'bare repository = true is retrieved correctly' \ + 'git init --bare' 'bare' 'layout.bare' 'true' + +test_repo_info 'shallow repository = false is retrieved correctly' \ + 'git init' 'nonshallow' 'layout.shallow' 'false' + +test_expect_success 'setup remote' ' + git init remote && + echo x >remote/x && + git -C remote add x && + git -C remote commit -m x +' + +test_repo_info 'shallow repository = true is retrieved correctly' \ + 'git clone --depth 1 "file://$PWD/remote"' 'shallow' 'layout.shallow' 'true' + +test_expect_success 'values returned in order requested' ' + cat >expect <<-\EOF && + layout.bare=false + references.format=files + layout.bare=false + EOF + git init --ref-format=files ordered && + git -C ordered repo info layout.bare references.format layout.bare >actual && + test_cmp expect actual +' + +test_expect_success 'git-repo-info fails if an invalid key is requested' ' + echo "error: key ${SQ}foo${SQ} not found" >expect && + test_must_fail git repo info foo 2>actual && + test_cmp expect actual +' + +test_expect_success 'git-repo-info outputs data even if there is an invalid field' ' + echo "references.format=$(test_detect_ref_format)" >expect && + test_must_fail git repo info foo references.format bar >actual && + test_cmp expect actual +' + +test_expect_success 'git-repo-info aborts when requesting an invalid format' ' + echo "fatal: invalid format ${SQ}foo${SQ}" >expect && + test_must_fail git repo info --format=foo 2>actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 6bac217ed3..34d6ad0770 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -2263,6 +2263,7 @@ test_expect_success 'non-merge commands reject merge commits' ' edit $oid fixup $oid squash $oid + drop $oid # acceptable, no advice EOF ( set_replace_editor todo && diff --git a/t/t3415-rebase-autosquash.sh b/t/t3415-rebase-autosquash.sh index 26b42a526a..5d093e3a7a 100755 --- a/t/t3415-rebase-autosquash.sh +++ b/t/t3415-rebase-autosquash.sh @@ -394,6 +394,16 @@ test_expect_success 'autosquash with empty custom instructionFormat' ' ) ' +test_expect_success 'autosquash with invalid custom instructionFormat' ' + git reset --hard base && + test_commit invalid-instructionFormat-test && + ( + test_must_fail git -c rebase.instructionFormat=blah \ + rebase --autosquash --force-rebase -i HEAD^ && + test_path_is_missing .git/rebase-merge + ) +' + set_backup_editor () { write_script backup-editor.sh <<-\EOF cp "$1" .git/backup-"$(basename "$1")" diff --git a/t/t3701-add-interactive.sh b/t/t3701-add-interactive.sh index b8a05d95f3..04d2a19835 100755 --- a/t/t3701-add-interactive.sh +++ b/t/t3701-add-interactive.sh @@ -63,7 +63,7 @@ test_expect_success 'setup (initial)' ' ' test_expect_success 'status works (initial)' ' git add -i </dev/null >output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'setup expected' ' @@ -86,7 +86,7 @@ test_expect_success 'revert works (initial)' ' git add file && test_write_lines r 1 | git add -i && git ls-files >output && - ! grep . output + test_grep ! . output ' test_expect_success 'add untracked (multiple)' ' @@ -109,7 +109,7 @@ test_expect_success 'setup (commit)' ' ' test_expect_success 'status works (commit)' ' git add -i </dev/null >output && - grep "+1/-0 *+2/-0 file" output + test_grep "+1/-0 *+2/-0 file" output ' test_expect_success 'update can stage deletions' ' @@ -141,7 +141,7 @@ test_expect_success 'revert works (commit)' ' git add file && test_write_lines r 1 | git add -i && git add -i </dev/null >output && - grep "unchanged *+3/-0 file" output + test_grep "unchanged *+3/-0 file" output ' test_expect_success 'reject multi-key input' ' @@ -185,7 +185,7 @@ test_expect_success 'setup fake editor' ' test_expect_success 'bad edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -198,7 +198,7 @@ test_expect_success 'setup patch' ' test_expect_success 'garbage edit rejected' ' git reset && test_write_lines e n d | git add -p >output && - grep "hunk does not apply" output + test_grep "hunk does not apply" output ' test_expect_success 'setup patch' ' @@ -313,8 +313,8 @@ test_expect_success FILEMODE 'stage mode and hunk' ' chmod +x file && printf "y\\ny\\n" | git add -p && git diff --cached file >out && - grep "new mode" out && - grep "+content" out && + test_grep "new mode" out && + test_grep "+content" out && git diff file >out && test_must_be_empty out ' @@ -636,7 +636,7 @@ test_expect_success 'split hunk "add -p (edit)"' ' printf "%s\n" s e q n q q | EDITOR=: git add -p && git diff >actual && - ! grep "^+15" actual + test_grep ! "^+15" actual ' test_expect_success 'split hunk "add -p (no, yes, edit)"' ' @@ -648,7 +648,7 @@ test_expect_success 'split hunk "add -p (no, yes, edit)"' ' EDITOR=: git add -p 2>error && test_must_be_empty error && git diff >actual && - ! grep "^+31" actual + test_grep ! "^+31" actual ' test_expect_success 'split hunk with incomplete line at end' ' @@ -682,7 +682,7 @@ test_expect_success 'edit, adding lines to the first hunk' ' EDITOR=./fake_editor.sh git add -p 2>error && test_must_be_empty error && git diff --cached >actual && - grep "^+22" actual + test_grep "^+22" actual ' test_expect_success 'patch mode ignores unmerged entries' ' @@ -696,7 +696,7 @@ test_expect_success 'patch mode ignores unmerged entries' ' test_must_fail git merge side && echo changed >non-conflict.t && echo y | git add -p >output && - ! grep a/conflict.t output && + test_grep ! a/conflict.t output && cat >expected <<-\EOF && * Unmerged path conflict.t diff --git a/non-conflict.t b/non-conflict.t @@ -728,7 +728,7 @@ test_expect_success 'diffs can be colorized' ' # We do not want to depend on the exact coloring scheme # git uses for diffs, so just check that we saw some kind of color. - grep "$(printf "\\033")" output + test_grep "$(printf "\\033")" output ' test_expect_success 'colors can be overridden' ' @@ -743,7 +743,7 @@ test_expect_success 'colors can be overridden' ' -c color.interactive.error=blue \ add -i 2>err.raw <input && test_decode_color <err.raw >err && - grep "<BLUE>Huh (trigger)?<RESET>" err && + test_grep "<BLUE>Huh (trigger)?<RESET>" err && test_write_lines help quit >input && force_color git \ @@ -863,7 +863,7 @@ test_expect_success 'colorized diffs respect diff.wsErrorHighlight' ' printf y >y && force_color git -c diff.wsErrorHighlight=all add -p >output.raw 2>&1 <y && test_decode_color <output.raw >output && - grep "old<" output + test_grep "old<" output ' test_expect_success 'diffFilter filters diff' ' @@ -876,7 +876,7 @@ test_expect_success 'diffFilter filters diff' ' # avoid depending on the exact coloring or content of the prompts, # and just make sure we saw our diff prefixed - grep foo:.*content output + test_grep foo:.*content output ' test_expect_success 'detect bogus diffFilter output' ' @@ -886,7 +886,7 @@ test_expect_success 'detect bogus diffFilter output' ' test_config interactive.diffFilter "sed 6d" && printf y >y && force_color test_must_fail git add -p <y >output 2>&1 && - grep "mismatched output" output + test_grep "mismatched output" output ' test_expect_success 'handle iffy colored hunk headers' ' @@ -896,7 +896,7 @@ test_expect_success 'handle iffy colored hunk headers' ' printf n >n && force_color git -c interactive.diffFilter="sed s/.*@@.*/XX/" \ add -p >output 2>&1 <n && - grep "^XX$" output + test_grep "^XX$" output ' test_expect_success 'handle very large filtered diff' ' @@ -1002,7 +1002,7 @@ test_expect_success 'add -p does not expand argument lists' ' # update it, but we want to be sure that our "." pathspec # was not expanded into the argument list of any command. # So look only for "not-changed". - ! grep -E "^trace: (built-in|exec|run_command): .*not-changed" trace.out + test_grep ! -E "^trace: (built-in|exec|run_command): .*not-changed" trace.out ' test_expect_success 'hunk-editing handles custom comment char' ' @@ -1072,21 +1072,21 @@ test_expect_success 'setup different kinds of dirty submodules' ' test_expect_success 'status ignores dirty submodules (except HEAD)' ' git -C for-submodules add -i </dev/null >output && - grep dirty-head output && - grep dirty-both-ways output && - ! grep dirty-otherwise output + test_grep dirty-head output && + test_grep dirty-both-ways output && + test_grep ! dirty-otherwise output ' test_expect_success 'handle submodules' ' echo 123 >>for-submodules/dirty-otherwise/initial.t && force_color git -C for-submodules add -p dirty-otherwise >output 2>&1 && - grep "No changes" output && + test_grep "No changes" output && force_color git -C for-submodules add -p dirty-head >output 2>&1 <y && git -C for-submodules ls-files --stage dirty-head >actual && rev="$(git -C for-submodules/dirty-head rev-parse HEAD)" && - grep "$rev" actual + test_grep "$rev" actual ' test_expect_success 'set up pathological context' ' @@ -1230,4 +1230,75 @@ test_expect_success 'hunk splitting works with diff.suppressBlankEmpty' ' test_cmp expect actual ' +test_expect_success 'add -p respects diff.context' ' + test_write_lines a b c d e f g h i j k l m >file && + git add file && + test_write_lines a b c d e f G h i j k l m >file && + echo y | git -c diff.context=5 add -p >actual && + test_grep "@@ -2,11 +2,11 @@" actual +' + +test_expect_success 'add -p respects diff.interHunkContext' ' + test_write_lines a b c d e f g h i j k l m n o p q r s >file && + git add file && + test_write_lines a b c d E f g i i j k l m N o p q r s >file && + echo y | git -c diff.interhunkcontext=2 add -p >actual && + test_grep "@@ -2,16 +2,16 @@" actual +' + +test_expect_success 'add -p rejects negative diff.context' ' + test_config diff.context -1 && + test_must_fail git add -p 2>output && + test_grep "diff.context cannot be negative" output +' + +for cmd in add checkout restore 'commit -m file' +do + test_expect_success "${cmd%% *} accepts -U and --inter-hunk-context" ' + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git add file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + $cmd -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual + ' +done + +test_expect_success 'reset accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git add file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + reset -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +test_expect_success 'stash accepts -U and --inter-hunk-context' ' + test_write_lines a b c d e F g h i j k l m n o p Q r s t u v >file && + git commit -m file file && + test_write_lines a b c d e f g h i j k l m n o p q r s t u v >file && + echo y | git -c diff.context=5 -c diff.interhunkcontext=1 \ + stash -p -U 4 --inter-hunk-context 2 >actual && + test_grep "@@ -2,20 +2,20 @@" actual +' + +for cmd in add checkout commit reset restore "stash save" "stash push" +do + test_expect_success "$cmd rejects invalid context options" ' + test_must_fail git $cmd -p -U -3 2>actual && + cat actual | echo && + test_grep -e ".--unified. cannot be negative" actual && + + test_must_fail git $cmd -p --inter-hunk-context -3 2>actual && + test_grep -e ".--inter-hunk-context. cannot be negative" actual && + + test_must_fail git $cmd -U 7 2>actual && + test_grep -E ".--unified. requires .(--interactive/)?--patch." actual && + + test_must_fail git $cmd --inter-hunk-context 2 2>actual && + test_grep -E ".--inter-hunk-context. requires .(--interactive/)?--patch." actual + ' +done + test_done diff --git a/t/t4013-diff-various.sh b/t/t4013-diff-various.sh index 8ebd170451..cfeec239e0 100755 --- a/t/t4013-diff-various.sh +++ b/t/t4013-diff-various.sh @@ -648,6 +648,19 @@ test_expect_success 'diff -I<regex>: detect malformed regex' ' test_grep "invalid regex given to -I: " error ' +test_expect_success 'diff -I<regex>: ignore matching file' ' + test_when_finished "git rm -f file1" && + test_seq 50 >file1 && + git add file1 && + test_seq 50 | sed -e "s/13/ten and three/" -e "s/^[124-9].*/& /" >file1 && + + : >actual && + git diff --raw --ignore-blank-lines -I"ten.*e" -I"^[124-9]" >>actual && + git diff --name-only --ignore-blank-lines -I"ten.*e" -I"^[124-9]" >>actual && + git diff --name-status --ignore-blank-lines -I"ten.*e" -I"^[124-9]" >>actual && + test_grep ! "file1" actual +' + # check_prefix <patch> <src> <dst> # check only lines with paths to avoid dependency on exact oid/contents check_prefix () { diff --git a/t/t4015-diff-whitespace.sh b/t/t4015-diff-whitespace.sh index 52e3e476ff..9de7f73f42 100755 --- a/t/t4015-diff-whitespace.sh +++ b/t/t4015-diff-whitespace.sh @@ -11,12 +11,8 @@ test_description='Test special whitespace in diff engine. . "$TEST_DIRECTORY"/lib-diff.sh for opt_res in --patch --quiet -s --stat --shortstat --dirstat=lines \ - --raw! --name-only! --name-status! + --raw --name-only --name-status do - opts=${opt_res%!} expect_failure= - test "$opts" = "$opt_res" || - expect_failure="test_expect_code 1" - test_expect_success "status with $opts (different)" ' echo foo >x && git add x && @@ -43,7 +39,7 @@ do echo foo >x && git add x && echo " foo" >x && - $expect_failure git diff -w $opts --exit-code x + git diff -w $opts --exit-code x ' done diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 01db9243ab..44b4b13f5d 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -26,6 +26,23 @@ test_expect_success 'git diff --no-index directories' ' test_line_count = 14 cnt ' +test_expect_success 'git diff --no-index with -' ' + cat >expect <<-\EOF && + diff --git a/- b/- + new file mode 100644 + --- /dev/null + +++ b/- + @@ -0,0 +1 @@ + +frotz + EOF + ( + cd a && + echo frotz | + test_expect_code 1 git diff --no-index /dev/null - >../actual + ) && + test_cmp expect actual +' + test_expect_success 'git diff --no-index relative path outside repo' ' ( cd repo && diff --git a/t/t4055-diff-context.sh b/t/t4055-diff-context.sh index ec2804eea6..1384a81957 100755 --- a/t/t4055-diff-context.sh +++ b/t/t4055-diff-context.sh @@ -38,55 +38,55 @@ test_expect_success 'setup' ' test_expect_success 'the default number of context lines is 3' ' git diff >output && - ! grep "^ d" output && - grep "^ e" output && - grep "^ j" output && - ! grep "^ k" output + test_grep ! "^ d" output && + test_grep "^ e" output && + test_grep "^ j" output && + test_grep ! "^ k" output ' test_expect_success 'diff.context honored by "log"' ' git log -1 -p >output && - ! grep firstline output && - git config diff.context 8 && + test_grep ! firstline output && + test_config diff.context 8 && git log -1 -p >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'The -U option overrides diff.context' ' - git config diff.context 8 && + test_config diff.context 8 && git log -U4 -1 >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'diff.context honored by "diff"' ' - git config diff.context 8 && + test_config diff.context 8 && git diff >output && - grep "^ firstline" output + test_grep "^ firstline" output ' test_expect_success 'plumbing not affected' ' - git config diff.context 8 && + test_config diff.context 8 && git diff-files -p >output && - ! grep "^ firstline" output + test_grep ! "^ firstline" output ' test_expect_success 'non-integer config parsing' ' - git config diff.context no && + test_config diff.context no && test_must_fail git diff 2>output && test_grep "bad numeric config value" output ' test_expect_success 'negative integer config parsing' ' - git config diff.context -1 && + test_config diff.context -1 && test_must_fail git diff 2>output && test_grep "bad config variable" output ' test_expect_success '-U0 is valid, so is diff.context=0' ' - git config diff.context 0 && + test_config diff.context 0 && git diff >output && - grep "^-ADDED" output && - grep "^+MODIFIED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output ' test_expect_success '-U2147483647 works' ' @@ -94,9 +94,9 @@ test_expect_success '-U2147483647 works' ' test_line_count = 16 x && git diff -U2147483647 >output && test_line_count = 22 output && - grep "^-ADDED" output && - grep "^+MODIFIED" output && - grep "^+APPENDED" output + test_grep "^-ADDED" output && + test_grep "^+MODIFIED" output && + test_grep "^+APPENDED" output ' test_done diff --git a/t/t4072-diff-max-depth.sh b/t/t4072-diff-max-depth.sh new file mode 100755 index 0000000000..0fbf1321f7 --- /dev/null +++ b/t/t4072-diff-max-depth.sh @@ -0,0 +1,116 @@ +#!/bin/sh + +test_description='check that diff --max-depth will limit recursion' +. ./test-lib.sh + +make_dir() { + mkdir -p "$1" && + echo "$2" >"$1/file" +} + +make_files() { + echo "$1" >file && + make_dir one "$1" && + make_dir one/two "$1" && + make_dir one/two/three "$1" +} + +test_expect_success 'setup' ' + git commit --allow-empty -m empty && + git tag empty && + make_files added && + git add . && + git commit -m added && + make_files modified && + git add . && + git commit -m modified && + make_files index && + git add . && + make_files worktree +' + +test_expect_success '--max-depth is disallowed with wildcard pathspecs' ' + test_must_fail git diff-tree --max-depth=0 HEAD^ HEAD -- "f*" +' + +check_one() { + type=$1; shift + args=$1; shift + path=$1; shift + depth=$1; shift + test_expect_${expect:-success} "diff-$type $args, path=$path, depth=$depth" " + for i in $*; do echo \$i; done >expect && + git diff-$type --max-depth=$depth --name-only $args -- $path >actual && + test_cmp expect actual + " +} + +# For tree comparisons, we expect to see subtrees at the boundary +# get their own entry. +check_trees() { + check_one tree "$*" '' 0 file one + check_one tree "$*" '' 1 file one/file one/two + check_one tree "$*" '' 2 file one/file one/two/file one/two/three + check_one tree "$*" '' 3 file one/file one/two/file one/two/three/file + check_one tree "$*" '' -1 file one/file one/two/file one/two/three/file + check_one tree "$*" one 0 one + check_one tree "$*" one 1 one/file one/two + check_one tree "$*" one 2 one/file one/two/file one/two/three + check_one tree "$*" one 3 one/file one/two/file one/two/three/file + check_one tree "$*" one/two 0 one/two + check_one tree "$*" one/two 1 one/two/file one/two/three + check_one tree "$*" one/two 2 one/two/file one/two/three/file + check_one tree "$*" one/two 2 one/two/file one/two/three/file + check_one tree "$*" one/two/three 0 one/two/three + check_one tree "$*" one/two/three 1 one/two/three/file +} + +# But for index comparisons, we do not store subtrees at all, so we do not +# expect them. +check_index() { + check_one "$@" '' 0 file + check_one "$@" '' 1 file one/file + check_one "$@" '' 2 file one/file one/two/file + check_one "$@" '' 3 file one/file one/two/file one/two/three/file + check_one "$@" one 0 + check_one "$@" one 1 one/file + check_one "$@" one 2 one/file one/two/file + check_one "$@" one 3 one/file one/two/file one/two/three/file + check_one "$@" one/two 0 + check_one "$@" one/two 1 one/two/file + check_one "$@" one/two 2 one/two/file one/two/three/file + check_one "$@" one/two/three 0 + check_one "$@" one/two/three 1 one/two/three/file + + # Value '-1' for '--max-depth is the same as recursion without limit, + # and thus should always succeed. + local expect= + check_one "$@" '' -1 file one/file one/two/file one/two/three/file +} + +# Check as a modification... +check_trees HEAD^ HEAD +# ...and as an addition... +check_trees empty HEAD +# ...and as a deletion. +check_trees HEAD empty + +# We currently only implement max-depth for trees. +expect=failure +# Check index against a tree +check_index index "--cached HEAD" +# and index against the worktree +check_index files "" +expect= + +test_expect_success 'find shortest path within embedded pathspecs' ' + cat >expect <<-\EOF && + one/file + one/two/file + one/two/three/file + EOF + git diff-tree --max-depth=2 --name-only HEAD^ HEAD -- one one/two >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t4216-log-bloom.sh b/t/t4216-log-bloom.sh index 639868ac56..1064990de3 100755 --- a/t/t4216-log-bloom.sh +++ b/t/t4216-log-bloom.sh @@ -154,11 +154,34 @@ test_expect_success 'git log with multiple literal paths uses Bloom filter' ' test_bloom_filters_used "-- file*" ' -test_expect_success 'git log with path contains a wildcard does not use Bloom filter' ' +test_expect_success 'git log with paths all contain non-wildcard part uses Bloom filter' ' + test_bloom_filters_used "-- A/\* file4" && + test_bloom_filters_used "-- A/file\*" && + test_bloom_filters_used "-- * A/\*" +' + +test_expect_success 'git log with path only contains wildcard part does not use Bloom filter' ' test_bloom_filters_not_used "-- file\*" && - test_bloom_filters_not_used "-- A/\* file4" && - test_bloom_filters_not_used "-- file4 A/\*" && - test_bloom_filters_not_used "-- * A/\*" + test_bloom_filters_not_used "-- file\* A/\*" && + test_bloom_filters_not_used "-- file\* *" && + test_bloom_filters_not_used "-- \*" +' + +test_expect_success 'git log with path contains various magic signatures' ' + cd A && + test_bloom_filters_used "-- \:\(top\)B" && + cd .. && + + test_bloom_filters_used "-- \:\(glob\)A/\*\*/C" && + test_bloom_filters_not_used "-- \:\(icase\)FILE4" && + test_bloom_filters_not_used "-- \:\(exclude\)A/B/C" && + + test_when_finished "rm -f .gitattributes" && + cat >.gitattributes <<-EOF && + A/file1 text + A/B/file2 -text + EOF + test_bloom_filters_used "-- \:\(attr\:text\)A" ' test_expect_success 'setup - add commit-graph to the chain without Bloom filters' ' diff --git a/t/t4256/1/mailinfo.c b/t/t4256/1/mailinfo.c index b395adbdf2..39caeba865 100644 --- a/t/t4256/1/mailinfo.c +++ b/t/t4256/1/mailinfo.c @@ -1214,7 +1214,7 @@ void setup_mailinfo(struct mailinfo *mi) mi->header_stage = 1; mi->use_inbody_headers = 1; mi->content_top = mi->content; - git_config(git_mailinfo_config, mi); + repo_config(the_repository, git_mailinfo_config, mi); } void clear_mailinfo(struct mailinfo *mi) diff --git a/t/t4256/1/mailinfo.c.orig b/t/t4256/1/mailinfo.c.orig index 3281a37d51..b76eb866aa 100644 --- a/t/t4256/1/mailinfo.c.orig +++ b/t/t4256/1/mailinfo.c.orig @@ -1154,7 +1154,7 @@ void setup_mailinfo(struct mailinfo *mi) mi->header_stage = 1; mi->use_inbody_headers = 1; mi->content_top = mi->content; - git_config(git_mailinfo_config, mi); + repo_config(the_repository, git_mailinfo_config, mi); } void clear_mailinfo(struct mailinfo *mi) diff --git a/t/t5200-update-server-info.sh b/t/t5200-update-server-info.sh index 8365907055..a551e955b5 100755 --- a/t/t5200-update-server-info.sh +++ b/t/t5200-update-server-info.sh @@ -46,4 +46,9 @@ test_expect_success 'midx does not create duplicate pack entries' ' test_must_be_empty dups ' +test_expect_success 'update-server-info does not crash with -h' ' + test_expect_code 129 git update-server-info -h >usage && + test_grep "[Uu]sage: git update-server-info " usage +' + test_done diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 1f1f664871..2be7cd30de 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -364,4 +364,9 @@ test_expect_success 'gc.recentObjectsHook' ' git cat-file -p $BLOB ' +test_expect_success 'prune does not crash with -h' ' + test_expect_code 129 git prune -h >usage && + test_grep "[Uu]sage: git prune " usage +' + test_done diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index 2701eef85e..e592c0bcde 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -1658,4 +1658,77 @@ test_expect_success 'forbid adding superset of existing remote' ' test_grep ".outer. is a superset of existing remote .outer/inner." err ' +test_expect_success 'rename handles unborn HEAD' ' + test_when_finished "git remote remove unborn-renamed" && + git remote add unborn url && + git symbolic-ref refs/remotes/unborn/HEAD refs/remotes/unborn/nonexistent && + git remote rename unborn unborn-renamed && + git symbolic-ref refs/remotes/unborn-renamed/HEAD >actual && + echo refs/remotes/unborn-renamed/nonexistent >expected && + test_cmp expected actual +' + +test_expect_success 'rename can nest a remote into itself' ' + test_commit parent-commit && + COMMIT_ID=$(git rev-parse HEAD) && + test_when_finished "git remote remove parent || true" && + git remote add parent url && + git update-ref refs/remotes/parent/branch $COMMIT_ID && + test_when_finished "git remote remove parent/child" && + git remote rename parent parent/child && + git for-each-ref refs/remotes/ >actual && + printf "$COMMIT_ID commit\trefs/remotes/parent/child/branch\n" >expected && + test_cmp expected actual +' + +test_expect_success 'rename can nest a remote into itself with a conflicting branch name' ' + test_commit parent-conflict && + COMMIT_ID=$(git rev-parse HEAD) && + test_when_finished "git remote remove parent || true" && + git remote add parent url && + git update-ref refs/remotes/parent/child $COMMIT_ID && + test_when_finished "git remote remove parent/child" && + test_must_fail git remote rename parent parent/child 2>err && + test_grep "renaming remote references failed" err && + test_grep "The remote you are trying to rename has conflicting references" err && + git for-each-ref refs/remotes/ >actual && + printf "$COMMIT_ID commit\trefs/remotes/parent/child\n" >expected && + test_cmp expected actual +' + +test_expect_success 'rename can unnest a remote' ' + test_commit parent-child-commit && + COMMIT_ID=$(git rev-parse HEAD) && + test_when_finished "git remote remove parent/child || true" && + git remote add parent/child url && + git update-ref refs/remotes/parent/child/branch $COMMIT_ID && + git remote rename parent/child parent && + git for-each-ref refs/remotes/ >actual && + printf "$COMMIT_ID commit\trefs/remotes/parent/branch\n" >expected && + test_cmp expected actual +' + +test_expect_success 'rename moves around the reflog' ' + test_commit reflog-old && + COMMIT_ID=$(git rev-parse HEAD) && + test_config core.logAllRefUpdates true && + test_when_finished "git remote remove reflog-old || true" && + git remote add reflog-old url && + git update-ref refs/remotes/reflog-old/branch $COMMIT_ID && + test-tool ref-store main for-each-reflog >actual && + test_grep refs/remotes/reflog-old/branch actual && + test-tool ref-store main for-each-reflog-ent refs/remotes/reflog-old/branch >reflog-entries-old && + test_line_count = 1 reflog-entries-old && + git remote rename reflog-old reflog-new && + test-tool ref-store main for-each-reflog >actual && + test_grep ! refs/remotes/reflog-old actual && + test_grep refs/remotes/reflog-new/branch actual && + test-tool ref-store main for-each-reflog-ent refs/remotes/reflog-new/branch >reflog-entries-new && + cat >expect <<-EOF && + $(cat reflog-entries-old) + $COMMIT_ID $COMMIT_ID $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> 1112912173 -0700 remote: renamed refs/remotes/reflog-old/branch to refs/remotes/reflog-new/branch + EOF + test_cmp expect reflog-entries-new +' + test_done diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index ebc696546b..83d1aadf9f 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -14,8 +14,6 @@ then test_done fi -D=$(pwd) - test_expect_success setup ' echo >file original && git add file && @@ -51,46 +49,50 @@ test_expect_success "clone and setup child repos" ' ' test_expect_success "fetch test" ' - cd "$D" && echo >file updated by origin && git commit -a -m "updated by origin" && - cd two && - git fetch && - git rev-parse --verify refs/heads/one && - mine=$(git rev-parse refs/heads/one) && - his=$(cd ../one && git rev-parse refs/heads/main) && - test "z$mine" = "z$his" + ( + cd two && + git fetch && + git rev-parse --verify refs/heads/one && + mine=$(git rev-parse refs/heads/one) && + his=$(cd ../one && git rev-parse refs/heads/main) && + test "z$mine" = "z$his" + ) ' test_expect_success "fetch test for-merge" ' - cd "$D" && - cd three && - git fetch && - git rev-parse --verify refs/heads/two && - git rev-parse --verify refs/heads/one && - main_in_two=$(cd ../two && git rev-parse main) && - one_in_two=$(cd ../two && git rev-parse one) && - { - echo "$one_in_two " && - echo "$main_in_two not-for-merge" - } >expected && - cut -f -2 .git/FETCH_HEAD >actual && - test_cmp expected actual' + ( + cd three && + git fetch && + git rev-parse --verify refs/heads/two && + git rev-parse --verify refs/heads/one && + main_in_two=$(cd ../two && git rev-parse main) && + one_in_two=$(cd ../two && git rev-parse one) && + { + echo "$one_in_two " && + echo "$main_in_two not-for-merge" + } >expected && + cut -f -2 .git/FETCH_HEAD >actual && + test_cmp expected actual + ) +' test_expect_success "fetch test remote HEAD" ' - cd "$D" && - cd two && - git fetch && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/main) && - test "z$head" = "z$branch"' + ( + cd two && + git fetch && + git rev-parse --verify refs/remotes/origin/HEAD && + git rev-parse --verify refs/remotes/origin/main && + head=$(git rev-parse refs/remotes/origin/HEAD) && + branch=$(git rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" + ) +' test_expect_success "fetch test remote HEAD in bare repository" ' test_when_finished rm -rf barerepo && ( - cd "$D" && git init --bare barerepo && cd barerepo && git remote add upstream ../two && @@ -105,262 +107,235 @@ test_expect_success "fetch test remote HEAD in bare repository" ' test_expect_success "fetch test remote HEAD change" ' - cd "$D" && - cd two && - git switch -c other && - git push -u origin other && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && - git fetch && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/other) && - test "z$head" = "z$branch"' - -test_expect_success "fetch test followRemoteHEAD never" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git update-ref --no-deref -d refs/remotes/origin/HEAD && - git config set remote.origin.followRemoteHEAD "never" && - GIT_TRACE_PACKET=$PWD/trace.out git fetch && - # Confirm that we do not even ask for HEAD when we are - # not going to act on it. - test_grep ! "ref-prefix HEAD" trace.out && - test_must_fail git rev-parse --verify refs/remotes/origin/HEAD - ) -' - -test_expect_success "fetch test followRemoteHEAD warn no change" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && ( - cd "$D" && cd two && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && + git switch -c other && + git push -u origin other && git rev-parse --verify refs/remotes/origin/HEAD && git rev-parse --verify refs/remotes/origin/main && - git config set remote.origin.followRemoteHEAD "warn" && - git fetch >output && - echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ - "but we have ${SQ}other${SQ} locally." >expect && - test_cmp expect output && + git rev-parse --verify refs/remotes/origin/other && + git remote set-head origin other && + git fetch && head=$(git rev-parse refs/remotes/origin/HEAD) && branch=$(git rev-parse refs/remotes/origin/other) && test "z$head" = "z$branch" ) ' +test_expect_success "fetch test followRemoteHEAD never" ' + git -C two update-ref --no-deref -d refs/remotes/origin/HEAD && + test_config -C two remote.origin.followRemoteHEAD "never" && + GIT_TRACE_PACKET=$PWD/trace.out git -C two fetch && + # Confirm that we do not even ask for HEAD when we are + # not going to act on it. + test_grep ! "ref-prefix HEAD" trace.out && + test_must_fail git -C two rev-parse --verify refs/remotes/origin/HEAD +' + +test_expect_success "fetch test followRemoteHEAD warn no change" ' + git -C two rev-parse --verify refs/remotes/origin/other && + git -C two remote set-head origin other && + git -C two rev-parse --verify refs/remotes/origin/HEAD && + git -C two rev-parse --verify refs/remotes/origin/main && + test_config -C two remote.origin.followRemoteHEAD "warn" && + git -C two fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect output && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" +' + test_expect_success "fetch test followRemoteHEAD warn create" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git update-ref --no-deref -d refs/remotes/origin/HEAD && - git config set remote.origin.followRemoteHEAD "warn" && - git rev-parse --verify refs/remotes/origin/main && - output=$(git fetch) && - test "z" = "z$output" && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/main) && - test "z$head" = "z$branch" - ) + git -C two update-ref --no-deref -d refs/remotes/origin/HEAD && + test_config -C two remote.origin.followRemoteHEAD "warn" && + git -C two rev-parse --verify refs/remotes/origin/main && + output=$(git -C two fetch) && + test "z" = "z$output" && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" ' test_expect_success "fetch test followRemoteHEAD warn detached" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git update-ref --no-deref -d refs/remotes/origin/HEAD && - git update-ref refs/remotes/origin/HEAD HEAD && - HEAD=$(git log --pretty="%H") && - git config set remote.origin.followRemoteHEAD "warn" && - git fetch >output && - echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ - "but we have a detached HEAD pointing to" \ - "${SQ}${HEAD}${SQ} locally." >expect && - test_cmp expect output - ) + git -C two update-ref --no-deref -d refs/remotes/origin/HEAD && + git -C two update-ref refs/remotes/origin/HEAD HEAD && + HEAD=$(git -C two log --pretty="%H") && + test_config -C two remote.origin.followRemoteHEAD "warn" && + git -C two fetch >output && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have a detached HEAD pointing to" \ + "${SQ}${HEAD}${SQ} locally." >expect && + test_cmp expect output ' test_expect_success "fetch test followRemoteHEAD warn quiet" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - git config set remote.origin.followRemoteHEAD "warn" && - output=$(git fetch --quiet) && - test "z" = "z$output" && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/other) && - test "z$head" = "z$branch" - ) + git -C two rev-parse --verify refs/remotes/origin/other && + git -C two remote set-head origin other && + git -C two rev-parse --verify refs/remotes/origin/HEAD && + git -C two rev-parse --verify refs/remotes/origin/main && + test_config -C two remote.origin.followRemoteHEAD "warn" && + output=$(git -C two fetch --quiet) && + test "z" = "z$output" && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" ' test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is same" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - git config set remote.origin.followRemoteHEAD "warn-if-not-main" && - actual=$(git fetch) && - test "z" = "z$actual" && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/other) && - test "z$head" = "z$branch" - ) + git -C two rev-parse --verify refs/remotes/origin/other && + git -C two remote set-head origin other && + git -C two rev-parse --verify refs/remotes/origin/HEAD && + git -C two rev-parse --verify refs/remotes/origin/main && + test_config -C two remote.origin.followRemoteHEAD "warn-if-not-main" && + actual=$(git -C two fetch) && + test "z" = "z$actual" && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" ' test_expect_success "fetch test followRemoteHEAD warn-if-not-branch branch is different" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - git config set remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" && - git fetch >actual && - echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ - "but we have ${SQ}other${SQ} locally." >expect && - test_cmp expect actual && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/other) && - test "z$head" = "z$branch" - ) + git -C two rev-parse --verify refs/remotes/origin/other && + git -C two remote set-head origin other && + git -C two rev-parse --verify refs/remotes/origin/HEAD && + git -C two rev-parse --verify refs/remotes/origin/main && + test_config -C two remote.origin.followRemoteHEAD "warn-if-not-some/different-branch" && + git -C two fetch >actual && + echo "${SQ}HEAD${SQ} at ${SQ}origin${SQ} is ${SQ}main${SQ}," \ + "but we have ${SQ}other${SQ} locally." >expect && + test_cmp expect actual && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/other) && + test "z$head" = "z$branch" ' test_expect_success "fetch test followRemoteHEAD always" ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git rev-parse --verify refs/remotes/origin/other && - git remote set-head origin other && - git rev-parse --verify refs/remotes/origin/HEAD && - git rev-parse --verify refs/remotes/origin/main && - git config set remote.origin.followRemoteHEAD "always" && - git fetch && - head=$(git rev-parse refs/remotes/origin/HEAD) && - branch=$(git rev-parse refs/remotes/origin/main) && - test "z$head" = "z$branch" - ) + git -C two rev-parse --verify refs/remotes/origin/other && + git -C two remote set-head origin other && + git -C two rev-parse --verify refs/remotes/origin/HEAD && + git -C two rev-parse --verify refs/remotes/origin/main && + test_config -C two remote.origin.followRemoteHEAD "always" && + git -C two fetch && + head=$(git -C two rev-parse refs/remotes/origin/HEAD) && + branch=$(git -C two rev-parse refs/remotes/origin/main) && + test "z$head" = "z$branch" ' test_expect_success 'followRemoteHEAD does not kick in with refspecs' ' - test_when_finished "git config unset remote.origin.followRemoteHEAD" && - ( - cd "$D" && - cd two && - git remote set-head origin other && - git config set remote.origin.followRemoteHEAD always && - git fetch origin refs/heads/main:refs/remotes/origin/main && - echo refs/remotes/origin/other >expect && - git symbolic-ref refs/remotes/origin/HEAD >actual && - test_cmp expect actual - ) + git -C two remote set-head origin other && + test_config -C two remote.origin.followRemoteHEAD always && + git -C two fetch origin refs/heads/main:refs/remotes/origin/main && + echo refs/remotes/origin/other >expect && + git -C two symbolic-ref refs/remotes/origin/HEAD >actual && + test_cmp expect actual +' + +test_expect_success 'followRemoteHEAD create does not overwrite dangling symref' ' + git -C two remote add -m does-not-exist custom-head ../one && + test_config -C two remote.custom-head.followRemoteHEAD create && + git -C two fetch custom-head && + echo refs/remotes/custom-head/does-not-exist >expect && + git -C two symbolic-ref refs/remotes/custom-head/HEAD >actual && + test_cmp expect actual ' test_expect_success 'fetch --prune on its own works as expected' ' - cd "$D" && git clone . prune && - cd prune && - git update-ref refs/remotes/origin/extrabranch main && + ( + cd prune && + git update-ref refs/remotes/origin/extrabranch main && - git fetch --prune origin && - test_must_fail git rev-parse origin/extrabranch + git fetch --prune origin && + test_must_fail git rev-parse origin/extrabranch + ) ' test_expect_success 'fetch --prune with a branch name keeps branches' ' - cd "$D" && git clone . prune-branch && - cd prune-branch && - git update-ref refs/remotes/origin/extrabranch main && + ( + cd prune-branch && + git update-ref refs/remotes/origin/extrabranch main && - git fetch --prune origin main && - git rev-parse origin/extrabranch + git fetch --prune origin main && + git rev-parse origin/extrabranch + ) ' test_expect_success 'fetch --prune with a namespace keeps other namespaces' ' - cd "$D" && git clone . prune-namespace && - cd prune-namespace && + ( + cd prune-namespace && - git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* && - git rev-parse origin/main + git fetch --prune origin refs/heads/a/*:refs/remotes/origin/a/* && + git rev-parse origin/main + ) ' test_expect_success 'fetch --prune handles overlapping refspecs' ' - cd "$D" && git update-ref refs/pull/42/head main && git clone . prune-overlapping && - cd prune-overlapping && - git config --add remote.origin.fetch refs/pull/*/head:refs/remotes/origin/pr/* && + ( + cd prune-overlapping && + git config --add remote.origin.fetch refs/pull/*/head:refs/remotes/origin/pr/* && - git fetch --prune origin && - git rev-parse origin/main && - git rev-parse origin/pr/42 && + git fetch --prune origin && + git rev-parse origin/main && + git rev-parse origin/pr/42 && - git config --unset-all remote.origin.fetch && - git config remote.origin.fetch refs/pull/*/head:refs/remotes/origin/pr/* && - git config --add remote.origin.fetch refs/heads/*:refs/remotes/origin/* && + git config --unset-all remote.origin.fetch && + git config remote.origin.fetch refs/pull/*/head:refs/remotes/origin/pr/* && + git config --add remote.origin.fetch refs/heads/*:refs/remotes/origin/* && - git fetch --prune origin && - git rev-parse origin/main && - git rev-parse origin/pr/42 + git fetch --prune origin && + git rev-parse origin/main && + git rev-parse origin/pr/42 + ) ' test_expect_success 'fetch --prune --tags prunes branches but not tags' ' - cd "$D" && git clone . prune-tags && - cd prune-tags && - git tag sometag main && - # Create what looks like a remote-tracking branch from an earlier - # fetch that has since been deleted from the remote: - git update-ref refs/remotes/origin/fake-remote main && - - git fetch --prune --tags origin && - git rev-parse origin/main && - test_must_fail git rev-parse origin/fake-remote && - git rev-parse sometag + ( + cd prune-tags && + git tag sometag main && + # Create what looks like a remote-tracking branch from an earlier + # fetch that has since been deleted from the remote: + git update-ref refs/remotes/origin/fake-remote main && + + git fetch --prune --tags origin && + git rev-parse origin/main && + test_must_fail git rev-parse origin/fake-remote && + git rev-parse sometag + ) ' test_expect_success 'fetch --prune --tags with branch does not prune other things' ' - cd "$D" && git clone . prune-tags-branch && - cd prune-tags-branch && - git tag sometag main && - git update-ref refs/remotes/origin/extrabranch main && + ( + cd prune-tags-branch && + git tag sometag main && + git update-ref refs/remotes/origin/extrabranch main && - git fetch --prune --tags origin main && - git rev-parse origin/extrabranch && - git rev-parse sometag + git fetch --prune --tags origin main && + git rev-parse origin/extrabranch && + git rev-parse sometag + ) ' test_expect_success 'fetch --prune --tags with refspec prunes based on refspec' ' - cd "$D" && git clone . prune-tags-refspec && - cd prune-tags-refspec && - git tag sometag main && - git update-ref refs/remotes/origin/foo/otherbranch main && - git update-ref refs/remotes/origin/extrabranch main && - - git fetch --prune --tags origin refs/heads/foo/*:refs/remotes/origin/foo/* && - test_must_fail git rev-parse refs/remotes/origin/foo/otherbranch && - git rev-parse origin/extrabranch && - git rev-parse sometag + ( + cd prune-tags-refspec && + git tag sometag main && + git update-ref refs/remotes/origin/foo/otherbranch main && + git update-ref refs/remotes/origin/extrabranch main && + + git fetch --prune --tags origin refs/heads/foo/*:refs/remotes/origin/foo/* && + test_must_fail git rev-parse refs/remotes/origin/foo/otherbranch && + git rev-parse origin/extrabranch && + git rev-parse sometag + ) ' test_expect_success 'fetch --tags gets tags even without a configured remote' ' @@ -381,21 +356,21 @@ test_expect_success 'fetch --tags gets tags even without a configured remote' ' ' test_expect_success REFFILES 'fetch --prune fails to delete branches' ' - cd "$D" && git clone . prune-fail && - cd prune-fail && - git update-ref refs/remotes/origin/extrabranch main && - git pack-refs --all && - : this will prevent --prune from locking packed-refs for deleting refs, but adding loose refs still succeeds && - >.git/packed-refs.new && + ( + cd prune-fail && + git update-ref refs/remotes/origin/extrabranch main && + git pack-refs --all && + : this will prevent --prune from locking packed-refs for deleting refs, but adding loose refs still succeeds && + >.git/packed-refs.new && - test_must_fail git fetch --prune origin + test_must_fail git fetch --prune origin + ) ' test_expect_success 'fetch --atomic works with a single branch' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && git branch atomic-branch && oid=$(git rev-parse atomic-branch) && @@ -408,9 +383,8 @@ test_expect_success 'fetch --atomic works with a single branch' ' ' test_expect_success 'fetch --atomic works with multiple branches' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && git branch atomic-branch-1 && git branch atomic-branch-2 && @@ -423,9 +397,8 @@ test_expect_success 'fetch --atomic works with multiple branches' ' ' test_expect_success 'fetch --atomic works with mixed branches and tags' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && git branch atomic-mixed-branch && git tag atomic-mixed-tag && @@ -437,9 +410,8 @@ test_expect_success 'fetch --atomic works with mixed branches and tags' ' ' test_expect_success 'fetch --atomic prunes references' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git branch atomic-prune-delete && git clone . atomic && git branch --delete atomic-prune-delete && @@ -453,9 +425,8 @@ test_expect_success 'fetch --atomic prunes references' ' ' test_expect_success 'fetch --atomic aborts with non-fast-forward update' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git branch atomic-non-ff && git clone . atomic && git rev-parse HEAD >actual && @@ -472,9 +443,8 @@ test_expect_success 'fetch --atomic aborts with non-fast-forward update' ' ' test_expect_success 'fetch --atomic executes a single reference transaction only' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && git branch atomic-hooks-1 && git branch atomic-hooks-2 && @@ -499,9 +469,8 @@ test_expect_success 'fetch --atomic executes a single reference transaction only ' test_expect_success 'fetch --atomic aborts all reference updates if hook aborts' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && git branch atomic-hooks-abort-1 && git branch atomic-hooks-abort-2 && @@ -536,9 +505,8 @@ test_expect_success 'fetch --atomic aborts all reference updates if hook aborts' ' test_expect_success 'fetch --atomic --append appends to FETCH_HEAD' ' - test_when_finished "rm -rf \"$D\"/atomic" && + test_when_finished "rm -rf atomic" && - cd "$D" && git clone . atomic && oid=$(git rev-parse HEAD) && @@ -574,8 +542,7 @@ test_expect_success REFFILES 'fetch --atomic fails transaction if reference lock ' test_expect_success '--refmap="" ignores configured refspec' ' - cd "$TRASH_DIRECTORY" && - git clone "$D" remote-refs && + git clone . remote-refs && git -C remote-refs rev-parse remotes/origin/main >old && git -C remote-refs update-ref refs/remotes/origin/main main~1 && git -C remote-refs rev-parse remotes/origin/main >new && @@ -599,34 +566,26 @@ test_expect_success '--refmap="" and --prune' ' test_expect_success 'fetch tags when there is no tags' ' - cd "$D" && - - mkdir notags && - cd notags && - git init && - - git fetch -t .. + git init notags && + git -C notags fetch -t .. ' test_expect_success 'fetch following tags' ' - cd "$D" && git tag -a -m "annotated" anno HEAD && git tag light HEAD && - mkdir four && - cd four && - git init && - - git fetch .. :track && - git show-ref --verify refs/tags/anno && - git show-ref --verify refs/tags/light - + git init four && + ( + cd four && + git fetch .. :track && + git show-ref --verify refs/tags/anno && + git show-ref --verify refs/tags/light + ) ' test_expect_success 'fetch uses remote ref names to describe new refs' ' - cd "$D" && git init descriptive && ( cd descriptive && @@ -654,30 +613,20 @@ test_expect_success 'fetch uses remote ref names to describe new refs' ' test_expect_success 'fetch must not resolve short tag name' ' - cd "$D" && - - mkdir five && - cd five && - git init && - - test_must_fail git fetch .. anno:five + git init five && + test_must_fail git -C five fetch .. anno:five ' test_expect_success 'fetch can now resolve short remote name' ' - cd "$D" && git update-ref refs/remotes/six/HEAD HEAD && - mkdir six && - cd six && - git init && - - git fetch .. six:six + git init six && + git -C six fetch .. six:six ' test_expect_success 'create bundle 1' ' - cd "$D" && echo >file updated again by origin && git commit -a -m "tip" && git bundle create --version=3 bundle1 main^..main @@ -691,35 +640,36 @@ test_expect_success 'header of bundle looks right' ' OID refs/heads/main EOF - sed -e "s/$OID_REGEX/OID/g" -e "5q" "$D"/bundle1 >actual && + sed -e "s/$OID_REGEX/OID/g" -e "5q" bundle1 >actual && test_cmp expect actual ' test_expect_success 'create bundle 2' ' - cd "$D" && git bundle create bundle2 main~2..main ' test_expect_success 'unbundle 1' ' - cd "$D/bundle" && - git checkout -b some-branch && - test_must_fail git fetch "$D/bundle1" main:main + ( + cd bundle && + git checkout -b some-branch && + test_must_fail git fetch bundle1 main:main + ) ' test_expect_success 'bundle 1 has only 3 files ' ' - cd "$D" && test_bundle_object_count bundle1 3 ' test_expect_success 'unbundle 2' ' - cd "$D/bundle" && - git fetch ../bundle2 main:main && - test "tip" = "$(git log -1 --pretty=oneline main | cut -d" " -f2)" + ( + cd bundle && + git fetch ../bundle2 main:main && + test "tip" = "$(git log -1 --pretty=oneline main | cut -d" " -f2)" + ) ' test_expect_success 'bundle does not prerequisite objects' ' - cd "$D" && touch file2 && git add file2 && git commit -m add.file2 file2 && @@ -729,7 +679,6 @@ test_expect_success 'bundle does not prerequisite objects' ' test_expect_success 'bundle should be able to create a full history' ' - cd "$D" && git tag -a -m "1.0" v1.0 main && git bundle create bundle4 v1.0 @@ -783,7 +732,6 @@ test_expect_success 'quoting of a strangely named repo' ' test_expect_success 'bundle should record HEAD correctly' ' - cd "$D" && git bundle create bundle5 HEAD main && git bundle list-heads bundle5 >actual && for h in HEAD refs/heads/main @@ -803,7 +751,6 @@ test_expect_success 'mark initial state of origin/main' ' test_expect_success 'explicit fetch should update tracking' ' - cd "$D" && git branch -f side && ( cd three && @@ -818,7 +765,6 @@ test_expect_success 'explicit fetch should update tracking' ' test_expect_success 'explicit pull should update tracking' ' - cd "$D" && git branch -f side && ( cd three && @@ -832,7 +778,6 @@ test_expect_success 'explicit pull should update tracking' ' ' test_expect_success 'explicit --refmap is allowed only with command-line refspec' ' - cd "$D" && ( cd three && test_must_fail git fetch --refmap="*:refs/remotes/none/*" @@ -840,7 +785,6 @@ test_expect_success 'explicit --refmap is allowed only with command-line refspec ' test_expect_success 'explicit --refmap option overrides remote.*.fetch' ' - cd "$D" && git branch -f side && ( cd three && @@ -855,7 +799,6 @@ test_expect_success 'explicit --refmap option overrides remote.*.fetch' ' ' test_expect_success 'explicitly empty --refmap option disables remote.*.fetch' ' - cd "$D" && git branch -f side && ( cd three && @@ -870,7 +813,6 @@ test_expect_success 'explicitly empty --refmap option disables remote.*.fetch' ' test_expect_success 'configured fetch updates tracking' ' - cd "$D" && git branch -f side && ( cd three && @@ -884,7 +826,6 @@ test_expect_success 'configured fetch updates tracking' ' ' test_expect_success 'non-matching refspecs do not confuse tracking update' ' - cd "$D" && git update-ref refs/odd/location HEAD && ( cd three && @@ -901,14 +842,12 @@ test_expect_success 'non-matching refspecs do not confuse tracking update' ' test_expect_success 'pushing nonexistent branch by mistake should not segv' ' - cd "$D" && test_must_fail git push seven no:no ' test_expect_success 'auto tag following fetches minimum' ' - cd "$D" && git clone .git follow && git checkout HEAD^0 && ( @@ -1307,7 +1246,7 @@ test_expect_success 'fetch --prune prints the remotes url' ' cd only-prunes && git fetch --prune origin 2>&1 | head -n1 >../actual ) && - echo "From ${D}/." >expect && + echo "From $(pwd)/." >expect && test_cmp expect actual ' @@ -1357,14 +1296,14 @@ test_expect_success 'fetching with auto-gc does not lock up' ' echo "$*" && false EOF - git clone "file://$D" auto-gc && + git clone "file://$PWD" auto-gc && test_commit test2 && ( cd auto-gc && git config fetch.unpackLimit 1 && git config gc.autoPackLimit 1 && git config gc.autoDetach false && - GIT_ASK_YESNO="$D/askyesno" git fetch --verbose >fetch.out 2>&1 && + GIT_ASK_YESNO="$TRASH_DIRECTORY/askyesno" git fetch --verbose >fetch.out 2>&1 && test_grep "Auto packing the repository" fetch.out && ! grep "Should I try again" fetch.out ) diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 4e9c27b0f2..46926e7bbd 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -105,7 +105,6 @@ check_push_result () { } test_expect_success setup ' - >path1 && git add path1 && test_tick && @@ -117,7 +116,6 @@ test_expect_success setup ' test_tick && git commit -a -m second && the_commit=$(git show-ref -s --verify refs/heads/main) - ' for cmd in push fetch @@ -322,104 +320,82 @@ test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf ' test_expect_success 'push with matching heads' ' - mk_test testrepo heads/main && git push testrepo : && check_push_result testrepo $the_commit heads/main - ' test_expect_success 'push with matching heads on the command line' ' - mk_test testrepo heads/main && git push testrepo : && check_push_result testrepo $the_commit heads/main - ' test_expect_success 'failed (non-fast-forward) push with matching heads' ' - mk_test testrepo heads/main && git push testrepo : && git commit --amend -massaged && test_must_fail git push testrepo && check_push_result testrepo $the_commit heads/main && git reset --hard $the_commit - ' test_expect_success 'push --force with matching heads' ' - mk_test testrepo heads/main && git push testrepo : && git commit --amend -massaged && git push --force testrepo : && ! check_push_result testrepo $the_commit heads/main && git reset --hard $the_commit - ' test_expect_success 'push with matching heads and forced update' ' - mk_test testrepo heads/main && git push testrepo : && git commit --amend -massaged && git push testrepo +: && ! check_push_result testrepo $the_commit heads/main && git reset --hard $the_commit - ' test_expect_success 'push with no ambiguity (1)' ' - mk_test testrepo heads/main && git push testrepo main:main && check_push_result testrepo $the_commit heads/main - ' test_expect_success 'push with no ambiguity (2)' ' - mk_test testrepo remotes/origin/main && git push testrepo main:origin/main && check_push_result testrepo $the_commit remotes/origin/main - ' test_expect_success 'push with colon-less refspec, no ambiguity' ' - mk_test testrepo heads/main heads/t/main && git branch -f t/main main && git push testrepo main && check_push_result testrepo $the_commit heads/main && check_push_result testrepo $the_first_commit heads/t/main - ' test_expect_success 'push with weak ambiguity (1)' ' - mk_test testrepo heads/main remotes/origin/main && git push testrepo main:main && check_push_result testrepo $the_commit heads/main && check_push_result testrepo $the_first_commit remotes/origin/main - ' test_expect_success 'push with weak ambiguity (2)' ' - mk_test testrepo heads/main remotes/origin/main remotes/another/main && git push testrepo main:main && check_push_result testrepo $the_commit heads/main && check_push_result testrepo $the_first_commit remotes/origin/main remotes/another/main - ' test_expect_success 'push with ambiguity' ' - mk_test testrepo heads/frotz tags/frotz && test_must_fail git push testrepo main:frotz && check_push_result testrepo $the_first_commit heads/frotz tags/frotz - ' test_expect_success 'push with onelevel ref' ' @@ -428,17 +404,14 @@ test_expect_success 'push with onelevel ref' ' ' test_expect_success 'push with colon-less refspec (1)' ' - mk_test testrepo heads/frotz tags/frotz && git branch -f frotz main && git push testrepo frotz && check_push_result testrepo $the_commit heads/frotz && check_push_result testrepo $the_first_commit tags/frotz - ' test_expect_success 'push with colon-less refspec (2)' ' - mk_test testrepo heads/frotz tags/frotz && if git show-ref --verify -q refs/heads/frotz then @@ -448,7 +421,6 @@ test_expect_success 'push with colon-less refspec (2)' ' git push -f testrepo frotz && check_push_result testrepo $the_commit tags/frotz && check_push_result testrepo $the_first_commit heads/frotz - ' test_expect_success 'push with colon-less refspec (3)' ' @@ -465,7 +437,6 @@ test_expect_success 'push with colon-less refspec (3)' ' ' test_expect_success 'push with colon-less refspec (4)' ' - mk_test testrepo && if git show-ref --verify -q refs/heads/frotz then @@ -475,38 +446,34 @@ test_expect_success 'push with colon-less refspec (4)' ' git push testrepo frotz && check_push_result testrepo $the_commit tags/frotz && test 1 = $( cd testrepo && git show-ref | wc -l ) - ' test_expect_success 'push head with non-existent, incomplete dest' ' - mk_test testrepo && git push testrepo main:branch && check_push_result testrepo $the_commit heads/branch - ' test_expect_success 'push tag with non-existent, incomplete dest' ' - mk_test testrepo && git tag -f v1.0 && git push testrepo v1.0:tag && check_push_result testrepo $the_commit tags/tag - ' test_expect_success 'push oid with non-existent, incomplete dest' ' - mk_test testrepo && test_must_fail git push testrepo $(git rev-parse main):foo - ' test_expect_success 'push ref expression with non-existent, incomplete dest' ' - mk_test testrepo && test_must_fail git push testrepo main^:branch +' +test_expect_success 'push ref expression with non-existent oid src' ' + mk_test testrepo && + test_must_fail git push testrepo $(test_oid 001):branch ' for head in HEAD @ @@ -550,7 +517,6 @@ do git checkout main && git push testrepo $head:branch && check_push_result testrepo $the_commit heads/branch - ' test_expect_success "push with config remote.*.push = $head" ' @@ -596,7 +562,6 @@ test_expect_success 'push with remote.pushdefault' ' ' test_expect_success 'push with config remote.*.pushurl' ' - mk_test testrepo heads/main && git checkout main && test_config remote.there.url test2repo && @@ -655,7 +620,6 @@ test_expect_success 'push ignores "branch." config without subsection' ' ' test_expect_success 'push with dry-run' ' - mk_test testrepo heads/main && old_commit=$(git -C testrepo show-ref -s --verify refs/heads/main) && git push --dry-run testrepo : && @@ -663,7 +627,6 @@ test_expect_success 'push with dry-run' ' ' test_expect_success 'push updates local refs' ' - mk_test testrepo heads/main && mk_child testrepo child && ( @@ -673,11 +636,9 @@ test_expect_success 'push updates local refs' ' test $(git rev-parse main) = \ $(git rev-parse remotes/origin/main) ) - ' test_expect_success 'push updates up-to-date local refs' ' - mk_test testrepo heads/main && mk_child testrepo child1 && mk_child testrepo child2 && @@ -689,11 +650,9 @@ test_expect_success 'push updates up-to-date local refs' ' test $(git rev-parse main) = \ $(git rev-parse remotes/origin/main) ) - ' test_expect_success 'push preserves up-to-date packed refs' ' - mk_test testrepo heads/main && mk_child testrepo child && ( @@ -701,11 +660,9 @@ test_expect_success 'push preserves up-to-date packed refs' ' git push && ! test -f .git/refs/remotes/origin/main ) - ' test_expect_success 'push does not update local refs on failure' ' - mk_test testrepo heads/main && mk_child testrepo child && echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive && @@ -717,16 +674,13 @@ test_expect_success 'push does not update local refs on failure' ' test $(git rev-parse main) != \ $(git rev-parse remotes/origin/main) ) - ' test_expect_success 'allow deleting an invalid remote ref' ' - mk_test testrepo heads/branch && rm -f testrepo/.git/objects/??/* && git push testrepo :refs/heads/branch && (cd testrepo && test_must_fail git rev-parse --verify refs/heads/branch) - ' test_expect_success 'pushing valid refs triggers post-receive and post-update hooks' ' diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 63c9a8f04b..0e0019347e 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -472,6 +472,66 @@ test_expect_success 'pull --no-autostash & merge.autostash unset' ' test_pull_autostash_fail --no-autostash --no-rebase ' +test_expect_success 'pull succeeds with dirty working directory and pull.autostash=true' ' + test_config pull.autostash true && + test_pull_autostash 1 --rebase && + test_pull_autostash 2 --no-rebase && + test_pull_autostash 1 --autostash --rebase && + test_pull_autostash 2 --autostash --no-rebase +' + +test_expect_success 'pull fails with dirty working directory and pull.autostash=false' ' + test_config pull.autostash false && + test_pull_autostash_fail --rebase && + test_pull_autostash_fail --no-rebase && + test_pull_autostash_fail --no-autostash --rebase && + test_pull_autostash_fail --no-autostash --no-rebase +' + +test_expect_success 'pull --autostash overrides pull.autostash=false' ' + test_config pull.autostash false && + test_pull_autostash 1 --autostash --rebase && + test_pull_autostash 2 --autostash --no-rebase +' + +test_expect_success 'pull --no-autostash overrides pull.autostash=true' ' + test_config pull.autostash true && + test_pull_autostash_fail --no-autostash --rebase && + test_pull_autostash_fail --no-autostash --no-rebase +' + +test_expect_success 'pull.autostash=true overrides rebase.autostash' ' + test_config pull.autostash true && + test_config rebase.autostash true && + test_pull_autostash 1 --rebase && + test_config rebase.autostash false && + test_pull_autostash 1 --rebase +' + +test_expect_success 'pull.autostash=false overrides rebase.autostash' ' + test_config pull.autostash false && + test_config rebase.autostash true && + test_pull_autostash_fail --rebase && + test_config rebase.autostash false && + test_pull_autostash_fail --rebase +' + +test_expect_success 'pull.autostash=true overrides merge.autostash' ' + test_config pull.autostash true && + test_config merge.autostash true && + test_pull_autostash 2 --no-rebase && + test_config merge.autostash false && + test_pull_autostash 2 --no-rebase +' + +test_expect_success 'pull.autostash=false overrides merge.autostash' ' + test_config pull.autostash false && + test_config merge.autostash true && + test_pull_autostash_fail --no-rebase && + test_config merge.autostash false && + test_pull_autostash_fail --no-rebase +' + test_expect_success 'pull.rebase' ' git reset --hard before-rebase && test_config pull.rebase true && diff --git a/t/t6120-describe.sh b/t/t6120-describe.sh index 256ccaefb7..2c70cc561a 100755 --- a/t/t6120-describe.sh +++ b/t/t6120-describe.sh @@ -409,6 +409,36 @@ test_expect_success 'describe tag object' ' test_grep "fatal: test-blob-1 is neither a commit nor blob" actual ' +test_expect_success 'describe an unreachable blob' ' + blob=$(echo not-found-anywhere | git hash-object -w --stdin) && + test_must_fail git describe $blob 2>actual && + test_grep "blob .$blob. not reachable from HEAD" actual +' + +test_expect_success 'describe blob on an unborn branch' ' + oldbranch=$(git symbolic-ref HEAD) && + test_when_finished "git symbolic-ref HEAD $oldbranch" && + git symbolic-ref HEAD refs/heads/does-not-exist && + test_must_fail git describe test-blob 2>actual && + test_grep "cannot search .* on an unborn branch" actual +' + +# This test creates a repository state that we generally try to disallow: HEAD +# is pointing to an object that is not a commit. The ref update code forbids +# non-commit writes directly to HEAD or to any branch in refs/heads/. But we +# can use the loophole of pointing HEAD to another non-branch ref (something we +# should forbid, but don't for historical reasons). +# +# Do not take this test as an endorsement of the loophole! If we ever tighten +# it, it is reasonable to just drop this test entirely. +test_expect_success 'describe blob on a non-commit HEAD' ' + oldbranch=$(git symbolic-ref HEAD) && + test_when_finished "git symbolic-ref HEAD $oldbranch" && + git symbolic-ref HEAD refs/tags/test-blob && + test_must_fail git describe test-blob 2>actual && + test_grep "blob .* not reachable from HEAD" actual +' + test_expect_success ULIMIT_STACK_SIZE 'name-rev works in a deep repo' ' i=1 && while test $i -lt 8000 diff --git a/t/t6137-pathspec-wildcards-literal.sh b/t/t6137-pathspec-wildcards-literal.sh index 20abad5667..17a03085ef 100755 --- a/t/t6137-pathspec-wildcards-literal.sh +++ b/t/t6137-pathspec-wildcards-literal.sh @@ -3,8 +3,8 @@ test_description='test wildcards and literals with git add/commit (subshell styl . ./test-lib.sh -test_have_prereq FUNNYNAMES || { - skip_all='skipping: needs FUNNYNAMES (non-Windows only)' +test_have_prereq BSLASHPSPEC || { + skip_all='skipping: needs BSLASHPSPEC (backslashes in pathspecs)' test_done } @@ -184,7 +184,7 @@ test_expect_success 'add wildcard f?z' ' ) ' -test_expect_success 'add literal \? literal' ' +test_expect_success 'add literal \?' ' git init test-q-lit && ( cd test-q-lit && @@ -241,7 +241,7 @@ test_expect_success 'add literal hello\?world' ' ) ' -test_expect_success 'add literal [abc]' ' +test_expect_success 'add literal \[abc\]' ' git init test-brackets-lit && ( cd test-brackets-lit && @@ -280,7 +280,7 @@ test_expect_success 'commit: wildcard *' ' ) ' -test_expect_success 'commit: literal *' ' +test_expect_success 'commit: literal \*' ' git init test-c-asterisk-lit && ( cd test-c-asterisk-lit && @@ -328,7 +328,7 @@ test_expect_success 'commit: literal f\*' ' ) ' -test_expect_success 'commit: wildcard pathspec limits commit' ' +test_expect_success 'commit: wildcard f**' ' git init test-c-pathlimit && ( cd test-c-pathlimit && diff --git a/t/t6300-for-each-ref.sh b/t/t6300-for-each-ref.sh index ce9af79ab1..1d9809114d 100755 --- a/t/t6300-for-each-ref.sh +++ b/t/t6300-for-each-ref.sh @@ -6,2150 +6,14 @@ test_description='for-each-ref test' . ./test-lib.sh -GNUPGHOME_NOT_USED=$GNUPGHOME -. "$TEST_DIRECTORY"/lib-gpg.sh -. "$TEST_DIRECTORY"/lib-terminal.sh -# Mon Jul 3 23:18:43 2006 +0000 -datestamp=1151968723 -setdate_and_increment () { - GIT_COMMITTER_DATE="$datestamp +0200" - datestamp=$(expr "$datestamp" + 1) - GIT_AUTHOR_DATE="$datestamp +0200" - datestamp=$(expr "$datestamp" + 1) - export GIT_COMMITTER_DATE GIT_AUTHOR_DATE -} - -test_object_file_size () { - oid=$(git rev-parse "$1") - path=".git/objects/$(test_oid_to_path $oid)" - test_file_size "$path" -} - -test_expect_success setup ' - # setup .mailmap - cat >.mailmap <<-EOF && - A Thor <athor@example.com> A U Thor <author@example.com> - C Mitter <cmitter@example.com> C O Mitter <committer@example.com> - EOF - - setdate_and_increment && - echo "Using $datestamp" > one && - git add one && - git commit -m "Initial" && - git branch -M main && - setdate_and_increment && - git tag -a -m "Tagging at $datestamp" testtag && - git update-ref refs/remotes/origin/main main && - git remote add origin nowhere && - git config branch.main.remote origin && - git config branch.main.merge refs/heads/main && - git remote add myfork elsewhere && - git config remote.pushdefault myfork && - git config push.default current -' - -test_atom () { - case "$1" in - head) ref=refs/heads/main ;; - tag) ref=refs/tags/testtag ;; - sym) ref=refs/heads/sym ;; - *) ref=$1 ;; - esac - format=$2 - test_do=test_expect_${4:-success} - - printf '%s\n' "$3" >expected - $test_do $PREREQ "basic atom: $ref $format" ' - git for-each-ref --format="%($format)" "$ref" >actual && - sanitize_pgp <actual >actual.clean && - test_cmp expected actual.clean - ' - - # Automatically test "contents:size" atom after testing "contents" - if test "$format" = "contents" - then - # for commit leg, $3 is changed there - expect=$(printf '%s' "$3" | wc -c) - $test_do $PREREQ "basic atom: $ref contents:size" ' - type=$(git cat-file -t "$ref") && - case $type in - tag) - # We cannot use $3 as it expects sanitize_pgp to run - git cat-file tag $ref >out && - expect=$(tail -n +6 out | wc -c) && - rm -f out ;; - tree | blob) - expect="" ;; - commit) - : "use the calculated expect" ;; - *) - BUG "unknown object type" ;; - esac && - # Leave $expect unquoted to lose possible leading whitespaces - echo $expect >expected && - git for-each-ref --format="%(contents:size)" "$ref" >actual && - test_cmp expected actual - ' - fi -} - -hexlen=$(test_oid hexsz) - -test_atom head refname refs/heads/main -test_atom head refname: refs/heads/main -test_atom head refname:short main -test_atom head refname:lstrip=1 heads/main -test_atom head refname:lstrip=2 main -test_atom head refname:lstrip=-1 main -test_atom head refname:lstrip=-2 heads/main -test_atom head refname:rstrip=1 refs/heads -test_atom head refname:rstrip=2 refs -test_atom head refname:rstrip=-1 refs -test_atom head refname:rstrip=-2 refs/heads -test_atom head refname:strip=1 heads/main -test_atom head refname:strip=2 main -test_atom head refname:strip=-1 main -test_atom head refname:strip=-2 heads/main -test_atom head upstream refs/remotes/origin/main -test_atom head upstream:short origin/main -test_atom head upstream:lstrip=2 origin/main -test_atom head upstream:lstrip=-2 origin/main -test_atom head upstream:rstrip=2 refs/remotes -test_atom head upstream:rstrip=-2 refs/remotes -test_atom head upstream:strip=2 origin/main -test_atom head upstream:strip=-2 origin/main -test_atom head push refs/remotes/myfork/main -test_atom head push:short myfork/main -test_atom head push:lstrip=1 remotes/myfork/main -test_atom head push:lstrip=-1 main -test_atom head push:rstrip=1 refs/remotes/myfork -test_atom head push:rstrip=-1 refs -test_atom head push:strip=1 remotes/myfork/main -test_atom head push:strip=-1 main -test_atom head objecttype commit -test_atom head objectsize $((131 + hexlen)) -test_atom head objectsize:disk $(test_object_file_size refs/heads/main) -test_atom head deltabase $ZERO_OID -test_atom head objectname $(git rev-parse refs/heads/main) -test_atom head objectname:short $(git rev-parse --short refs/heads/main) -test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) -test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) -test_atom head tree $(git rev-parse refs/heads/main^{tree}) -test_atom head tree:short $(git rev-parse --short refs/heads/main^{tree}) -test_atom head tree:short=1 $(git rev-parse --short=1 refs/heads/main^{tree}) -test_atom head tree:short=10 $(git rev-parse --short=10 refs/heads/main^{tree}) -test_atom head parent '' -test_atom head parent:short '' -test_atom head parent:short=1 '' -test_atom head parent:short=10 '' -test_atom head numparent 0 -test_atom head object '' -test_atom head type '' -test_atom head raw "$(git cat-file commit refs/heads/main) -" -test_atom head '*objectname' '' -test_atom head '*objecttype' '' -test_atom head author 'A U Thor <author@example.com> 1151968724 +0200' -test_atom head authorname 'A U Thor' -test_atom head authorname:mailmap 'A Thor' -test_atom head authoremail '<author@example.com>' -test_atom head authoremail:trim 'author@example.com' -test_atom head authoremail:localpart 'author' -test_atom head authoremail:trim,localpart 'author' -test_atom head authoremail:mailmap '<athor@example.com>' -test_atom head authoremail:mailmap,trim 'athor@example.com' -test_atom head authoremail:trim,mailmap 'athor@example.com' -test_atom head authoremail:mailmap,localpart 'athor' -test_atom head authoremail:localpart,mailmap 'athor' -test_atom head authoremail:mailmap,trim,localpart,mailmap,trim 'athor' -test_atom head authordate 'Tue Jul 4 01:18:44 2006 +0200' -test_atom head committer 'C O Mitter <committer@example.com> 1151968723 +0200' -test_atom head committername 'C O Mitter' -test_atom head committername:mailmap 'C Mitter' -test_atom head committeremail '<committer@example.com>' -test_atom head committeremail:trim 'committer@example.com' -test_atom head committeremail:localpart 'committer' -test_atom head committeremail:localpart,trim 'committer' -test_atom head committeremail:mailmap '<cmitter@example.com>' -test_atom head committeremail:mailmap,trim 'cmitter@example.com' -test_atom head committeremail:trim,mailmap 'cmitter@example.com' -test_atom head committeremail:mailmap,localpart 'cmitter' -test_atom head committeremail:localpart,mailmap 'cmitter' -test_atom head committeremail:trim,mailmap,trim,trim,localpart 'cmitter' -test_atom head committerdate 'Tue Jul 4 01:18:43 2006 +0200' -test_atom head tag '' -test_atom head tagger '' -test_atom head taggername '' -test_atom head taggeremail '' -test_atom head taggeremail:trim '' -test_atom head taggeremail:localpart '' -test_atom head taggerdate '' -test_atom head creator 'C O Mitter <committer@example.com> 1151968723 +0200' -test_atom head creatordate 'Tue Jul 4 01:18:43 2006 +0200' -test_atom head subject 'Initial' -test_atom head subject:sanitize 'Initial' -test_atom head contents:subject 'Initial' -test_atom head body '' -test_atom head contents:body '' -test_atom head contents:signature '' -test_atom head contents 'Initial -' -test_atom head HEAD '*' - -test_atom tag refname refs/tags/testtag -test_atom tag refname:short testtag -test_atom tag upstream '' -test_atom tag push '' -test_atom tag objecttype tag -test_atom tag objectsize $((114 + hexlen)) -test_atom tag objectsize:disk $(test_object_file_size refs/tags/testtag) -test_atom tag '*objectsize:disk' $(test_object_file_size refs/heads/main) -test_atom tag deltabase $ZERO_OID -test_atom tag '*deltabase' $ZERO_OID -test_atom tag objectname $(git rev-parse refs/tags/testtag) -test_atom tag objectname:short $(git rev-parse --short refs/tags/testtag) -test_atom head objectname:short=1 $(git rev-parse --short=1 refs/heads/main) -test_atom head objectname:short=10 $(git rev-parse --short=10 refs/heads/main) -test_atom tag tree '' -test_atom tag tree:short '' -test_atom tag tree:short=1 '' -test_atom tag tree:short=10 '' -test_atom tag parent '' -test_atom tag parent:short '' -test_atom tag parent:short=1 '' -test_atom tag parent:short=10 '' -test_atom tag numparent '' -test_atom tag object $(git rev-parse refs/tags/testtag^0) -test_atom tag type 'commit' -test_atom tag '*objectname' $(git rev-parse refs/tags/testtag^{}) -test_atom tag '*objecttype' 'commit' -test_atom tag author '' -test_atom tag authorname '' -test_atom tag authorname:mailmap '' -test_atom tag authoremail '' -test_atom tag authoremail:trim '' -test_atom tag authoremail:localpart '' -test_atom tag authoremail:trim,localpart '' -test_atom tag authoremail:mailmap '' -test_atom tag authoremail:mailmap,trim '' -test_atom tag authoremail:trim,mailmap '' -test_atom tag authoremail:mailmap,localpart '' -test_atom tag authoremail:localpart,mailmap '' -test_atom tag authoremail:mailmap,trim,localpart,mailmap,trim '' -test_atom tag authordate '' -test_atom tag committer '' -test_atom tag committername '' -test_atom tag committername:mailmap '' -test_atom tag committeremail '' -test_atom tag committeremail:trim '' -test_atom tag committeremail:localpart '' -test_atom tag committeremail:localpart,trim '' -test_atom tag committeremail:mailmap '' -test_atom tag committeremail:mailmap,trim '' -test_atom tag committeremail:trim,mailmap '' -test_atom tag committeremail:mailmap,localpart '' -test_atom tag committeremail:localpart,mailmap '' -test_atom tag committeremail:trim,mailmap,trim,trim,localpart '' -test_atom tag committerdate '' -test_atom tag tag 'testtag' -test_atom tag tagger 'C O Mitter <committer@example.com> 1151968725 +0200' -test_atom tag taggername 'C O Mitter' -test_atom tag taggername:mailmap 'C Mitter' -test_atom tag taggeremail '<committer@example.com>' -test_atom tag taggeremail:trim 'committer@example.com' -test_atom tag taggeremail:localpart 'committer' -test_atom tag taggeremail:trim,localpart 'committer' -test_atom tag taggeremail:mailmap '<cmitter@example.com>' -test_atom tag taggeremail:mailmap,trim 'cmitter@example.com' -test_atom tag taggeremail:trim,mailmap 'cmitter@example.com' -test_atom tag taggeremail:mailmap,localpart 'cmitter' -test_atom tag taggeremail:localpart,mailmap 'cmitter' -test_atom tag taggeremail:trim,mailmap,trim,localpart,localpart 'cmitter' -test_atom tag taggerdate 'Tue Jul 4 01:18:45 2006 +0200' -test_atom tag creator 'C O Mitter <committer@example.com> 1151968725 +0200' -test_atom tag creatordate 'Tue Jul 4 01:18:45 2006 +0200' -test_atom tag subject 'Tagging at 1151968727' -test_atom tag subject:sanitize 'Tagging-at-1151968727' -test_atom tag contents:subject 'Tagging at 1151968727' -test_atom tag body '' -test_atom tag contents:body '' -test_atom tag contents:signature '' -test_atom tag contents 'Tagging at 1151968727 -' -test_atom tag HEAD ' ' - -test_expect_success 'basic atom: refs/tags/testtag *raw' ' - git cat-file commit refs/tags/testtag^{} >expected && - git for-each-ref --format="%(*raw)" refs/tags/testtag >actual && - sanitize_pgp <expected >expected.clean && - echo >>expected.clean && - sanitize_pgp <actual >actual.clean && - test_cmp expected.clean actual.clean -' - -test_expect_success 'Check invalid atoms names are errors' ' - test_must_fail git for-each-ref --format="%(INVALID)" refs/heads -' - -test_expect_success 'for-each-ref does not crash with -h' ' +test_expect_success "for-each-ref does not crash with -h" ' test_expect_code 129 git for-each-ref -h >usage && test_grep "[Uu]sage: git for-each-ref " usage && test_expect_code 129 nongit git for-each-ref -h >usage && test_grep "[Uu]sage: git for-each-ref " usage ' -test_expect_success 'Check format specifiers are ignored in naming date atoms' ' - git for-each-ref --format="%(authordate)" refs/heads && - git for-each-ref --format="%(authordate:default) %(authordate)" refs/heads && - git for-each-ref --format="%(authordate) %(authordate:default)" refs/heads && - git for-each-ref --format="%(authordate:default) %(authordate:default)" refs/heads -' - -test_expect_success 'Check valid format specifiers for date fields' ' - git for-each-ref --format="%(authordate:default)" refs/heads && - git for-each-ref --format="%(authordate:relative)" refs/heads && - git for-each-ref --format="%(authordate:short)" refs/heads && - git for-each-ref --format="%(authordate:local)" refs/heads && - git for-each-ref --format="%(authordate:iso8601)" refs/heads && - git for-each-ref --format="%(authordate:rfc2822)" refs/heads -' - -test_expect_success 'Check invalid format specifiers are errors' ' - test_must_fail git for-each-ref --format="%(authordate:INVALID)" refs/heads -' - -test_expect_success 'arguments to %(objectname:short=) must be positive integers' ' - test_must_fail git for-each-ref --format="%(objectname:short=0)" && - test_must_fail git for-each-ref --format="%(objectname:short=-1)" && - test_must_fail git for-each-ref --format="%(objectname:short=foo)" -' - -test_bad_atom () { - case "$1" in - head) ref=refs/heads/main ;; - tag) ref=refs/tags/testtag ;; - sym) ref=refs/heads/sym ;; - *) ref=$1 ;; - esac - format=$2 - test_do=test_expect_${4:-success} - - printf '%s\n' "$3" >expect - $test_do $PREREQ "err basic atom: $ref $format" ' - test_must_fail git for-each-ref \ - --format="%($format)" "$ref" 2>error && - test_cmp expect error - ' -} - -test_bad_atom head 'authoremail:foo' \ - 'fatal: unrecognized %(authoremail) argument: foo' - -test_bad_atom head 'authoremail:mailmap,trim,bar' \ - 'fatal: unrecognized %(authoremail) argument: bar' - -test_bad_atom head 'authoremail:trim,' \ - 'fatal: unrecognized %(authoremail) argument: ' - -test_bad_atom head 'authoremail:mailmaptrim' \ - 'fatal: unrecognized %(authoremail) argument: trim' - -test_bad_atom head 'committeremail: ' \ - 'fatal: unrecognized %(committeremail) argument: ' - -test_bad_atom head 'committeremail: trim,foo' \ - 'fatal: unrecognized %(committeremail) argument: trim,foo' - -test_bad_atom head 'committeremail:mailmap,localpart ' \ - 'fatal: unrecognized %(committeremail) argument: ' - -test_bad_atom head 'committeremail:trim_localpart' \ - 'fatal: unrecognized %(committeremail) argument: _localpart' - -test_bad_atom head 'committeremail:localpart,,,trim' \ - 'fatal: unrecognized %(committeremail) argument: ,,trim' - -test_bad_atom tag 'taggeremail:mailmap,trim, foo ' \ - 'fatal: unrecognized %(taggeremail) argument: foo ' - -test_bad_atom tag 'taggeremail:trim,localpart,' \ - 'fatal: unrecognized %(taggeremail) argument: ' - -test_bad_atom tag 'taggeremail:mailmap;localpart trim' \ - 'fatal: unrecognized %(taggeremail) argument: ;localpart trim' - -test_bad_atom tag 'taggeremail:localpart trim' \ - 'fatal: unrecognized %(taggeremail) argument: trim' - -test_bad_atom tag 'taggeremail:mailmap,mailmap,trim,qux,localpart,trim' \ - 'fatal: unrecognized %(taggeremail) argument: qux,localpart,trim' - -test_date () { - f=$1 && - committer_date=$2 && - author_date=$3 && - tagger_date=$4 && - cat >expected <<-EOF && - 'refs/heads/main' '$committer_date' '$author_date' - 'refs/tags/testtag' '$tagger_date' - EOF - ( - git for-each-ref --shell \ - --format="%(refname) %(committerdate${f:+:$f}) %(authordate${f:+:$f})" \ - refs/heads && - git for-each-ref --shell \ - --format="%(refname) %(taggerdate${f:+:$f})" \ - refs/tags - ) >actual && - test_cmp expected actual -} - -test_expect_success 'Check unformatted date fields output' ' - test_date "" \ - "Tue Jul 4 01:18:43 2006 +0200" \ - "Tue Jul 4 01:18:44 2006 +0200" \ - "Tue Jul 4 01:18:45 2006 +0200" -' - -test_expect_success 'Check format "default" formatted date fields output' ' - test_date default \ - "Tue Jul 4 01:18:43 2006 +0200" \ - "Tue Jul 4 01:18:44 2006 +0200" \ - "Tue Jul 4 01:18:45 2006 +0200" -' - -test_expect_success 'Check format "default-local" date fields output' ' - test_date default-local "Mon Jul 3 23:18:43 2006" "Mon Jul 3 23:18:44 2006" "Mon Jul 3 23:18:45 2006" -' - -# Don't know how to do relative check because I can't know when this script -# is going to be run and can't fake the current time to git, and hence can't -# provide expected output. Instead, I'll just make sure that "relative" -# doesn't exit in error -test_expect_success 'Check format "relative" date fields output' ' - f=relative && - (git for-each-ref --shell --format="%(refname) %(committerdate:$f) %(authordate:$f)" refs/heads && - git for-each-ref --shell --format="%(refname) %(taggerdate:$f)" refs/tags) >actual -' - -# We just check that this is the same as "relative" for now. -test_expect_success 'Check format "relative-local" date fields output' ' - test_date relative-local \ - "$(git for-each-ref --format="%(committerdate:relative)" refs/heads)" \ - "$(git for-each-ref --format="%(authordate:relative)" refs/heads)" \ - "$(git for-each-ref --format="%(taggerdate:relative)" refs/tags)" -' - -test_expect_success 'Check format "short" date fields output' ' - test_date short 2006-07-04 2006-07-04 2006-07-04 -' - -test_expect_success 'Check format "short-local" date fields output' ' - test_date short-local 2006-07-03 2006-07-03 2006-07-03 -' - -test_expect_success 'Check format "local" date fields output' ' - test_date local \ - "Mon Jul 3 23:18:43 2006" \ - "Mon Jul 3 23:18:44 2006" \ - "Mon Jul 3 23:18:45 2006" -' - -test_expect_success 'Check format "iso8601" date fields output' ' - test_date iso8601 \ - "2006-07-04 01:18:43 +0200" \ - "2006-07-04 01:18:44 +0200" \ - "2006-07-04 01:18:45 +0200" -' - -test_expect_success 'Check format "iso8601-local" date fields output' ' - test_date iso8601-local "2006-07-03 23:18:43 +0000" "2006-07-03 23:18:44 +0000" "2006-07-03 23:18:45 +0000" -' - -test_expect_success 'Check format "rfc2822" date fields output' ' - test_date rfc2822 \ - "Tue, 4 Jul 2006 01:18:43 +0200" \ - "Tue, 4 Jul 2006 01:18:44 +0200" \ - "Tue, 4 Jul 2006 01:18:45 +0200" -' - -test_expect_success 'Check format "rfc2822-local" date fields output' ' - test_date rfc2822-local "Mon, 3 Jul 2006 23:18:43 +0000" "Mon, 3 Jul 2006 23:18:44 +0000" "Mon, 3 Jul 2006 23:18:45 +0000" -' - -test_expect_success 'Check format "raw" date fields output' ' - test_date raw "1151968723 +0200" "1151968724 +0200" "1151968725 +0200" -' - -test_expect_success 'Check format "raw-local" date fields output' ' - test_date raw-local "1151968723 +0000" "1151968724 +0000" "1151968725 +0000" -' - -test_expect_success 'Check format of strftime date fields' ' - echo "my date is 2006-07-04" >expected && - git for-each-ref \ - --format="%(authordate:format:my date is %Y-%m-%d)" \ - refs/heads >actual && - test_cmp expected actual -' - -test_expect_success 'Check format of strftime-local date fields' ' - echo "my date is 2006-07-03" >expected && - git for-each-ref \ - --format="%(authordate:format-local:my date is %Y-%m-%d)" \ - refs/heads >actual && - test_cmp expected actual -' - -test_expect_success 'exercise strftime with odd fields' ' - echo >expected && - git for-each-ref --format="%(authordate:format:)" refs/heads >actual && - test_cmp expected actual && - long="long format -- $ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID$ZERO_OID" && - echo $long >expected && - git for-each-ref --format="%(authordate:format:$long)" refs/heads >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -refs/heads/main -refs/remotes/origin/main -refs/tags/testtag -EOF - -test_expect_success 'Verify ascending sort' ' - git for-each-ref --format="%(refname)" --sort=refname >actual && - test_cmp expected actual -' - - -cat >expected <<\EOF -refs/tags/testtag -refs/remotes/origin/main -refs/heads/main -EOF - -test_expect_success 'Verify descending sort' ' - git for-each-ref --format="%(refname)" --sort=-refname >actual && - test_cmp expected actual -' - -test_expect_success 'Give help even with invalid sort atoms' ' - test_expect_code 129 git for-each-ref --sort=bogus -h >actual 2>&1 && - grep "^usage: git for-each-ref" actual -' - -cat >expected <<\EOF -refs/tags/testtag -refs/tags/testtag-2 -EOF - -test_expect_success 'exercise patterns with prefixes' ' - git tag testtag-2 && - test_when_finished "git tag -d testtag-2" && - git for-each-ref --format="%(refname)" \ - refs/tags/testtag refs/tags/testtag-2 >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -refs/tags/testtag -refs/tags/testtag-2 -EOF - -test_expect_success 'exercise glob patterns with prefixes' ' - git tag testtag-2 && - test_when_finished "git tag -d testtag-2" && - git for-each-ref --format="%(refname)" \ - refs/tags/testtag "refs/tags/testtag-*" >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -refs/tags/bar -refs/tags/baz -refs/tags/testtag -EOF - -test_expect_success 'exercise patterns with prefix exclusions' ' - for tag in foo/one foo/two foo/three bar baz - do - git tag "$tag" || return 1 - done && - test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && - git for-each-ref --format="%(refname)" \ - refs/tags/ --exclude=refs/tags/foo >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -refs/tags/bar -refs/tags/baz -refs/tags/foo/one -refs/tags/testtag -EOF - -test_expect_success 'exercise patterns with pattern exclusions' ' - for tag in foo/one foo/two foo/three bar baz - do - git tag "$tag" || return 1 - done && - test_when_finished "git tag -d foo/one foo/two foo/three bar baz" && - git for-each-ref --format="%(refname)" \ - refs/tags/ --exclude="refs/tags/foo/t*" >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -'refs/heads/main' -'refs/remotes/origin/main' -'refs/tags/testtag' -EOF - -test_expect_success 'Quoting style: shell' ' - git for-each-ref --shell --format="%(refname)" >actual && - test_cmp expected actual -' - -test_expect_success 'Quoting style: perl' ' - git for-each-ref --perl --format="%(refname)" >actual && - test_cmp expected actual -' - -test_expect_success 'Quoting style: python' ' - git for-each-ref --python --format="%(refname)" >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -"refs/heads/main" -"refs/remotes/origin/main" -"refs/tags/testtag" -EOF - -test_expect_success 'Quoting style: tcl' ' - git for-each-ref --tcl --format="%(refname)" >actual && - test_cmp expected actual -' - -for i in "--perl --shell" "-s --python" "--python --tcl" "--tcl --perl"; do - test_expect_success "more than one quoting style: $i" " - test_must_fail git for-each-ref $i 2>err && - grep '^error: more than one quoting style' err - " -done - -test_expect_success 'setup for upstream:track[short]' ' - test_commit two -' - -test_atom head upstream:track '[ahead 1]' -test_atom head upstream:trackshort '>' -test_atom head upstream:track,nobracket 'ahead 1' -test_atom head upstream:nobracket,track 'ahead 1' - -test_expect_success 'setup for push:track[short]' ' - test_commit third && - git update-ref refs/remotes/myfork/main main && - git reset main~1 -' - -test_atom head push:track '[behind 1]' -test_atom head push:trackshort '<' - -test_expect_success 'Check that :track[short] cannot be used with other atoms' ' - test_must_fail git for-each-ref --format="%(refname:track)" 2>/dev/null && - test_must_fail git for-each-ref --format="%(refname:trackshort)" 2>/dev/null -' - -test_expect_success 'Check that :track[short] works when upstream is invalid' ' - cat >expected <<-\EOF && - [gone] - - EOF - test_when_finished "git config branch.main.merge refs/heads/main" && - git config branch.main.merge refs/heads/does-not-exist && - git for-each-ref \ - --format="%(upstream:track)$LF%(upstream:trackshort)" \ - refs/heads >actual && - test_cmp expected actual -' - -test_expect_success 'Check for invalid refname format' ' - test_must_fail git for-each-ref --format="%(refname:INVALID)" -' - -test_expect_success 'set up color tests' ' - cat >expected.color <<-EOF && - $(git rev-parse --short refs/heads/main) <GREEN>main<RESET> - $(git rev-parse --short refs/remotes/myfork/main) <GREEN>myfork/main<RESET> - $(git rev-parse --short refs/remotes/origin/main) <GREEN>origin/main<RESET> - $(git rev-parse --short refs/tags/testtag) <GREEN>testtag<RESET> - $(git rev-parse --short refs/tags/third) <GREEN>third<RESET> - $(git rev-parse --short refs/tags/two) <GREEN>two<RESET> - EOF - sed "s/<[^>]*>//g" <expected.color >expected.bare && - color_format="%(objectname:short) %(color:green)%(refname:short)" -' - -test_expect_success TTY '%(color) shows color with a tty' ' - test_terminal git for-each-ref --format="$color_format" >actual.raw && - test_decode_color <actual.raw >actual && - test_cmp expected.color actual -' - -test_expect_success '%(color) does not show color without tty' ' - TERM=vt100 git for-each-ref --format="$color_format" >actual && - test_cmp expected.bare actual -' - -test_expect_success '--color can override tty check' ' - git for-each-ref --color --format="$color_format" >actual.raw && - test_decode_color <actual.raw >actual && - test_cmp expected.color actual -' - -test_expect_success 'color.ui=always does not override tty check' ' - git -c color.ui=always for-each-ref --format="$color_format" >actual && - test_cmp expected.bare actual -' - -test_expect_success 'setup for describe atom tests' ' - git init -b master describe-repo && - ( - cd describe-repo && - - test_commit --no-tag one && - git tag tagone && - - test_commit --no-tag two && - git tag -a -m "tag two" tagtwo - ) -' - -test_expect_success 'describe atom vs git describe' ' - ( - cd describe-repo && - - git for-each-ref --format="%(objectname)" \ - refs/tags/ >obj && - while read hash - do - if desc=$(git describe $hash) - then - : >expect-contains-good - else - : >expect-contains-bad - fi && - echo "$hash $desc" || return 1 - done <obj >expect && - test_path_exists expect-contains-good && - test_path_exists expect-contains-bad && - - git for-each-ref --format="%(objectname) %(describe)" \ - refs/tags/ >actual 2>err && - test_cmp expect actual && - test_must_be_empty err - ) -' - -test_expect_success 'describe:tags vs describe --tags' ' - ( - cd describe-repo && - git describe --tags >expect && - git for-each-ref --format="%(describe:tags)" \ - refs/heads/master >actual && - test_cmp expect actual - ) -' - -test_expect_success 'describe:abbrev=... vs describe --abbrev=...' ' - ( - cd describe-repo && - - # Case 1: We have commits between HEAD and the most - # recent tag reachable from it - test_commit --no-tag file && - git describe --abbrev=14 >expect && - git for-each-ref --format="%(describe:abbrev=14)" \ - refs/heads/master >actual && - test_cmp expect actual && - - # Make sure the hash used is at least 14 digits long - sed -e "s/^.*-g\([0-9a-f]*\)$/\1/" <actual >hexpart && - test 15 -le $(wc -c <hexpart) && - - # Case 2: We have a tag at HEAD, describe directly gives - # the name of the tag - git tag -a -m tagged tagname && - git describe --abbrev=14 >expect && - git for-each-ref --format="%(describe:abbrev=14)" \ - refs/heads/master >actual && - test_cmp expect actual && - test tagname = $(cat actual) - ) -' - -test_expect_success 'describe:match=... vs describe --match ...' ' - ( - cd describe-repo && - git tag -a -m "tag foo" tag-foo && - git describe --match "*-foo" >expect && - git for-each-ref --format="%(describe:match="*-foo")" \ - refs/heads/master >actual && - test_cmp expect actual - ) -' - -test_expect_success 'describe:exclude:... vs describe --exclude ...' ' - ( - cd describe-repo && - git tag -a -m "tag bar" tag-bar && - git describe --exclude "*-bar" >expect && - git for-each-ref --format="%(describe:exclude="*-bar")" \ - refs/heads/master >actual && - test_cmp expect actual - ) -' - -test_expect_success 'deref with describe atom' ' - ( - cd describe-repo && - cat >expect <<-\EOF && - - tagname - tagname - tagname - - tagtwo - EOF - git for-each-ref --format="%(*describe)" >actual && - test_cmp expect actual - ) -' - -test_expect_success 'err on bad describe atom arg' ' - ( - cd describe-repo && - - # The bad arg is the only arg passed to describe atom - cat >expect <<-\EOF && - fatal: unrecognized %(describe) argument: baz - EOF - test_must_fail git for-each-ref --format="%(describe:baz)" \ - refs/heads/master 2>actual && - test_cmp expect actual && - - # The bad arg is in the middle of the option string - # passed to the describe atom - cat >expect <<-\EOF && - fatal: unrecognized %(describe) argument: qux=1,abbrev=14 - EOF - test_must_fail git for-each-ref \ - --format="%(describe:tags,qux=1,abbrev=14)" \ - ref/heads/master 2>actual && - test_cmp expect actual - ) -' - -cat >expected <<\EOF -heads/main -tags/main -EOF - -test_expect_success 'Check ambiguous head and tag refs (strict)' ' - git config --bool core.warnambiguousrefs true && - git checkout -b newtag && - echo "Using $datestamp" > one && - git add one && - git commit -m "Branch" && - setdate_and_increment && - git tag -m "Tagging at $datestamp" main && - git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -heads/main -main -EOF - -test_expect_success 'Check ambiguous head and tag refs (loose)' ' - git config --bool core.warnambiguousrefs false && - git for-each-ref --format "%(refname:short)" refs/heads/main refs/tags/main >actual && - test_cmp expected actual -' - -cat >expected <<\EOF -heads/ambiguous -ambiguous -EOF - -test_expect_success 'Check ambiguous head and tag refs II (loose)' ' - git checkout main && - git tag ambiguous testtag^0 && - git branch ambiguous testtag^0 && - git for-each-ref --format "%(refname:short)" refs/heads/ambiguous refs/tags/ambiguous >actual && - test_cmp expected actual -' - -test_expect_success 'create tag without tagger' ' - git tag -a -m "Broken tag" taggerless && - git tag -f taggerless $(git cat-file tag taggerless | - sed -e "/^tagger /d" | - git hash-object --literally --stdin -w -t tag) -' - -test_atom refs/tags/taggerless type 'commit' -test_atom refs/tags/taggerless tag 'taggerless' -test_atom refs/tags/taggerless tagger '' -test_atom refs/tags/taggerless taggername '' -test_atom refs/tags/taggerless taggeremail '' -test_atom refs/tags/taggerless taggeremail:trim '' -test_atom refs/tags/taggerless taggeremail:localpart '' -test_atom refs/tags/taggerless taggerdate '' -test_atom refs/tags/taggerless committer '' -test_atom refs/tags/taggerless committername '' -test_atom refs/tags/taggerless committeremail '' -test_atom refs/tags/taggerless committeremail:trim '' -test_atom refs/tags/taggerless committeremail:localpart '' -test_atom refs/tags/taggerless committerdate '' -test_atom refs/tags/taggerless subject 'Broken tag' - -test_expect_success 'an unusual tag with an incomplete line' ' - - git tag -m "bogo" bogo && - bogo=$(git cat-file tag bogo) && - bogo=$(printf "%s" "$bogo" | git mktag) && - git tag -f bogo "$bogo" && - git for-each-ref --format "%(body)" refs/tags/bogo - -' - -test_expect_success 'create tag with subject and body content' ' - cat >>msg <<-\EOF && - the subject line - - first body line - second body line - EOF - git tag -F msg subject-body -' -test_atom refs/tags/subject-body subject 'the subject line' -test_atom refs/tags/subject-body subject:sanitize 'the-subject-line' -test_atom refs/tags/subject-body body 'first body line -second body line -' -test_atom refs/tags/subject-body contents 'the subject line - -first body line -second body line -' - -test_expect_success 'create tag with multiline subject' ' - cat >msg <<-\EOF && - first subject line - second subject line - - first body line - second body line - EOF - git tag -F msg multiline -' -test_atom refs/tags/multiline subject 'first subject line second subject line' -test_atom refs/tags/multiline subject:sanitize 'first-subject-line-second-subject-line' -test_atom refs/tags/multiline contents:subject 'first subject line second subject line' -test_atom refs/tags/multiline body 'first body line -second body line -' -test_atom refs/tags/multiline contents:body 'first body line -second body line -' -test_atom refs/tags/multiline contents:signature '' -test_atom refs/tags/multiline contents 'first subject line -second subject line - -first body line -second body line -' - -test_expect_success GPG 'create signed tags' ' - git tag -s -m "" signed-empty && - git tag -s -m "subject line" signed-short && - cat >msg <<-\EOF && - subject line - - body contents - EOF - git tag -s -F msg signed-long -' - -sig='-----BEGIN PGP SIGNATURE----- ------END PGP SIGNATURE----- -' - -PREREQ=GPG -test_atom refs/tags/signed-empty subject '' -test_atom refs/tags/signed-empty subject:sanitize '' -test_atom refs/tags/signed-empty contents:subject '' -test_atom refs/tags/signed-empty body "$sig" -test_atom refs/tags/signed-empty contents:body '' -test_atom refs/tags/signed-empty contents:signature "$sig" -test_atom refs/tags/signed-empty contents "$sig" - -test_expect_success GPG 'basic atom: refs/tags/signed-empty raw' ' - git cat-file tag refs/tags/signed-empty >expected && - git for-each-ref --format="%(raw)" refs/tags/signed-empty >actual && - sanitize_pgp <expected >expected.clean && - echo >>expected.clean && - sanitize_pgp <actual >actual.clean && - test_cmp expected.clean actual.clean -' - -test_atom refs/tags/signed-short subject 'subject line' -test_atom refs/tags/signed-short subject:sanitize 'subject-line' -test_atom refs/tags/signed-short contents:subject 'subject line' -test_atom refs/tags/signed-short body "$sig" -test_atom refs/tags/signed-short contents:body '' -test_atom refs/tags/signed-short contents:signature "$sig" -test_atom refs/tags/signed-short contents "subject line -$sig" - -test_expect_success GPG 'basic atom: refs/tags/signed-short raw' ' - git cat-file tag refs/tags/signed-short >expected && - git for-each-ref --format="%(raw)" refs/tags/signed-short >actual && - sanitize_pgp <expected >expected.clean && - echo >>expected.clean && - sanitize_pgp <actual >actual.clean && - test_cmp expected.clean actual.clean -' - -test_atom refs/tags/signed-long subject 'subject line' -test_atom refs/tags/signed-long subject:sanitize 'subject-line' -test_atom refs/tags/signed-long contents:subject 'subject line' -test_atom refs/tags/signed-long body "body contents -$sig" -test_atom refs/tags/signed-long contents:body 'body contents -' -test_atom refs/tags/signed-long contents:signature "$sig" -test_atom refs/tags/signed-long contents "subject line - -body contents -$sig" - -test_expect_success GPG 'basic atom: refs/tags/signed-long raw' ' - git cat-file tag refs/tags/signed-long >expected && - git for-each-ref --format="%(raw)" refs/tags/signed-long >actual && - sanitize_pgp <expected >expected.clean && - echo >>expected.clean && - sanitize_pgp <actual >actual.clean && - test_cmp expected.clean actual.clean -' - -test_expect_success 'set up refs pointing to tree and blob' ' - git update-ref refs/mytrees/first refs/heads/main^{tree} && - git update-ref refs/myblobs/first refs/heads/main:one -' - -test_atom refs/mytrees/first subject "" -test_atom refs/mytrees/first contents:subject "" -test_atom refs/mytrees/first body "" -test_atom refs/mytrees/first contents:body "" -test_atom refs/mytrees/first contents:signature "" -test_atom refs/mytrees/first contents "" - -test_expect_success 'basic atom: refs/mytrees/first raw' ' - git cat-file tree refs/mytrees/first >expected && - echo >>expected && - git for-each-ref --format="%(raw)" refs/mytrees/first >actual && - test_cmp expected actual && - git cat-file -s refs/mytrees/first >expected && - git for-each-ref --format="%(raw:size)" refs/mytrees/first >actual && - test_cmp expected actual -' - -test_atom refs/myblobs/first subject "" -test_atom refs/myblobs/first contents:subject "" -test_atom refs/myblobs/first body "" -test_atom refs/myblobs/first contents:body "" -test_atom refs/myblobs/first contents:signature "" -test_atom refs/myblobs/first contents "" - -test_expect_success 'basic atom: refs/myblobs/first raw' ' - git cat-file blob refs/myblobs/first >expected && - echo >>expected && - git for-each-ref --format="%(raw)" refs/myblobs/first >actual && - test_cmp expected actual && - git cat-file -s refs/myblobs/first >expected && - git for-each-ref --format="%(raw:size)" refs/myblobs/first >actual && - test_cmp expected actual -' - -test_expect_success 'set up refs pointing to binary blob' ' - printf "a\0b\0c" >blob1 && - printf "a\0c\0b" >blob2 && - printf "\0a\0b\0c" >blob3 && - printf "abc" >blob4 && - printf "\0 \0 \0 " >blob5 && - printf "\0 \0a\0 " >blob6 && - printf " " >blob7 && - >blob8 && - obj=$(git hash-object -w blob1) && - git update-ref refs/myblobs/blob1 "$obj" && - obj=$(git hash-object -w blob2) && - git update-ref refs/myblobs/blob2 "$obj" && - obj=$(git hash-object -w blob3) && - git update-ref refs/myblobs/blob3 "$obj" && - obj=$(git hash-object -w blob4) && - git update-ref refs/myblobs/blob4 "$obj" && - obj=$(git hash-object -w blob5) && - git update-ref refs/myblobs/blob5 "$obj" && - obj=$(git hash-object -w blob6) && - git update-ref refs/myblobs/blob6 "$obj" && - obj=$(git hash-object -w blob7) && - git update-ref refs/myblobs/blob7 "$obj" && - obj=$(git hash-object -w blob8) && - git update-ref refs/myblobs/blob8 "$obj" -' - -test_expect_success 'Verify sorts with raw' ' - cat >expected <<-EOF && - refs/myblobs/blob8 - refs/myblobs/blob5 - refs/myblobs/blob6 - refs/myblobs/blob3 - refs/myblobs/blob7 - refs/mytrees/first - refs/myblobs/first - refs/myblobs/blob1 - refs/myblobs/blob2 - refs/myblobs/blob4 - refs/heads/main - EOF - git for-each-ref --format="%(refname)" --sort=raw \ - refs/heads/main refs/myblobs/ refs/mytrees/first >actual && - test_cmp expected actual -' - -test_expect_success 'Verify sorts with raw:size' ' - cat >expected <<-EOF && - refs/myblobs/blob8 - refs/myblobs/blob7 - refs/myblobs/blob4 - refs/myblobs/blob1 - refs/myblobs/blob2 - refs/myblobs/blob3 - refs/myblobs/blob5 - refs/myblobs/blob6 - refs/myblobs/first - refs/mytrees/first - refs/heads/main - EOF - git for-each-ref --format="%(refname)" --sort=raw:size \ - refs/heads/main refs/myblobs/ refs/mytrees/first >actual && - test_cmp expected actual -' - -test_expect_success 'validate raw atom with %(if:equals)' ' - cat >expected <<-EOF && - not equals - not equals - not equals - not equals - not equals - not equals - refs/myblobs/blob4 - not equals - not equals - not equals - not equals - not equals - EOF - git for-each-ref --format="%(if:equals=abc)%(raw)%(then)%(refname)%(else)not equals%(end)" \ - refs/myblobs/ refs/heads/ >actual && - test_cmp expected actual -' - -test_expect_success 'validate raw atom with %(if:notequals)' ' - cat >expected <<-EOF && - refs/heads/ambiguous - refs/heads/main - refs/heads/newtag - refs/myblobs/blob1 - refs/myblobs/blob2 - refs/myblobs/blob3 - equals - refs/myblobs/blob5 - refs/myblobs/blob6 - refs/myblobs/blob7 - refs/myblobs/blob8 - refs/myblobs/first - EOF - git for-each-ref --format="%(if:notequals=abc)%(raw)%(then)%(refname)%(else)equals%(end)" \ - refs/myblobs/ refs/heads/ >actual && - test_cmp expected actual -' - -test_expect_success 'empty raw refs with %(if)' ' - cat >expected <<-EOF && - refs/myblobs/blob1 not empty - refs/myblobs/blob2 not empty - refs/myblobs/blob3 not empty - refs/myblobs/blob4 not empty - refs/myblobs/blob5 not empty - refs/myblobs/blob6 not empty - refs/myblobs/blob7 empty - refs/myblobs/blob8 empty - refs/myblobs/first not empty - EOF - git for-each-ref --format="%(refname) %(if)%(raw)%(then)not empty%(else)empty%(end)" \ - refs/myblobs/ >actual && - test_cmp expected actual -' - -test_expect_success '%(raw) with --python must fail' ' - test_must_fail git for-each-ref --format="%(raw)" --python -' - -test_expect_success '%(raw) with --tcl must fail' ' - test_must_fail git for-each-ref --format="%(raw)" --tcl -' - -test_expect_success PERL_TEST_HELPERS '%(raw) with --perl' ' - git for-each-ref --format="\$name= %(raw); -print \"\$name\"" refs/myblobs/blob1 --perl | perl >actual && - cmp blob1 actual && - git for-each-ref --format="\$name= %(raw); -print \"\$name\"" refs/myblobs/blob3 --perl | perl >actual && - cmp blob3 actual && - git for-each-ref --format="\$name= %(raw); -print \"\$name\"" refs/myblobs/blob8 --perl | perl >actual && - cmp blob8 actual && - git for-each-ref --format="\$name= %(raw); -print \"\$name\"" refs/myblobs/first --perl | perl >actual && - cmp one actual && - git cat-file tree refs/mytrees/first > expected && - git for-each-ref --format="\$name= %(raw); -print \"\$name\"" refs/mytrees/first --perl | perl >actual && - cmp expected actual -' - -test_expect_success '%(raw) with --shell must fail' ' - test_must_fail git for-each-ref --format="%(raw)" --shell -' - -test_expect_success '%(raw) with --shell and --sort=raw must fail' ' - test_must_fail git for-each-ref --format="%(raw)" --sort=raw --shell -' - -test_expect_success '%(raw:size) with --shell' ' - git for-each-ref --format="%(raw:size)" | sed "s/^/$SQ/;s/$/$SQ/" >expect && - git for-each-ref --format="%(raw:size)" --shell >actual && - test_cmp expect actual -' - -test_expect_success 'for-each-ref --format compare with cat-file --batch' ' - git rev-parse refs/mytrees/first | git cat-file --batch >expected && - git for-each-ref --format="%(objectname) %(objecttype) %(objectsize) -%(raw)" refs/mytrees/first >actual && - test_cmp expected actual -' - -test_expect_success 'verify sorts with contents:size' ' - cat >expect <<-\EOF && - refs/heads/main - refs/heads/newtag - refs/heads/ambiguous - EOF - git for-each-ref --format="%(refname)" \ - --sort=contents:size refs/heads/ >actual && - test_cmp expect actual -' - -test_expect_success 'set up multiple-sort tags' ' - for when in 100000 200000 - do - for email in user1 user2 - do - for ref in ref1 ref2 - do - GIT_COMMITTER_DATE="@$when +0000" \ - GIT_COMMITTER_EMAIL="$email@example.com" \ - git tag -m "tag $ref-$when-$email" \ - multi-$ref-$when-$email || return 1 - done - done - done -' - -test_expect_success 'Verify sort with multiple keys' ' - cat >expected <<-\EOF && - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 - EOF - git for-each-ref \ - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ - --sort=-refname \ - --sort=taggeremail \ - --sort=taggerdate \ - "refs/tags/multi-*" >actual && - test_cmp expected actual -' - -test_expect_success 'equivalent sorts fall back on refname' ' - cat >expected <<-\EOF && - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 - EOF - git for-each-ref \ - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ - --sort=taggerdate \ - "refs/tags/multi-*" >actual && - test_cmp expected actual -' - -test_expect_success '--no-sort cancels the previous sort keys' ' - cat >expected <<-\EOF && - 100000 <user1@example.com> refs/tags/multi-ref1-100000-user1 - 100000 <user2@example.com> refs/tags/multi-ref1-100000-user2 - 100000 <user1@example.com> refs/tags/multi-ref2-100000-user1 - 100000 <user2@example.com> refs/tags/multi-ref2-100000-user2 - 200000 <user1@example.com> refs/tags/multi-ref1-200000-user1 - 200000 <user2@example.com> refs/tags/multi-ref1-200000-user2 - 200000 <user1@example.com> refs/tags/multi-ref2-200000-user1 - 200000 <user2@example.com> refs/tags/multi-ref2-200000-user2 - EOF - git for-each-ref \ - --format="%(taggerdate:unix) %(taggeremail) %(refname)" \ - --sort=-refname \ - --sort=taggeremail \ - --no-sort \ - --sort=taggerdate \ - "refs/tags/multi-*" >actual && - test_cmp expected actual -' - -test_expect_success '--no-sort without subsequent --sort prints expected refs' ' - cat >expected <<-\EOF && - refs/tags/multi-ref1-100000-user1 - refs/tags/multi-ref1-100000-user2 - refs/tags/multi-ref1-200000-user1 - refs/tags/multi-ref1-200000-user2 - refs/tags/multi-ref2-100000-user1 - refs/tags/multi-ref2-100000-user2 - refs/tags/multi-ref2-200000-user1 - refs/tags/multi-ref2-200000-user2 - EOF - - # Sort the results with `sort` for a consistent comparison against - # expected - git for-each-ref \ - --format="%(refname)" \ - --no-sort \ - "refs/tags/multi-*" | sort >actual && - test_cmp expected actual -' - -test_expect_success 'set up custom date sorting' ' - # Dates: - # - Wed Feb 07 2024 21:34:20 +0000 - # - Tue Dec 14 1999 00:05:22 +0000 - # - Fri Jun 04 2021 11:26:51 +0000 - # - Mon Jan 22 2007 16:44:01 GMT+0000 - i=1 && - for when in 1707341660 945129922 1622806011 1169484241 - do - GIT_COMMITTER_DATE="@$when +0000" \ - GIT_COMMITTER_EMAIL="user@example.com" \ - git tag -m "tag $when" custom-dates-$i && - i=$(($i+1)) || return 1 - done -' - -test_expect_success 'sort by date defaults to full timestamp' ' - cat >expected <<-\EOF && - 945129922 refs/tags/custom-dates-2 - 1169484241 refs/tags/custom-dates-4 - 1622806011 refs/tags/custom-dates-3 - 1707341660 refs/tags/custom-dates-1 - EOF - - git for-each-ref \ - --format="%(creatordate:unix) %(refname)" \ - --sort=creatordate \ - "refs/tags/custom-dates-*" >actual && - test_cmp expected actual -' - -test_expect_success 'sort by custom date format' ' - cat >expected <<-\EOF && - 00:05:22 refs/tags/custom-dates-2 - 11:26:51 refs/tags/custom-dates-3 - 16:44:01 refs/tags/custom-dates-4 - 21:34:20 refs/tags/custom-dates-1 - EOF - - git for-each-ref \ - --format="%(creatordate:format:%H:%M:%S) %(refname)" \ - --sort="creatordate:format:%H:%M:%S" \ - "refs/tags/custom-dates-*" >actual && - test_cmp expected actual -' - -test_expect_success 'do not dereference NULL upon %(HEAD) on unborn branch' ' - test_when_finished "git checkout main" && - git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && - sed -e "s/^\* / /" actual >expect && - git checkout --orphan orphaned-branch && - git for-each-ref --format="%(HEAD) %(refname:short)" refs/heads/ >actual && - test_cmp expect actual -' - -cat >trailers <<EOF -Reviewed-by: A U Thor <author@example.com> -Signed-off-by: A U Thor <author@example.com> -[ v2 updated patch description ] -Acked-by: A U Thor - <author@example.com> -EOF - -unfold () { - perl -0pe 's/\n\s+/ /g' -} - -test_expect_success 'set up trailers for next test' ' - echo "Some contents" > two && - git add two && - git commit -F - <<-EOF - trailers: this commit message has trailers - - Some message contents - - $(cat trailers) - EOF -' - -test_trailer_option () { - if test "$#" -eq 3 - then - prereq="$1" - shift - fi && - title=$1 option=$2 - cat >expect - test_expect_success $prereq "$title" ' - git for-each-ref --format="%($option)" refs/heads/main >actual && - test_cmp expect actual && - git for-each-ref --format="%(contents:$option)" refs/heads/main >actual && - test_cmp expect actual - ' -} - -test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) unfolds trailers' \ - 'trailers:unfold' <<-EOF - $(unfold <trailers) - - EOF - -test_trailer_option '%(trailers:only) shows only "key: value" trailers' \ - 'trailers:only' <<-EOF - $(grep -v patch.description <trailers) - - EOF - -test_trailer_option '%(trailers:only=no,only=true) shows only "key: value" trailers' \ - 'trailers:only=no,only=true' <<-EOF - $(grep -v patch.description <trailers) - - EOF - -test_trailer_option '%(trailers:only=yes) shows only "key: value" trailers' \ - 'trailers:only=yes' <<-EOF - $(grep -v patch.description <trailers) - - EOF - -test_trailer_option '%(trailers:only=no) shows all trailers' \ - 'trailers:only=no' <<-EOF - $(cat trailers) - - EOF - -test_trailer_option PERL_TEST_HELPERS '%(trailers:only) and %(trailers:unfold) work together' \ - 'trailers:only,unfold' <<-EOF - $(grep -v patch.description <trailers | unfold) - - EOF - -test_trailer_option PERL_TEST_HELPERS '%(trailers:unfold) and %(trailers:only) work together' \ - 'trailers:unfold,only' <<-EOF - $(grep -v patch.description <trailers | unfold) - - EOF - -test_trailer_option '%(trailers:key=foo) shows that trailer' \ - 'trailers:key=Signed-off-by' <<-EOF - Signed-off-by: A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:key=foo) is case insensitive' \ - 'trailers:key=SiGned-oFf-bY' <<-EOF - Signed-off-by: A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:key=foo:) trailing colon also works' \ - 'trailers:key=Signed-off-by:' <<-EOF - Signed-off-by: A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:key=foo) multiple keys' \ - 'trailers:key=Reviewed-by:,key=Signed-off-by' <<-EOF - Reviewed-by: A U Thor <author@example.com> - Signed-off-by: A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:key=nonexistent) becomes empty' \ - 'trailers:key=Shined-off-by:' <<-EOF - - EOF - -test_trailer_option '%(trailers:key=foo) handles multiple lines even if folded' \ - 'trailers:key=Acked-by' <<-EOF - $(grep -v patch.description <trailers | grep -v Signed-off-by | grep -v Reviewed-by) - - EOF - -test_trailer_option '%(trailers:key=foo,unfold) properly unfolds' \ - 'trailers:key=Signed-Off-by,unfold' <<-EOF - $(unfold <trailers | grep Signed-off-by) - - EOF - -test_trailer_option '%(trailers:key=foo,only=no) also includes nontrailer lines' \ - 'trailers:key=Signed-off-by,only=no' <<-EOF - Signed-off-by: A U Thor <author@example.com> - $(grep patch.description <trailers) - - EOF - -test_trailer_option '%(trailers:key=foo,valueonly) shows only value' \ - 'trailers:key=Signed-off-by,valueonly' <<-EOF - A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:separator) changes separator' \ - 'trailers:separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF - Reviewed-by: A U Thor <author@example.com>,Signed-off-by: A U Thor <author@example.com> - EOF - -test_trailer_option '%(trailers:key_value_separator) changes key-value separator' \ - 'trailers:key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF - Reviewed-by,A U Thor <author@example.com> - Signed-off-by,A U Thor <author@example.com> - - EOF - -test_trailer_option '%(trailers:separator,key_value_separator) changes both separators' \ - 'trailers:separator=%x2C,key_value_separator=%x2C,key=Reviewed-by,key=Signed-off-by:' <<-EOF - Reviewed-by,A U Thor <author@example.com>,Signed-off-by,A U Thor <author@example.com> - EOF - -test_expect_success 'multiple %(trailers) use their own options' ' - git tag -F - tag-with-trailers <<-\EOF && - body - - one: foo - one: bar - two: baz - two: qux - EOF - t1="%(trailers:key=one,key_value_separator=W,separator=X)" && - t2="%(trailers:key=two,key_value_separator=Y,separator=Z)" && - git for-each-ref --format="$t1%0a$t2" refs/tags/tag-with-trailers >actual && - cat >expect <<-\EOF && - oneWfooXoneWbar - twoYbazZtwoYqux - EOF - test_cmp expect actual -' - -test_failing_trailer_option () { - title=$1 option=$2 - cat >expect - test_expect_success "$title" ' - # error message cannot be checked under i18n - test_must_fail git for-each-ref --format="%($option)" refs/heads/main 2>actual && - test_cmp expect actual && - test_must_fail git for-each-ref --format="%(contents:$option)" refs/heads/main 2>actual && - test_cmp expect actual - ' -} - -test_failing_trailer_option '%(trailers) rejects unknown trailers arguments' \ - 'trailers:unsupported' <<-\EOF - fatal: unknown %(trailers) argument: unsupported - EOF - -test_failing_trailer_option '%(trailers:key) without value is error' \ - 'trailers:key' <<-\EOF - fatal: expected %(trailers:key=<value>) - EOF - -test_expect_success 'if arguments, %(contents:trailers) shows error if colon is missing' ' - cat >expect <<-EOF && - fatal: unrecognized %(contents) argument: trailersonly - EOF - test_must_fail git for-each-ref --format="%(contents:trailersonly)" 2>actual && - test_cmp expect actual -' - -test_expect_success 'basic atom: head contents:trailers' ' - git for-each-ref --format="%(contents:trailers)" refs/heads/main >actual && - sanitize_pgp <actual >actual.clean && - # git for-each-ref ends with a blank line - cat >expect <<-EOF && - $(cat trailers) - - EOF - test_cmp expect actual.clean -' - -test_expect_success 'basic atom: rest must fail' ' - test_must_fail git for-each-ref --format="%(rest)" refs/heads/main -' - -test_expect_success 'HEAD atom does not take arguments' ' - test_must_fail git for-each-ref --format="%(HEAD:foo)" 2>err && - echo "fatal: %(HEAD) does not take arguments" >expect && - test_cmp expect err -' - -test_expect_success 'subject atom rejects unknown arguments' ' - test_must_fail git for-each-ref --format="%(subject:foo)" 2>err && - echo "fatal: unrecognized %(subject) argument: foo" >expect && - test_cmp expect err -' - -test_expect_success 'refname atom rejects unknown arguments' ' - test_must_fail git for-each-ref --format="%(refname:foo)" 2>err && - echo "fatal: unrecognized %(refname) argument: foo" >expect && - test_cmp expect err -' - -test_expect_success 'trailer parsing not fooled by --- line' ' - git commit --allow-empty -F - <<-\EOF && - this is the subject - - This is the body. The message has a "---" line which would confuse a - message+patch parser. But here we know we have only a commit message, - so we get it right. - - trailer: wrong - --- - This is more body. - - trailer: right - EOF - - { - echo "trailer: right" && - echo - } >expect && - git for-each-ref --format="%(trailers)" refs/heads/main >actual && - test_cmp expect actual -' - -test_expect_success 'Add symbolic ref for the following tests' ' - git symbolic-ref refs/heads/sym refs/heads/main -' - -cat >expected <<EOF -refs/heads/main -EOF - -test_expect_success 'Verify usage of %(symref) atom' ' - git for-each-ref --format="%(symref)" refs/heads/sym >actual && - test_cmp expected actual -' - -cat >expected <<EOF -heads/main -EOF - -test_expect_success 'Verify usage of %(symref:short) atom' ' - git for-each-ref --format="%(symref:short)" refs/heads/sym >actual && - test_cmp expected actual -' - -cat >expected <<EOF -main -heads/main -EOF - -test_expect_success 'Verify usage of %(symref:lstrip) atom' ' - git for-each-ref --format="%(symref:lstrip=2)" refs/heads/sym > actual && - git for-each-ref --format="%(symref:lstrip=-2)" refs/heads/sym >> actual && - test_cmp expected actual && - - git for-each-ref --format="%(symref:strip=2)" refs/heads/sym > actual && - git for-each-ref --format="%(symref:strip=-2)" refs/heads/sym >> actual && - test_cmp expected actual -' - -cat >expected <<EOF -refs -refs/heads -EOF - -test_expect_success 'Verify usage of %(symref:rstrip) atom' ' - git for-each-ref --format="%(symref:rstrip=2)" refs/heads/sym > actual && - git for-each-ref --format="%(symref:rstrip=-2)" refs/heads/sym >> actual && - test_cmp expected actual -' - -test_expect_success ':remotename and :remoteref' ' - git init remote-tests && - ( - cd remote-tests && - test_commit initial && - git branch -M main && - git remote add from fifth.coffee:blub && - git config branch.main.remote from && - git config branch.main.merge refs/heads/stable && - git remote add to southridge.audio:repo && - git config remote.to.push "refs/heads/*:refs/heads/pushed/*" && - git config branch.main.pushRemote to && - for pair in "%(upstream)=refs/remotes/from/stable" \ - "%(upstream:remotename)=from" \ - "%(upstream:remoteref)=refs/heads/stable" \ - "%(push)=refs/remotes/to/pushed/main" \ - "%(push:remotename)=to" \ - "%(push:remoteref)=refs/heads/pushed/main" - do - echo "${pair#*=}" >expect && - git for-each-ref --format="${pair%=*}" \ - refs/heads/main >actual && - test_cmp expect actual || exit 1 - done && - git branch push-simple && - git config branch.push-simple.pushRemote from && - actual="$(git for-each-ref \ - --format="%(push:remotename),%(push:remoteref)" \ - refs/heads/push-simple)" && - test from, = "$actual" - ) -' - -test_expect_success 'for-each-ref --ignore-case ignores case' ' - git for-each-ref --format="%(refname)" refs/heads/MAIN >actual && - test_must_be_empty actual && - - echo refs/heads/main >expect && - git for-each-ref --format="%(refname)" --ignore-case \ - refs/heads/MAIN >actual && - test_cmp expect actual -' - -test_expect_success 'for-each-ref --omit-empty works' ' - git for-each-ref --format="%(refname)" >actual && - test_line_count -gt 1 actual && - git for-each-ref --format="%(if:equals=refs/heads/main)%(refname)%(then)%(refname)%(end)" --omit-empty >actual && - echo refs/heads/main >expect && - test_cmp expect actual -' - -test_expect_success 'for-each-ref --ignore-case works on multiple sort keys' ' - # name refs numerically to avoid case-insensitive filesystem conflicts - nr=0 && - for email in a A b B - do - for subject in a A b B - do - GIT_COMMITTER_EMAIL="$email@example.com" \ - git tag -m "tag $subject" icase-$(printf %02d $nr) && - nr=$((nr+1))|| - return 1 - done - done && - git for-each-ref --ignore-case \ - --format="%(taggeremail) %(subject) %(refname)" \ - --sort=refname \ - --sort=subject \ - --sort=taggeremail \ - refs/tags/icase-* >actual && - cat >expect <<-\EOF && - <a@example.com> tag a refs/tags/icase-00 - <a@example.com> tag A refs/tags/icase-01 - <A@example.com> tag a refs/tags/icase-04 - <A@example.com> tag A refs/tags/icase-05 - <a@example.com> tag b refs/tags/icase-02 - <a@example.com> tag B refs/tags/icase-03 - <A@example.com> tag b refs/tags/icase-06 - <A@example.com> tag B refs/tags/icase-07 - <b@example.com> tag a refs/tags/icase-08 - <b@example.com> tag A refs/tags/icase-09 - <B@example.com> tag a refs/tags/icase-12 - <B@example.com> tag A refs/tags/icase-13 - <b@example.com> tag b refs/tags/icase-10 - <b@example.com> tag B refs/tags/icase-11 - <B@example.com> tag b refs/tags/icase-14 - <B@example.com> tag B refs/tags/icase-15 - EOF - test_cmp expect actual -' - -test_expect_success 'for-each-ref reports broken tags' ' - git tag -m "good tag" broken-tag-good HEAD && - git cat-file tag broken-tag-good >good && - sed s/commit/blob/ <good >bad && - bad=$(git hash-object -w -t tag bad) && - git update-ref refs/tags/broken-tag-bad $bad && - test_must_fail git for-each-ref --format="%(*objectname)" \ - refs/tags/broken-tag-* -' - -test_expect_success 'set up tag with signature and no blank lines' ' - git tag -F - fake-sig-no-blanks <<-\EOF - this is the subject - -----BEGIN PGP SIGNATURE----- - not a real signature, but we just care about the - subject/body parsing. It is important here that - there are no blank lines in the signature. - -----END PGP SIGNATURE----- - EOF -' - -test_atom refs/tags/fake-sig-no-blanks contents:subject 'this is the subject' -test_atom refs/tags/fake-sig-no-blanks contents:body '' -test_atom refs/tags/fake-sig-no-blanks contents:signature "$sig" - -test_expect_success 'set up tag with CRLF signature' ' - append_cr <<-\EOF | - this is the subject - -----BEGIN PGP SIGNATURE----- - - not a real signature, but we just care about - the subject/body parsing. It is important here - that there is a blank line separating this - from the signature header. - -----END PGP SIGNATURE----- - EOF - git tag -F - --cleanup=verbatim fake-sig-crlf -' - -test_atom refs/tags/fake-sig-crlf contents:subject 'this is the subject' -test_atom refs/tags/fake-sig-crlf contents:body '' - -# CRLF is retained in the signature, so we have to pass our expected value -# through append_cr. But test_atom requires a shell string, which means command -# substitution, and the shell will strip trailing newlines from the output of -# the substitution. Hack around it by adding and then removing a dummy line. -sig_crlf="$(printf "%s" "$sig" | append_cr; echo dummy)" -sig_crlf=${sig_crlf%dummy} -test_atom refs/tags/fake-sig-crlf contents:signature "$sig_crlf" - -test_expect_success 'set up tag with signature and trailers' ' - git tag -F - fake-sig-trailer <<-\EOF - this is the subject - - this is the body - - My-Trailer: foo - -----BEGIN PGP SIGNATURE----- - - not a real signature, but we just care about the - subject/body/trailer parsing. - -----END PGP SIGNATURE----- - EOF -' - -# use "separator=" here to suppress the terminating newline -test_atom refs/tags/fake-sig-trailer trailers:separator= 'My-Trailer: foo' - -test_expect_success 'git for-each-ref --stdin: empty' ' - >in && - git for-each-ref --format="%(refname)" --stdin <in >actual && - git for-each-ref --format="%(refname)" >expect && - test_cmp expect actual -' - -test_expect_success 'git for-each-ref --stdin: fails if extra args' ' - >in && - test_must_fail git for-each-ref --format="%(refname)" \ - --stdin refs/heads/extra <in 2>err && - grep "unknown arguments supplied with --stdin" err -' - -test_expect_success 'git for-each-ref --stdin: matches' ' - cat >in <<-EOF && - refs/tags/multi* - refs/heads/amb* - EOF - - cat >expect <<-EOF && - refs/heads/ambiguous - refs/tags/multi-ref1-100000-user1 - refs/tags/multi-ref1-100000-user2 - refs/tags/multi-ref1-200000-user1 - refs/tags/multi-ref1-200000-user2 - refs/tags/multi-ref2-100000-user1 - refs/tags/multi-ref2-100000-user2 - refs/tags/multi-ref2-200000-user1 - refs/tags/multi-ref2-200000-user2 - refs/tags/multiline - EOF - - git for-each-ref --format="%(refname)" --stdin <in >actual && - test_cmp expect actual -' - -test_expect_success 'git for-each-ref with non-existing refs' ' - cat >in <<-EOF && - refs/heads/this-ref-does-not-exist - refs/tags/bogus - EOF - - git for-each-ref --format="%(refname)" --stdin <in >actual && - test_must_be_empty actual && - - xargs git for-each-ref --format="%(refname)" <in >actual && - test_must_be_empty actual -' - -test_expect_success 'git for-each-ref with nested tags' ' - git tag -am "Normal tag" nested/base HEAD && - git tag -am "Nested tag" nested/nest1 refs/tags/nested/base && - git tag -am "Double nested tag" nested/nest2 refs/tags/nested/nest1 && - - head_oid="$(git rev-parse HEAD)" && - base_tag_oid="$(git rev-parse refs/tags/nested/base)" && - nest1_tag_oid="$(git rev-parse refs/tags/nested/nest1)" && - nest2_tag_oid="$(git rev-parse refs/tags/nested/nest2)" && - - cat >expect <<-EOF && - refs/tags/nested/base $base_tag_oid tag $head_oid commit - refs/tags/nested/nest1 $nest1_tag_oid tag $head_oid commit - refs/tags/nested/nest2 $nest2_tag_oid tag $head_oid commit - EOF - - git for-each-ref \ - --format="%(refname) %(objectname) %(objecttype) %(*objectname) %(*objecttype)" \ - refs/tags/nested/ >actual && - test_cmp expect actual -' - -test_expect_success 'is-base atom with non-commits' ' - git for-each-ref --format="%(is-base:HEAD) %(refname)" >out 2>err && - grep "(HEAD) refs/heads/main" out && - - test_line_count = 2 err && - grep "error: object .* is a commit, not a blob" err && - grep "error: bad tag pointer to" err -' - -GRADE_FORMAT="%(signature:grade)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" -TRUSTLEVEL_FORMAT="%(signature:trustlevel)%0a%(signature:key)%0a%(signature:signer)%0a%(signature:fingerprint)%0a%(signature:primarykeyfingerprint)" - -test_expect_success GPG 'setup for signature atom using gpg' ' - git checkout -b signed && - - test_when_finished "test_unconfig commit.gpgSign" && - - echo "1" >file && - git add file && - test_tick && - git commit -S -m "file: 1" && - git tag first-signed && - - echo "2" >file && - test_tick && - git commit -a -m "file: 2" && - git tag second-unsigned && - - git config commit.gpgSign 1 && - echo "3" >file && - test_tick && - git commit -a --no-gpg-sign -m "file: 3" && - git tag third-unsigned && - - test_tick && - git rebase -f HEAD^^ && git tag second-signed HEAD^ && - git tag third-signed && - - echo "4" >file && - test_tick && - git commit -a -SB7227189 -m "file: 4" && - git tag fourth-signed && - - echo "5" >file && - test_tick && - git commit -a --no-gpg-sign -m "file: 5" && - git tag fifth-unsigned && - - echo "6" >file && - test_tick && - git commit -a --no-gpg-sign -m "file: 6" && - - test_tick && - git rebase -f HEAD^^ && - git tag fifth-signed HEAD^ && - git tag sixth-signed && - - echo "7" >file && - test_tick && - git commit -a --no-gpg-sign -m "file: 7" && - git tag seventh-unsigned -' - -test_expect_success GPGSSH 'setup for signature atom using ssh' ' - test_when_finished "test_unconfig gpg.format user.signingkey" && - - test_config gpg.format ssh && - test_config user.signingkey "${GPGSSH_KEY_PRIMARY}" && - echo "8" >file && - test_tick && - git add file && - git commit -S -m "file: 8" && - git tag eighth-signed-ssh -' - -test_expect_success GPG2 'bare signature atom' ' - git verify-commit first-signed 2>expect && - echo >>expect && - git for-each-ref refs/tags/first-signed \ - --format="%(signature)" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show good signature with custom format' ' - git verify-commit first-signed && - cat >expect <<-\EOF && - G - 13B6F51ECDDE430D - C O Mitter <committer@example.com> - 73D758744BE721698EC54E8713B6F51ECDDE430D - 73D758744BE721698EC54E8713B6F51ECDDE430D - EOF - git for-each-ref refs/tags/first-signed \ - --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' -test_expect_success GPGSSH 'show good signature with custom format with ssh' ' - test_config gpg.ssh.allowedSignersFile "${GPGSSH_ALLOWED_SIGNERS}" && - FINGERPRINT=$(ssh-keygen -lf "${GPGSSH_KEY_PRIMARY}" | awk "{print \$2;}") && - cat >expect.tmpl <<-\EOF && - G - FINGERPRINT - principal with number 1 - FINGERPRINT - - EOF - sed "s|FINGERPRINT|$FINGERPRINT|g" expect.tmpl >expect && - git for-each-ref refs/tags/eighth-signed-ssh \ - --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'signature atom with grade option and bad signature' ' - git cat-file commit third-signed >raw && - sed -e "s/^file: 3/file: 3 forged/" raw >forged1 && - FORGED1=$(git hash-object -w -t commit forged1) && - git update-ref refs/tags/third-signed "$FORGED1" && - test_must_fail git verify-commit "$FORGED1" && - - cat >expect <<-\EOF && - B - 13B6F51ECDDE430D - C O Mitter <committer@example.com> - - - EOF - git for-each-ref refs/tags/third-signed \ - --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show untrusted signature with custom format' ' - cat >expect <<-\EOF && - U - 65A0EEA02E30CAD7 - Eris Discordia <discord@example.net> - F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 - D4BE22311AD3131E5EDA29A461092E85B7227189 - EOF - git for-each-ref refs/tags/fourth-signed \ - --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show untrusted signature with undefined trust level' ' - cat >expect <<-\EOF && - undefined - 65A0EEA02E30CAD7 - Eris Discordia <discord@example.net> - F8364A59E07FFE9F4D63005A65A0EEA02E30CAD7 - D4BE22311AD3131E5EDA29A461092E85B7227189 - EOF - git for-each-ref refs/tags/fourth-signed \ - --format="$TRUSTLEVEL_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show untrusted signature with ultimate trust level' ' - cat >expect <<-\EOF && - ultimate - 13B6F51ECDDE430D - C O Mitter <committer@example.com> - 73D758744BE721698EC54E8713B6F51ECDDE430D - 73D758744BE721698EC54E8713B6F51ECDDE430D - EOF - git for-each-ref refs/tags/sixth-signed \ - --format="$TRUSTLEVEL_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show unknown signature with custom format' ' - cat >expect <<-\EOF && - E - 13B6F51ECDDE430D - - - - EOF - GNUPGHOME="$GNUPGHOME_NOT_USED" git for-each-ref \ - refs/tags/sixth-signed --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' - -test_expect_success GPG 'show lack of signature with custom format' ' - cat >expect <<-\EOF && - N - - - - - EOF - git for-each-ref refs/tags/seventh-unsigned \ - --format="$GRADE_FORMAT" >actual && - test_cmp expect actual -' +. "$TEST_DIRECTORY"/for-each-ref-tests.sh test_done diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index bb02b86c16..9b80ea1e3b 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -541,4 +541,217 @@ test_expect_success 'validate worktree atom' ' test_cmp expect actual ' +test_expect_success 'start after with empty value' ' + cat >expect <<-\EOF && + refs/heads/main + refs/heads/main_worktree + refs/heads/side + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after="" >actual && + test_cmp expect actual +' + +test_expect_success 'start after a specific reference' ' + cat >expect <<-\EOF && + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/spot >actual && + test_cmp expect actual +' + +test_expect_success 'start after a specific reference with partial match' ' + cat >expect <<-\EOF && + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/sp >actual && + test_cmp expect actual +' + +test_expect_success 'start after, just behind a specific reference' ' + cat >expect <<-\EOF && + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/parrot >actual && + test_cmp expect actual +' + +test_expect_success 'start after with specific directory match' ' + cat >expect <<-\EOF && + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd >actual && + test_cmp expect actual +' + +test_expect_success 'start after with specific directory and trailing slash' ' + cat >expect <<-\EOF && + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/ >actual && + test_cmp expect actual +' + +test_expect_success 'start after, just behind a specific directory' ' + cat >expect <<-\EOF && + refs/odd/spot + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/lost >actual && + test_cmp expect actual +' + +test_expect_success 'start after, overflow specific reference length' ' + cat >expect <<-\EOF && + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/spotnew >actual && + test_cmp expect actual +' + +test_expect_success 'start after, overflow specific reference path' ' + cat >expect <<-\EOF && + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/spot/new >actual && + test_cmp expect actual +' + +test_expect_success 'start after, with exclude pattern' ' + cat >expect <<-\EOF && + refs/tags/annotated-tag + refs/tags/doubly-annotated-tag + refs/tags/doubly-signed-tag + refs/tags/foo1.10 + refs/tags/foo1.3 + refs/tags/foo1.6 + refs/tags/four + refs/tags/one + refs/tags/signed-tag + refs/tags/three + refs/tags/two + EOF + git for-each-ref --format="%(refname)" --start-after=refs/odd/spot \ + --exclude=refs/tags/foo >actual && + test_cmp expect actual +' + +test_expect_success 'start after, last reference' ' + cat >expect <<-\EOF && + EOF + git for-each-ref --format="%(refname)" --start-after=refs/tags/two >actual && + test_cmp expect actual +' + +test_expect_success 'start after used with a pattern' ' + cat >expect <<-\EOF && + fatal: cannot use --start-after with patterns + EOF + test_must_fail git for-each-ref --format="%(refname)" --start-after=refs/odd/spot refs/tags 2>actual && + test_cmp expect actual +' + +test_expect_success 'start after used with custom sort order' ' + cat >expect <<-\EOF && + fatal: cannot use --start-after with custom sort options + EOF + test_must_fail git for-each-ref --format="%(refname)" --start-after=refs/odd/spot --sort=author 2>actual && + test_cmp expect actual +' + test_done diff --git a/t/t6423-merge-rename-directories.sh b/t/t6423-merge-rename-directories.sh index f48ed6d035..533ac85dc8 100755 --- a/t/t6423-merge-rename-directories.sh +++ b/t/t6423-merge-rename-directories.sh @@ -4731,7 +4731,7 @@ test_setup_12i () { mkdir -p source/subdir && echo foo >source/subdir/foo && - echo bar >source/bar && + printf "%d\n" 1 2 3 4 5 6 7 >source/bar && echo baz >source/baz && git add source && git commit -m orig && @@ -4747,6 +4747,7 @@ test_setup_12i () { git switch B && git mv source/bar source/subdir/bar && echo more baz >>source/baz && + git add source/baz && git commit -m B ) } @@ -4758,6 +4759,88 @@ test_expect_success '12i: Directory rename causes rename-to-self' ' git checkout A^0 && + # NOTE: A potentially better resolution would be for + # source/bar -> source/subdir/bar + # to use the directory rename to become + # source/bar -> source/bar + # (a rename to self), and thus we end up with bar with + # a path conflict (given merge.directoryRenames=conflict). + # However, since the relevant renames optimization + # prevents us from noticing + # source/bar -> source/subdir/bar + # as a rename and looking at it just as + # delete source/bar + # add source/subdir/bar + # the directory rename of source/subdir/bar -> source/bar does + # not look like a rename-to-self situation but a + # rename-on-top-of-other-file situation. We do not want + # stage 1 entries from an unrelated file, so we expect an + # error about there being a file in the way. + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + + grep "CONFLICT (implicit dir rename).*source/bar in the way" out && + test_path_is_missing source/bar && + test_path_is_file source/subdir/bar && + test_path_is_file source/baz && + + git ls-files >actual && + uniq <actual >tracked && + test_line_count = 3 tracked && + + git status --porcelain -uno >actual && + cat >expect <<-\EOF && + M source/baz + R source/bar -> source/subdir/bar + EOF + test_cmp expect actual + ) +' + +# Testcase 12i2, Identical to 12i except that source/subdir/bar modified on unrenamed side +# Commit O: source/{subdir/foo, bar, baz_1} +# Commit A: source/{foo, bar_2, baz_1} +# Commit B: source/{subdir/{foo, bar}, baz_2} +# Expected: source/{foo, bar, baz_2}, with conflicts on +# source/bar vs. source/subdir/bar + +test_setup_12i2 () { + git init 12i2 && + ( + cd 12i2 && + + mkdir -p source/subdir && + echo foo >source/subdir/foo && + printf "%d\n" 1 2 3 4 5 6 7 >source/bar && + echo baz >source/baz && + git add source && + git commit -m orig && + + git branch O && + git branch A && + git branch B && + + git switch A && + git mv source/subdir/foo source/foo && + echo 8 >> source/bar && + git add source/bar && + git commit -m A && + + git switch B && + git mv source/bar source/subdir/bar && + echo more baz >>source/baz && + git add source/baz && + git commit -m B + ) +} + +test_expect_success '12i2: Directory rename causes rename-to-self' ' + test_setup_12i2 && + ( + cd 12i2 && + + git checkout A^0 && + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 && test_path_is_missing source/subdir && @@ -4771,7 +4854,7 @@ test_expect_success '12i: Directory rename causes rename-to-self' ' git status --porcelain -uno >actual && cat >expect <<-\EOF && UU source/bar - M source/baz + M source/baz EOF test_cmp expect actual ) @@ -4806,6 +4889,7 @@ test_setup_12j () { git switch B && git mv bar subdir/bar && echo more baz >>baz && + git add baz && git commit -m B ) } @@ -4817,10 +4901,29 @@ test_expect_success '12j: Directory rename to root causes rename-to-self' ' git checkout A^0 && - test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 && - - test_path_is_missing subdir && - test_path_is_file bar && + # NOTE: A potentially better resolution would be for + # bar -> subdir/bar + # to use the directory rename to become + # bar -> bar + # (a rename to self), and thus we end up with bar with + # a path conflict (given merge.directoryRenames=conflict). + # However, since the relevant renames optimization + # prevents us from noticing + # bar -> subdir/bar + # as a rename and looking at it just as + # delete bar + # add subdir/bar + # the directory rename of subdir/bar -> bar does not look + # like a rename-to-self situation but a + # rename-on-top-of-other-file situation. We do not want + # stage 1 entries from an unrelated file, so we expect an + # error about there being a file in the way. + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + grep "CONFLICT (implicit dir rename).*bar in the way" out && + + test_path_is_missing bar && + test_path_is_file subdir/bar && test_path_is_file baz && git ls-files >actual && @@ -4829,8 +4932,8 @@ test_expect_success '12j: Directory rename to root causes rename-to-self' ' git status --porcelain -uno >actual && cat >expect <<-\EOF && - UU bar - M baz + M baz + R bar -> subdir/bar EOF test_cmp expect actual ) @@ -4865,6 +4968,7 @@ test_setup_12k () { git switch B && git mv dirA/bar dirB/bar && echo more baz >>dirA/baz && + git add dirA/baz && git commit -m B ) } @@ -4876,10 +4980,29 @@ test_expect_success '12k: Directory rename with sibling causes rename-to-self' ' git checkout A^0 && - test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 && - - test_path_is_missing dirB && - test_path_is_file dirA/bar && + # NOTE: A potentially better resolution would be for + # dirA/bar -> dirB/bar + # to use the directory rename (dirB/ -> dirA/) to become + # dirA/bar -> dirA/bar + # (a rename to self), and thus we end up with bar with + # a path conflict (given merge.directoryRenames=conflict). + # However, since the relevant renames optimization + # prevents us from noticing + # dirA/bar -> dirB/bar + # as a rename and looking at it just as + # delete dirA/bar + # add dirB/bar + # the directory rename of dirA/bar -> dirB/bar does + # not look like a rename-to-self situation but a + # rename-on-top-of-other-file situation. We do not want + # stage 1 entries from an unrelated file, so we expect an + # error about there being a file in the way. + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + grep "CONFLICT (implicit dir rename).*dirA/bar in the way" out && + + test_path_is_missing dirA/bar && + test_path_is_file dirB/bar && test_path_is_file dirA/baz && git ls-files >actual && @@ -4888,8 +5011,8 @@ test_expect_success '12k: Directory rename with sibling causes rename-to-self' ' git status --porcelain -uno >actual && cat >expect <<-\EOF && - UU dirA/bar - M dirA/baz + M dirA/baz + R dirA/bar -> dirB/bar EOF test_cmp expect actual ) @@ -5056,6 +5179,25 @@ test_expect_success '12m: Change parent of renamed-dir to symlink on other side' ) ' +# Testcase 12n, Directory rename transitively makes rename back to self +# +# (Since this is a cherry-pick instead of merge, the labels are a bit weird. +# O, the original commit, is A~1 rather than what branch O points to.) +# +# Commit O: tools/hello +# world +# Commit A: tools/hello +# tools/world +# Commit B: hello +# In words: +# A: world -> tools/world +# B: tools/ -> /, i.e. rename all of tools to toplevel directory +# delete world +# +# Expected: +# CONFLICT (file location): tools/world vs. world +# + test_setup_12n () { git init 12n && ( @@ -5092,10 +5234,357 @@ test_expect_success '12n: Directory rename transitively makes rename back to sel git checkout -q B^0 && test_must_fail git cherry-pick A^0 >out && - grep "CONFLICT (file location).*should perhaps be moved" out + test_grep "CONFLICT (file location).*should perhaps be moved" out && + + # Should have 1 entry for hello, and 2 for world + test_stdout_line_count = 3 git ls-files -s && + test_stdout_line_count = 1 git ls-files -s hello && + test_stdout_line_count = 2 git ls-files -s world + ) +' + +# Testcase 12n2, Directory rename transitively makes rename back to self +# +# Commit O: tools/hello +# world +# Commit A: tools/hello +# tools/world +# Commit B: hello +# In words: +# A: world -> tools/world +# B: tools/ -> /, i.e. rename all of tools to toplevel directory +# delete world +# +# Expected: +# CONFLICT (file location): tools/world vs. world +# + +test_setup_12n2 () { + git init 12n2 && + ( + cd 12n2 && + + mkdir tools && + echo hello >tools/hello && + git add tools/hello && + echo world >world && + git add world && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git switch A && + git mv world tools/world && + git commit -m "Move world into tools/" && + + git switch B && + git mv tools/hello hello && + git rm world && + git commit -m "Move hello from tools/ to toplevel" + ) +} + +test_expect_success '12n2: Directory rename transitively makes rename back to self' ' + test_setup_12n2 && + ( + cd 12n2 && + + git checkout -q B^0 && + + test_might_fail git -c merge.directoryRenames=true merge A^0 >out && + + # Should have 1 entry for hello, and either 0 or 2 for world + # + # NOTE: Since merge.directoryRenames=true, there is no path + # conflict for world vs. tools/world; it should end up at + # world. The fact that world was unmodified on side A, means + # there was no content conflict; we should just take the + # content from side B -- i.e. delete the file. So merging + # could just delete world. + # + # However, rename-to-self-via-directory-rename is a bit more + # challenging. Relax this test to allow world to be treated + # as a modify/delete conflict as well, meaning it will have + # two higher order stages, that just so happen to match. + # + test_stdout_line_count = 1 git ls-files -s hello && + test_stdout_line_count = 2 git ls-files -s world && + test_grep "CONFLICT (modify/delete).*world deleted in HEAD" out ) ' +# Testcase 12o, Directory rename hits other rename source; file still in way on same side +# Commit O: A/file1_1 +# A/stuff +# B/file1_2 +# B/stuff +# C/other +# Commit A: A/file1_1 +# A/stuff +# B/stuff +# C/file1_2 +# C/other +# Commit B: D/file2_1 +# A/stuff +# B/file1_2 +# B/stuff +# A/other +# In words: +# A: rename B/file1_2 -> C/file1_2 +# B: rename C/ -> A/ +# rename A/file1_1 -> D/file2_1 +# Rationale: +# A/stuff is unmodified, it shows up in final output +# B/stuff is unmodified, it shows up in final output +# C/other touched on one side (rename to A), so A/other shows up in output +# A/file1 is renamed to D/file2 +# B/file1 -> C/file1 and even though C/ -> A/, A/file1 is +# "in the way" so we don't do the directory rename +# Expected: A/stuff +# B/stuff +# A/other +# D/file2 +# C/file1 +# + CONFLICT (implicit dir rename): A/file1 in way of C/file1 +# + +test_setup_12o () { + git init 12o && + ( + cd 12o && + + mkdir -p A B C && + echo 1 >A/file1 && + echo 2 >B/file1 && + echo other >C/other && + echo Astuff >A/stuff && + echo Bstuff >B/stuff && + git add . && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git switch A && + git mv B/file1 C/ && + git add . && + git commit -m "A" && + + git switch B && + mkdir -p D && + git mv A/file1 D/file2 && + git mv C/other A/other && + git add . && + git commit -m "B" + ) +} + +test_expect_success '12o: Directory rename hits other rename source; file still in way on same side' ' + test_setup_12o && + ( + cd 12o && + + git checkout -q A^0 && + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + + test_stdout_line_count = 5 git ls-files -s && + test_stdout_line_count = 1 git ls-files -s A/other && + test_stdout_line_count = 1 git ls-files -s A/stuff && + test_stdout_line_count = 1 git ls-files -s B/stuff && + test_stdout_line_count = 1 git ls-files -s D/file2 && + + grep "CONFLICT (implicit dir rename).*Existing file/dir at A/file1 in the way" out && + test_stdout_line_count = 1 git ls-files -s C/file1 + ) +' + +# Testcase 12p, Directory rename hits other rename source; file still in way on other side +# Commit O: A/file1_1 +# A/stuff +# B/file1_2 +# B/stuff +# C/other +# Commit A: D/file2_1 +# A/stuff +# B/stuff +# C/file1_2 +# C/other +# Commit B: A/file1_1 +# A/stuff +# B/file1_2 +# B/stuff +# A/other +# Short version: +# A: rename A/file1_1 -> D/file2_1 +# rename B/file1_2 -> C/file1_2 +# B: Rename C/ -> A/ +# Rationale: +# A/stuff is unmodified, it shows up in final output +# B/stuff is unmodified, it shows up in final output +# C/other touched on one side (rename to A), so A/other shows up in output +# A/file1 is renamed to D/file2 +# B/file1 -> C/file1 and even though C/ -> A/, A/file1 is +# "in the way" so we don't do the directory rename +# Expected: A/stuff +# B/stuff +# A/other +# D/file2 +# C/file1 +# + CONFLICT (implicit dir rename): A/file1 in way of C/file1 +# + +test_setup_12p () { + git init 12p && + ( + cd 12p && + + mkdir -p A B C && + echo 1 >A/file1 && + echo 2 >B/file1 && + echo other >C/other && + echo Astuff >A/stuff && + echo Bstuff >B/stuff && + git add . && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git switch A && + mkdir -p D && + git mv A/file1 D/file2 && + git mv B/file1 C/ && + git add . && + git commit -m "A" && + + git switch B && + git mv C/other A/other && + git add . && + git commit -m "B" + ) +} + +test_expect_success '12p: Directory rename hits other rename source; file still in way on other side' ' + test_setup_12p && + ( + cd 12p && + + git checkout -q A^0 && + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + + test_stdout_line_count = 5 git ls-files -s && + test_stdout_line_count = 1 git ls-files -s A/other && + test_stdout_line_count = 1 git ls-files -s A/stuff && + test_stdout_line_count = 1 git ls-files -s B/stuff && + test_stdout_line_count = 1 git ls-files -s D/file2 && + + grep "CONFLICT (implicit dir rename).*Existing file/dir at A/file1 in the way" out && + test_stdout_line_count = 1 git ls-files -s C/file1 + ) +' + +# Testcase 12q, Directory rename hits other rename source; file removed though +# Commit O: A/file1_1 +# A/stuff +# B/file1_2 +# B/stuff +# C/other +# Commit A: A/stuff +# B/stuff +# C/file1_2 +# C/other +# Commit B: D/file2_1 +# A/stuff +# B/file1_2 +# B/stuff +# A/other +# In words: +# A: delete A/file1_1, rename B/file1_2 -> C/file1_2 +# B: Rename C/ -> A/, rename A/file1_1 -> D/file2_1 +# Rationale: +# A/stuff is unmodified, it shows up in final output +# B/stuff is unmodified, it shows up in final output +# C/other touched on one side (rename to A), so A/other shows up in output +# A/file1 is rename/delete to D/file2, so two stages for D/file2 +# B/file1 -> C/file1 and even though C/ -> A/, A/file1 as a source was +# "in the way" (ish) so we don't do the directory rename +# Expected: A/stuff +# B/stuff +# A/other +# D/file2 (two stages) +# C/file1 +# + CONFLICT (implicit dir rename): A/file1 in way of C/file1 +# + CONFLICT (rename/delete): D/file2 +# + +test_setup_12q () { + git init 12q && + ( + cd 12q && + + mkdir -p A B C && + echo 1 >A/file1 && + echo 2 >B/file1 && + echo other >C/other && + echo Astuff >A/stuff && + echo Bstuff >B/stuff && + git add . && + git commit -m "O" && + + git branch O && + git branch A && + git branch B && + + git switch A && + git rm A/file1 && + git mv B/file1 C/ && + git add . && + git commit -m "A" && + + git switch B && + mkdir -p D && + git mv A/file1 D/file2 && + git mv C/other A/other && + git add . && + git commit -m "B" + ) +} + +test_expect_success '12q: Directory rename hits other rename source; file removed though' ' + test_setup_12q && + ( + cd 12q && + + git checkout -q A^0 && + + test_must_fail git -c merge.directoryRenames=conflict merge -s recursive B^0 >out && + + grep "CONFLICT (rename/delete).*A/file1.*D/file2" out && + grep "CONFLICT (implicit dir rename).*Existing file/dir at A/file1 in the way" out && + + test_stdout_line_count = 6 git ls-files -s && + test_stdout_line_count = 1 git ls-files -s A/other && + test_stdout_line_count = 1 git ls-files -s A/stuff && + test_stdout_line_count = 1 git ls-files -s B/stuff && + test_stdout_line_count = 2 git ls-files -s D/file2 && + + # This is a slightly suboptimal resolution; allowing the + # rename of C/ -> A/ to affect C/file1 and further rename + # it to A/file1 would probably be preferable, but since + # A/file1 existed as the source of another rename, allowing + # the dir rename of C/file1 -> A/file1 would mean modifying + # the code so that renames do not adjust both their source + # and target paths in all cases. + ! grep "CONFLICT (file location)" out && + test_stdout_line_count = 1 git ls-files -s C/file1 + ) +' ########################################################################### # SECTION 13: Checking informational and conflict messages diff --git a/t/t7005-editor.sh b/t/t7005-editor.sh index 5fcf281dfb..c490e5707a 100755 --- a/t/t7005-editor.sh +++ b/t/t7005-editor.sh @@ -7,125 +7,96 @@ test_description='GIT_EDITOR, core.editor, and stuff' unset EDITOR VISUAL GIT_EDITOR test_expect_success 'determine default editor' ' - vi=$(TERM=vt100 git var GIT_EDITOR) && test -n "$vi" - ' -if ! expr "$vi" : '[a-z]*$' >/dev/null -then - vi= -fi - -for i in GIT_EDITOR core_editor EDITOR VISUAL $vi -do - cat >e-$i.sh <<-EOF - #!$SHELL_PATH - echo "Edited by $i" >"\$1" - EOF - chmod +x e-$i.sh -done +test_expect_success setup ' + if ! expr "$vi" : "[a-z]*$" >/dev/null + then + vi= + fi && -if ! test -z "$vi" -then - mv e-$vi.sh $vi -fi + for i in GIT_EDITOR core_editor EDITOR VISUAL $vi + do + write_script e-$i.sh <<-EOF || return 1 + echo "Edited by $i" >"\$1" + EOF + done && -test_expect_success setup ' + if ! test -z "$vi" + then + mv e-$vi.sh $vi + fi && msg="Hand-edited" && test_commit "$msg" && - echo "$msg" >expect && - git show -s --format=%s > actual && - test_cmp expect actual - + test_commit_message HEAD -m "$msg" ' -TERM=dumb -export TERM test_expect_success 'dumb should error out when falling back on vi' ' - - if git commit --amend - then - echo "Oops?" - false - else - : happy - fi + test_must_fail env TERM=dumb git commit --amend ' test_expect_success 'dumb should prefer EDITOR to VISUAL' ' - - EDITOR=./e-EDITOR.sh && - VISUAL=./e-VISUAL.sh && - export EDITOR VISUAL && - git commit --amend && - test "$(git show -s --format=%s)" = "Edited by EDITOR" - + TERM=dumb EDITOR=./e-EDITOR.sh VISUAL=./e-VISUAL.sh \ + git commit --amend && + test_commit_message HEAD -m "Edited by EDITOR" ' -TERM=vt100 -export TERM for i in $vi EDITOR VISUAL core_editor GIT_EDITOR do - echo "Edited by $i" >expect - unset EDITOR VISUAL GIT_EDITOR - git config --unset-all core.editor - case "$i" in - core_editor) - git config core.editor ./e-core_editor.sh - ;; - [A-Z]*) - eval "$i=./e-$i.sh" - export $i - ;; - esac test_expect_success "Using $i" ' - git --exec-path=. commit --amend && - git show -s --pretty=oneline | - sed -e "s/^[0-9a-f]* //" >actual && - test_cmp expect actual + if test "$i" = core_editor + then + test_config core.editor ./e-core_editor.sh + fi && + ( + case "$i" in + [A-Z]*) + eval "$i=./e-$i.sh" && + export $i + ;; + esac && + PATH="$PWD:$PATH" TERM=vt100 git commit --amend + ) && + test_commit_message HEAD -m "Edited by $i" ' done -unset EDITOR VISUAL GIT_EDITOR -git config --unset-all core.editor -for i in $vi EDITOR VISUAL core_editor GIT_EDITOR -do - echo "Edited by $i" >expect - case "$i" in - core_editor) - git config core.editor ./e-core_editor.sh - ;; - [A-Z]*) - eval "$i=./e-$i.sh" - export $i - ;; - esac - test_expect_success "Using $i (override)" ' - git --exec-path=. commit --amend && - git show -s --pretty=oneline | - sed -e "s/^[0-9a-f]* //" >actual && - test_cmp expect actual - ' -done +test_expect_success 'Using editors with overrides' ' + ( + TERM=vt100 && + export TERM && + for i in $vi EDITOR VISUAL core_editor GIT_EDITOR + do + echo "Edited by $i" >expect && + case "$i" in + core_editor) + git config core.editor ./e-core_editor.sh + ;; + [A-Z]*) + eval "$i=./e-$i.sh" && + export $i + ;; + esac && + PATH="$PWD:$PATH" git commit --amend && + test_commit_message HEAD expect || exit 1 + done + ) +' test_expect_success 'editor with a space' ' echo "echo space >\"\$1\"" >"e space.sh" && chmod a+x "e space.sh" && GIT_EDITOR="./e\ space.sh" git commit --amend && - test space = "$(git show -s --pretty=format:%s)" - + test_commit_message HEAD -m space ' -unset GIT_EDITOR test_expect_success 'core.editor with a space' ' - - git config core.editor \"./e\ space.sh\" && + test_config core.editor \"./e\ space.sh\" && git commit --amend && - test space = "$(git show -s --pretty=format:%s)" - + test_commit_message HEAD -m space ' test_done diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index d6a501d453..fd3e7e355e 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -1482,4 +1482,27 @@ test_expect_success '`submodule init` and `init.templateDir`' ' ) ' +test_expect_success 'submodule add fails when name is reused' ' + git init test-submodule && + ( + cd test-submodule && + git commit --allow-empty -m init && + + git init ../child-origin && + git -C ../child-origin commit --allow-empty -m init && + + git submodule add ../child-origin child && + git commit -m "Add submodule child" && + + git mv child child_old && + git commit -m "Move child to child_old" && + + # Now adding a *new* repo at the old name must fail + git init ../child2-origin && + git -C ../child2-origin commit --allow-empty -m init && + test_must_fail git submodule add ../child2-origin child 2>err && + test_grep "already used for" err + ) +' + test_done diff --git a/t/t7413-submodule-is-active.sh b/t/t7413-submodule-is-active.sh index 9509dc18fd..6fd3b870de 100755 --- a/t/t7413-submodule-is-active.sh +++ b/t/t7413-submodule-is-active.sh @@ -124,4 +124,19 @@ test_expect_success 'is-active, submodule.active and submodule add' ' git -C super2 config --get submodule.mod.active ' +test_expect_success 'submodule add skips redundant active entry' ' + git init repo && + ( + cd repo && + git config submodule.active "lib/*" && + git commit --allow-empty -m init && + + git init ../lib-origin && + git -C ../lib-origin commit --allow-empty -m init && + + git submodule add ../lib-origin lib/foo && + test_must_fail git config --get submodule.lib/foo.active + ) +' + test_done diff --git a/t/t7450-bad-git-dotfiles.sh b/t/t7450-bad-git-dotfiles.sh index 14b5743b96..f512eed278 100755 --- a/t/t7450-bad-git-dotfiles.sh +++ b/t/t7450-bad-git-dotfiles.sh @@ -401,7 +401,7 @@ test_expect_success SYMLINKS,!WINDOWS,!MINGW 'submodule must not checkout into d git -C repo commit -m submodule && git -c protocol.file.allow=always clone --recurse-submodules repo bad-clone && - ! test -f "$PWD/foo" && + ! test -f "$PWD/bad-clone/sub/foo" && test -f $(printf "bad-clone/sub\r/post-checkout") ' diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 39677e859a..1201c85ba6 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -449,7 +449,17 @@ test_expect_success 'custom `gpg.program`' ' test_must_fail env LET_GPG_PROGRAM_FAIL=1 \ git commit -S --allow-empty -m must-fail 2>err && - grep zOMG err + grep zOMG err && + + # `gpg.program` starts with `~`, the path should be interpreted to be relative to `$HOME` + test_config gpg.program "~/fake-gpg" && + env HOME="$(pwd)" \ + git commit -S --allow-empty -m signed-commit && + + # `gpg.program` does not specify an absolute path, it should find a program in `$PATH` + test_config gpg.program "fake-gpg" && + env PATH="$PWD:$PATH" \ + git commit -S --allow-empty -m signed-commit ' test_done diff --git a/t/t7700-repack.sh b/t/t7700-repack.sh index 611755cc13..73b78bdd88 100755 --- a/t/t7700-repack.sh +++ b/t/t7700-repack.sh @@ -838,4 +838,67 @@ test_expect_success '-n overrides repack.updateServerInfo=true' ' test_server_info_missing ' +test_expect_success 'pending objects are repacked appropriately' ' + test_when_finished rm -rf pending && + git init pending && + + ( + cd pending && + + # Commit file, a/b/c and never change them. + mkdir -p a/b && + echo singleton >file && + echo stuff >a/b/c && + echo more >a/d && + git add file a && + git commit -m "single blobs" && + + # Files a/d and a/e will not be singletons. + echo d >a/d && + echo e >a/e && + git add a && + git commit -m "more blobs" && + + # This use of a sparse index helps to force + # test that the cache-tree is walked, too. + git sparse-checkout set --sparse-index a x && + + # Create staged changes: + # * a/e now has multiple versions. + # * a/i now has only one version. + echo f >a/d && + echo h >a/e && + echo i >a/i && + git add a && + + # Stage and unstage a change to make use of + # resolve-undo cache and how that impacts fsck. + mkdir x && + echo y >x/y && + git add x && + xy=$(git rev-parse :x/y) && + git rm --cached x/y && + + # The blob for x/y must persist through repacks, + # but fsck currently ignores the REUC extension + # for finding links to the blob. + cat >expect <<-EOF && + dangling blob $xy + EOF + + # Bring the loose objects into a packfile to avoid + # leftovers in next test. Without this, the loose + # objects persist and the test succeeds for other + # reasons. + git repack -adf && + git fsck >out && + test_cmp expect out && + + # Test path walk version with pack.useSparse. + git -c pack.useSparse=true repack -adf --path-walk && + git fsck >out && + test_cmp expect out + ) +' + test_done diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 46700dbc40..8f85c69d62 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -48,12 +48,11 @@ test_expect_success 'fast-export | fast-import' ' mkdir new && git --git-dir=new/.git init && git fast-export --all >actual && - (cd new && - git fast-import && - test $MAIN = $(git rev-parse --verify refs/heads/main) && - test $REIN = $(git rev-parse --verify refs/tags/rein) && - test $WER = $(git rev-parse --verify refs/heads/wer) && - test $MUSS = $(git rev-parse --verify refs/tags/muss)) <actual + git -C new fast-import <actual && + test $MAIN = $(git -C new rev-parse --verify refs/heads/main) && + test $REIN = $(git -C new rev-parse --verify refs/tags/rein) && + test $WER = $(git -C new rev-parse --verify refs/heads/wer) && + test $MUSS = $(git -C new rev-parse --verify refs/tags/muss) ' @@ -87,13 +86,11 @@ test_expect_success 'fast-export --mark-tags ^muss^{commit} muss' ' test_expect_success 'fast-export main~2..main' ' git fast-export main~2..main >actual && - sed "s/main/partial/" actual | - (cd new && - git fast-import && - test $MAIN != $(git rev-parse --verify refs/heads/partial) && - git diff --exit-code main partial && - git diff --exit-code main^ partial^ && - test_must_fail git rev-parse partial~2) + sed "s/main/partial/" actual | git -C new fast-import && + test $MAIN != $(git -C new rev-parse --verify refs/heads/partial) && + git -C new diff --exit-code main partial && + git -C new diff --exit-code main^ partial^ && + test_must_fail git -C new rev-parse partial~2 ' @@ -102,10 +99,8 @@ test_expect_success 'fast-export --reference-excluded-parents main~2..main' ' git fast-export --reference-excluded-parents main~2..main >actual && grep commit.refs/heads/main actual >commit-count && test_line_count = 2 commit-count && - sed "s/main/rewrite/" actual | - (cd new && - git fast-import && - test $MAIN = $(git rev-parse --verify refs/heads/rewrite)) + sed "s/main/rewrite/" actual | git -C new fast-import && + test $MAIN = $(git -C new rev-parse --verify refs/heads/rewrite) ' test_expect_success 'fast-export --show-original-ids' ' @@ -133,20 +128,19 @@ test_expect_success ICONV 'reencoding iso-8859-7' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n/" iso-8859-7.fi | - (cd new && - git fast-import && - # The commit object, if not re-encoded, would be 200 bytes plus hash. - # Removing the "encoding iso-8859-7\n" header drops 20 bytes. - # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 - # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for - # the expected size. - test $(($(test_oid hexsz) + 181)) -eq "$(git cat-file -s i18n)" && - # ...and for the expected translation of bytes. - git cat-file commit i18n >actual && - grep $(printf "\317\200") actual && - # Also make sure the commit does not have the "encoding" header - ! grep ^encoding actual) + sed "s/wer/i18n/" iso-8859-7.fi | git -C new fast-import && + + # The commit object, if not re-encoded, would be 200 bytes plus hash. + # Removing the "encoding iso-8859-7\n" header drops 20 bytes. + # Re-encoding the Pi character from \xF0 (\360) in iso-8859-7 + # to \xCF\x80 (\317\200) in UTF-8 adds a byte. Check for + # the expected size. + test $(($(test_oid hexsz) + 181)) -eq "$(git -C new cat-file -s i18n)" && + # ...and for the expected translation of bytes. + git -C new cat-file commit i18n >actual && + grep $(printf "\317\200") actual && + # Also make sure the commit does not have the "encoding" header + ! grep ^encoding actual ' test_expect_success 'aborting on iso-8859-7' ' @@ -165,20 +159,19 @@ test_expect_success 'preserving iso-8859-7' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/simple-iso-8859-7-commit-message.txt" file && git fast-export --reencode=no wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | - (cd new && - git fast-import && - # The commit object, if not re-encoded, is 200 bytes plus hash. - # Removing the "encoding iso-8859-7\n" header would drops 20 - # bytes. Re-encoding the Pi character from \xF0 (\360) in - # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. - # Check for the expected size... - test $(($(test_oid hexsz) + 200)) -eq "$(git cat-file -s i18n-no-recoding)" && - # ...as well as the expected byte. - git cat-file commit i18n-no-recoding >actual && - grep $(printf "\360") actual && - # Also make sure the commit has the "encoding" header - grep ^encoding actual) + sed "s/wer/i18n-no-recoding/" iso-8859-7.fi | git -C new fast-import && + + # The commit object, if not re-encoded, is 200 bytes plus hash. + # Removing the "encoding iso-8859-7\n" header would drops 20 + # bytes. Re-encoding the Pi character from \xF0 (\360) in + # iso-8859-7 to \xCF\x80 (\317\200) in UTF-8 adds a byte. + # Check for the expected size... + test $(($(test_oid hexsz) + 200)) -eq "$(git -C new cat-file -s i18n-no-recoding)" && + # ...as well as the expected byte. + git -C new cat-file commit i18n-no-recoding >actual && + grep $(printf "\360") actual && + # Also make sure the commit has the "encoding" header + grep ^encoding actual ' test_expect_success 'encoding preserved if reencoding fails' ' @@ -188,18 +181,17 @@ test_expect_success 'encoding preserved if reencoding fails' ' echo rosten >file && git commit -s -F "$TEST_DIRECTORY/t9350/broken-iso-8859-7-commit-message.txt" file && git fast-export --reencode=yes wer^..wer >iso-8859-7.fi && - sed "s/wer/i18n-invalid/" iso-8859-7.fi | - (cd new && - git fast-import && - git cat-file commit i18n-invalid >actual && - # Make sure the commit still has the encoding header - grep ^encoding actual && - # Verify that the commit has the expected size; i.e. - # that no bytes were re-encoded to a different encoding. - test $(($(test_oid hexsz) + 212)) -eq "$(git cat-file -s i18n-invalid)" && - # ...and check for the original special bytes - grep $(printf "\360") actual && - grep $(printf "\377") actual) + sed "s/wer/i18n-invalid/" iso-8859-7.fi | git -C new fast-import && + git -C new cat-file commit i18n-invalid >actual && + + # Make sure the commit still has the encoding header + grep ^encoding actual && + # Verify that the commit has the expected size; i.e. + # that no bytes were re-encoded to a different encoding. + test $(($(test_oid hexsz) + 212)) -eq "$(git -C new cat-file -s i18n-invalid)" && + # ...and check for the original special bytes + grep $(printf "\360") actual && + grep $(printf "\377") actual ' test_expect_success 'import/export-marks' ' @@ -316,12 +308,9 @@ test_expect_success GPG 'signed-commits=verbatim' ' git fast-export --signed-commits=verbatim --reencode=no commit-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH openpgp" output && grep "encoding ISO-8859-1" output && - ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-signing) && - test $COMMIT_SIGNING = $STRIPPED - ) <output + git -C new fast-import <output && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-signing) && + test $COMMIT_SIGNING = $STRIPPED ' @@ -331,12 +320,9 @@ test_expect_success GPG 'signed-commits=warn-verbatim' ' test_grep -E "^gpgsig $GIT_DEFAULT_HASH openpgp" output && grep "encoding ISO-8859-1" output && test -s err && - ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-signing) && - test $COMMIT_SIGNING = $STRIPPED - ) <output + git -C new fast-import <output && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-signing) && + test $COMMIT_SIGNING = $STRIPPED ' @@ -345,12 +331,9 @@ test_expect_success GPG 'signed-commits=strip' ' git fast-export --signed-commits=strip --reencode=no commit-signing >output && ! grep ^gpgsig output && grep "^encoding ISO-8859-1" output && - sed "s/commit-signing/commit-strip-signing/" output | ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) && - test $COMMIT_SIGNING != $STRIPPED - ) + sed "s/commit-signing/commit-strip-signing/" output | git -C new fast-import && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-strip-signing) && + test $COMMIT_SIGNING != $STRIPPED ' @@ -360,12 +343,9 @@ test_expect_success GPG 'signed-commits=warn-strip' ' ! grep ^gpgsig output && grep "^encoding ISO-8859-1" output && test -s err && - sed "s/commit-signing/commit-strip-signing/" output | ( - cd new && - git fast-import && - STRIPPED=$(git rev-parse --verify refs/heads/commit-strip-signing) && - test $COMMIT_SIGNING != $STRIPPED - ) + sed "s/commit-signing/commit-strip-signing/" output | git -C new fast-import && + STRIPPED=$(git -C new rev-parse --verify refs/heads/commit-strip-signing) && + test $COMMIT_SIGNING != $STRIPPED ' @@ -386,14 +366,11 @@ test_expect_success GPGSM 'round-trip X.509 signed commit' ' git fast-export --signed-commits=verbatim x509-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH x509" output && - ( - cd new && - git fast-import && - git cat-file commit refs/heads/x509-signing >actual && - grep "^gpgsig" actual && - IMPORTED=$(git rev-parse refs/heads/x509-signing) && - test $X509_COMMIT = $IMPORTED - ) <output + git -C new fast-import <output && + git -C new cat-file commit refs/heads/x509-signing >actual && + grep "^gpgsig" actual && + IMPORTED=$(git -C new rev-parse refs/heads/x509-signing) && + test $X509_COMMIT = $IMPORTED ' @@ -414,14 +391,11 @@ test_expect_success GPGSSH 'round-trip SSH signed commit' ' git fast-export --signed-commits=verbatim ssh-signing >output && test_grep -E "^gpgsig $GIT_DEFAULT_HASH ssh" output && - ( - cd new && - git fast-import && - git cat-file commit refs/heads/ssh-signing >actual && - grep "^gpgsig" actual && - IMPORTED=$(git rev-parse refs/heads/ssh-signing) && - test $SSH_COMMIT = $IMPORTED - ) <output + git -C new fast-import <output && + git -C new cat-file commit refs/heads/ssh-signing >actual && + grep "^gpgsig" actual && + IMPORTED=$(git -C new rev-parse refs/heads/ssh-signing) && + test $SSH_COMMIT = $IMPORTED ' @@ -461,14 +435,13 @@ test_expect_success 'submodule fast-export | fast-import' ' mkdir new && git --git-dir=new/.git init && git fast-export --signed-tags=strip --all >actual && - (cd new && - git fast-import && - test "$SUBENT1" = "$(git ls-tree refs/heads/main^ sub)" && - test "$SUBENT2" = "$(git ls-tree refs/heads/main sub)" && - git checkout main && - git submodule init && - git submodule update && - cmp sub/file ../sub/file) <actual + git -C new fast-import <actual && + test "$SUBENT1" = "$(git -C new ls-tree refs/heads/main^ sub)" && + test "$SUBENT2" = "$(git -C new ls-tree refs/heads/main sub)" && + git -C new checkout main && + git -C new submodule init && + git -C new submodule update && + cmp new/sub/file sub/file ' @@ -510,10 +483,8 @@ test_expect_success 'fast-export -C -C | fast-import' ' git --git-dir=new/.git init && git fast-export -C -C --signed-tags=strip --all > output && grep "^C file2 file4\$" output && - cat output | - (cd new && - git fast-import && - test $ENTRY = $(git rev-parse --verify refs/heads/copy)) + git -C new fast-import <output && + test $ENTRY = $(git -C new rev-parse --verify refs/heads/copy) ' @@ -986,21 +957,17 @@ test_expect_success GPG 'export and import of doubly signed commit' ' git -C explicit-sha256 fast-export --signed-commits=verbatim dual-signed >output && test_grep -E "^gpgsig sha1 openpgp" output && test_grep -E "^gpgsig sha256 openpgp" output && - - ( - cd new && - git fast-import && - git cat-file commit refs/heads/dual-signed >actual && - test_grep -E "^gpgsig " actual && - test_grep -E "^gpgsig-sha256 " actual && - IMPORTED=$(git rev-parse refs/heads/dual-signed) && - if test "$GIT_DEFAULT_HASH" = "sha1" - then - test $SHA1_B = $IMPORTED - else - test $SHA256_B = $IMPORTED - fi - ) <output + git -C new fast-import <output && + git -C new cat-file commit refs/heads/dual-signed >actual && + test_grep -E "^gpgsig " actual && + test_grep -E "^gpgsig-sha256 " actual && + IMPORTED=$(git -C new rev-parse refs/heads/dual-signed) && + if test "$GIT_DEFAULT_HASH" = "sha1" + then + test $SHA1_B = $IMPORTED + else + test $SHA256_B = $IMPORTED + fi ' test_done diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 343b8cd191..6650d33fba 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -2596,6 +2596,8 @@ test_expect_success 'double dash "git checkout"' ' --merge Z --conflict=Z --patch Z + --unified=Z + --inter-hunk-context=Z --ignore-skip-worktree-bits Z --ignore-other-worktrees Z --recurse-submodules Z diff --git a/t/unit-tests/clar/clar.c b/t/unit-tests/clar/clar.c index d54e455367..03a3aa8e87 100644 --- a/t/unit-tests/clar/clar.c +++ b/t/unit-tests/clar/clar.c @@ -350,7 +350,7 @@ static void clar_run_suite(const struct clar_suite *suite, const char *filter) { const struct clar_func *test = suite->tests; - size_t i, matchlen; + size_t i, matchlen = 0; struct clar_report *report; int exact = 0; diff --git a/t/unit-tests/lib-reftable.c b/t/unit-tests/lib-reftable.c index 8a69612266..fdb5b11a20 100644 --- a/t/unit-tests/lib-reftable.c +++ b/t/unit-tests/lib-reftable.c @@ -1,12 +1,14 @@ -#define DISABLE_SIGN_COMPARE_WARNINGS - +#include "unit-test.h" #include "lib-reftable.h" -#include "test-lib.h" +#include "hex.h" +#include "parse-options.h" #include "reftable/constants.h" #include "reftable/writer.h" #include "strbuf.h" +#include "string-list.h" +#include "strvec.h" -void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id) +void cl_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id) { memset(p, (uint8_t)i, hash_size(id)); } @@ -22,17 +24,17 @@ static int strbuf_writer_flush(void *arg UNUSED) return 0; } -struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf, +struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf, struct reftable_write_options *opts) { struct reftable_writer *writer; int ret = reftable_writer_new(&writer, &strbuf_writer_write, &strbuf_writer_flush, buf, opts); - check(!ret); + cl_assert(!ret); return writer; } -void t_reftable_write_to_buf(struct reftable_buf *buf, +void cl_reftable_write_to_buf(struct reftable_buf *buf, struct reftable_ref_record *refs, size_t nrefs, struct reftable_log_record *logs, @@ -64,35 +66,36 @@ void t_reftable_write_to_buf(struct reftable_buf *buf, min = ui; } - writer = t_reftable_strbuf_writer(buf, &opts); - reftable_writer_set_limits(writer, min, max); + writer = cl_reftable_strbuf_writer(buf, &opts); + ret = reftable_writer_set_limits(writer, min, max); + cl_assert(!ret); if (nrefs) { ret = reftable_writer_add_refs(writer, refs, nrefs); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } if (nlogs) { ret = reftable_writer_add_logs(writer, logs, nlogs); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } ret = reftable_writer_close(writer); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); stats = reftable_writer_stats(writer); - for (size_t i = 0; i < stats->ref_stats.blocks; i++) { + for (size_t i = 0; i < (size_t)stats->ref_stats.blocks; i++) { size_t off = i * (opts.block_size ? opts.block_size : DEFAULT_BLOCK_SIZE); if (!off) off = header_size(opts.hash_id == REFTABLE_HASH_SHA256 ? 2 : 1); - check_char(buf->buf[off], ==, 'r'); + cl_assert(buf->buf[off] == 'r'); } if (nrefs) - check_int(stats->ref_stats.blocks, >, 0); + cl_assert(stats->ref_stats.blocks > 0); if (nlogs) - check_int(stats->log_stats.blocks, >, 0); + cl_assert(stats->log_stats.blocks > 0); reftable_writer_free(writer); } diff --git a/t/unit-tests/lib-reftable.h b/t/unit-tests/lib-reftable.h index e4c360fa7e..d7e6d3136f 100644 --- a/t/unit-tests/lib-reftable.h +++ b/t/unit-tests/lib-reftable.h @@ -1,21 +1,20 @@ -#ifndef LIB_REFTABLE_H -#define LIB_REFTABLE_H - +#include "git-compat-util.h" +#include "clar/clar.h" +#include "clar-decls.h" #include "git-compat-util.h" #include "reftable/reftable-writer.h" +#include "strbuf.h" struct reftable_buf; -void t_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id); +void cl_reftable_set_hash(uint8_t *p, int i, enum reftable_hash id); -struct reftable_writer *t_reftable_strbuf_writer(struct reftable_buf *buf, +struct reftable_writer *cl_reftable_strbuf_writer(struct reftable_buf *buf, struct reftable_write_options *opts); -void t_reftable_write_to_buf(struct reftable_buf *buf, +void cl_reftable_write_to_buf(struct reftable_buf *buf, struct reftable_ref_record *refs, size_t nrecords, struct reftable_log_record *logs, size_t nlogs, struct reftable_write_options *opts); - -#endif diff --git a/t/unit-tests/t-reftable-basics.c b/t/unit-tests/t-reftable-basics.c deleted file mode 100644 index c9e751e49e..0000000000 --- a/t/unit-tests/t-reftable-basics.c +++ /dev/null @@ -1,219 +0,0 @@ -/* -Copyright 2020 Google LLC - -Use of this source code is governed by a BSD-style -license that can be found in the LICENSE file or at -https://developers.google.com/open-source/licenses/bsd -*/ - -#include "test-lib.h" -#include "reftable/basics.h" - -struct integer_needle_lesseq_args { - int needle; - int *haystack; -}; - -static int integer_needle_lesseq(size_t i, void *_args) -{ - struct integer_needle_lesseq_args *args = _args; - return args->needle <= args->haystack[i]; -} - -static void *realloc_stub(void *p UNUSED, size_t size UNUSED) -{ - return NULL; -} - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - if_test ("binary search with binsearch works") { - int haystack[] = { 2, 4, 6, 8, 10 }; - struct { - int needle; - size_t expected_idx; - } testcases[] = { - {-9000, 0}, - {-1, 0}, - {0, 0}, - {2, 0}, - {3, 1}, - {4, 1}, - {7, 3}, - {9, 4}, - {10, 4}, - {11, 5}, - {9000, 5}, - }; - - for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) { - struct integer_needle_lesseq_args args = { - .haystack = haystack, - .needle = testcases[i].needle, - }; - size_t idx; - - idx = binsearch(ARRAY_SIZE(haystack), - &integer_needle_lesseq, &args); - check_int(idx, ==, testcases[i].expected_idx); - } - } - - if_test ("names_length returns size of a NULL-terminated string array") { - const char *a[] = { "a", "b", NULL }; - check_int(names_length(a), ==, 2); - } - - if_test ("names_equal compares NULL-terminated string arrays") { - const char *a[] = { "a", "b", "c", NULL }; - const char *b[] = { "a", "b", "d", NULL }; - const char *c[] = { "a", "b", NULL }; - - check(names_equal(a, a)); - check(!names_equal(a, b)); - check(!names_equal(a, c)); - } - - if_test ("parse_names works for basic input") { - char in1[] = "line\n"; - char in2[] = "a\nb\nc"; - char **out = parse_names(in1, strlen(in1)); - check(out != NULL); - check_str(out[0], "line"); - check(!out[1]); - free_names(out); - - out = parse_names(in2, strlen(in2)); - check(out != NULL); - check_str(out[0], "a"); - check_str(out[1], "b"); - check_str(out[2], "c"); - check(!out[3]); - free_names(out); - } - - if_test ("parse_names drops empty string") { - char in[] = "a\n\nb\n"; - char **out = parse_names(in, strlen(in)); - check(out != NULL); - check_str(out[0], "a"); - /* simply '\n' should be dropped as empty string */ - check_str(out[1], "b"); - check(!out[2]); - free_names(out); - } - - if_test ("common_prefix_size works") { - struct reftable_buf a = REFTABLE_BUF_INIT; - struct reftable_buf b = REFTABLE_BUF_INIT; - struct { - const char *a, *b; - int want; - } cases[] = { - {"abcdef", "abc", 3}, - { "abc", "ab", 2 }, - { "", "abc", 0 }, - { "abc", "abd", 2 }, - { "abc", "pqr", 0 }, - }; - - for (size_t i = 0; i < ARRAY_SIZE(cases); i++) { - check(!reftable_buf_addstr(&a, cases[i].a)); - check(!reftable_buf_addstr(&b, cases[i].b)); - check_uint(common_prefix_size(&a, &b), ==, cases[i].want); - reftable_buf_reset(&a); - reftable_buf_reset(&b); - } - reftable_buf_release(&a); - reftable_buf_release(&b); - } - - if_test ("reftable_put_be64 and reftable_get_be64 work") { - uint64_t in = 0x1122334455667788; - uint8_t dest[8]; - uint64_t out; - reftable_put_be64(dest, in); - out = reftable_get_be64(dest); - check_int(in, ==, out); - } - - if_test ("reftable_put_be32 and reftable_get_be32 work") { - uint32_t in = 0x11223344; - uint8_t dest[4]; - uint32_t out; - reftable_put_be32(dest, in); - out = reftable_get_be32(dest); - check_int(in, ==, out); - } - - if_test ("reftable_put_be24 and reftable_get_be24 work") { - uint32_t in = 0x112233; - uint8_t dest[3]; - uint32_t out; - reftable_put_be24(dest, in); - out = reftable_get_be24(dest); - check_int(in, ==, out); - } - - if_test ("put_be16 and get_be16 work") { - uint32_t in = 0xfef1; - uint8_t dest[3]; - uint32_t out; - reftable_put_be16(dest, in); - out = reftable_get_be16(dest); - check_int(in, ==, out); - } - - if_test ("REFTABLE_ALLOC_GROW works") { - int *arr = NULL, *old_arr; - size_t alloc = 0, old_alloc; - - check(!REFTABLE_ALLOC_GROW(arr, 1, alloc)); - check(arr != NULL); - check_uint(alloc, >=, 1); - arr[0] = 42; - - old_alloc = alloc; - old_arr = arr; - reftable_set_alloc(NULL, realloc_stub, NULL); - check(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); - check(arr == old_arr); - check_uint(alloc, ==, old_alloc); - - old_alloc = alloc; - reftable_set_alloc(NULL, NULL, NULL); - check(!REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); - check(arr != NULL); - check_uint(alloc, >, old_alloc); - arr[alloc - 1] = 42; - - reftable_free(arr); - } - - if_test ("REFTABLE_ALLOC_GROW_OR_NULL works") { - int *arr = NULL; - size_t alloc = 0, old_alloc; - - REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc); - check(arr != NULL); - check_uint(alloc, >=, 1); - arr[0] = 42; - - old_alloc = alloc; - REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); - check(arr != NULL); - check_uint(alloc, >, old_alloc); - arr[alloc - 1] = 42; - - old_alloc = alloc; - reftable_set_alloc(NULL, realloc_stub, NULL); - REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); - check(arr == NULL); - check_uint(alloc, ==, 0); - reftable_set_alloc(NULL, NULL, NULL); - - reftable_free(arr); - } - - return test_done(); -} diff --git a/t/unit-tests/u-dir.c b/t/unit-tests/u-dir.c new file mode 100644 index 0000000000..2d0adaa39e --- /dev/null +++ b/t/unit-tests/u-dir.c @@ -0,0 +1,47 @@ +#include "unit-test.h" +#include "dir.h" + +#define TEST_WITHIN_DEPTH(path, depth, max_depth, expect) do { \ + int actual = within_depth(path, strlen(path), \ + depth, max_depth); \ + if (actual != expect) \ + cl_failf("path '%s' with depth '%d' and max-depth '%d': expected %d, got %d", \ + path, depth, max_depth, expect, actual); \ + } while (0) + +void test_dir__within_depth(void) +{ + /* depth = 0; max_depth = 0 */ + TEST_WITHIN_DEPTH("", 0, 0, 1); + TEST_WITHIN_DEPTH("file", 0, 0, 1); + TEST_WITHIN_DEPTH("a", 0, 0, 1); + TEST_WITHIN_DEPTH("a/file", 0, 0, 0); + TEST_WITHIN_DEPTH("a/b", 0, 0, 0); + TEST_WITHIN_DEPTH("a/b/file", 0, 0, 0); + + /* depth = 0; max_depth = 1 */ + TEST_WITHIN_DEPTH("", 0, 1, 1); + TEST_WITHIN_DEPTH("file", 0, 1, 1); + TEST_WITHIN_DEPTH("a", 0, 1, 1); + TEST_WITHIN_DEPTH("a/file", 0, 1, 1); + TEST_WITHIN_DEPTH("a/b", 0, 1, 1); + TEST_WITHIN_DEPTH("a/b/file", 0, 1, 0); + + /* depth = 1; max_depth = 1 */ + TEST_WITHIN_DEPTH("", 1, 1, 1); + TEST_WITHIN_DEPTH("file", 1, 1, 1); + TEST_WITHIN_DEPTH("a", 1, 1, 1); + TEST_WITHIN_DEPTH("a/file", 1, 1, 0); + TEST_WITHIN_DEPTH("a/b", 1, 1, 0); + TEST_WITHIN_DEPTH("a/b/file", 1, 1, 0); + + /* depth = 1; max_depth = 0 */ + TEST_WITHIN_DEPTH("", 1, 0, 0); + TEST_WITHIN_DEPTH("file", 1, 0, 0); + TEST_WITHIN_DEPTH("a", 1, 0, 0); + TEST_WITHIN_DEPTH("a/file", 1, 0, 0); + TEST_WITHIN_DEPTH("a/b", 1, 0, 0); + TEST_WITHIN_DEPTH("a/b/file", 1, 0, 0); + + +} diff --git a/t/unit-tests/u-reftable-basics.c b/t/unit-tests/u-reftable-basics.c new file mode 100644 index 0000000000..a0471083e7 --- /dev/null +++ b/t/unit-tests/u-reftable-basics.c @@ -0,0 +1,227 @@ +/* +Copyright 2020 Google LLC + +Use of this source code is governed by a BSD-style +license that can be found in the LICENSE file or at +https://developers.google.com/open-source/licenses/bsd +*/ + +#include "unit-test.h" +#include "lib-reftable.h" +#include "reftable/basics.h" + +struct integer_needle_lesseq_args { + int needle; + int *haystack; +}; + +static int integer_needle_lesseq(size_t i, void *_args) +{ + struct integer_needle_lesseq_args *args = _args; + return args->needle <= args->haystack[i]; +} + +static void *realloc_stub(void *p UNUSED, size_t size UNUSED) +{ + return NULL; +} + +void test_reftable_basics__binsearch(void) +{ + int haystack[] = { 2, 4, 6, 8, 10 }; + struct { + int needle; + size_t expected_idx; + } testcases[] = { + {-9000, 0}, + {-1, 0}, + {0, 0}, + {2, 0}, + {3, 1}, + {4, 1}, + {7, 3}, + {9, 4}, + {10, 4}, + {11, 5}, + {9000, 5}, + }; + + for (size_t i = 0; i < ARRAY_SIZE(testcases); i++) { + struct integer_needle_lesseq_args args = { + .haystack = haystack, + .needle = testcases[i].needle, + }; + size_t idx; + + idx = binsearch(ARRAY_SIZE(haystack), + &integer_needle_lesseq, &args); + cl_assert_equal_i(idx, testcases[i].expected_idx); + } +} + +void test_reftable_basics__names_length(void) +{ + const char *a[] = { "a", "b", NULL }; + cl_assert_equal_i(names_length(a), 2); +} + +void test_reftable_basics__names_equal(void) +{ + const char *a[] = { "a", "b", "c", NULL }; + const char *b[] = { "a", "b", "d", NULL }; + const char *c[] = { "a", "b", NULL }; + + cl_assert(names_equal(a, a)); + cl_assert(!names_equal(a, b)); + cl_assert(!names_equal(a, c)); +} + +void test_reftable_basics__parse_names(void) +{ + char in1[] = "line\n"; + char in2[] = "a\nb\nc"; + char **out = parse_names(in1, strlen(in1)); + cl_assert(out != NULL); + cl_assert_equal_s(out[0], "line"); + cl_assert(!out[1]); + free_names(out); + + out = parse_names(in2, strlen(in2)); + cl_assert(out != NULL); + cl_assert_equal_s(out[0], "a"); + cl_assert_equal_s(out[1], "b"); + cl_assert_equal_s(out[2], "c"); + cl_assert(!out[3]); + free_names(out); +} + +void test_reftable_basics__parse_names_drop_empty_string(void) +{ + char in[] = "a\n\nb\n"; + char **out = parse_names(in, strlen(in)); + cl_assert(out != NULL); + cl_assert_equal_s(out[0], "a"); + /* simply '\n' should be dropped as empty string */ + cl_assert_equal_s(out[1], "b"); + cl_assert(out[2] == NULL); + free_names(out); +} + +void test_reftable_basics__common_prefix_size(void) +{ + struct reftable_buf a = REFTABLE_BUF_INIT; + struct reftable_buf b = REFTABLE_BUF_INIT; + struct { + const char *a, *b; + int want; + } cases[] = { + {"abcdef", "abc", 3}, + { "abc", "ab", 2 }, + { "", "abc", 0 }, + { "abc", "abd", 2 }, + { "abc", "pqr", 0 }, + }; + + for (size_t i = 0; i < ARRAY_SIZE(cases); i++) { + cl_assert_equal_i(reftable_buf_addstr(&a, cases[i].a), 0); + cl_assert_equal_i(reftable_buf_addstr(&b, cases[i].b), 0); + cl_assert_equal_i(common_prefix_size(&a, &b), cases[i].want); + reftable_buf_reset(&a); + reftable_buf_reset(&b); + } + reftable_buf_release(&a); + reftable_buf_release(&b); +} + +void test_reftable_basics__put_get_be64(void) +{ + uint64_t in = 0x1122334455667788; + uint8_t dest[8]; + uint64_t out; + reftable_put_be64(dest, in); + out = reftable_get_be64(dest); + cl_assert(in == out); +} + +void test_reftable_basics__put_get_be32(void) +{ + uint32_t in = 0x11223344; + uint8_t dest[4]; + uint32_t out; + reftable_put_be32(dest, in); + out = reftable_get_be32(dest); + cl_assert_equal_i(in, out); +} + +void test_reftable_basics__put_get_be24(void) +{ + uint32_t in = 0x112233; + uint8_t dest[3]; + uint32_t out; + reftable_put_be24(dest, in); + out = reftable_get_be24(dest); + cl_assert_equal_i(in, out); +} + +void test_reftable_basics__put_get_be16(void) +{ + uint32_t in = 0xfef1; + uint8_t dest[3]; + uint32_t out; + reftable_put_be16(dest, in); + out = reftable_get_be16(dest); + cl_assert_equal_i(in, out); +} + +void test_reftable_basics__alloc_grow(void) +{ + int *arr = NULL, *old_arr; + size_t alloc = 0, old_alloc; + + cl_assert_equal_i(REFTABLE_ALLOC_GROW(arr, 1, alloc), 0); + cl_assert(arr != NULL); + cl_assert(alloc >= 1); + arr[0] = 42; + + old_alloc = alloc; + old_arr = arr; + reftable_set_alloc(NULL, realloc_stub, NULL); + cl_assert(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc)); + cl_assert(arr == old_arr); + cl_assert_equal_i(alloc, old_alloc); + + old_alloc = alloc; + reftable_set_alloc(NULL, NULL, NULL); + cl_assert_equal_i(REFTABLE_ALLOC_GROW(arr, old_alloc + 1, alloc), 0); + cl_assert(arr != NULL); + cl_assert(alloc > old_alloc); + arr[alloc - 1] = 42; + + reftable_free(arr); +} + +void test_reftable_basics__alloc_grow_or_null(void) +{ + int *arr = NULL; + size_t alloc = 0, old_alloc; + + REFTABLE_ALLOC_GROW_OR_NULL(arr, 1, alloc); + cl_assert(arr != NULL); + cl_assert(alloc >= 1); + arr[0] = 42; + + old_alloc = alloc; + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + cl_assert(arr != NULL); + cl_assert(alloc > old_alloc); + arr[alloc - 1] = 42; + + old_alloc = alloc; + reftable_set_alloc(NULL, realloc_stub, NULL); + REFTABLE_ALLOC_GROW_OR_NULL(arr, old_alloc + 1, alloc); + cl_assert(arr == NULL); + cl_assert_equal_i(alloc, 0); + reftable_set_alloc(NULL, NULL, NULL); + + reftable_free(arr); +} diff --git a/t/unit-tests/t-reftable-block.c b/t/unit-tests/u-reftable-block.c index 52f1dae1c9..f4bded7d26 100644 --- a/t/unit-tests/t-reftable-block.c +++ b/t/unit-tests/u-reftable-block.c @@ -6,14 +6,15 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "test-lib.h" +#include "unit-test.h" +#include "lib-reftable.h" #include "reftable/block.h" #include "reftable/blocksource.h" #include "reftable/constants.h" #include "reftable/reftable-error.h" #include "strbuf.h" -static void t_ref_block_read_write(void) +void test_reftable_block__read_write(void) { const int header_off = 21; /* random */ struct reftable_record recs[30]; @@ -34,17 +35,18 @@ static void t_ref_block_read_write(void) struct reftable_buf block_data = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block_data.buf, block_size); - check(block_data.buf != NULL); + cl_assert(block_data.buf != NULL); block_data.len = block_size; - ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_REF, (uint8_t *) block_data.buf, block_size, + ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_REF, + (uint8_t *) block_data.buf, block_size, header_off, hash_size(REFTABLE_HASH_SHA1)); - check(!ret); + cl_assert(!ret); rec.u.ref.refname = (char *) ""; rec.u.ref.value_type = REFTABLE_REF_DELETION; ret = block_writer_add(&bw, &rec); - check_int(ret, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(ret, REFTABLE_API_ERROR); for (i = 0; i < N; i++) { rec.u.ref.refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); @@ -55,11 +57,11 @@ static void t_ref_block_read_write(void) ret = block_writer_add(&bw, &rec); rec.u.ref.refname = NULL; rec.u.ref.value_type = REFTABLE_REF_DELETION; - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } ret = block_writer_finish(&bw); - check_int(ret, >, 0); + cl_assert(ret > 0); block_writer_release(&bw); @@ -71,32 +73,32 @@ static void t_ref_block_read_write(void) for (i = 0; ; i++) { ret = block_iter_next(&it, &rec); - check_int(ret, >=, 0); + cl_assert(ret >= 0); if (ret > 0) { - check_int(i, ==, N); + cl_assert_equal_i(i, N); break; } - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } for (i = 0; i < N; i++) { reftable_record_key(&recs[i], &want); ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); want.len--; ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(ret, 0); + cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } reftable_block_release(&block); @@ -108,7 +110,7 @@ static void t_ref_block_read_write(void) reftable_record_release(&recs[i]); } -static void t_log_block_read_write(void) +void test_reftable_block__log_read_write(void) { const int header_off = 21; struct reftable_record recs[30]; @@ -129,12 +131,12 @@ static void t_log_block_read_write(void) struct reftable_buf block_data = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block_data.buf, block_size); - check(block_data.buf != NULL); + cl_assert(block_data.buf != NULL); block_data.len = block_size; ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_LOG, (uint8_t *) block_data.buf, block_size, header_off, hash_size(REFTABLE_HASH_SHA1)); - check(!ret); + cl_assert(!ret); for (i = 0; i < N; i++) { rec.u.log.refname = xstrfmt("branch%02"PRIuMAX , (uintmax_t)i); @@ -145,11 +147,11 @@ static void t_log_block_read_write(void) ret = block_writer_add(&bw, &rec); rec.u.log.refname = NULL; rec.u.log.value_type = REFTABLE_LOG_DELETION; - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } ret = block_writer_finish(&bw); - check_int(ret, >, 0); + cl_assert(ret > 0); block_writer_release(&bw); @@ -161,33 +163,33 @@ static void t_log_block_read_write(void) for (i = 0; ; i++) { ret = block_iter_next(&it, &rec); - check_int(ret, >=, 0); + cl_assert(ret >= 0); if (ret > 0) { - check_int(i, ==, N); + cl_assert_equal_i(i, N); break; } - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } for (i = 0; i < N; i++) { reftable_buf_reset(&want); - check(!reftable_buf_addstr(&want, recs[i].u.log.refname)); + cl_assert(reftable_buf_addstr(&want, recs[i].u.log.refname) == 0); ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); want.len--; ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(ret, 0); + cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } reftable_block_release(&block); @@ -199,7 +201,7 @@ static void t_log_block_read_write(void) reftable_record_release(&recs[i]); } -static void t_obj_block_read_write(void) +void test_reftable_block__obj_read_write(void) { const int header_off = 21; struct reftable_record recs[30]; @@ -220,12 +222,12 @@ static void t_obj_block_read_write(void) struct reftable_buf block_data = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block_data.buf, block_size); - check(block_data.buf != NULL); + cl_assert(block_data.buf != NULL); block_data.len = block_size; ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_OBJ, (uint8_t *) block_data.buf, block_size, header_off, hash_size(REFTABLE_HASH_SHA1)); - check(!ret); + cl_assert(!ret); for (i = 0; i < N; i++) { uint8_t bytes[] = { i, i + 1, i + 2, i + 3, i + 5 }, *allocated; @@ -238,11 +240,11 @@ static void t_obj_block_read_write(void) ret = block_writer_add(&bw, &rec); rec.u.obj.hash_prefix = NULL; rec.u.obj.hash_prefix_len = 0; - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } ret = block_writer_finish(&bw); - check_int(ret, >, 0); + cl_assert(ret > 0); block_writer_release(&bw); @@ -254,24 +256,24 @@ static void t_obj_block_read_write(void) for (i = 0; ; i++) { ret = block_iter_next(&it, &rec); - check_int(ret, >=, 0); + cl_assert(ret >= 0); if (ret > 0) { - check_int(i, ==, N); + cl_assert_equal_i(i, N); break; } - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } for (i = 0; i < N; i++) { reftable_record_key(&recs[i], &want); ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } reftable_block_release(&block); @@ -283,7 +285,7 @@ static void t_obj_block_read_write(void) reftable_record_release(&recs[i]); } -static void t_index_block_read_write(void) +void test_reftable_block__ref_read_write(void) { const int header_off = 21; struct reftable_record recs[30]; @@ -305,12 +307,12 @@ static void t_index_block_read_write(void) struct reftable_buf block_data = REFTABLE_BUF_INIT; REFTABLE_CALLOC_ARRAY(block_data.buf, block_size); - check(block_data.buf != NULL); + cl_assert(block_data.buf != NULL); block_data.len = block_size; ret = block_writer_init(&bw, REFTABLE_BLOCK_TYPE_INDEX, (uint8_t *) block_data.buf, block_size, header_off, hash_size(REFTABLE_HASH_SHA1)); - check(!ret); + cl_assert(!ret); for (i = 0; i < N; i++) { char buf[128]; @@ -319,15 +321,15 @@ static void t_index_block_read_write(void) reftable_buf_init(&recs[i].u.idx.last_key); recs[i].type = REFTABLE_BLOCK_TYPE_INDEX; - check(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf)); + cl_assert(!reftable_buf_addstr(&recs[i].u.idx.last_key, buf)); recs[i].u.idx.offset = i; ret = block_writer_add(&bw, &recs[i]); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); } ret = block_writer_finish(&bw); - check_int(ret, >, 0); + cl_assert(ret > 0); block_writer_release(&bw); @@ -339,32 +341,32 @@ static void t_index_block_read_write(void) for (i = 0; ; i++) { ret = block_iter_next(&it, &rec); - check_int(ret, >=, 0); + cl_assert(ret >= 0); if (ret > 0) { - check_int(i, ==, N); + cl_assert_equal_i(i, N); break; } - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } for (i = 0; i < N; i++) { reftable_record_key(&recs[i], &want); ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); - check(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_record_equal(&recs[i], &rec, REFTABLE_HASH_SIZE_SHA1), 1); want.len--; ret = block_iter_seek_key(&it, &want); - check_int(ret, ==, 0); + cl_assert_equal_i(ret, 0); ret = block_iter_next(&it, &rec); - check_int(ret, ==, 0); - check(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(ret, 0); + cl_assert_equal_i(reftable_record_equal(&recs[10 * (i / 10)], &rec, REFTABLE_HASH_SIZE_SHA1), 1); } reftable_block_release(&block); @@ -376,7 +378,7 @@ static void t_index_block_read_write(void) reftable_record_release(&recs[i]); } -static void t_block_iterator(void) +void test_reftable_block__iterator(void) { struct reftable_block_source source = { 0 }; struct block_writer writer = { @@ -391,11 +393,12 @@ static void t_block_iterator(void) data.len = 1024; REFTABLE_CALLOC_ARRAY(data.buf, data.len); - check(data.buf != NULL); + cl_assert(data.buf != NULL); - err = block_writer_init(&writer, REFTABLE_BLOCK_TYPE_REF, (uint8_t *) data.buf, data.len, + err = block_writer_init(&writer, REFTABLE_BLOCK_TYPE_REF, + (uint8_t *) data.buf, data.len, 0, hash_size(REFTABLE_HASH_SHA1)); - check(!err); + cl_assert(!err); for (size_t i = 0; i < ARRAY_SIZE(expected_refs); i++) { expected_refs[i] = (struct reftable_record) { @@ -408,42 +411,42 @@ static void t_block_iterator(void) memset(expected_refs[i].u.ref.value.val1, i, REFTABLE_HASH_SIZE_SHA1); err = block_writer_add(&writer, &expected_refs[i]); - check_int(err, ==, 0); + cl_assert_equal_i(err, 0); } err = block_writer_finish(&writer); - check_int(err, >, 0); + cl_assert(err > 0); block_source_from_buf(&source, &data); reftable_block_init(&block, &source, 0, 0, data.len, REFTABLE_HASH_SIZE_SHA1, REFTABLE_BLOCK_TYPE_REF); err = reftable_block_init_iterator(&block, &it); - check_int(err, ==, 0); + cl_assert_equal_i(err, 0); for (size_t i = 0; ; i++) { err = reftable_iterator_next_ref(&it, &ref); if (err > 0) { - check_int(i, ==, ARRAY_SIZE(expected_refs)); + cl_assert_equal_i(i, ARRAY_SIZE(expected_refs)); break; } - check_int(err, ==, 0); + cl_assert_equal_i(err, 0); - check(reftable_ref_record_equal(&ref, &expected_refs[i].u.ref, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_ref_record_equal(&ref, + &expected_refs[i].u.ref, REFTABLE_HASH_SIZE_SHA1)); } err = reftable_iterator_seek_ref(&it, "refs/heads/does-not-exist"); - check_int(err, ==, 0); + cl_assert_equal_i(err, 0); err = reftable_iterator_next_ref(&it, &ref); - check_int(err, ==, 1); + cl_assert_equal_i(err, 1); err = reftable_iterator_seek_ref(&it, "refs/heads/branch-13"); - check_int(err, ==, 0); + cl_assert_equal_i(err, 0); err = reftable_iterator_next_ref(&it, &ref); - check_int(err, ==, 0); - check(reftable_ref_record_equal(&ref, &expected_refs[13].u.ref, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(err, 0); + cl_assert(reftable_ref_record_equal(&ref, + &expected_refs[13].u.ref,REFTABLE_HASH_SIZE_SHA1)); for (size_t i = 0; i < ARRAY_SIZE(expected_refs); i++) reftable_free(expected_refs[i].u.ref.refname); @@ -453,14 +456,3 @@ static void t_block_iterator(void) block_writer_release(&writer); reftable_buf_release(&data); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_index_block_read_write(), "read-write operations on index blocks work"); - TEST(t_log_block_read_write(), "read-write operations on log blocks work"); - TEST(t_obj_block_read_write(), "read-write operations on obj blocks work"); - TEST(t_ref_block_read_write(), "read-write operations on ref blocks work"); - TEST(t_block_iterator(), "block iterator works"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-merged.c b/t/unit-tests/u-reftable-merged.c index 18c3251a56..54cb7fc2a7 100644 --- a/t/unit-tests/t-reftable-merged.c +++ b/t/unit-tests/u-reftable-merged.c @@ -6,7 +6,7 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "test-lib.h" +#include "unit-test.h" #include "lib-reftable.h" #include "reftable/blocksource.h" #include "reftable/constants.h" @@ -29,21 +29,21 @@ merged_table_from_records(struct reftable_ref_record **refs, int err; REFTABLE_CALLOC_ARRAY(*tables, n); - check(*tables != NULL); + cl_assert(*tables != NULL); REFTABLE_CALLOC_ARRAY(*source, n); - check(*source != NULL); + cl_assert(*source != NULL); for (size_t i = 0; i < n; i++) { - t_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts); + cl_reftable_write_to_buf(&buf[i], refs[i], sizes[i], NULL, 0, &opts); block_source_from_buf(&(*source)[i], &buf[i]); err = reftable_table_new(&(*tables)[i], &(*source)[i], "name"); - check(!err); + cl_assert(!err); } err = reftable_merged_table_new(&mt, *tables, n, REFTABLE_HASH_SHA1); - check(!err); + cl_assert(!err); return mt; } @@ -54,7 +54,7 @@ static void tables_destroy(struct reftable_table **tables, const size_t n) reftable_free(tables); } -static void t_merged_single_record(void) +void test_reftable_merged__single_record(void) { struct reftable_ref_record r1[] = { { .refname = (char *) "b", @@ -85,13 +85,14 @@ static void t_merged_single_record(void) int err; err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, "a"); - check(!err); + cl_assert(!err); err = reftable_iterator_next_ref(&it, &ref); - check(!err); - check(reftable_ref_record_equal(&r2[0], &ref, REFTABLE_HASH_SIZE_SHA1)); + cl_assert(!err); + cl_assert(reftable_ref_record_equal(&r2[0], &ref, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); tables_destroy(tables, 3); @@ -101,7 +102,7 @@ static void t_merged_single_record(void) reftable_free(bs); } -static void t_merged_refs(void) +void test_reftable_merged__refs(void) { struct reftable_ref_record r1[] = { { @@ -165,12 +166,12 @@ static void t_merged_refs(void) size_t i; err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, "a"); - check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); - check_int(reftable_merged_table_min_update_index(mt), ==, 1); - check_int(reftable_merged_table_max_update_index(mt), ==, 3); + cl_assert(err == 0); + cl_assert_equal_i(reftable_merged_table_hash_id(mt), REFTABLE_HASH_SHA1); + cl_assert_equal_i(reftable_merged_table_min_update_index(mt), 1); + cl_assert_equal_i(reftable_merged_table_max_update_index(mt), 3); while (len < 100) { /* cap loops/recursion. */ struct reftable_ref_record ref = { 0 }; @@ -178,15 +179,15 @@ static void t_merged_refs(void) if (err > 0) break; - check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); + cl_assert(REFTABLE_ALLOC_GROW(out, len + 1, cap) == 0); out[len++] = ref; } reftable_iterator_destroy(&it); - check_int(ARRAY_SIZE(want), ==, len); + cl_assert_equal_i(ARRAY_SIZE(want), len); for (i = 0; i < len; i++) - check(reftable_ref_record_equal(want[i], &out[i], - REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_ref_record_equal(want[i], &out[i], + REFTABLE_HASH_SIZE_SHA1) != 0); for (i = 0; i < len; i++) reftable_ref_record_release(&out[i]); reftable_free(out); @@ -198,7 +199,7 @@ static void t_merged_refs(void) reftable_free(bs); } -static void t_merged_seek_multiple_times(void) +void test_reftable_merged__seek_multiple_times(void) { struct reftable_ref_record r1[] = { { @@ -248,20 +249,17 @@ static void t_merged_seek_multiple_times(void) for (size_t i = 0; i < 5; i++) { int err = reftable_iterator_seek_ref(&it, "c"); - check(!err); + cl_assert(!err); - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - err = reftable_ref_record_equal(&rec, &r1[1], REFTABLE_HASH_SIZE_SHA1); - check(err == 1); + cl_assert(reftable_iterator_next_ref(&it, &rec) == 0); + cl_assert_equal_i(reftable_ref_record_equal(&rec, &r1[1], + REFTABLE_HASH_SIZE_SHA1), 1); - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - err = reftable_ref_record_equal(&rec, &r2[1], REFTABLE_HASH_SIZE_SHA1); - check(err == 1); + cl_assert(reftable_iterator_next_ref(&it, &rec) == 0); + cl_assert_equal_i(reftable_ref_record_equal(&rec, &r2[1], + REFTABLE_HASH_SIZE_SHA1), 1); - err = reftable_iterator_next_ref(&it, &rec); - check(err > 0); + cl_assert(reftable_iterator_next_ref(&it, &rec) > 0); } for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) @@ -273,7 +271,7 @@ static void t_merged_seek_multiple_times(void) reftable_free(sources); } -static void t_merged_seek_multiple_times_without_draining(void) +void test_reftable_merged__seek_multiple_times_no_drain(void) { struct reftable_ref_record r1[] = { { @@ -317,24 +315,19 @@ static void t_merged_seek_multiple_times_without_draining(void) struct reftable_ref_record rec = { 0 }; struct reftable_iterator it = { 0 }; struct reftable_merged_table *mt; - int err; mt = merged_table_from_records(refs, &sources, &tables, sizes, bufs, 2); merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_REF); - err = reftable_iterator_seek_ref(&it, "b"); - check(!err); - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - err = reftable_ref_record_equal(&rec, &r2[0], REFTABLE_HASH_SIZE_SHA1); - check(err == 1); + cl_assert(reftable_iterator_seek_ref(&it, "b") == 0); + cl_assert(reftable_iterator_next_ref(&it, &rec) == 0); + cl_assert_equal_i(reftable_ref_record_equal(&rec, &r2[0], + REFTABLE_HASH_SIZE_SHA1), 1); - err = reftable_iterator_seek_ref(&it, "a"); - check(!err); - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - err = reftable_ref_record_equal(&rec, &r1[0], REFTABLE_HASH_SIZE_SHA1); - check(err == 1); + cl_assert(reftable_iterator_seek_ref(&it, "a") == 0); + cl_assert(reftable_iterator_next_ref(&it, &rec) == 0); + cl_assert_equal_i(reftable_ref_record_equal(&rec, &r1[0], + REFTABLE_HASH_SIZE_SHA1), 1); for (size_t i = 0; i < ARRAY_SIZE(bufs); i++) reftable_buf_release(&bufs[i]); @@ -359,25 +352,25 @@ merged_table_from_log_records(struct reftable_log_record **logs, int err; REFTABLE_CALLOC_ARRAY(*tables, n); - check(*tables != NULL); + cl_assert(*tables != NULL); REFTABLE_CALLOC_ARRAY(*source, n); - check(*source != NULL); + cl_assert(*source != NULL); for (size_t i = 0; i < n; i++) { - t_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts); + cl_reftable_write_to_buf(&buf[i], NULL, 0, logs[i], sizes[i], &opts); block_source_from_buf(&(*source)[i], &buf[i]); err = reftable_table_new(&(*tables)[i], &(*source)[i], "name"); - check(!err); + cl_assert(!err); } err = reftable_merged_table_new(&mt, *tables, n, REFTABLE_HASH_SHA1); - check(!err); + cl_assert(!err); return mt; } -static void t_merged_logs(void) +void test_reftable_merged__logs(void) { struct reftable_log_record r1[] = { { @@ -439,19 +432,19 @@ static void t_merged_logs(void) struct reftable_merged_table *mt = merged_table_from_log_records( logs, &bs, &tables, sizes, bufs, 3); struct reftable_iterator it = { 0 }; - int err; struct reftable_log_record *out = NULL; size_t len = 0; size_t cap = 0; size_t i; + int err; err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_LOG); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_log(&it, "a"); - check(!err); - check_int(reftable_merged_table_hash_id(mt), ==, REFTABLE_HASH_SHA1); - check_int(reftable_merged_table_min_update_index(mt), ==, 1); - check_int(reftable_merged_table_max_update_index(mt), ==, 3); + cl_assert(!err); + cl_assert_equal_i(reftable_merged_table_hash_id(mt), REFTABLE_HASH_SHA1); + cl_assert_equal_i(reftable_merged_table_min_update_index(mt), 1); + cl_assert_equal_i(reftable_merged_table_max_update_index(mt), 3); while (len < 100) { /* cap loops/recursion. */ struct reftable_log_record log = { 0 }; @@ -459,24 +452,24 @@ static void t_merged_logs(void) if (err > 0) break; - check(!REFTABLE_ALLOC_GROW(out, len + 1, cap)); + cl_assert(REFTABLE_ALLOC_GROW(out, len + 1, cap) == 0); out[len++] = log; } reftable_iterator_destroy(&it); - check_int(ARRAY_SIZE(want), ==, len); + cl_assert_equal_i(ARRAY_SIZE(want), len); for (i = 0; i < len; i++) - check(reftable_log_record_equal(want[i], &out[i], - REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_log_record_equal(want[i], &out[i], + REFTABLE_HASH_SIZE_SHA1) != 0); err = merged_table_init_iter(mt, &it, REFTABLE_BLOCK_TYPE_LOG); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_log_at(&it, "a", 2); - check(!err); + cl_assert(!err); reftable_log_record_release(&out[0]); - err = reftable_iterator_next_log(&it, &out[0]); - check(!err); - check(reftable_log_record_equal(&out[0], &r3[0], REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_iterator_next_log(&it, &out[0]) == 0); + cl_assert(reftable_log_record_equal(&out[0], &r3[0], + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_iterator_destroy(&it); for (i = 0; i < len; i++) @@ -490,11 +483,11 @@ static void t_merged_logs(void) reftable_free(bs); } -static void t_default_write_opts(void) +void test_reftable_merged__default_write_opts(void) { struct reftable_write_options opts = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record rec = { .refname = (char *) "master", .update_index = 1, @@ -507,40 +500,25 @@ static void t_default_write_opts(void) reftable_writer_set_limits(w, 1, 1); - err = reftable_writer_add_ref(w, &rec); - check(!err); + cl_assert_equal_i(reftable_writer_add_ref(w, &rec), 0); - err = reftable_writer_close(w); - check(!err); + cl_assert_equal_i(reftable_writer_close(w), 0); reftable_writer_free(w); block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "filename"); - check(!err); + cl_assert(!err); hash_id = reftable_table_hash_id(table); - check_int(hash_id, ==, REFTABLE_HASH_SHA1); + cl_assert_equal_i(hash_id, REFTABLE_HASH_SHA1); err = reftable_merged_table_new(&merged, &table, 1, REFTABLE_HASH_SHA256); - check_int(err, ==, REFTABLE_FORMAT_ERROR); + cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR); err = reftable_merged_table_new(&merged, &table, 1, REFTABLE_HASH_SHA1); - check(!err); + cl_assert(!err); reftable_table_decref(table); reftable_merged_table_free(merged); reftable_buf_release(&buf); } - - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_default_write_opts(), "merged table with default write opts"); - TEST(t_merged_logs(), "merged table with multiple log updates for same ref"); - TEST(t_merged_refs(), "merged table with multiple updates to same ref"); - TEST(t_merged_seek_multiple_times(), "merged table can seek multiple times"); - TEST(t_merged_seek_multiple_times_without_draining(), "merged table can seek multiple times without draining"); - TEST(t_merged_single_record(), "ref occurring in only one record can be fetched"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-pq.c b/t/unit-tests/u-reftable-pq.c index fb5a4eb187..f8a28f6e07 100644 --- a/t/unit-tests/t-reftable-pq.c +++ b/t/unit-tests/u-reftable-pq.c @@ -6,7 +6,8 @@ license that can be found in the LICENSE file or at https://developers.google.com/open-source/licenses/bsd */ -#include "test-lib.h" +#include "unit-test.h" +#include "lib-reftable.h" #include "reftable/constants.h" #include "reftable/pq.h" #include "strbuf.h" @@ -15,18 +16,18 @@ static void merged_iter_pqueue_check(const struct merged_iter_pqueue *pq) { for (size_t i = 1; i < pq->len; i++) { size_t parent = (i - 1) / 2; - check(pq_less(&pq->heap[parent], &pq->heap[i])); + cl_assert(pq_less(&pq->heap[parent], &pq->heap[i]) != 0); } } static int pq_entry_equal(struct pq_entry *a, struct pq_entry *b) { int cmp; - check(!reftable_record_cmp(a->rec, b->rec, &cmp)); + cl_assert_equal_i(reftable_record_cmp(a->rec, b->rec, &cmp), 0); return !cmp && (a->index == b->index); } -static void t_pq_record(void) +void test_reftable_pq__record(void) { struct merged_iter_pqueue pq = { 0 }; struct reftable_record recs[54]; @@ -34,7 +35,8 @@ static void t_pq_record(void) char *last = NULL; for (i = 0; i < N; i++) { - check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF)); + cl_assert(!reftable_record_init(&recs[i], + REFTABLE_BLOCK_TYPE_REF)); recs[i].u.ref.refname = xstrfmt("%02"PRIuMAX, (uintmax_t)i); } @@ -53,13 +55,13 @@ static void t_pq_record(void) struct pq_entry top = merged_iter_pqueue_top(pq); struct pq_entry e; - check(!merged_iter_pqueue_remove(&pq, &e)); + cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0); merged_iter_pqueue_check(&pq); - check(pq_entry_equal(&top, &e)); - check(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF); + cl_assert(pq_entry_equal(&top, &e)); + cl_assert(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF); if (last) - check_int(strcmp(last, e.rec->u.ref.refname), <, 0); + cl_assert(strcmp(last, e.rec->u.ref.refname) < 0); last = e.rec->u.ref.refname; } @@ -68,7 +70,7 @@ static void t_pq_record(void) merged_iter_pqueue_release(&pq); } -static void t_pq_index(void) +void test_reftable_pq__index(void) { struct merged_iter_pqueue pq = { 0 }; struct reftable_record recs[13]; @@ -76,7 +78,8 @@ static void t_pq_index(void) size_t N = ARRAY_SIZE(recs), i; for (i = 0; i < N; i++) { - check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF)); + cl_assert(!reftable_record_init(&recs[i], + REFTABLE_BLOCK_TYPE_REF)); recs[i].u.ref.refname = (char *) "refs/heads/master"; } @@ -96,28 +99,29 @@ static void t_pq_index(void) struct pq_entry top = merged_iter_pqueue_top(pq); struct pq_entry e; - check(!merged_iter_pqueue_remove(&pq, &e)); + cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0); merged_iter_pqueue_check(&pq); - check(pq_entry_equal(&top, &e)); - check(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF); - check_int(e.index, ==, i); + cl_assert(pq_entry_equal(&top, &e)); + cl_assert(reftable_record_type(e.rec) == REFTABLE_BLOCK_TYPE_REF); + cl_assert_equal_i(e.index, i); if (last) - check_str(last, e.rec->u.ref.refname); + cl_assert_equal_s(last, e.rec->u.ref.refname); last = e.rec->u.ref.refname; } merged_iter_pqueue_release(&pq); } -static void t_merged_iter_pqueue_top(void) +void test_reftable_pq__merged_iter_pqueue_top(void) { struct merged_iter_pqueue pq = { 0 }; struct reftable_record recs[13]; size_t N = ARRAY_SIZE(recs), i; for (i = 0; i < N; i++) { - check(!reftable_record_init(&recs[i], REFTABLE_BLOCK_TYPE_REF)); + cl_assert(!reftable_record_init(&recs[i], + REFTABLE_BLOCK_TYPE_REF)); recs[i].u.ref.refname = (char *) "refs/heads/master"; } @@ -137,25 +141,16 @@ static void t_merged_iter_pqueue_top(void) struct pq_entry top = merged_iter_pqueue_top(pq); struct pq_entry e; - check(!merged_iter_pqueue_remove(&pq, &e)); + cl_assert_equal_i(merged_iter_pqueue_remove(&pq, &e), 0); merged_iter_pqueue_check(&pq); - check(pq_entry_equal(&top, &e)); - check(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1)); + cl_assert(pq_entry_equal(&top, &e) != 0); + cl_assert(reftable_record_equal(top.rec, &recs[i], REFTABLE_HASH_SIZE_SHA1) != 0); for (size_t j = 0; i < pq.len; j++) { - check(pq_less(&top, &pq.heap[j])); - check_int(top.index, >, j); + cl_assert(pq_less(&top, &pq.heap[j]) != 0); + cl_assert(top.index > j); } } merged_iter_pqueue_release(&pq); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_pq_record(), "pq works with record-based comparison"); - TEST(t_pq_index(), "pq works with index-based comparison"); - TEST(t_merged_iter_pqueue_top(), "merged_iter_pqueue_top works"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-readwrite.c b/t/unit-tests/u-reftable-readwrite.c index 4c49129439..4d8c4be5f1 100644 --- a/t/unit-tests/t-reftable-readwrite.c +++ b/t/unit-tests/u-reftable-readwrite.c @@ -8,7 +8,7 @@ https://developers.google.com/open-source/licenses/bsd #define DISABLE_SIGN_COMPARE_WARNINGS -#include "test-lib.h" +#include "unit-test.h" #include "lib-reftable.h" #include "reftable/basics.h" #include "reftable/blocksource.h" @@ -19,24 +19,24 @@ https://developers.google.com/open-source/licenses/bsd static const int update_index = 5; -static void t_buffer(void) +void test_reftable_readwrite__buffer(void) { struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_block_data out = { 0 }; int n; uint8_t in[] = "hello"; - check(!reftable_buf_add(&buf, in, sizeof(in))); + cl_assert_equal_i(reftable_buf_add(&buf, in, sizeof(in)), 0); block_source_from_buf(&source, &buf); - check_int(block_source_size(&source), ==, 6); + cl_assert_equal_i(block_source_size(&source), 6); n = block_source_read_data(&source, &out, 0, sizeof(in)); - check_int(n, ==, sizeof(in)); - check(!memcmp(in, out.data, n)); + cl_assert_equal_i(n, sizeof(in)); + cl_assert(!memcmp(in, out.data, n)); block_source_release_data(&out); n = block_source_read_data(&source, &out, 1, 2); - check_int(n, ==, 2); - check(!memcmp(out.data, "el", 2)); + cl_assert_equal_i(n, 2); + cl_assert(!memcmp(out.data, "el", 2)); block_source_release_data(&out); block_source_close(&source); @@ -55,41 +55,41 @@ static void write_table(char ***names, struct reftable_buf *buf, int N, int i; REFTABLE_CALLOC_ARRAY(*names, N + 1); - check(*names != NULL); + cl_assert(*names != NULL); REFTABLE_CALLOC_ARRAY(refs, N); - check(refs != NULL); + cl_assert(refs != NULL); REFTABLE_CALLOC_ARRAY(logs, N); - check(logs != NULL); + cl_assert(logs != NULL); for (i = 0; i < N; i++) { refs[i].refname = (*names)[i] = xstrfmt("refs/heads/branch%02d", i); refs[i].update_index = update_index; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(refs[i].value.val1, i, + REFTABLE_HASH_SHA1); } for (i = 0; i < N; i++) { logs[i].refname = (*names)[i]; logs[i].update_index = update_index; logs[i].value_type = REFTABLE_LOG_UPDATE; - t_reftable_set_hash(logs[i].value.update.new_hash, i, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(logs[i].value.update.new_hash, i, + REFTABLE_HASH_SHA1); logs[i].value.update.message = (char *) "message"; } - t_reftable_write_to_buf(buf, refs, N, logs, N, &opts); + cl_reftable_write_to_buf(buf, refs, N, logs, N, &opts); reftable_free(refs); reftable_free(logs); } -static void t_log_buffer_size(void) +void test_reftable_readwrite__log_buffer_size(void) { struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_write_options opts = { .block_size = 4096, }; - int err; int i; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", @@ -102,7 +102,8 @@ static void t_log_buffer_size(void) .time = 0x5e430672, .message = (char *) "commit: 9\n", } } }; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, + &opts); /* This tests buffer extension for log compression. Must use a random hash, to ensure that the compressed part is larger than the original. @@ -112,22 +113,19 @@ static void t_log_buffer_size(void) log.value.update.new_hash[i] = (uint8_t)(git_rand(0) % 256); } reftable_writer_set_limits(w, update_index, update_index); - err = reftable_writer_add_log(w, &log); - check(!err); - err = reftable_writer_close(w); - check(!err); + cl_assert_equal_i(reftable_writer_add_log(w, &log), 0); + cl_assert_equal_i(reftable_writer_close(w), 0); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_log_overflow(void) +void test_reftable_readwrite__log_overflow(void) { struct reftable_buf buf = REFTABLE_BUF_INIT; char msg[256] = { 0 }; struct reftable_write_options opts = { .block_size = ARRAY_SIZE(msg), }; - int err; struct reftable_log_record log = { .refname = (char *) "refs/heads/master", .update_index = update_index, @@ -144,21 +142,22 @@ static void t_log_overflow(void) }, }, }; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, + &opts); memset(msg, 'x', sizeof(msg) - 1); reftable_writer_set_limits(w, update_index, update_index); - err = reftable_writer_add_log(w, &log); - check_int(err, ==, REFTABLE_ENTRY_TOO_BIG_ERROR); + cl_assert_equal_i(reftable_writer_add_log(w, &log), REFTABLE_ENTRY_TOO_BIG_ERROR); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_log_write_limits(void) +void test_reftable_readwrite__log_write_limits(void) { struct reftable_write_options opts = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, + &opts); struct reftable_log_record log = { .refname = (char *)"refs/head/master", .update_index = 0, @@ -174,29 +173,25 @@ static void t_log_write_limits(void) }, }, }; - int err; reftable_writer_set_limits(w, 1, 1); /* write with update_index (0) below set limits (1, 1) */ - err = reftable_writer_add_log(w, &log); - check_int(err, ==, 0); + cl_assert_equal_i(reftable_writer_add_log(w, &log), 0); /* write with update_index (1) in the set limits (1, 1) */ log.update_index = 1; - err = reftable_writer_add_log(w, &log); - check_int(err, ==, 0); + cl_assert_equal_i(reftable_writer_add_log(w, &log), 0); /* write with update_index (3) above set limits (1, 1) */ log.update_index = 3; - err = reftable_writer_add_log(w, &log); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_writer_add_log(w, &log), REFTABLE_API_ERROR); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_log_write_read(void) +void test_reftable_readwrite__log_write_read(void) { struct reftable_write_options opts = { .block_size = 256, @@ -207,13 +202,14 @@ static void t_log_write_read(void) struct reftable_table *table; struct reftable_block_source source = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); const struct reftable_stats *stats = NULL; - int N = 2, err, i, n; + int N = 2, i; char **names; + int err; names = reftable_calloc(N + 1, sizeof(*names)); - check(names != NULL); + cl_assert(names != NULL); reftable_writer_set_limits(w, 0, N); @@ -225,8 +221,7 @@ static void t_log_write_read(void) ref.refname = name; ref.update_index = i; - err = reftable_writer_add_ref(w, &ref); - check(!err); + cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0); } for (i = 0; i < N; i++) { @@ -235,60 +230,57 @@ static void t_log_write_read(void) log.refname = names[i]; log.update_index = i; log.value_type = REFTABLE_LOG_UPDATE; - t_reftable_set_hash(log.value.update.old_hash, i, - REFTABLE_HASH_SHA1); - t_reftable_set_hash(log.value.update.new_hash, i + 1, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(log.value.update.old_hash, i, + REFTABLE_HASH_SHA1); + cl_reftable_set_hash(log.value.update.new_hash, i + 1, + REFTABLE_HASH_SHA1); - err = reftable_writer_add_log(w, &log); - check(!err); + cl_assert_equal_i(reftable_writer_add_log(w, &log), 0); } - n = reftable_writer_close(w); - check_int(n, ==, 0); + cl_assert_equal_i(reftable_writer_close(w), 0); stats = reftable_writer_stats(w); - check_int(stats->log_stats.blocks, >, 0); + cl_assert(stats->log_stats.blocks > 0); reftable_writer_free(w); w = NULL; block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.log"); - check(!err); + cl_assert(!err); err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, names[N - 1]); - check(!err); + cl_assert(!err); err = reftable_iterator_next_ref(&it, &ref); - check(!err); + cl_assert(!err); /* end of iteration. */ - err = reftable_iterator_next_ref(&it, &ref); - check_int(err, >, 0); + cl_assert(reftable_iterator_next_ref(&it, &ref) > 0); reftable_iterator_destroy(&it); reftable_ref_record_release(&ref); err = reftable_table_init_log_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_log(&it, ""); - check(!err); + cl_assert(!err); for (i = 0; ; i++) { int err = reftable_iterator_next_log(&it, &log); if (err > 0) break; - check(!err); - check_str(names[i], log.refname); - check_int(i, ==, log.update_index); + cl_assert(!err); + cl_assert_equal_s(names[i], log.refname); + cl_assert_equal_i(i, log.update_index); reftable_log_record_release(&log); } - check_int(i, ==, N); + cl_assert_equal_i(i, N); reftable_iterator_destroy(&it); /* cleanup. */ @@ -297,7 +289,7 @@ static void t_log_write_read(void) reftable_table_decref(table); } -static void t_log_zlib_corruption(void) +void test_reftable_readwrite__log_zlib_corruption(void) { struct reftable_write_options opts = { .block_size = 256, @@ -306,10 +298,12 @@ static void t_log_zlib_corruption(void) struct reftable_table *table; struct reftable_block_source source = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, + &opts); const struct reftable_stats *stats = NULL; char message[100] = { 0 }; - int err, i, n; + int i; + int err; struct reftable_log_record log = { .refname = (char *) "refname", .value_type = REFTABLE_LOG_UPDATE, @@ -329,14 +323,11 @@ static void t_log_zlib_corruption(void) reftable_writer_set_limits(w, 1, 1); - err = reftable_writer_add_log(w, &log); - check(!err); - - n = reftable_writer_close(w); - check_int(n, ==, 0); + cl_assert_equal_i(reftable_writer_add_log(w, &log), 0); + cl_assert_equal_i(reftable_writer_close(w), 0); stats = reftable_writer_stats(w); - check_int(stats->log_stats.blocks, >, 0); + cl_assert(stats->log_stats.blocks > 0); reftable_writer_free(w); w = NULL; @@ -346,12 +337,12 @@ static void t_log_zlib_corruption(void) block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.log"); - check(!err); + cl_assert(!err); err = reftable_table_init_log_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_log(&it, "refname"); - check_int(err, ==, REFTABLE_ZLIB_ERROR); + cl_assert_equal_i(err, REFTABLE_ZLIB_ERROR); reftable_iterator_destroy(&it); @@ -360,7 +351,7 @@ static void t_log_zlib_corruption(void) reftable_buf_release(&buf); } -static void t_table_read_write_sequential(void) +void test_reftable_readwrite__table_read_write_sequential(void) { char **names; struct reftable_buf buf = REFTABLE_BUF_INIT; @@ -376,24 +367,24 @@ static void t_table_read_write_sequential(void) block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.ref"); - check(!err); + cl_assert(!err); err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, ""); - check(!err); + cl_assert(!err); for (j = 0; ; j++) { struct reftable_ref_record ref = { 0 }; int r = reftable_iterator_next_ref(&it, &ref); - check_int(r, >=, 0); + cl_assert(r >= 0); if (r > 0) break; - check_str(names[j], ref.refname); - check_int(update_index, ==, ref.update_index); + cl_assert_equal_s(names[j], ref.refname); + cl_assert_equal_i(update_index, ref.update_index); reftable_ref_record_release(&ref); } - check_int(j, ==, N); + cl_assert_equal_i(j, N); reftable_iterator_destroy(&it); reftable_table_decref(table); @@ -401,42 +392,42 @@ static void t_table_read_write_sequential(void) free_names(names); } -static void t_table_write_small_table(void) +void test_reftable_readwrite__table_write_small_table(void) { char **names; struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 1; write_table(&names, &buf, N, 4096, REFTABLE_HASH_SHA1); - check_int(buf.len, <, 200); + cl_assert(buf.len < 200); reftable_buf_release(&buf); free_names(names); } -static void t_table_read_api(void) +void test_reftable_readwrite__table_read_api(void) { char **names; struct reftable_buf buf = REFTABLE_BUF_INIT; int N = 50; struct reftable_table *table; struct reftable_block_source source = { 0 }; - int err; struct reftable_log_record log = { 0 }; struct reftable_iterator it = { 0 }; + int err; write_table(&names, &buf, N, 256, REFTABLE_HASH_SHA1); block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.ref"); - check(!err); + cl_assert(!err); err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, names[0]); - check(!err); + cl_assert(!err); err = reftable_iterator_next_log(&it, &log); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(err, REFTABLE_API_ERROR); reftable_buf_release(&buf); free_names(names); @@ -464,42 +455,43 @@ static void t_table_read_write_seek(int index, enum reftable_hash hash_id) block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.ref"); - check(!err); - check_int(hash_id, ==, reftable_table_hash_id(table)); + cl_assert(!err); + cl_assert_equal_i(hash_id, reftable_table_hash_id(table)); if (!index) { table->ref_offsets.index_offset = 0; } else { - check_int(table->ref_offsets.index_offset, >, 0); + cl_assert(table->ref_offsets.index_offset > 0); } for (i = 1; i < N; i++) { err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, names[i]); - check(!err); + cl_assert(!err); err = reftable_iterator_next_ref(&it, &ref); - check(!err); - check_str(names[i], ref.refname); - check_int(REFTABLE_REF_VAL1, ==, ref.value_type); - check_int(i, ==, ref.value.val1[0]); + cl_assert(!err); + cl_assert_equal_s(names[i], ref.refname); + cl_assert_equal_i(REFTABLE_REF_VAL1, ref.value_type); + cl_assert_equal_i(i, ref.value.val1[0]); reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); } - check(!reftable_buf_addstr(&pastLast, names[N - 1])); - check(!reftable_buf_addstr(&pastLast, "/")); + cl_assert_equal_i(reftable_buf_addstr(&pastLast, names[N - 1]), + 0); + cl_assert_equal_i(reftable_buf_addstr(&pastLast, "/"), 0); err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, pastLast.buf); if (err == 0) { struct reftable_ref_record ref = { 0 }; int err = reftable_iterator_next_ref(&it, &ref); - check_int(err, >, 0); + cl_assert(err > 0); } else { - check_int(err, >, 0); + cl_assert(err > 0); } reftable_buf_release(&pastLast); @@ -510,17 +502,17 @@ static void t_table_read_write_seek(int index, enum reftable_hash hash_id) reftable_table_decref(table); } -static void t_table_read_write_seek_linear(void) +void test_reftable_readwrite__table_read_write_seek_linear(void) { t_table_read_write_seek(0, REFTABLE_HASH_SHA1); } -static void t_table_read_write_seek_linear_sha256(void) +void test_reftable_readwrite__table_read_write_seek_linear_sha256(void) { t_table_read_write_seek(0, REFTABLE_HASH_SHA256); } -static void t_table_read_write_seek_index(void) +void test_reftable_readwrite__table_read_write_seek_index(void) { t_table_read_write_seek(1, REFTABLE_HASH_SHA1); } @@ -538,14 +530,16 @@ static void t_table_refs_for(int indexed) struct reftable_table *table; struct reftable_block_source source = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, + &opts); struct reftable_iterator it = { 0 }; - int N = 50, n, j, err, i; + int N = 50, j, i; + int err; want_names = reftable_calloc(N + 1, sizeof(*want_names)); - check(want_names != NULL); + cl_assert(want_names != NULL); - t_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(want_hash, 4, REFTABLE_HASH_SHA1); for (i = 0; i < N; i++) { uint8_t hash[REFTABLE_HASH_SIZE_SHA1]; @@ -561,24 +555,22 @@ static void t_table_refs_for(int indexed) ref.refname = name; ref.value_type = REFTABLE_REF_VAL2; - t_reftable_set_hash(ref.value.val2.value, i / 4, - REFTABLE_HASH_SHA1); - t_reftable_set_hash(ref.value.val2.target_value, 3 + i / 4, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(ref.value.val2.value, i / 4, + REFTABLE_HASH_SHA1); + cl_reftable_set_hash(ref.value.val2.target_value, + 3 + i / 4, REFTABLE_HASH_SHA1); /* 80 bytes / entry, so 3 entries per block. Yields 17 */ /* blocks. */ - n = reftable_writer_add_ref(w, &ref); - check_int(n, ==, 0); + cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0); if (!memcmp(ref.value.val2.value, want_hash, REFTABLE_HASH_SIZE_SHA1) || !memcmp(ref.value.val2.target_value, want_hash, REFTABLE_HASH_SIZE_SHA1)) want_names[want_names_len++] = xstrdup(name); } - n = reftable_writer_close(w); - check_int(n, ==, 0); + cl_assert_equal_i(reftable_writer_close(w), 0); reftable_writer_free(w); w = NULL; @@ -586,29 +578,29 @@ static void t_table_refs_for(int indexed) block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.ref"); - check(!err); + cl_assert(!err); if (!indexed) table->obj_offsets.is_present = 0; err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, ""); - check(!err); + cl_assert(!err); reftable_iterator_destroy(&it); err = reftable_table_refs_for(table, &it, want_hash); - check(!err); + cl_assert(!err); for (j = 0; ; j++) { int err = reftable_iterator_next_ref(&it, &ref); - check_int(err, >=, 0); + cl_assert(err >= 0); if (err > 0) break; - check_int(j, <, want_names_len); - check_str(ref.refname, want_names[j]); + cl_assert(j < want_names_len); + cl_assert_equal_s(ref.refname, want_names[j]); reftable_ref_record_release(&ref); } - check_int(j, ==, want_names_len); + cl_assert_equal_i(j, want_names_len); reftable_buf_release(&buf); free_names(want_names); @@ -616,21 +608,21 @@ static void t_table_refs_for(int indexed) reftable_table_decref(table); } -static void t_table_refs_for_no_index(void) +void test_reftable_readwrite__table_refs_for_no_index(void) { t_table_refs_for(0); } -static void t_table_refs_for_obj_index(void) +void test_reftable_readwrite__table_refs_for_obj_index(void) { t_table_refs_for(1); } -static void t_write_empty_table(void) +void test_reftable_readwrite__write_empty_table(void) { struct reftable_write_options opts = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_block_source source = { 0 }; struct reftable_table *table = NULL; struct reftable_ref_record rec = { 0 }; @@ -639,43 +631,41 @@ static void t_write_empty_table(void) reftable_writer_set_limits(w, 1, 1); - err = reftable_writer_close(w); - check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR); + cl_assert_equal_i(reftable_writer_close(w), REFTABLE_EMPTY_TABLE_ERROR); reftable_writer_free(w); - check_uint(buf.len, ==, header_size(1) + footer_size(1)); + cl_assert_equal_i(buf.len, header_size(1) + footer_size(1)); block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "filename"); - check(!err); + cl_assert(!err); err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, ""); - check(!err); + cl_assert(!err); err = reftable_iterator_next_ref(&it, &rec); - check_int(err, >, 0); + cl_assert(err > 0); reftable_iterator_destroy(&it); reftable_table_decref(table); reftable_buf_release(&buf); } -static void t_write_object_id_min_length(void) +void test_reftable_readwrite__write_object_id_min_length(void) { struct reftable_write_options opts = { .block_size = 75, }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, .value.val1 = {42}, }; - int err; int i; reftable_writer_set_limits(w, 1, 1); @@ -686,30 +676,27 @@ static void t_write_object_id_min_length(void) char name[256]; snprintf(name, sizeof(name), "ref%05d", i); ref.refname = name; - err = reftable_writer_add_ref(w, &ref); - check(!err); + cl_assert_equal_i(reftable_writer_add_ref(w, &ref), 0); } - err = reftable_writer_close(w); - check(!err); - check_int(reftable_writer_stats(w)->object_id_len, ==, 2); + cl_assert_equal_i(reftable_writer_close(w), 0); + cl_assert_equal_i(reftable_writer_stats(w)->object_id_len, 2); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_write_object_id_length(void) +void test_reftable_readwrite__write_object_id_length(void) { struct reftable_write_options opts = { .block_size = 75, }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .update_index = 1, .value_type = REFTABLE_REF_VAL1, .value.val1 = {42}, }; - int err; int i; reftable_writer_set_limits(w, 1, 1); @@ -721,44 +708,39 @@ static void t_write_object_id_length(void) snprintf(name, sizeof(name), "ref%05d", i); ref.refname = name; ref.value.val1[15] = i; - err = reftable_writer_add_ref(w, &ref); - check(!err); + cl_assert(reftable_writer_add_ref(w, &ref) == 0); } - err = reftable_writer_close(w); - check(!err); - check_int(reftable_writer_stats(w)->object_id_len, ==, 16); + cl_assert_equal_i(reftable_writer_close(w), 0); + cl_assert_equal_i(reftable_writer_stats(w)->object_id_len, 16); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_write_empty_key(void) +void test_reftable_readwrite__write_empty_key(void) { struct reftable_write_options opts = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record ref = { .refname = (char *) "", .update_index = 1, .value_type = REFTABLE_REF_DELETION, }; - int err; reftable_writer_set_limits(w, 1, 1); - err = reftable_writer_add_ref(w, &ref); - check_int(err, ==, REFTABLE_API_ERROR); - - err = reftable_writer_close(w); - check_int(err, ==, REFTABLE_EMPTY_TABLE_ERROR); + cl_assert_equal_i(reftable_writer_add_ref(w, &ref), REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_writer_close(w), + REFTABLE_EMPTY_TABLE_ERROR); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_write_key_order(void) +void test_reftable_readwrite__write_key_order(void) { struct reftable_write_options opts = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; - struct reftable_writer *w = t_reftable_strbuf_writer(&buf, &opts); + struct reftable_writer *w = cl_reftable_strbuf_writer(&buf, &opts); struct reftable_ref_record refs[2] = { { .refname = (char *) "b", @@ -776,24 +758,21 @@ static void t_write_key_order(void) }, } }; - int err; reftable_writer_set_limits(w, 1, 1); - err = reftable_writer_add_ref(w, &refs[0]); - check(!err); - err = reftable_writer_add_ref(w, &refs[1]); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_writer_add_ref(w, &refs[0]), 0); + cl_assert_equal_i(reftable_writer_add_ref(w, &refs[1]), + REFTABLE_API_ERROR); refs[0].update_index = 2; - err = reftable_writer_add_ref(w, &refs[0]); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_writer_add_ref(w, &refs[0]), REFTABLE_API_ERROR); reftable_writer_close(w); reftable_writer_free(w); reftable_buf_release(&buf); } -static void t_write_multiple_indices(void) +void test_reftable_readwrite__write_multiple_indices(void) { struct reftable_write_options opts = { .block_size = 100, @@ -805,9 +784,10 @@ static void t_write_multiple_indices(void) struct reftable_writer *writer; struct reftable_table *table; char buf[128]; - int err, i; + int i; + int err; - writer = t_reftable_strbuf_writer(&writer_buf, &opts); + writer = cl_reftable_strbuf_writer(&writer_buf, &opts); reftable_writer_set_limits(writer, 1, 1); for (i = 0; i < 100; i++) { struct reftable_ref_record ref = { @@ -819,8 +799,7 @@ static void t_write_multiple_indices(void) snprintf(buf, sizeof(buf), "refs/heads/%04d", i); ref.refname = buf; - err = reftable_writer_add_ref(writer, &ref); - check(!err); + cl_assert_equal_i(reftable_writer_add_ref(writer, &ref), 0); } for (i = 0; i < 100; i++) { @@ -836,8 +815,7 @@ static void t_write_multiple_indices(void) snprintf(buf, sizeof(buf), "refs/heads/%04d", i); log.refname = buf; - err = reftable_writer_add_log(writer, &log); - check(!err); + cl_assert_equal_i(reftable_writer_add_log(writer, &log), 0); } reftable_writer_close(writer); @@ -847,22 +825,22 @@ static void t_write_multiple_indices(void) * for each of the block types. */ stats = reftable_writer_stats(writer); - check_int(stats->ref_stats.index_offset, >, 0); - check_int(stats->obj_stats.index_offset, >, 0); - check_int(stats->log_stats.index_offset, >, 0); + cl_assert(stats->ref_stats.index_offset > 0); + cl_assert(stats->obj_stats.index_offset > 0); + cl_assert(stats->log_stats.index_offset > 0); block_source_from_buf(&source, &writer_buf); err = reftable_table_new(&table, &source, "filename"); - check(!err); + cl_assert(!err); /* * Seeking the log uses the log index now. In case there is any * confusion regarding indices we would notice here. */ err = reftable_table_init_log_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_log(&it, ""); - check(!err); + cl_assert(!err); reftable_iterator_destroy(&it); reftable_writer_free(writer); @@ -870,7 +848,7 @@ static void t_write_multiple_indices(void) reftable_buf_release(&writer_buf); } -static void t_write_multi_level_index(void) +void test_reftable_readwrite__write_multi_level_index(void) { struct reftable_write_options opts = { .block_size = 100, @@ -883,7 +861,7 @@ static void t_write_multi_level_index(void) struct reftable_table *table; int err; - writer = t_reftable_strbuf_writer(&writer_buf, &opts); + writer = cl_reftable_strbuf_writer(&writer_buf, &opts); reftable_writer_set_limits(writer, 1, 1); for (size_t i = 0; i < 200; i++) { struct reftable_ref_record ref = { @@ -896,8 +874,7 @@ static void t_write_multi_level_index(void) snprintf(buf, sizeof(buf), "refs/heads/%03" PRIuMAX, (uintmax_t)i); ref.refname = buf; - err = reftable_writer_add_ref(writer, &ref); - check(!err); + cl_assert_equal_i(reftable_writer_add_ref(writer, &ref), 0); } reftable_writer_close(writer); @@ -906,19 +883,19 @@ static void t_write_multi_level_index(void) * multi-level index. */ stats = reftable_writer_stats(writer); - check_int(stats->ref_stats.max_index_level, ==, 2); + cl_assert_equal_i(stats->ref_stats.max_index_level, 2); block_source_from_buf(&source, &writer_buf); err = reftable_table_new(&table, &source, "filename"); - check(!err); + cl_assert(!err); /* * Seeking the last ref should work as expected. */ err = reftable_table_init_ref_iterator(table, &it); - check(!err); + cl_assert(!err); err = reftable_iterator_seek_ref(&it, "refs/heads/199"); - check(!err); + cl_assert(!err); reftable_iterator_destroy(&it); reftable_writer_free(writer); @@ -927,7 +904,7 @@ static void t_write_multi_level_index(void) reftable_buf_release(&buf); } -static void t_corrupt_table_empty(void) +void test_reftable_readwrite__corrupt_table_empty(void) { struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; @@ -936,50 +913,22 @@ static void t_corrupt_table_empty(void) block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.log"); - check_int(err, ==, REFTABLE_FORMAT_ERROR); + cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR); } -static void t_corrupt_table(void) +void test_reftable_readwrite__corrupt_table(void) { uint8_t zeros[1024] = { 0 }; struct reftable_buf buf = REFTABLE_BUF_INIT; struct reftable_block_source source = { 0 }; struct reftable_table *table; int err; - check(!reftable_buf_add(&buf, zeros, sizeof(zeros))); + + cl_assert(!reftable_buf_add(&buf, zeros, sizeof(zeros))); block_source_from_buf(&source, &buf); err = reftable_table_new(&table, &source, "file.log"); - check_int(err, ==, REFTABLE_FORMAT_ERROR); + cl_assert_equal_i(err, REFTABLE_FORMAT_ERROR); reftable_buf_release(&buf); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_buffer(), "strbuf works as blocksource"); - TEST(t_corrupt_table(), "read-write on corrupted table"); - TEST(t_corrupt_table_empty(), "read-write on an empty table"); - TEST(t_log_buffer_size(), "buffer extension for log compression"); - TEST(t_log_overflow(), "log overflow returns expected error"); - TEST(t_log_write_limits(), "writer limits for writing log records"); - TEST(t_log_write_read(), "read-write on log records"); - TEST(t_log_zlib_corruption(), "reading corrupted log record returns expected error"); - TEST(t_table_read_api(), "read on a table"); - TEST(t_table_read_write_seek_index(), "read-write on a table with index"); - TEST(t_table_read_write_seek_linear(), "read-write on a table without index (SHA1)"); - TEST(t_table_read_write_seek_linear_sha256(), "read-write on a table without index (SHA256)"); - TEST(t_table_read_write_sequential(), "sequential read-write on a table"); - TEST(t_table_refs_for_no_index(), "refs-only table with no index"); - TEST(t_table_refs_for_obj_index(), "refs-only table with index"); - TEST(t_table_write_small_table(), "write_table works"); - TEST(t_write_empty_key(), "write on refs with empty keys"); - TEST(t_write_empty_table(), "read-write on empty tables"); - TEST(t_write_key_order(), "refs must be written in increasing order"); - TEST(t_write_multi_level_index(), "table with multi-level index"); - TEST(t_write_multiple_indices(), "table with indices for multiple block types"); - TEST(t_write_object_id_length(), "prefix compression on writing refs"); - TEST(t_write_object_id_min_length(), "prefix compression on writing refs"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-record.c b/t/unit-tests/u-reftable-record.c index 553a007664..6c8c0d5374 100644 --- a/t/unit-tests/t-reftable-record.c +++ b/t/unit-tests/u-reftable-record.c @@ -6,7 +6,8 @@ https://developers.google.com/open-source/licenses/bsd */ -#include "test-lib.h" +#include "unit-test.h" +#include "lib-reftable.h" #include "reftable/basics.h" #include "reftable/constants.h" #include "reftable/record.h" @@ -17,16 +18,17 @@ static void t_copy(struct reftable_record *rec) uint8_t typ; typ = reftable_record_type(rec); - check(!reftable_record_init(©, typ)); + cl_assert_equal_i(reftable_record_init(©, typ), 0); reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); /* do it twice to catch memory leaks */ reftable_record_copy_from(©, rec, REFTABLE_HASH_SIZE_SHA1); - check(reftable_record_equal(rec, ©, REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_record_equal(rec, ©, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_record_release(©); } -static void t_varint_roundtrip(void) +void test_reftable_record__varint_roundtrip(void) { uint64_t inputs[] = { 0, 1, @@ -49,16 +51,16 @@ static void t_varint_roundtrip(void) int n = put_var_int(&out, in); uint64_t got = 0; - check_int(n, >, 0); + cl_assert(n > 0); out.len = n; n = get_var_int(&got, &out); - check_int(n, >, 0); + cl_assert(n > 0); - check_int(got, ==, in); + cl_assert_equal_i(got, in); } } -static void t_varint_overflow(void) +void test_reftable_record__varint_overflow(void) { unsigned char buf[] = { 0xFF, 0xFF, 0xFF, 0xFF, @@ -70,8 +72,7 @@ static void t_varint_overflow(void) .len = sizeof(buf), }; uint64_t value; - int err = get_var_int(&value, &view); - check_int(err, ==, -1); + cl_assert_equal_i(get_var_int(&value, &view), -1); } static void set_hash(uint8_t *h, int j) @@ -80,7 +81,7 @@ static void set_hash(uint8_t *h, int j) h[i] = (j >> i) & 0xff; } -static void t_reftable_ref_record_comparison(void) +void test_reftable_record__ref_record_comparison(void) { struct reftable_record in[3] = { { @@ -102,21 +103,23 @@ static void t_reftable_ref_record_comparison(void) }; int cmp; - check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1) == 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); - check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[1], &in[2], &cmp)); - check_int(cmp, >, 0); + cl_assert(reftable_record_equal(&in[1], &in[2], + REFTABLE_HASH_SIZE_SHA1) == 0); + cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0); + cl_assert(cmp > 0); in[1].u.ref.value_type = in[0].u.ref.value_type; - check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1) != 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); } -static void t_reftable_ref_record_compare_name(void) +void test_reftable_record__ref_record_compare_name(void) { struct reftable_ref_record recs[3] = { { @@ -130,12 +133,15 @@ static void t_reftable_ref_record_compare_name(void) }, }; - check_int(reftable_ref_record_compare_name(&recs[0], &recs[1]), <, 0); - check_int(reftable_ref_record_compare_name(&recs[1], &recs[0]), >, 0); - check_int(reftable_ref_record_compare_name(&recs[0], &recs[2]), ==, 0); + cl_assert(reftable_ref_record_compare_name(&recs[0], + &recs[1]) < 0); + cl_assert(reftable_ref_record_compare_name(&recs[1], + &recs[0]) > 0); + cl_assert_equal_i(reftable_ref_record_compare_name(&recs[0], + &recs[2]), 0); } -static void t_reftable_ref_record_roundtrip(void) +void test_reftable_record__ref_record_roundtrip(void) { struct reftable_buf scratch = REFTABLE_BUF_INIT; @@ -172,19 +178,21 @@ static void t_reftable_ref_record_roundtrip(void) t_copy(&in); - check_int(reftable_record_val_type(&in), ==, i); - check_int(reftable_record_is_deletion(&in), ==, i == REFTABLE_REF_DELETION); + cl_assert_equal_i(reftable_record_val_type(&in), i); + cl_assert_equal_i(reftable_record_is_deletion(&in), + i == REFTABLE_REF_DELETION); reftable_record_key(&in, &key); n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); - check_int(n, >, 0); + cl_assert(n > 0); /* decode into a non-zero reftable_record to test for leaks. */ m = reftable_record_decode(&out, key, i, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); - check_int(n, ==, m); + cl_assert_equal_i(n, m); - check(reftable_ref_record_equal(&in.u.ref, &out.u.ref, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_ref_record_equal(&in.u.ref, + &out.u.ref, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_record_release(&in); reftable_buf_release(&key); @@ -194,7 +202,7 @@ static void t_reftable_ref_record_roundtrip(void) reftable_buf_release(&scratch); } -static void t_reftable_log_record_comparison(void) +void test_reftable_record__log_record_comparison(void) { struct reftable_record in[3] = { { @@ -215,21 +223,24 @@ static void t_reftable_log_record_comparison(void) }; int cmp; - check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[1], &in[2], &cmp)); - check_int(cmp, >, 0); + cl_assert_equal_i(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_equal(&in[1], &in[2], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0); + cl_assert(cmp > 0); /* comparison should be reversed for equal keys, because * comparison is now performed on the basis of update indices */ - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check_int(cmp, <, 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(cmp < 0); in[1].u.log.update_index = in[0].u.log.update_index; - check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); + cl_assert(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1) != 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); } -static void t_reftable_log_record_compare_key(void) +void test_reftable_record__log_record_compare_key(void) { struct reftable_log_record logs[3] = { { @@ -246,19 +257,24 @@ static void t_reftable_log_record_compare_key(void) }, }; - check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0); - check_int(reftable_log_record_compare_key(&logs[1], &logs[0]), >, 0); + cl_assert(reftable_log_record_compare_key(&logs[0], + &logs[1]) < 0); + cl_assert(reftable_log_record_compare_key(&logs[1], + &logs[0]) > 0); logs[1].update_index = logs[0].update_index; - check_int(reftable_log_record_compare_key(&logs[0], &logs[1]), <, 0); + cl_assert(reftable_log_record_compare_key(&logs[0], + &logs[1]) < 0); - check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), >, 0); - check_int(reftable_log_record_compare_key(&logs[2], &logs[0]), <, 0); + cl_assert(reftable_log_record_compare_key(&logs[0], + &logs[2]) > 0); + cl_assert(reftable_log_record_compare_key(&logs[2], + &logs[0]) < 0); logs[2].update_index = logs[0].update_index; - check_int(reftable_log_record_compare_key(&logs[0], &logs[2]), ==, 0); + cl_assert_equal_i(reftable_log_record_compare_key(&logs[0], &logs[2]), 0); } -static void t_reftable_log_record_roundtrip(void) +void test_reftable_record__log_record_roundtrip(void) { struct reftable_log_record in[] = { { @@ -292,9 +308,9 @@ static void t_reftable_log_record_roundtrip(void) set_hash(in[2].value.update.new_hash, 3); set_hash(in[2].value.update.old_hash, 4); - check(!reftable_log_record_is_deletion(&in[0])); - check(reftable_log_record_is_deletion(&in[1])); - check(!reftable_log_record_is_deletion(&in[2])); + cl_assert_equal_i(reftable_log_record_is_deletion(&in[0]), 0); + cl_assert(reftable_log_record_is_deletion(&in[1]) != 0); + cl_assert_equal_i(reftable_log_record_is_deletion(&in[2]), 0); for (size_t i = 0; i < ARRAY_SIZE(in); i++) { struct reftable_record rec = { .type = REFTABLE_BLOCK_TYPE_LOG }; @@ -328,14 +344,14 @@ static void t_reftable_log_record_roundtrip(void) reftable_record_key(&rec, &key); n = reftable_record_encode(&rec, dest, REFTABLE_HASH_SIZE_SHA1); - check_int(n, >=, 0); + cl_assert(n >= 0); valtype = reftable_record_val_type(&rec); m = reftable_record_decode(&out, key, valtype, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); - check_int(n, ==, m); + cl_assert_equal_i(n, m); - check(reftable_log_record_equal(&in[i], &out.u.log, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_log_record_equal(&in[i], &out.u.log, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_log_record_release(&in[i]); reftable_buf_release(&key); reftable_record_release(&out); @@ -344,7 +360,7 @@ static void t_reftable_log_record_roundtrip(void) reftable_buf_release(&scratch); } -static void t_key_roundtrip(void) +void test_reftable_record__key_roundtrip(void) { uint8_t buffer[1024] = { 0 }; struct string_view dest = { @@ -359,25 +375,28 @@ static void t_key_roundtrip(void) int n, m; uint8_t rt_extra; - check(!reftable_buf_addstr(&last_key, "refs/heads/master")); - check(!reftable_buf_addstr(&key, "refs/tags/bla")); + cl_assert_equal_i(reftable_buf_addstr(&last_key, + "refs/heads/master"), 0); + cl_assert_equal_i(reftable_buf_addstr(&key, + "refs/tags/bla"), 0); extra = 6; n = reftable_encode_key(&restart, dest, last_key, key, extra); - check(!restart); - check_int(n, >, 0); + cl_assert(!restart); + cl_assert(n > 0); - check(!reftable_buf_addstr(&roundtrip, "refs/heads/master")); + cl_assert_equal_i(reftable_buf_addstr(&roundtrip, + "refs/heads/master"), 0); m = reftable_decode_key(&roundtrip, &rt_extra, dest); - check_int(n, ==, m); - check(!reftable_buf_cmp(&key, &roundtrip)); - check_int(rt_extra, ==, extra); + cl_assert_equal_i(n, m); + cl_assert_equal_i(reftable_buf_cmp(&key, &roundtrip), 0); + cl_assert_equal_i(rt_extra, extra); reftable_buf_release(&last_key); reftable_buf_release(&key); reftable_buf_release(&roundtrip); } -static void t_reftable_obj_record_comparison(void) +void test_reftable_record__obj_record_comparison(void) { uint8_t id_bytes[] = { 0, 1, 2, 3, 4, 5, 6 }; @@ -405,21 +424,23 @@ static void t_reftable_obj_record_comparison(void) }; int cmp; - check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert_equal_i(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); - check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[1], &in[2], &cmp)); - check_int(cmp, >, 0); + cl_assert_equal_i(reftable_record_equal(&in[1], &in[2], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0); + cl_assert(cmp > 0); in[1].u.obj.offset_len = in[0].u.obj.offset_len; - check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1) != 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); } -static void t_reftable_obj_record_roundtrip(void) +void test_reftable_record__obj_record_roundtrip(void) { uint8_t testHash1[REFTABLE_HASH_SIZE_SHA1] = { 1, 2, 3, 4, 0 }; uint64_t till9[] = { 1, 2, 3, 4, 500, 600, 700, 800, 9000 }; @@ -460,17 +481,18 @@ static void t_reftable_obj_record_roundtrip(void) int n, m; uint8_t extra; - check(!reftable_record_is_deletion(&in)); + cl_assert_equal_i(reftable_record_is_deletion(&in), 0); t_copy(&in); reftable_record_key(&in, &key); n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); - check_int(n, >, 0); + cl_assert(n > 0); extra = reftable_record_val_type(&in); m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1, &scratch); - check_int(n, ==, m); + cl_assert_equal_i(n, m); - check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_record_equal(&in, &out, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_buf_release(&key); reftable_record_release(&out); } @@ -478,7 +500,7 @@ static void t_reftable_obj_record_roundtrip(void) reftable_buf_release(&scratch); } -static void t_reftable_index_record_comparison(void) +void test_reftable_record__index_record_comparison(void) { struct reftable_record in[3] = { { @@ -499,28 +521,33 @@ static void t_reftable_index_record_comparison(void) }; int cmp; - check(!reftable_buf_addstr(&in[0].u.idx.last_key, "refs/heads/master")); - check(!reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master")); - check(!reftable_buf_addstr(&in[2].u.idx.last_key, "refs/heads/branch")); + cl_assert_equal_i(reftable_buf_addstr(&in[0].u.idx.last_key, + "refs/heads/master"), 0); + cl_assert_equal_i(reftable_buf_addstr(&in[1].u.idx.last_key, "refs/heads/master"), 0); + cl_assert(reftable_buf_addstr(&in[2].u.idx.last_key, + "refs/heads/branch") == 0); - check(!reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert_equal_i(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); - check(!reftable_record_equal(&in[1], &in[2], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[1], &in[2], &cmp)); - check_int(cmp, >, 0); + cl_assert_equal_i(reftable_record_equal(&in[1], &in[2], + REFTABLE_HASH_SIZE_SHA1), 0); + cl_assert_equal_i(reftable_record_cmp(&in[1], &in[2], &cmp), 0); + cl_assert(cmp > 0); in[1].u.idx.offset = in[0].u.idx.offset; - check(reftable_record_equal(&in[0], &in[1], REFTABLE_HASH_SIZE_SHA1)); - check(!reftable_record_cmp(&in[0], &in[1], &cmp)); - check(!cmp); + cl_assert(reftable_record_equal(&in[0], &in[1], + REFTABLE_HASH_SIZE_SHA1) != 0); + cl_assert_equal_i(reftable_record_cmp(&in[0], &in[1], &cmp), 0); + cl_assert(!cmp); for (size_t i = 0; i < ARRAY_SIZE(in); i++) reftable_record_release(&in[i]); } -static void t_reftable_index_record_roundtrip(void) +void test_reftable_record__index_record_roundtrip(void) { struct reftable_record in = { .type = REFTABLE_BLOCK_TYPE_INDEX, @@ -543,43 +570,26 @@ static void t_reftable_index_record_roundtrip(void) int n, m; uint8_t extra; - check(!reftable_buf_addstr(&in.u.idx.last_key, "refs/heads/master")); + cl_assert_equal_i(reftable_buf_addstr(&in.u.idx.last_key, + "refs/heads/master"), 0); reftable_record_key(&in, &key); t_copy(&in); - check(!reftable_record_is_deletion(&in)); - check(!reftable_buf_cmp(&key, &in.u.idx.last_key)); + cl_assert_equal_i(reftable_record_is_deletion(&in), 0); + cl_assert_equal_i(reftable_buf_cmp(&key, &in.u.idx.last_key), 0); n = reftable_record_encode(&in, dest, REFTABLE_HASH_SIZE_SHA1); - check_int(n, >, 0); + cl_assert(n > 0); extra = reftable_record_val_type(&in); - m = reftable_record_decode(&out, key, extra, dest, REFTABLE_HASH_SIZE_SHA1, - &scratch); - check_int(m, ==, n); + m = reftable_record_decode(&out, key, extra, dest, + REFTABLE_HASH_SIZE_SHA1, &scratch); + cl_assert_equal_i(m, n); - check(reftable_record_equal(&in, &out, REFTABLE_HASH_SIZE_SHA1)); + cl_assert(reftable_record_equal(&in, &out, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_record_release(&out); reftable_buf_release(&key); reftable_buf_release(&scratch); reftable_buf_release(&in.u.idx.last_key); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_reftable_ref_record_comparison(), "comparison operations work on ref record"); - TEST(t_reftable_log_record_comparison(), "comparison operations work on log record"); - TEST(t_reftable_index_record_comparison(), "comparison operations work on index record"); - TEST(t_reftable_obj_record_comparison(), "comparison operations work on obj record"); - TEST(t_reftable_ref_record_compare_name(), "reftable_ref_record_compare_name works"); - TEST(t_reftable_log_record_compare_key(), "reftable_log_record_compare_key works"); - TEST(t_reftable_log_record_roundtrip(), "record operations work on log record"); - TEST(t_reftable_ref_record_roundtrip(), "record operations work on ref record"); - TEST(t_varint_roundtrip(), "put_var_int and get_var_int work"); - TEST(t_varint_overflow(), "get_var_int notices an integer overflow"); - TEST(t_key_roundtrip(), "reftable_encode_key and reftable_decode_key work"); - TEST(t_reftable_obj_record_roundtrip(), "record operations work on obj record"); - TEST(t_reftable_index_record_roundtrip(), "record operations work on index record"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-stack.c b/t/unit-tests/u-reftable-stack.c index 2f49c97519..a8b91812e8 100644 --- a/t/unit-tests/t-reftable-stack.c +++ b/t/unit-tests/u-reftable-stack.c @@ -8,9 +8,9 @@ https://developers.google.com/open-source/licenses/bsd #define DISABLE_SIGN_COMPARE_WARNINGS -#include "test-lib.h" -#include "lib-reftable.h" +#include "unit-test.h" #include "dir.h" +#include "lib-reftable.h" #include "reftable/merged.h" #include "reftable/reftable-error.h" #include "reftable/stack.h" @@ -70,11 +70,11 @@ static char *get_tmp_template(int linenumber) static char *get_tmp_dir(int linenumber) { char *dir = get_tmp_template(linenumber); - check(mkdtemp(dir) != NULL); + cl_assert(mkdtemp(dir) != NULL); return dir; } -static void t_read_file(void) +void test_reftable_stack__read_file(void) { char *fn = get_tmp_template(__LINE__); struct tempfile *tmp = mks_tempfile(fn); @@ -84,17 +84,17 @@ static void t_read_file(void) char **names = NULL; const char *want[] = { "line1", "line2", "line3" }; - check_int(fd, >, 0); + cl_assert(fd > 0); n = write_in_full(fd, out, strlen(out)); - check_int(n, ==, strlen(out)); + cl_assert_equal_i(n, strlen(out)); err = close(fd); - check_int(err, >=, 0); + cl_assert(err >= 0); err = read_lines(fn, &names); - check(!err); + cl_assert(!err); for (size_t i = 0; names[i]; i++) - check_str(want[i], names[i]); + cl_assert_equal_s(want[i], names[i]); free_names(names); (void) remove(fn); delete_tempfile(&tmp); @@ -103,8 +103,8 @@ static void t_read_file(void) static int write_test_ref(struct reftable_writer *wr, void *arg) { struct reftable_ref_record *ref = arg; - check(!reftable_writer_set_limits(wr, ref->update_index, - ref->update_index)); + cl_assert_equal_i(reftable_writer_set_limits(wr, + ref->update_index, ref->update_index), 0); return reftable_writer_add_ref(wr, ref); } @@ -112,7 +112,6 @@ static void write_n_ref_tables(struct reftable_stack *st, size_t n) { int disable_auto_compact; - int err; disable_auto_compact = st->opts.disable_auto_compact; st->opts.disable_auto_compact = 1; @@ -126,10 +125,10 @@ static void write_n_ref_tables(struct reftable_stack *st, snprintf(buf, sizeof(buf), "refs/heads/branch-%04"PRIuMAX, (uintmax_t)i); ref.refname = buf; - t_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(ref.value.val1, i, REFTABLE_HASH_SHA1); - err = reftable_stack_add(st, &write_test_ref, &ref); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, + &write_test_ref, &ref, 0), 0); } st->opts.disable_auto_compact = disable_auto_compact; @@ -144,12 +143,13 @@ static int write_test_log(struct reftable_writer *wr, void *arg) { struct write_log_arg *wla = arg; - check(!reftable_writer_set_limits(wr, wla->update_index, - wla->update_index)); + cl_assert_equal_i(reftable_writer_set_limits(wr, + wla->update_index, + wla->update_index), 0); return reftable_writer_add_log(wr, wla->log); } -static void t_reftable_stack_add_one(void) +void test_reftable_stack__add_one(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_buf scratch = REFTABLE_BUF_INIT; @@ -158,7 +158,6 @@ static void t_reftable_stack_add_one(void) .default_permissions = 0660, }; struct reftable_stack *st = NULL; - int err; struct reftable_ref_record ref = { .refname = (char *) "HEAD", .update_index = 1, @@ -167,32 +166,37 @@ static void t_reftable_stack_add_one(void) }; struct reftable_ref_record dest = { 0 }; struct stat stat_result = { 0 }; + int err; + err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert(!err); - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); + err = reftable_stack_add(st, write_test_ref, &ref, 0); + cl_assert(!err); err = reftable_stack_read_ref(st, ref.refname, &dest); - check(!err); - check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); - check_int(st->tables_len, >, 0); + cl_assert(!err); + cl_assert(reftable_ref_record_equal(&ref, &dest, + REFTABLE_HASH_SIZE_SHA1)); + cl_assert(st->tables_len > 0); #ifndef GIT_WINDOWS_NATIVE - check(!reftable_buf_addstr(&scratch, dir)); - check(!reftable_buf_addstr(&scratch, "/tables.list")); - err = stat(scratch.buf, &stat_result); - check(!err); - check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); + cl_assert_equal_i(reftable_buf_addstr(&scratch, dir), 0); + cl_assert_equal_i(reftable_buf_addstr(&scratch, + "/tables.list"), 0); + cl_assert_equal_i(stat(scratch.buf, &stat_result), 0); + cl_assert_equal_i((stat_result.st_mode & 0777), + opts.default_permissions); reftable_buf_reset(&scratch); - check(!reftable_buf_addstr(&scratch, dir)); - check(!reftable_buf_addstr(&scratch, "/")); + cl_assert_equal_i(reftable_buf_addstr(&scratch, dir), 0); + cl_assert_equal_i(reftable_buf_addstr(&scratch, "/"), 0); /* do not try at home; not an external API for reftable. */ - check(!reftable_buf_addstr(&scratch, st->tables[0]->name)); + cl_assert(!reftable_buf_addstr(&scratch, st->tables[0]->name)); err = stat(scratch.buf, &stat_result); - check(!err); - check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); + cl_assert(!err); + cl_assert_equal_i((stat_result.st_mode & 0777), + opts.default_permissions); #else (void) stat_result; #endif @@ -204,14 +208,13 @@ static void t_reftable_stack_add_one(void) umask(mask); } -static void t_reftable_stack_uptodate(void) +void test_reftable_stack__uptodate(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st1 = NULL; struct reftable_stack *st2 = NULL; char *dir = get_tmp_dir(__LINE__); - int err; struct reftable_ref_record ref1 = { .refname = (char *) "HEAD", .update_index = 1, @@ -229,34 +232,25 @@ static void t_reftable_stack_uptodate(void) /* simulate multi-process access to the same stack by creating two stacks for the same directory. */ - err = reftable_new_stack(&st1, dir, &opts); - check(!err); - - err = reftable_new_stack(&st2, dir, &opts); - check(!err); - - err = reftable_stack_add(st1, write_test_ref, &ref1); - check(!err); - - err = reftable_stack_add(st2, write_test_ref, &ref2); - check_int(err, ==, REFTABLE_OUTDATED_ERROR); - - err = reftable_stack_reload(st2); - check(!err); - - err = reftable_stack_add(st2, write_test_ref, &ref2); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0); + cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_add(st1, write_test_ref, + &ref1, 0), 0); + cl_assert_equal_i(reftable_stack_add(st2, write_test_ref, + &ref2, 0), REFTABLE_OUTDATED_ERROR); + cl_assert_equal_i(reftable_stack_reload(st2), 0); + cl_assert_equal_i(reftable_stack_add(st2, write_test_ref, + &ref2, 0), 0); reftable_stack_destroy(st1); reftable_stack_destroy(st2); clear_dir(dir); } -static void t_reftable_stack_transaction_api(void) +void test_reftable_stack__transaction_api(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err; struct reftable_addition *add = NULL; struct reftable_ref_record ref = { @@ -267,37 +261,32 @@ static void t_reftable_stack_transaction_api(void) }; struct reftable_ref_record dest = { 0 }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); reftable_addition_destroy(add); - err = reftable_stack_new_addition(&add, st, 0); - check(!err); - - err = reftable_addition_add(add, write_test_ref, &ref); - check(!err); - - err = reftable_addition_commit(add); - check(!err); + cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0); + cl_assert_equal_i(reftable_addition_add(add, write_test_ref, + &ref), 0); + cl_assert_equal_i(reftable_addition_commit(add), 0); reftable_addition_destroy(add); - err = reftable_stack_read_ref(st, ref.refname, &dest); - check(!err); - check_int(REFTABLE_REF_SYMREF, ==, dest.value_type); - check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_stack_read_ref(st, ref.refname, + &dest), 0); + cl_assert_equal_i(REFTABLE_REF_SYMREF, dest.value_type); + cl_assert(reftable_ref_record_equal(&ref, &dest, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_ref_record_release(&dest); reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_transaction_with_reload(void) +void test_reftable_stack__transaction_with_reload(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_stack *st1 = NULL, *st2 = NULL; - int err; struct reftable_addition *add = NULL; struct reftable_ref_record refs[2] = { { @@ -315,17 +304,12 @@ static void t_reftable_stack_transaction_with_reload(void) }; struct reftable_ref_record ref = { 0 }; - err = reftable_new_stack(&st1, dir, NULL); - check(!err); - err = reftable_new_stack(&st2, dir, NULL); - check(!err); - - err = reftable_stack_new_addition(&add, st1, 0); - check(!err); - err = reftable_addition_add(add, write_test_ref, &refs[0]); - check(!err); - err = reftable_addition_commit(add); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st1, dir, NULL), 0); + cl_assert_equal_i(reftable_new_stack(&st2, dir, NULL), 0); + cl_assert_equal_i(reftable_stack_new_addition(&add, st1, 0), 0); + cl_assert_equal_i(reftable_addition_add(add, write_test_ref, + &refs[0]), 0); + cl_assert_equal_i(reftable_addition_commit(add), 0); reftable_addition_destroy(add); /* @@ -333,20 +317,20 @@ static void t_reftable_stack_transaction_with_reload(void) * create the addition and lock the stack by default, but allow the * reload to happen when REFTABLE_STACK_NEW_ADDITION_RELOAD is set. */ - err = reftable_stack_new_addition(&add, st2, 0); - check_int(err, ==, REFTABLE_OUTDATED_ERROR); - err = reftable_stack_new_addition(&add, st2, REFTABLE_STACK_NEW_ADDITION_RELOAD); - check(!err); - err = reftable_addition_add(add, write_test_ref, &refs[1]); - check(!err); - err = reftable_addition_commit(add); - check(!err); + cl_assert_equal_i(reftable_stack_new_addition(&add, st2, 0), + REFTABLE_OUTDATED_ERROR); + cl_assert_equal_i(reftable_stack_new_addition(&add, st2, + REFTABLE_STACK_NEW_ADDITION_RELOAD), 0); + cl_assert_equal_i(reftable_addition_add(add, write_test_ref, + &refs[1]), 0); + cl_assert_equal_i(reftable_addition_commit(add), 0); reftable_addition_destroy(add); for (size_t i = 0; i < ARRAY_SIZE(refs); i++) { - err = reftable_stack_read_ref(st2, refs[i].refname, &ref); - check(!err); - check(reftable_ref_record_equal(&refs[i], &ref, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_stack_read_ref(st2, + refs[i].refname, &ref) , 0); + cl_assert(reftable_ref_record_equal(&refs[i], &ref, + REFTABLE_HASH_SIZE_SHA1) != 0); } reftable_ref_record_release(&ref); @@ -355,17 +339,15 @@ static void t_reftable_stack_transaction_with_reload(void) clear_dir(dir); } -static void t_reftable_stack_transaction_api_performs_auto_compaction(void) +void test_reftable_stack__transaction_api_performs_auto_compaction(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = {0}; struct reftable_addition *add = NULL; struct reftable_stack *st = NULL; size_t n = 20; - int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (size_t i = 0; i <= n; i++) { struct reftable_ref_record ref = { @@ -385,14 +367,11 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void) */ st->opts.disable_auto_compact = i != n; - err = reftable_stack_new_addition(&add, st, 0); - check(!err); - - err = reftable_addition_add(add, write_test_ref, &ref); - check(!err); - - err = reftable_addition_commit(add); - check(!err); + cl_assert_equal_i(reftable_stack_new_addition(&add, + st, 0), 0); + cl_assert_equal_i(reftable_addition_add(add, + write_test_ref, &ref), 0); + cl_assert_equal_i(reftable_addition_commit(add), 0); reftable_addition_destroy(add); @@ -402,16 +381,16 @@ static void t_reftable_stack_transaction_api_performs_auto_compaction(void) * all tables in the stack. */ if (i != n) - check_int(st->merged->tables_len, ==, i + 1); + cl_assert_equal_i(st->merged->tables_len, i + 1); else - check_int(st->merged->tables_len, ==, 1); + cl_assert_equal_i(st->merged->tables_len, 1); } reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_auto_compaction_fails_gracefully(void) +void test_reftable_stack__auto_compaction_fails_gracefully(void) { struct reftable_ref_record ref = { .refname = (char *) "refs/heads/master", @@ -425,32 +404,31 @@ static void t_reftable_stack_auto_compaction_fails_gracefully(void) char *dir = get_tmp_dir(__LINE__); int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); - - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); - check_int(st->merged->tables_len, ==, 1); - check_int(st->stats.attempts, ==, 0); - check_int(st->stats.failures, ==, 0); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &ref, 0), 0); + cl_assert_equal_i(st->merged->tables_len, 1); + cl_assert_equal_i(st->stats.attempts, 0); + cl_assert_equal_i(st->stats.failures, 0); /* * Lock the newly written table such that it cannot be compacted. * Adding a new table to the stack should not be impacted by this, even * though auto-compaction will now fail. */ - check(!reftable_buf_addstr(&table_path, dir)); - check(!reftable_buf_addstr(&table_path, "/")); - check(!reftable_buf_addstr(&table_path, st->tables[0]->name)); - check(!reftable_buf_addstr(&table_path, ".lock")); + cl_assert(!reftable_buf_addstr(&table_path, dir)); + cl_assert(!reftable_buf_addstr(&table_path, "/")); + cl_assert(!reftable_buf_addstr(&table_path, + st->tables[0]->name)); + cl_assert(!reftable_buf_addstr(&table_path, ".lock")); write_file_buf(table_path.buf, "", 0); ref.update_index = 2; - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); - check_int(st->merged->tables_len, ==, 2); - check_int(st->stats.attempts, ==, 1); - check_int(st->stats.failures, ==, 1); + err = reftable_stack_add(st, write_test_ref, &ref, 0); + cl_assert(!err); + cl_assert_equal_i(st->merged->tables_len, 2); + cl_assert_equal_i(st->stats.attempts, 1); + cl_assert_equal_i(st->stats.failures, 1); reftable_stack_destroy(st); reftable_buf_release(&table_path); @@ -462,12 +440,11 @@ static int write_error(struct reftable_writer *wr UNUSED, void *arg) return *((int *)arg); } -static void t_reftable_stack_update_index_check(void) +void test_reftable_stack__update_index_check(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err; struct reftable_ref_record ref1 = { .refname = (char *) "name1", .update_index = 1, @@ -481,39 +458,33 @@ static void t_reftable_stack_update_index_check(void) .value.symref = (char *) "master", }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); - - err = reftable_stack_add(st, write_test_ref, &ref1); - check(!err); - - err = reftable_stack_add(st, write_test_ref, &ref2); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &ref1, 0), 0); + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &ref2, 0), REFTABLE_API_ERROR); reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_lock_failure(void) +void test_reftable_stack__lock_failure(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err, i; + int i; - err = reftable_new_stack(&st, dir, &opts); - check(!err); - for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) { - err = reftable_stack_add(st, write_error, &i); - check_int(err, ==, i); - } + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); + for (i = -1; i != REFTABLE_EMPTY_TABLE_ERROR; i--) + cl_assert_equal_i(reftable_stack_add(st, write_error, + &i, 0), i); reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_add(void) +void test_reftable_stack__add(void) { - int err = 0; struct reftable_write_options opts = { .exact_log_message = 1, .default_permissions = 0660, @@ -526,9 +497,10 @@ static void t_reftable_stack_add(void) struct reftable_buf path = REFTABLE_BUF_INIT; struct stat stat_result; size_t i, N = ARRAY_SIZE(refs); + int err = 0; err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert(!err); for (i = 0; i < N; i++) { char buf[256]; @@ -536,66 +508,66 @@ static void t_reftable_stack_add(void) refs[i].refname = xstrdup(buf); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(refs[i].value.val1, i, + REFTABLE_HASH_SHA1); logs[i].refname = xstrdup(buf); logs[i].update_index = N + i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("identity@invalid"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(logs[i].value.update.new_hash, i, + REFTABLE_HASH_SHA1); } - for (i = 0; i < N; i++) { - int err = reftable_stack_add(st, write_test_ref, &refs[i]); - check(!err); - } + for (i = 0; i < N; i++) + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &refs[i], 0), 0); for (i = 0; i < N; i++) { struct write_log_arg arg = { .log = &logs[i], .update_index = reftable_stack_next_update_index(st), }; - int err = reftable_stack_add(st, write_test_log, &arg); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); } - err = reftable_stack_compact_all(st, NULL); - check(!err); + cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0); for (i = 0; i < N; i++) { struct reftable_ref_record dest = { 0 }; - int err = reftable_stack_read_ref(st, refs[i].refname, &dest); - check(!err); - check(reftable_ref_record_equal(&dest, refs + i, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_stack_read_ref(st, + refs[i].refname, &dest), 0); + cl_assert(reftable_ref_record_equal(&dest, refs + i, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_ref_record_release(&dest); } for (i = 0; i < N; i++) { struct reftable_log_record dest = { 0 }; - int err = reftable_stack_read_log(st, refs[i].refname, &dest); - check(!err); - check(reftable_log_record_equal(&dest, logs + i, - REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_stack_read_log(st, + refs[i].refname, &dest), 0); + cl_assert(reftable_log_record_equal(&dest, logs + i, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_log_record_release(&dest); } #ifndef GIT_WINDOWS_NATIVE - check(!reftable_buf_addstr(&path, dir)); - check(!reftable_buf_addstr(&path, "/tables.list")); - err = stat(path.buf, &stat_result); - check(!err); - check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); + cl_assert_equal_i(reftable_buf_addstr(&path, dir), 0); + cl_assert_equal_i(reftable_buf_addstr(&path, "/tables.list"), 0); + cl_assert_equal_i(stat(path.buf, &stat_result), 0); + cl_assert_equal_i((stat_result.st_mode & 0777), opts.default_permissions); reftable_buf_reset(&path); - check(!reftable_buf_addstr(&path, dir)); - check(!reftable_buf_addstr(&path, "/")); + cl_assert_equal_i(reftable_buf_addstr(&path, dir), 0); + cl_assert_equal_i(reftable_buf_addstr(&path, "/"), 0); /* do not try at home; not an external API for reftable. */ - check(!reftable_buf_addstr(&path, st->tables[0]->name)); + cl_assert(!reftable_buf_addstr(&path, st->tables[0]->name)); err = stat(path.buf, &stat_result); - check(!err); - check_int((stat_result.st_mode & 0777), ==, opts.default_permissions); + cl_assert(!err); + cl_assert_equal_i((stat_result.st_mode & 0777), + opts.default_permissions); #else (void) stat_result; #endif @@ -610,7 +582,7 @@ static void t_reftable_stack_add(void) clear_dir(dir); } -static void t_reftable_stack_iterator(void) +void test_reftable_stack__iterator(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; @@ -621,27 +593,27 @@ static void t_reftable_stack_iterator(void) size_t N = ARRAY_SIZE(refs), i; int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (i = 0; i < N; i++) { refs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); refs[i].update_index = i + 1; refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(refs[i].value.val1, i, + REFTABLE_HASH_SHA1); logs[i].refname = xstrfmt("branch%02"PRIuMAX, (uintmax_t)i); logs[i].update_index = i + 1; logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.email = xstrdup("johndoe@invalid"); logs[i].value.update.message = xstrdup("commit\n"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); + cl_reftable_set_hash(logs[i].value.update.new_hash, i, + REFTABLE_HASH_SHA1); } - for (i = 0; i < N; i++) { - err = reftable_stack_add(st, write_test_ref, &refs[i]); - check(!err); - } + for (i = 0; i < N; i++) + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &refs[i], 0), 0); for (i = 0; i < N; i++) { struct write_log_arg arg = { @@ -649,8 +621,8 @@ static void t_reftable_stack_iterator(void) .update_index = reftable_stack_next_update_index(st), }; - err = reftable_stack_add(st, write_test_log, &arg); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); } reftable_stack_init_ref_iterator(st, &it); @@ -661,16 +633,16 @@ static void t_reftable_stack_iterator(void) err = reftable_iterator_next_ref(&it, &ref); if (err > 0) break; - check(!err); - check(reftable_ref_record_equal(&ref, &refs[i], REFTABLE_HASH_SIZE_SHA1)); + cl_assert(!err); + cl_assert(reftable_ref_record_equal(&ref, &refs[i], + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_ref_record_release(&ref); } - check_int(i, ==, N); + cl_assert_equal_i(i, N); reftable_iterator_destroy(&it); - err = reftable_stack_init_log_iterator(st, &it); - check(!err); + cl_assert_equal_i(reftable_stack_init_log_iterator(st, &it), 0); reftable_iterator_seek_log(&it, logs[0].refname); for (i = 0; ; i++) { @@ -679,11 +651,12 @@ static void t_reftable_stack_iterator(void) err = reftable_iterator_next_log(&it, &log); if (err > 0) break; - check(!err); - check(reftable_log_record_equal(&log, &logs[i], REFTABLE_HASH_SIZE_SHA1)); + cl_assert(!err); + cl_assert(reftable_log_record_equal(&log, &logs[i], + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_log_record_release(&log); } - check_int(i, ==, N); + cl_assert_equal_i(i, N); reftable_stack_destroy(st); reftable_iterator_destroy(&it); @@ -694,9 +667,8 @@ static void t_reftable_stack_iterator(void) clear_dir(dir); } -static void t_reftable_stack_log_normalize(void) +void test_reftable_stack__log_normalize(void) { - int err = 0; struct reftable_write_options opts = { 0, }; @@ -721,28 +693,26 @@ static void t_reftable_stack_log_normalize(void) .update_index = 1, }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); input.value.update.message = (char *) "one\ntwo"; - err = reftable_stack_add(st, write_test_log, &arg); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), REFTABLE_API_ERROR); input.value.update.message = (char *) "one"; - err = reftable_stack_add(st, write_test_log, &arg); - check(!err); - - err = reftable_stack_read_log(st, input.refname, &dest); - check(!err); - check_str(dest.value.update.message, "one\n"); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); + cl_assert_equal_i(reftable_stack_read_log(st, input.refname, + &dest), 0); + cl_assert_equal_s(dest.value.update.message, "one\n"); input.value.update.message = (char *) "two\n"; arg.update_index = 2; - err = reftable_stack_add(st, write_test_log, &arg); - check(!err); - err = reftable_stack_read_log(st, input.refname, &dest); - check(!err); - check_str(dest.value.update.message, "two\n"); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); + cl_assert_equal_i(reftable_stack_read_log(st, input.refname, + &dest), 0); + cl_assert_equal_s(dest.value.update.message, "two\n"); /* cleanup */ reftable_stack_destroy(st); @@ -750,20 +720,18 @@ static void t_reftable_stack_log_normalize(void) clear_dir(dir); } -static void t_reftable_stack_tombstone(void) +void test_reftable_stack__tombstone(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err; struct reftable_ref_record refs[2] = { 0 }; struct reftable_log_record logs[2] = { 0 }; size_t i, N = ARRAY_SIZE(refs); struct reftable_ref_record dest = { 0 }; struct reftable_log_record log_dest = { 0 }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); /* even entries add the refs, odd entries delete them. */ for (i = 0; i < N; i++) { @@ -772,8 +740,8 @@ static void t_reftable_stack_tombstone(void) refs[i].update_index = i + 1; if (i % 2 == 0) { refs[i].value_type = REFTABLE_REF_VAL1; - t_reftable_set_hash(refs[i].value.val1, i, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(refs[i].value.val1, i, + REFTABLE_HASH_SHA1); } logs[i].refname = xstrdup(buf); @@ -785,42 +753,37 @@ static void t_reftable_stack_tombstone(void) logs[i].update_index = 1; if (i % 2 == 0) { logs[i].value_type = REFTABLE_LOG_UPDATE; - t_reftable_set_hash(logs[i].value.update.new_hash, i, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(logs[i].value.update.new_hash, i, REFTABLE_HASH_SHA1); logs[i].value.update.email = xstrdup("identity@invalid"); } } - for (i = 0; i < N; i++) { - int err = reftable_stack_add(st, write_test_ref, &refs[i]); - check(!err); - } + for (i = 0; i < N; i++) + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &refs[i], 0), 0); for (i = 0; i < N; i++) { struct write_log_arg arg = { .log = &logs[i], .update_index = reftable_stack_next_update_index(st), }; - int err = reftable_stack_add(st, write_test_log, &arg); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); } - err = reftable_stack_read_ref(st, "branch", &dest); - check_int(err, ==, 1); + cl_assert_equal_i(reftable_stack_read_ref(st, "branch", + &dest), 1); reftable_ref_record_release(&dest); - err = reftable_stack_read_log(st, "branch", &log_dest); - check_int(err, ==, 1); + cl_assert_equal_i(reftable_stack_read_log(st, "branch", + &log_dest), 1); reftable_log_record_release(&log_dest); - err = reftable_stack_compact_all(st, NULL); - check(!err); - - err = reftable_stack_read_ref(st, "branch", &dest); - check_int(err, ==, 1); - - err = reftable_stack_read_log(st, "branch", &log_dest); - check_int(err, ==, 1); + cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0); + cl_assert_equal_i(reftable_stack_read_ref(st, "branch", + &dest), 1); + cl_assert_equal_i(reftable_stack_read_log(st, "branch", + &log_dest), 1); reftable_ref_record_release(&dest); reftable_log_record_release(&log_dest); @@ -833,12 +796,11 @@ static void t_reftable_stack_tombstone(void) clear_dir(dir); } -static void t_reftable_stack_hash_id(void) +void test_reftable_stack__hash_id(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err; struct reftable_ref_record ref = { .refname = (char *) "master", @@ -852,62 +814,57 @@ static void t_reftable_stack_hash_id(void) struct reftable_stack *st_default = NULL; struct reftable_ref_record dest = { 0 }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); - - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &ref, 0), 0); /* can't read it with the wrong hash ID. */ - err = reftable_new_stack(&st32, dir, &opts32); - check_int(err, ==, REFTABLE_FORMAT_ERROR); + cl_assert_equal_i(reftable_new_stack(&st32, dir, + &opts32), REFTABLE_FORMAT_ERROR); /* check that we can read it back with default opts too. */ - err = reftable_new_stack(&st_default, dir, &opts_default); - check(!err); - - err = reftable_stack_read_ref(st_default, "master", &dest); - check(!err); - - check(reftable_ref_record_equal(&ref, &dest, REFTABLE_HASH_SIZE_SHA1)); + cl_assert_equal_i(reftable_new_stack(&st_default, dir, + &opts_default), 0); + cl_assert_equal_i(reftable_stack_read_ref(st_default, "master", + &dest), 0); + cl_assert(reftable_ref_record_equal(&ref, &dest, + REFTABLE_HASH_SIZE_SHA1) != 0); reftable_ref_record_release(&dest); reftable_stack_destroy(st); reftable_stack_destroy(st_default); clear_dir(dir); } -static void t_suggest_compaction_segment(void) +void test_reftable_stack__suggest_compaction_segment(void) { uint64_t sizes[] = { 512, 64, 17, 16, 9, 9, 9, 16, 2, 16 }; struct segment min = suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2); - check_int(min.start, ==, 1); - check_int(min.end, ==, 10); + cl_assert_equal_i(min.start, 1); + cl_assert_equal_i(min.end, 10); } -static void t_suggest_compaction_segment_nothing(void) +void test_reftable_stack__suggest_compaction_segment_nothing(void) { uint64_t sizes[] = { 64, 32, 16, 8, 4, 2 }; struct segment result = suggest_compaction_segment(sizes, ARRAY_SIZE(sizes), 2); - check_int(result.start, ==, result.end); + cl_assert_equal_i(result.start, result.end); } -static void t_reflog_expire(void) +void test_reftable_stack__reflog_expire(void) { char *dir = get_tmp_dir(__LINE__); struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; struct reftable_log_record logs[20] = { 0 }; size_t i, N = ARRAY_SIZE(logs) - 1; - int err; struct reftable_log_expiry_config expiry = { .time = 10, }; struct reftable_log_record log = { 0 }; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (i = 1; i <= N; i++) { char buf[256]; @@ -918,8 +875,8 @@ static void t_reflog_expire(void) logs[i].value_type = REFTABLE_LOG_UPDATE; logs[i].value.update.time = i; logs[i].value.update.email = xstrdup("identity@invalid"); - t_reftable_set_hash(logs[i].value.update.new_hash, i, - REFTABLE_HASH_SHA1); + cl_reftable_set_hash(logs[i].value.update.new_hash, i, + REFTABLE_HASH_SHA1); } for (i = 1; i <= N; i++) { @@ -927,31 +884,23 @@ static void t_reflog_expire(void) .log = &logs[i], .update_index = reftable_stack_next_update_index(st), }; - int err = reftable_stack_add(st, write_test_log, &arg); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, write_test_log, + &arg, 0), 0); } - err = reftable_stack_compact_all(st, NULL); - check(!err); - - err = reftable_stack_compact_all(st, &expiry); - check(!err); - - err = reftable_stack_read_log(st, logs[9].refname, &log); - check_int(err, ==, 1); - - err = reftable_stack_read_log(st, logs[11].refname, &log); - check(!err); + cl_assert_equal_i(reftable_stack_compact_all(st, NULL), 0); + cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0); + cl_assert_equal_i(reftable_stack_read_log(st, logs[9].refname, + &log), 1); + cl_assert_equal_i(reftable_stack_read_log(st, logs[11].refname, + &log), 0); expiry.min_update_index = 15; - err = reftable_stack_compact_all(st, &expiry); - check(!err); - - err = reftable_stack_read_log(st, logs[14].refname, &log); - check_int(err, ==, 1); - - err = reftable_stack_read_log(st, logs[16].refname, &log); - check(!err); + cl_assert_equal_i(reftable_stack_compact_all(st, &expiry), 0); + cl_assert_equal_i(reftable_stack_read_log(st, logs[14].refname, + &log), 1); + cl_assert_equal_i(reftable_stack_read_log(st, logs[16].refname, + &log), 0); /* cleanup */ reftable_stack_destroy(st); @@ -963,26 +912,21 @@ static void t_reflog_expire(void) static int write_nothing(struct reftable_writer *wr, void *arg UNUSED) { - check(!reftable_writer_set_limits(wr, 1, 1)); + cl_assert_equal_i(reftable_writer_set_limits(wr, 1, 1), 0); return 0; } -static void t_empty_add(void) +void test_reftable_stack__empty_add(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; - int err; char *dir = get_tmp_dir(__LINE__); struct reftable_stack *st2 = NULL; - err = reftable_new_stack(&st, dir, &opts); - check(!err); - - err = reftable_stack_add(st, write_nothing, NULL); - check(!err); - - err = reftable_new_stack(&st2, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_add(st, write_nothing, + NULL, 0), 0); + cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0); clear_dir(dir); reftable_stack_destroy(st); reftable_stack_destroy(st2); @@ -998,18 +942,17 @@ static int fastlogN(uint64_t sz, uint64_t N) return l - 1; } -static void t_reftable_stack_auto_compaction(void) +void test_reftable_stack__auto_compaction(void) { struct reftable_write_options opts = { .disable_auto_compact = 1, }; struct reftable_stack *st = NULL; char *dir = get_tmp_dir(__LINE__); - int err; size_t i, N = 100; + int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (i = 0; i < N; i++) { char name[100]; @@ -1021,33 +964,32 @@ static void t_reftable_stack_auto_compaction(void) }; snprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i); - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); + err = reftable_stack_add(st, write_test_ref, &ref, 0); + cl_assert(!err); err = reftable_stack_auto_compact(st); - check(!err); - check(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2)); + cl_assert(!err); + cl_assert(i < 2 || st->merged->tables_len < 2 * fastlogN(i, 2)); } - check_int(reftable_stack_compaction_stats(st)->entries_written, <, - (uint64_t)(N * fastlogN(N, 2))); + cl_assert(reftable_stack_compaction_stats(st)->entries_written < + (uint64_t)(N * fastlogN(N, 2))); reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_auto_compaction_factor(void) +void test_reftable_stack__auto_compaction_factor(void) { struct reftable_write_options opts = { .auto_compaction_factor = 5, }; struct reftable_stack *st = NULL; char *dir = get_tmp_dir(__LINE__); - int err; size_t N = 100; + int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (size_t i = 0; i < N; i++) { char name[20]; @@ -1058,17 +1000,17 @@ static void t_reftable_stack_auto_compaction_factor(void) }; xsnprintf(name, sizeof(name), "branch%04"PRIuMAX, (uintmax_t)i); - err = reftable_stack_add(st, &write_test_ref, &ref); - check(!err); + err = reftable_stack_add(st, &write_test_ref, &ref, 0); + cl_assert(!err); - check(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5)); + cl_assert(i < 5 || st->merged->tables_len < 5 * fastlogN(i, 5)); } reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_auto_compaction_with_locked_tables(void) +void test_reftable_stack__auto_compaction_with_locked_tables(void) { struct reftable_write_options opts = { .disable_auto_compact = 1, @@ -1078,21 +1020,20 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void) char *dir = get_tmp_dir(__LINE__); int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); write_n_ref_tables(st, 5); - check_int(st->merged->tables_len, ==, 5); + cl_assert_equal_i(st->merged->tables_len, 5); /* * Given that all tables we have written should be roughly the same * size, we expect that auto-compaction will want to compact all of the * tables. Locking any of the tables will keep it from doing so. */ - check(!reftable_buf_addstr(&buf, dir)); - check(!reftable_buf_addstr(&buf, "/")); - check(!reftable_buf_addstr(&buf, st->tables[2]->name)); - check(!reftable_buf_addstr(&buf, ".lock")); + cl_assert(!reftable_buf_addstr(&buf, dir)); + cl_assert(!reftable_buf_addstr(&buf, "/")); + cl_assert(!reftable_buf_addstr(&buf, st->tables[2]->name)); + cl_assert(!reftable_buf_addstr(&buf, ".lock")); write_file_buf(buf.buf, "", 0); /* @@ -1102,25 +1043,23 @@ static void t_reftable_stack_auto_compaction_with_locked_tables(void) * only compact the newest two tables. */ err = reftable_stack_auto_compact(st); - check(!err); - check_int(st->stats.failures, ==, 0); - check_int(st->merged->tables_len, ==, 4); + cl_assert(!err); + cl_assert_equal_i(st->stats.failures, 0); + cl_assert_equal_i(st->merged->tables_len, 4); reftable_stack_destroy(st); reftable_buf_release(&buf); clear_dir(dir); } -static void t_reftable_stack_add_performs_auto_compaction(void) +void test_reftable_stack__add_performs_auto_compaction(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; char *dir = get_tmp_dir(__LINE__); - int err; size_t i, n = 20; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); for (i = 0; i <= n; i++) { struct reftable_ref_record ref = { @@ -1140,8 +1079,8 @@ static void t_reftable_stack_add_performs_auto_compaction(void) snprintf(buf, sizeof(buf), "branch-%04"PRIuMAX, (uintmax_t)i); ref.refname = buf; - err = reftable_stack_add(st, write_test_ref, &ref); - check(!err); + cl_assert_equal_i(reftable_stack_add(st, write_test_ref, + &ref, 0), 0); /* * The stack length should grow continuously for all runs where @@ -1149,16 +1088,16 @@ static void t_reftable_stack_add_performs_auto_compaction(void) * all tables in the stack. */ if (i != n) - check_int(st->merged->tables_len, ==, i + 1); + cl_assert_equal_i(st->merged->tables_len, i + 1); else - check_int(st->merged->tables_len, ==, 1); + cl_assert_equal_i(st->merged->tables_len, 1); } reftable_stack_destroy(st); clear_dir(dir); } -static void t_reftable_stack_compaction_with_locked_tables(void) +void test_reftable_stack__compaction_with_locked_tables(void) { struct reftable_write_options opts = { .disable_auto_compact = 1, @@ -1168,17 +1107,16 @@ static void t_reftable_stack_compaction_with_locked_tables(void) char *dir = get_tmp_dir(__LINE__); int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); write_n_ref_tables(st, 3); - check_int(st->merged->tables_len, ==, 3); + cl_assert_equal_i(st->merged->tables_len, 3); /* Lock one of the tables that we're about to compact. */ - check(!reftable_buf_addstr(&buf, dir)); - check(!reftable_buf_addstr(&buf, "/")); - check(!reftable_buf_addstr(&buf, st->tables[1]->name)); - check(!reftable_buf_addstr(&buf, ".lock")); + cl_assert(!reftable_buf_addstr(&buf, dir)); + cl_assert(!reftable_buf_addstr(&buf, "/")); + cl_assert(!reftable_buf_addstr(&buf, st->tables[1]->name)); + cl_assert(!reftable_buf_addstr(&buf, ".lock")); write_file_buf(buf.buf, "", 0); /* @@ -1186,36 +1124,31 @@ static void t_reftable_stack_compaction_with_locked_tables(void) * compact all tables. */ err = reftable_stack_compact_all(st, NULL); - check_int(err, ==, REFTABLE_LOCK_ERROR); - check_int(st->stats.failures, ==, 1); - check_int(st->merged->tables_len, ==, 3); + cl_assert_equal_i(err, REFTABLE_LOCK_ERROR); + cl_assert_equal_i(st->stats.failures, 1); + cl_assert_equal_i(st->merged->tables_len, 3); reftable_stack_destroy(st); reftable_buf_release(&buf); clear_dir(dir); } -static void t_reftable_stack_compaction_concurrent(void) +void test_reftable_stack__compaction_concurrent(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st1 = NULL, *st2 = NULL; char *dir = get_tmp_dir(__LINE__); - int err; - err = reftable_new_stack(&st1, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0); write_n_ref_tables(st1, 3); - err = reftable_new_stack(&st2, dir, &opts); - check(!err); - - err = reftable_stack_compact_all(st1, NULL); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0); reftable_stack_destroy(st1); reftable_stack_destroy(st2); - check_int(count_dir_entries(dir), ==, 2); + cl_assert_equal_i(count_dir_entries(dir), 2); clear_dir(dir); } @@ -1228,32 +1161,24 @@ static void unclean_stack_close(struct reftable_stack *st) REFTABLE_FREE_AND_NULL(st->tables); } -static void t_reftable_stack_compaction_concurrent_clean(void) +void test_reftable_stack__compaction_concurrent_clean(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st1 = NULL, *st2 = NULL, *st3 = NULL; char *dir = get_tmp_dir(__LINE__); - int err; - err = reftable_new_stack(&st1, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0); write_n_ref_tables(st1, 3); - err = reftable_new_stack(&st2, dir, &opts); - check(!err); - - err = reftable_stack_compact_all(st1, NULL); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st2, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_compact_all(st1, NULL), 0); unclean_stack_close(st1); unclean_stack_close(st2); - err = reftable_new_stack(&st3, dir, &opts); - check(!err); - - err = reftable_stack_clean(st3); - check(!err); - check_int(count_dir_entries(dir), ==, 2); + cl_assert_equal_i(reftable_new_stack(&st3, dir, &opts), 0); + cl_assert_equal_i(reftable_stack_clean(st3), 0); + cl_assert_equal_i(count_dir_entries(dir), 2); reftable_stack_destroy(st1); reftable_stack_destroy(st2); @@ -1262,7 +1187,7 @@ static void t_reftable_stack_compaction_concurrent_clean(void) clear_dir(dir); } -static void t_reftable_stack_read_across_reload(void) +void test_reftable_stack__read_across_reload(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st1 = NULL, *st2 = NULL; @@ -1272,37 +1197,35 @@ static void t_reftable_stack_read_across_reload(void) int err; /* Create a first stack and set up an iterator for it. */ - err = reftable_new_stack(&st1, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st1, dir, &opts), 0); write_n_ref_tables(st1, 2); - check_int(st1->merged->tables_len, ==, 2); + cl_assert_equal_i(st1->merged->tables_len, 2); reftable_stack_init_ref_iterator(st1, &it); - err = reftable_iterator_seek_ref(&it, ""); - check(!err); + cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0); /* Set up a second stack for the same directory and compact it. */ err = reftable_new_stack(&st2, dir, &opts); - check(!err); - check_int(st2->merged->tables_len, ==, 2); + cl_assert(!err); + cl_assert_equal_i(st2->merged->tables_len, 2); err = reftable_stack_compact_all(st2, NULL); - check(!err); - check_int(st2->merged->tables_len, ==, 1); + cl_assert(!err); + cl_assert_equal_i(st2->merged->tables_len, 1); /* * Verify that we can continue to use the old iterator even after we * have reloaded its stack. */ err = reftable_stack_reload(st1); - check(!err); - check_int(st1->merged->tables_len, ==, 1); + cl_assert(!err); + cl_assert_equal_i(st1->merged->tables_len, 1); err = reftable_iterator_next_ref(&it, &rec); - check(!err); - check_str(rec.refname, "refs/heads/branch-0000"); + cl_assert(!err); + cl_assert_equal_s(rec.refname, "refs/heads/branch-0000"); err = reftable_iterator_next_ref(&it, &rec); - check(!err); - check_str(rec.refname, "refs/heads/branch-0001"); + cl_assert(!err); + cl_assert_equal_s(rec.refname, "refs/heads/branch-0001"); err = reftable_iterator_next_ref(&it, &rec); - check_int(err, >, 0); + cl_assert(err > 0); reftable_ref_record_release(&rec); reftable_iterator_destroy(&it); @@ -1311,7 +1234,7 @@ static void t_reftable_stack_read_across_reload(void) clear_dir(dir); } -static void t_reftable_stack_reload_with_missing_table(void) +void test_reftable_stack__reload_with_missing_table(void) { struct reftable_write_options opts = { 0 }; struct reftable_stack *st = NULL; @@ -1322,46 +1245,40 @@ static void t_reftable_stack_reload_with_missing_table(void) int err; /* Create a first stack and set up an iterator for it. */ - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); write_n_ref_tables(st, 2); - check_int(st->merged->tables_len, ==, 2); + cl_assert_equal_i(st->merged->tables_len, 2); reftable_stack_init_ref_iterator(st, &it); - err = reftable_iterator_seek_ref(&it, ""); - check(!err); + cl_assert_equal_i(reftable_iterator_seek_ref(&it, ""), 0); /* * Update the tables.list file with some garbage data, while reusing * our old tables. This should trigger a partial reload of the stack, * where we try to reuse our old tables. */ - check(!reftable_buf_addstr(&content, st->tables[0]->name)); - check(!reftable_buf_addstr(&content, "\n")); - check(!reftable_buf_addstr(&content, st->tables[1]->name)); - check(!reftable_buf_addstr(&content, "\n")); - check(!reftable_buf_addstr(&content, "garbage\n")); - check(!reftable_buf_addstr(&table_path, st->list_file)); - check(!reftable_buf_addstr(&table_path, ".lock")); + cl_assert(!reftable_buf_addstr(&content, st->tables[0]->name)); + cl_assert(!reftable_buf_addstr(&content, "\n")); + cl_assert(!reftable_buf_addstr(&content, st->tables[1]->name)); + cl_assert(!reftable_buf_addstr(&content, "\n")); + cl_assert(!reftable_buf_addstr(&content, "garbage\n")); + cl_assert(!reftable_buf_addstr(&table_path, st->list_file)); + cl_assert(!reftable_buf_addstr(&table_path, ".lock")); write_file_buf(table_path.buf, content.buf, content.len); - err = rename(table_path.buf, st->list_file); - check(!err); + cl_assert_equal_i(rename(table_path.buf, st->list_file), 0); err = reftable_stack_reload(st); - check_int(err, ==, -4); - check_int(st->merged->tables_len, ==, 2); + cl_assert_equal_i(err, -4); + cl_assert_equal_i(st->merged->tables_len, 2); /* * Even though the reload has failed, we should be able to continue * using the iterator. */ - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - check_str(rec.refname, "refs/heads/branch-0000"); - err = reftable_iterator_next_ref(&it, &rec); - check(!err); - check_str(rec.refname, "refs/heads/branch-0001"); - err = reftable_iterator_next_ref(&it, &rec); - check_int(err, >, 0); + cl_assert_equal_i(reftable_iterator_next_ref(&it, &rec), 0); + cl_assert_equal_s(rec.refname, "refs/heads/branch-0000"); + cl_assert_equal_i(reftable_iterator_next_ref(&it, &rec), 0); + cl_assert_equal_s(rec.refname, "refs/heads/branch-0001"); + cl_assert(reftable_iterator_next_ref(&it, &rec) > 0); reftable_ref_record_release(&rec); reftable_iterator_destroy(&it); @@ -1374,12 +1291,13 @@ static void t_reftable_stack_reload_with_missing_table(void) static int write_limits_after_ref(struct reftable_writer *wr, void *arg) { struct reftable_ref_record *ref = arg; - check(!reftable_writer_set_limits(wr, ref->update_index, ref->update_index)); - check(!reftable_writer_add_ref(wr, ref)); + cl_assert_equal_i(reftable_writer_set_limits(wr, + ref->update_index, ref->update_index), 0); + cl_assert_equal_i(reftable_writer_add_ref(wr, ref), 0); return reftable_writer_set_limits(wr, ref->update_index, ref->update_index); } -static void t_reftable_invalid_limit_updates(void) +void test_reftable_stack__invalid_limit_updates(void) { struct reftable_ref_record ref = { .refname = (char *) "HEAD", @@ -1393,59 +1311,22 @@ static void t_reftable_invalid_limit_updates(void) struct reftable_addition *add = NULL; char *dir = get_tmp_dir(__LINE__); struct reftable_stack *st = NULL; - int err; - err = reftable_new_stack(&st, dir, &opts); - check(!err); + cl_assert_equal_i(reftable_new_stack(&st, dir, &opts), 0); reftable_addition_destroy(add); - err = reftable_stack_new_addition(&add, st, 0); - check(!err); + cl_assert_equal_i(reftable_stack_new_addition(&add, st, 0), 0); /* * write_limits_after_ref also updates the update indexes after adding * the record. This should cause an err to be returned, since the limits * must be set at the start. */ - err = reftable_addition_add(add, write_limits_after_ref, &ref); - check_int(err, ==, REFTABLE_API_ERROR); + cl_assert_equal_i(reftable_addition_add(add, + write_limits_after_ref, &ref), REFTABLE_API_ERROR); reftable_addition_destroy(add); reftable_stack_destroy(st); clear_dir(dir); } - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_empty_add(), "empty addition to stack"); - TEST(t_read_file(), "read_lines works"); - TEST(t_reflog_expire(), "expire reflog entries"); - TEST(t_reftable_invalid_limit_updates(), "prevent limit updates after adding records"); - TEST(t_reftable_stack_add(), "add multiple refs and logs to stack"); - TEST(t_reftable_stack_add_one(), "add a single ref record to stack"); - TEST(t_reftable_stack_add_performs_auto_compaction(), "addition to stack triggers auto-compaction"); - TEST(t_reftable_stack_auto_compaction(), "stack must form geometric sequence after compaction"); - TEST(t_reftable_stack_auto_compaction_factor(), "auto-compaction with non-default geometric factor"); - TEST(t_reftable_stack_auto_compaction_fails_gracefully(), "failure on auto-compaction"); - TEST(t_reftable_stack_auto_compaction_with_locked_tables(), "auto compaction with locked tables"); - TEST(t_reftable_stack_compaction_concurrent(), "compaction with concurrent stack"); - TEST(t_reftable_stack_compaction_concurrent_clean(), "compaction with unclean stack shutdown"); - TEST(t_reftable_stack_compaction_with_locked_tables(), "compaction with locked tables"); - TEST(t_reftable_stack_hash_id(), "read stack with wrong hash ID"); - TEST(t_reftable_stack_iterator(), "log and ref iterator for reftable stack"); - TEST(t_reftable_stack_lock_failure(), "stack addition with lockfile failure"); - TEST(t_reftable_stack_log_normalize(), "log messages should be normalized"); - TEST(t_reftable_stack_read_across_reload(), "stack iterators work across reloads"); - TEST(t_reftable_stack_reload_with_missing_table(), "stack iteration with garbage tables"); - TEST(t_reftable_stack_tombstone(), "'tombstone' refs in stack"); - TEST(t_reftable_stack_transaction_api(), "update transaction to stack"); - TEST(t_reftable_stack_transaction_with_reload(), "transaction with reload"); - TEST(t_reftable_stack_transaction_api_performs_auto_compaction(), "update transaction triggers auto-compaction"); - TEST(t_reftable_stack_update_index_check(), "update transactions with equal update indices"); - TEST(t_reftable_stack_uptodate(), "stack must be reloaded before ref update"); - TEST(t_suggest_compaction_segment(), "suggest_compaction_segment with basic input"); - TEST(t_suggest_compaction_segment_nothing(), "suggest_compaction_segment with pre-compacted input"); - - return test_done(); -} diff --git a/t/unit-tests/t-reftable-table.c b/t/unit-tests/u-reftable-table.c index 7e1eb533d0..14fae8b199 100644 --- a/t/unit-tests/t-reftable-table.c +++ b/t/unit-tests/u-reftable-table.c @@ -1,4 +1,4 @@ -#include "test-lib.h" +#include "unit-test.h" #include "lib-reftable.h" #include "reftable/blocksource.h" #include "reftable/constants.h" @@ -6,7 +6,7 @@ #include "reftable/table.h" #include "strbuf.h" -static int t_table_seek_once(void) +void test_reftable_table__seek_once(void) { struct reftable_ref_record records[] = { { @@ -22,32 +22,32 @@ static int t_table_seek_once(void) struct reftable_buf buf = REFTABLE_BUF_INIT; int ret; - t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); + cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); block_source_from_buf(&source, &buf); ret = reftable_table_new(&table, &source, "name"); - check(!ret); + cl_assert(!ret); reftable_table_init_ref_iterator(table, &it); ret = reftable_iterator_seek_ref(&it, ""); - check(!ret); + cl_assert(!ret); ret = reftable_iterator_next_ref(&it, &ref); - check(!ret); + cl_assert(!ret); - ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); - check_int(ret, ==, 1); + ret = reftable_ref_record_equal(&ref, &records[0], + REFTABLE_HASH_SIZE_SHA1); + cl_assert_equal_i(ret, 1); ret = reftable_iterator_next_ref(&it, &ref); - check_int(ret, ==, 1); + cl_assert_equal_i(ret, 1); reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); reftable_table_decref(table); reftable_buf_release(&buf); - return 0; } -static int t_table_reseek(void) +void test_reftable_table__reseek(void) { struct reftable_ref_record records[] = { { @@ -63,35 +63,35 @@ static int t_table_reseek(void) struct reftable_buf buf = REFTABLE_BUF_INIT; int ret; - t_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), NULL, 0, NULL); + cl_reftable_write_to_buf(&buf, records, ARRAY_SIZE(records), + NULL, 0, NULL); block_source_from_buf(&source, &buf); ret = reftable_table_new(&table, &source, "name"); - check(!ret); + cl_assert(!ret); reftable_table_init_ref_iterator(table, &it); for (size_t i = 0; i < 5; i++) { ret = reftable_iterator_seek_ref(&it, ""); - check(!ret); + cl_assert(!ret); ret = reftable_iterator_next_ref(&it, &ref); - check(!ret); + cl_assert(!ret); ret = reftable_ref_record_equal(&ref, &records[0], REFTABLE_HASH_SIZE_SHA1); - check_int(ret, ==, 1); + cl_assert_equal_i(ret, 1); ret = reftable_iterator_next_ref(&it, &ref); - check_int(ret, ==, 1); + cl_assert_equal_i(ret, 1); } reftable_ref_record_release(&ref); reftable_iterator_destroy(&it); reftable_table_decref(table); reftable_buf_release(&buf); - return 0; } -static int t_table_block_iterator(void) +void test_reftable_table__block_iterator(void) { struct reftable_block_source source = { 0 }; struct reftable_table_iterator it = { 0 }; @@ -147,14 +147,14 @@ static int t_table_block_iterator(void) (uintmax_t) i); } - t_reftable_write_to_buf(&buf, records, nrecords, NULL, 0, NULL); + cl_reftable_write_to_buf(&buf, records, nrecords, NULL, 0, NULL); block_source_from_buf(&source, &buf); ret = reftable_table_new(&table, &source, "name"); - check(!ret); + cl_assert(!ret); ret = reftable_table_iterator_init(&it, table); - check(!ret); + cl_assert(!ret); for (size_t i = 0; i < ARRAY_SIZE(expected_blocks); i++) { struct reftable_iterator record_it = { 0 }; @@ -163,22 +163,26 @@ static int t_table_block_iterator(void) }; ret = reftable_table_iterator_next(&it, &block); - check(!ret); + cl_assert(!ret); - check_int(block->block_type, ==, expected_blocks[i].block_type); - check_int(block->header_off, ==, expected_blocks[i].header_off); - check_int(block->restart_count, ==, expected_blocks[i].restart_count); + cl_assert_equal_i(block->block_type, + expected_blocks[i].block_type); + cl_assert_equal_i(block->header_off, + expected_blocks[i].header_off); + cl_assert_equal_i(block->restart_count, + expected_blocks[i].restart_count); ret = reftable_block_init_iterator(block, &record_it); - check(!ret); + cl_assert(!ret); for (size_t j = 0; ; j++) { ret = iterator_next(&record_it, &record); if (ret > 0) { - check_int(j, ==, expected_blocks[i].record_count); + cl_assert_equal_i(j, + expected_blocks[i].record_count); break; } - check(!ret); + cl_assert(!ret); } reftable_iterator_destroy(&record_it); @@ -186,7 +190,7 @@ static int t_table_block_iterator(void) } ret = reftable_table_iterator_next(&it, &block); - check_int(ret, ==, 1); + cl_assert_equal_i(ret, 1); for (size_t i = 0; i < nrecords; i++) reftable_free(records[i].refname); @@ -194,13 +198,4 @@ static int t_table_block_iterator(void) reftable_table_decref(table); reftable_buf_release(&buf); reftable_free(records); - return 0; -} - -int cmd_main(int argc UNUSED, const char *argv[] UNUSED) -{ - TEST(t_table_seek_once(), "table can seek once"); - TEST(t_table_reseek(), "table can reseek multiple times"); - TEST(t_table_block_iterator(), "table can iterate through blocks"); - return test_done(); } diff --git a/t/unit-tests/u-string-list.c b/t/unit-tests/u-string-list.c index d4ba5f9fa5..a2457d7b1e 100644 --- a/t/unit-tests/u-string-list.c +++ b/t/unit-tests/u-string-list.c @@ -43,7 +43,7 @@ static void t_string_list_equal(struct string_list *list, expected_strings->items[i].string); } -static void t_string_list_split(const char *data, int delim, int maxsplit, ...) +static void t_string_list_split(const char *data, const char *delim, int maxsplit, ...) { struct string_list expected_strings = STRING_LIST_INIT_DUP; struct string_list list = STRING_LIST_INIT_DUP; @@ -63,15 +63,94 @@ static void t_string_list_split(const char *data, int delim, int maxsplit, ...) string_list_clear(&list, 0); } +static void t_string_list_split_f(const char *data, const char *delim, + int maxsplit, unsigned flags, ...) +{ + struct string_list expected_strings = STRING_LIST_INIT_DUP; + struct string_list list = STRING_LIST_INIT_DUP; + va_list ap; + int len; + + va_start(ap, flags); + t_vcreate_string_list_dup(&expected_strings, 0, ap); + va_end(ap); + + string_list_clear(&list, 0); + len = string_list_split_f(&list, data, delim, maxsplit, flags); + cl_assert_equal_i(len, expected_strings.nr); + t_string_list_equal(&list, &expected_strings); + + string_list_clear(&expected_strings, 0); + string_list_clear(&list, 0); +} + +void test_string_list__split_f(void) +{ + t_string_list_split_f("::foo:bar:baz:", ":", -1, 0, + "", "", "foo", "bar", "baz", "", NULL); + t_string_list_split_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM, + "foo", "bar", "baz", NULL); + t_string_list_split_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM, + "a", "b c", NULL); + t_string_list_split_f("::foo::bar:baz:", ":", -1, STRING_LIST_SPLIT_NONEMPTY, + "foo", "bar", "baz", NULL); + t_string_list_split_f("foo:baz", ":", -1, STRING_LIST_SPLIT_NONEMPTY, + "foo", "baz", NULL); + t_string_list_split_f("foo :: : baz", ":", -1, + STRING_LIST_SPLIT_NONEMPTY | STRING_LIST_SPLIT_TRIM, + "foo", "baz", NULL); +} + +static void t_string_list_split_in_place_f(const char *data_, const char *delim, + int maxsplit, unsigned flags, ...) +{ + struct string_list expected_strings = STRING_LIST_INIT_DUP; + struct string_list list = STRING_LIST_INIT_NODUP; + char *data = xstrdup(data_); + va_list ap; + int len; + + va_start(ap, flags); + t_vcreate_string_list_dup(&expected_strings, 0, ap); + va_end(ap); + + string_list_clear(&list, 0); + len = string_list_split_in_place_f(&list, data, delim, maxsplit, flags); + cl_assert_equal_i(len, expected_strings.nr); + t_string_list_equal(&list, &expected_strings); + + free(data); + string_list_clear(&expected_strings, 0); + string_list_clear(&list, 0); +} + +void test_string_list__split_in_place_f(void) +{ + t_string_list_split_in_place_f("::foo:bar:baz:", ":", -1, 0, + "", "", "foo", "bar", "baz", "", NULL); + t_string_list_split_in_place_f(" foo:bar : baz", ":", -1, STRING_LIST_SPLIT_TRIM, + "foo", "bar", "baz", NULL); + t_string_list_split_in_place_f(" a b c ", " ", 1, STRING_LIST_SPLIT_TRIM, + "a", "b c", NULL); + t_string_list_split_in_place_f("::foo::bar:baz:", ":", -1, + STRING_LIST_SPLIT_NONEMPTY, + "foo", "bar", "baz", NULL); + t_string_list_split_in_place_f("foo:baz", ":", -1, STRING_LIST_SPLIT_NONEMPTY, + "foo", "baz", NULL); + t_string_list_split_in_place_f("foo :: : baz", ":", -1, + STRING_LIST_SPLIT_NONEMPTY | STRING_LIST_SPLIT_TRIM, + "foo", "baz", NULL); +} + void test_string_list__split(void) { - t_string_list_split("foo:bar:baz", ':', -1, "foo", "bar", "baz", NULL); - t_string_list_split("foo:bar:baz", ':', 0, "foo:bar:baz", NULL); - t_string_list_split("foo:bar:baz", ':', 1, "foo", "bar:baz", NULL); - t_string_list_split("foo:bar:baz", ':', 2, "foo", "bar", "baz", NULL); - t_string_list_split("foo:bar:", ':', -1, "foo", "bar", "", NULL); - t_string_list_split("", ':', -1, "", NULL); - t_string_list_split(":", ':', -1, "", "", NULL); + t_string_list_split("foo:bar:baz", ":", -1, "foo", "bar", "baz", NULL); + t_string_list_split("foo:bar:baz", ":", 0, "foo:bar:baz", NULL); + t_string_list_split("foo:bar:baz", ":", 1, "foo", "bar:baz", NULL); + t_string_list_split("foo:bar:baz", ":", 2, "foo", "bar", "baz", NULL); + t_string_list_split("foo:bar:", ":", -1, "foo", "bar", "", NULL); + t_string_list_split("", ":", -1, "", NULL); + t_string_list_split(":", ":", -1, "", "", NULL); } static void t_string_list_split_in_place(const char *data, const char *delim, diff --git a/t/unit-tests/unit-test.h b/t/unit-tests/unit-test.h index 85e5d6a948..39a0b72a05 100644 --- a/t/unit-tests/unit-test.h +++ b/t/unit-tests/unit-test.h @@ -1,8 +1,13 @@ #include "git-compat-util.h" #include "clar/clar.h" -#include "clar-decls.h" #include "strbuf.h" +#ifndef GIT_CLAR_DECLS_H +# include "clar-decls.h" +#else +# include GIT_CLAR_DECLS_H +#endif + #define cl_failf(fmt, ...) do { \ char desc[4096]; \ snprintf(desc, sizeof(desc), fmt, __VA_ARGS__); \ diff --git a/tmp-objdir.c b/tmp-objdir.c index ae01eae9c4..9f5a1788cd 100644 --- a/tmp-objdir.c +++ b/tmp-objdir.c @@ -227,7 +227,7 @@ static int migrate_one(struct tmp_objdir *t, return -1; return migrate_paths(t, src, dst, flags); } - return finalize_object_file_flags(src->buf, dst->buf, flags); + return finalize_object_file_flags(t->repo, src->buf, dst->buf, flags); } static int is_loose_object_shard(const char *name) diff --git a/trace2/tr2_cfg.c b/trace2/tr2_cfg.c index 22a99a0682..bbcfeda60a 100644 --- a/trace2/tr2_cfg.c +++ b/trace2/tr2_cfg.c @@ -8,89 +8,65 @@ #include "trace2/tr2_sysenv.h" #include "wildmatch.h" -static struct strbuf **tr2_cfg_patterns; -static int tr2_cfg_count_patterns; +static struct string_list tr2_cfg_patterns = STRING_LIST_INIT_DUP; static int tr2_cfg_loaded; -static struct strbuf **tr2_cfg_env_vars; -static int tr2_cfg_env_vars_count; +static struct string_list tr2_cfg_env_vars = STRING_LIST_INIT_DUP; static int tr2_cfg_env_vars_loaded; /* * Parse a string containing a comma-delimited list of config keys - * or wildcard patterns into a list of strbufs. + * or wildcard patterns into a string list. */ -static int tr2_cfg_load_patterns(void) +static size_t tr2_cfg_load_patterns(void) { - struct strbuf **s; const char *envvar; if (tr2_cfg_loaded) - return tr2_cfg_count_patterns; + return tr2_cfg_patterns.nr; tr2_cfg_loaded = 1; envvar = tr2_sysenv_get(TR2_SYSENV_CFG_PARAM); if (!envvar || !*envvar) - return tr2_cfg_count_patterns; + return tr2_cfg_patterns.nr; - tr2_cfg_patterns = strbuf_split_buf(envvar, strlen(envvar), ',', -1); - for (s = tr2_cfg_patterns; *s; s++) { - struct strbuf *buf = *s; - - if (buf->len && buf->buf[buf->len - 1] == ',') - strbuf_setlen(buf, buf->len - 1); - strbuf_trim_trailing_newline(*s); - strbuf_trim(*s); - } - - tr2_cfg_count_patterns = s - tr2_cfg_patterns; - return tr2_cfg_count_patterns; + string_list_split_f(&tr2_cfg_patterns, envvar, ",", -1, + STRING_LIST_SPLIT_TRIM); + return tr2_cfg_patterns.nr; } void tr2_cfg_free_patterns(void) { - if (tr2_cfg_patterns) - strbuf_list_free(tr2_cfg_patterns); - tr2_cfg_count_patterns = 0; + if (tr2_cfg_patterns.nr) + string_list_clear(&tr2_cfg_patterns, 0); tr2_cfg_loaded = 0; } /* * Parse a string containing a comma-delimited list of environment variable - * names into a list of strbufs. + * names into a string list. */ -static int tr2_load_env_vars(void) +static size_t tr2_load_env_vars(void) { - struct strbuf **s; const char *varlist; if (tr2_cfg_env_vars_loaded) - return tr2_cfg_env_vars_count; + return tr2_cfg_env_vars.nr; tr2_cfg_env_vars_loaded = 1; varlist = tr2_sysenv_get(TR2_SYSENV_ENV_VARS); if (!varlist || !*varlist) - return tr2_cfg_env_vars_count; - - tr2_cfg_env_vars = strbuf_split_buf(varlist, strlen(varlist), ',', -1); - for (s = tr2_cfg_env_vars; *s; s++) { - struct strbuf *buf = *s; - - if (buf->len && buf->buf[buf->len - 1] == ',') - strbuf_setlen(buf, buf->len - 1); - strbuf_trim_trailing_newline(*s); - strbuf_trim(*s); - } + return tr2_cfg_env_vars.nr; - tr2_cfg_env_vars_count = s - tr2_cfg_env_vars; - return tr2_cfg_env_vars_count; + string_list_split_f(&tr2_cfg_env_vars, varlist, ",", -1, + STRING_LIST_SPLIT_TRIM); + return tr2_cfg_env_vars.nr; } void tr2_cfg_free_env_vars(void) { - if (tr2_cfg_env_vars) - strbuf_list_free(tr2_cfg_env_vars); - tr2_cfg_env_vars_count = 0; + if (tr2_cfg_env_vars.nr) + string_list_clear(&tr2_cfg_env_vars, 0); tr2_cfg_env_vars_loaded = 0; } @@ -105,12 +81,11 @@ struct tr2_cfg_data { static int tr2_cfg_cb(const char *key, const char *value, const struct config_context *ctx, void *d) { - struct strbuf **s; + struct string_list_item *item; struct tr2_cfg_data *data = (struct tr2_cfg_data *)d; - for (s = tr2_cfg_patterns; *s; s++) { - struct strbuf *buf = *s; - int wm = wildmatch(buf->buf, key, WM_CASEFOLD); + for_each_string_list_item(item, &tr2_cfg_patterns) { + int wm = wildmatch(item->string, key, WM_CASEFOLD); if (wm == WM_MATCH) { trace2_def_param_fl(data->file, data->line, key, value, ctx->kvi); @@ -132,17 +107,16 @@ void tr2_cfg_list_config_fl(const char *file, int line) void tr2_list_env_vars_fl(const char *file, int line) { struct key_value_info kvi = KVI_INIT; - struct strbuf **s; + struct string_list_item *item; kvi_from_param(&kvi); if (tr2_load_env_vars() <= 0) return; - for (s = tr2_cfg_env_vars; *s; s++) { - struct strbuf *buf = *s; - const char *val = getenv(buf->buf); + for_each_string_list_item(item, &tr2_cfg_env_vars) { + const char *val = getenv(item->string); if (val && *val) - trace2_def_param_fl(file, line, buf->buf, val, &kvi); + trace2_def_param_fl(file, line, item->string, val, &kvi); } } @@ -595,8 +595,8 @@ void trailer_config_init(void) default_conf_info.where = WHERE_END; default_conf_info.if_exists = EXISTS_ADD_IF_DIFFERENT_NEIGHBOR; default_conf_info.if_missing = MISSING_ADD; - git_config(git_trailer_default_config, NULL); - git_config(git_trailer_config, NULL); + repo_config(the_repository, git_trailer_default_config, NULL); + repo_config(the_repository, git_trailer_config, NULL); configured = 1; } diff --git a/transport.c b/transport.c index c123ac1e38..6ac8aa402b 100644 --- a/transport.c +++ b/transport.c @@ -54,14 +54,14 @@ static int transport_color_config(void) return 0; initialized = 1; - if (!git_config_get_string(key, &value)) + if (!repo_config_get_string(the_repository, key, &value)) transport_use_color = git_config_colorbool(key, value); if (!want_color_stderr(transport_use_color)) return 0; for (size_t i = 0; i < ARRAY_SIZE(keys); i++) - if (!git_config_get_string(keys[i], &value)) { + if (!repo_config_get_string(the_repository, keys[i], &value)) { if (!value) return config_error_nonbool(keys[i]); if (color_parse(value, transport_colors[i]) < 0) @@ -202,7 +202,7 @@ static int fetch_refs_from_bundle(struct transport *transport, if (!data->get_refs_from_bundle_called) get_refs_from_bundle_inner(transport); - git_config(fetch_fsck_config_cb, &msg_types); + repo_config(the_repository, fetch_fsck_config_cb, &msg_types); opts.fsck_msg_types = msg_types.buf; ret = unbundle(the_repository, &data->header, data->fd, @@ -1042,7 +1042,7 @@ static const struct string_list *protocol_allow_list(void) if (enabled < 0) { const char *v = getenv("GIT_ALLOW_PROTOCOL"); if (v) { - string_list_split(&allowed, v, ':', -1); + string_list_split(&allowed, v, ":", -1); string_list_sort(&allowed); enabled = 1; } else { @@ -1078,7 +1078,7 @@ static enum protocol_allow_config get_protocol_config(const char *type) char *value; /* first check the per-protocol config */ - if (!git_config_get_string(key, &value)) { + if (!repo_config_get_string(the_repository, key, &value)) { enum protocol_allow_config ret = parse_protocol_config(key, value); free(key); @@ -1088,7 +1088,7 @@ static enum protocol_allow_config get_protocol_config(const char *type) free(key); /* if defined, fallback to user-defined default for unknown protocols */ - if (!git_config_get_string("protocol.allow", &value)) { + if (!repo_config_get_string(the_repository, "protocol.allow", &value)) { enum protocol_allow_config ret = parse_protocol_config("protocol.allow", value); free(value); @@ -1602,7 +1602,7 @@ int transport_get_remote_bundle_uri(struct transport *transport) * Don't request bundle-uri from the server unless configured to * do so by the transfer.bundleURI=true config option. */ - if (git_config_get_bool("transfer.bundleuri", &value) || !value) + if (repo_config_get_bool(the_repository, "transfer.bundleuri", &value) || !value) return 0; if (!transport->bundles->baseURI) diff --git a/tree-diff.c b/tree-diff.c index e00fc2f450..5988148b60 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -13,6 +13,7 @@ #include "tree-walk.h" #include "environment.h" #include "repository.h" +#include "dir.h" /* * Some mode bits are also used internally for computations. @@ -48,6 +49,73 @@ free((x)); \ } while(0) +/* Returns true if and only if "dir" is a leading directory of "path" */ +static int is_dir_prefix(const char *path, const char *dir, int dirlen) +{ + return !strncmp(path, dir, dirlen) && + (!path[dirlen] || path[dirlen] == '/'); +} + +static int check_recursion_depth(const struct strbuf *name, + const struct pathspec *ps, + int max_depth) +{ + int i; + + if (!ps->nr) + return within_depth(name->buf, name->len, 1, max_depth); + + /* + * We look through the pathspecs in reverse-sorted order, because we + * want to find the longest match first (e.g., "a/b" is better for + * checking depth than "a/b/c"). + */ + for (i = ps->nr - 1; i >= 0; i--) { + const struct pathspec_item *item = ps->items+i; + + /* + * If the name to match is longer than the pathspec, then we + * are only interested if the pathspec matches and we are + * within the allowed depth. + */ + if (name->len >= item->len) { + if (!is_dir_prefix(name->buf, item->match, item->len)) + continue; + return within_depth(name->buf + item->len, + name->len - item->len, + 1, max_depth); + } + + /* + * Otherwise, our name is shorter than the pathspec. We need to + * check if it is a prefix of the pathspec; if so, we must + * always recurse in order to process further (the resulting + * paths we find might or might not match our pathspec, but we + * cannot know until we recurse). + */ + if (is_dir_prefix(item->match, name->buf, name->len)) + return 1; + } + return 0; +} + +static int should_recurse(const struct strbuf *name, struct diff_options *opt) +{ + if (!opt->flags.recursive) + return 0; + if (!opt->max_depth_valid) + return 1; + + /* + * We catch this during diff_setup_done, but let's double-check + * against any internal munging. + */ + if (opt->pathspec.has_wildcard) + BUG("wildcard pathspecs are incompatible with max-depth"); + + return check_recursion_depth(name, &opt->pathspec, opt->max_depth); +} + static void ll_diff_tree_paths( struct combine_diff_path ***tail, const struct object_id *oid, const struct object_id **parents_oid, int nparent, @@ -170,9 +238,13 @@ static void emit_path(struct combine_diff_path ***tail, mode = 0; } - if (opt->flags.recursive && isdir) { - recurse = 1; - emitthis = opt->flags.tree_in_recursive; + if (isdir) { + strbuf_add(base, path, pathlen); + if (should_recurse(base, opt)) { + recurse = 1; + emitthis = opt->flags.tree_in_recursive; + } + strbuf_setlen(base, old_baselen); } if (emitthis) { diff --git a/upload-pack.c b/upload-pack.c index 4f26f6afc7..91fcdcad9b 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -1685,7 +1685,7 @@ static void process_args(struct packet_reader *request, if (data->uri_protocols.nr) send_err_and_die(data, "multiple packfile-uris lines forbidden"); - string_list_split(&data->uri_protocols, p, ',', -1); + string_list_split(&data->uri_protocols, p, ",", -1); continue; } @@ -192,7 +192,8 @@ static void show_usage_if_asked_helper(const char *err, ...) void show_usage_if_asked(int ac, const char **av, const char *err) { - if (ac == 2 && !strcmp(av[1], "-h")) + if (ac == 2 && (!strcmp(av[1], "-h") || + !strcmp(av[1], "--help-all"))) show_usage_if_asked_helper(err); } diff --git a/versioncmp.c b/versioncmp.c index b6eebdb989..3a81b17bc1 100644 --- a/versioncmp.c +++ b/versioncmp.c @@ -167,8 +167,8 @@ int versioncmp(const char *s1, const char *s2) const char *const oldk = "versionsort.prereleasesuffix"; const struct string_list *newl; const struct string_list *oldl; - int new = git_config_get_string_multi(newk, &newl); - int old = git_config_get_string_multi(oldk, &oldl); + int new = repo_config_get_string_multi(the_repository, newk, &newl); + int old = repo_config_get_string_multi(the_repository, oldk, &oldl); if (!new && !old) warning("ignoring %s because %s is set", oldk, newk); diff --git a/worktree.c b/worktree.c index c34b9eb74e..a2a5f51f29 100644 --- a/worktree.c +++ b/worktree.c @@ -991,9 +991,9 @@ done: static int move_config_setting(const char *key, const char *value, const char *from_file, const char *to_file) { - if (git_config_set_in_file_gently(to_file, key, NULL, value)) + if (repo_config_set_in_file_gently(the_repository, to_file, key, NULL, value)) return error(_("unable to set %s in '%s'"), key, to_file); - if (git_config_set_in_file_gently(from_file, key, NULL, NULL)) + if (repo_config_set_in_file_gently(the_repository, from_file, key, NULL, NULL)) return error(_("unable to unset %s in '%s'"), key, from_file); return 0; } @@ -1013,7 +1013,7 @@ int init_worktree_config(struct repository *r) */ if (r->repository_format_worktree_config) return 0; - if ((res = git_config_set_gently("extensions.worktreeConfig", "true"))) + if ((res = repo_config_set_gently(the_repository, "extensions.worktreeConfig", "true"))) return error(_("failed to set extensions.worktreeConfig setting")); common_config_file = xstrfmt("%s/config", r->commondir); @@ -1077,7 +1077,7 @@ void write_worktree_linking_files(struct strbuf dotgit, struct strbuf gitdir, if (use_relative_paths && !the_repository->repository_format_relative_worktrees) { if (upgrade_repository_format(1) < 0) die(_("unable to upgrade repository format to support relative worktrees")); - if (git_config_set_gently("extensions.relativeWorktrees", "true")) + if (repo_config_set_gently(the_repository, "extensions.relativeWorktrees", "true")) die(_("unable to set extensions.relativeWorktrees setting")); the_repository->repository_format_relative_worktrees = 1; } diff --git a/wt-status.c b/wt-status.c index 454601afa1..21dabab77d 100644 --- a/wt-status.c +++ b/wt-status.c @@ -972,7 +972,8 @@ static void wt_longstatus_print_changed(struct wt_status *s) wt_longstatus_print_trailer(s); } -static int stash_count_refs(struct object_id *ooid UNUSED, +static int stash_count_refs(const char *refname UNUSED, + struct object_id *ooid UNUSED, struct object_id *noid UNUSED, const char *email UNUSED, timestamp_t timestamp UNUSED, int tz UNUSED, @@ -1351,8 +1352,8 @@ static int split_commit_in_progress(struct wt_status *s) */ static void abbrev_oid_in_line(struct strbuf *line) { - struct strbuf **split; - int i; + struct string_list split = STRING_LIST_INIT_DUP; + struct object_id oid; if (starts_with(line->buf, "exec ") || starts_with(line->buf, "x ") || @@ -1360,26 +1361,15 @@ static void abbrev_oid_in_line(struct strbuf *line) starts_with(line->buf, "l ")) return; - split = strbuf_split_max(line, ' ', 3); - if (split[0] && split[1]) { - struct object_id oid; - - /* - * strbuf_split_max left a space. Trim it and re-add - * it after abbreviation. - */ - strbuf_trim(split[1]); - if (!repo_get_oid(the_repository, split[1]->buf, &oid)) { - strbuf_reset(split[1]); - strbuf_add_unique_abbrev(split[1], &oid, - DEFAULT_ABBREV); - strbuf_addch(split[1], ' '); - strbuf_reset(line); - for (i = 0; split[i]; i++) - strbuf_addbuf(line, split[i]); - } + if ((2 <= string_list_split(&split, line->buf, " ", 2)) && + !repo_get_oid(the_repository, split.items[1].string, &oid)) { + strbuf_reset(line); + strbuf_addf(line, "%s ", split.items[0].string); + strbuf_add_unique_abbrev(line, &oid, DEFAULT_ABBREV); + for (size_t i = 2; i < split.nr; i++) + strbuf_addf(line, " %s", split.items[i].string); } - strbuf_list_free(split); + string_list_clear(&split, 0); } static int read_rebase_todolist(const char *fname, struct string_list *lines) @@ -1664,7 +1654,8 @@ struct grab_1st_switch_cbdata { struct object_id noid; }; -static int grab_1st_switch(struct object_id *ooid UNUSED, +static int grab_1st_switch(const char *refname UNUSED, + struct object_id *ooid UNUSED, struct object_id *noid, const char *email UNUSED, timestamp_t timestamp UNUSED, int tz UNUSED, diff --git a/xdiff-interface.c b/xdiff-interface.c index 0e5d38c960..4971f722b3 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -2,6 +2,7 @@ #define DISABLE_SIGN_COMPARE_WARNINGS #include "git-compat-util.h" +#include "environment.h" #include "gettext.h" #include "config.h" #include "hex.h" diff --git a/xdiff-interface.h b/xdiff-interface.h index 1ed430b622..dfc55daddf 100644 --- a/xdiff-interface.h +++ b/xdiff-interface.h @@ -28,9 +28,9 @@ * from an error internal to xdiff, xdiff itself will see that * non-zero return and translate it to -1. * - * See "diff_grep" in diffcore-pickaxe.c for a trick to work around - * this, i.e. using the "consume_callback_data" to note the desired - * early return. + * See "diff_grep" in diffcore-pickaxe.c and "quick_consume" in diff.c + * for a trick to work around this, i.e. using the "consume_callback_data" + * to note the desired early return. */ typedef int (*xdiff_emit_line_fn)(void *, char *, unsigned long); typedef void (*xdiff_emit_hunk_fn)(void *data, diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 444a108f87..78d1cf74b1 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -249,7 +249,7 @@ int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags) return 1; } -static unsigned long xdl_hash_record_with_whitespace(char const **data, +unsigned long xdl_hash_record_with_whitespace(char const **data, char const *top, long flags) { unsigned long ha = 5381; char const *ptr = *data; @@ -294,19 +294,67 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data, return ha; } -unsigned long xdl_hash_record(char const **data, char const *top, long flags) { - unsigned long ha = 5381; +/* + * Compiler reassociation barrier: pretend to modify X and Y to disallow + * changing evaluation order with respect to following uses of X and Y. + */ +#ifdef __GNUC__ +#define REASSOC_FENCE(x, y) __asm__("" : "+r"(x), "+r"(y)) +#else +#define REASSOC_FENCE(x, y) +#endif + +unsigned long xdl_hash_record_verbatim(char const **data, char const *top) { + unsigned long ha = 5381, c0, c1; char const *ptr = *data; - - if (flags & XDF_WHITESPACE_FLAGS) - return xdl_hash_record_with_whitespace(data, top, flags); - +#if 0 + /* + * The baseline form of the optimized loop below. This is the djb2 + * hash (the above function uses a variant with XOR instead of ADD). + */ for (; ptr < top && *ptr != '\n'; ptr++) { ha += (ha << 5); - ha ^= (unsigned long) *ptr; + ha += (unsigned long) *ptr; } *data = ptr < top ? ptr + 1: ptr; - +#else + /* Process two characters per iteration. */ + if (top - ptr >= 2) do { + if ((c0 = ptr[0]) == '\n') { + *data = ptr + 1; + return ha; + } + if ((c1 = ptr[1]) == '\n') { + *data = ptr + 2; + c0 += ha; + REASSOC_FENCE(c0, ha); + ha = ha * 32 + c0; + return ha; + } + /* + * Combine characters C0 and C1 into the hash HA. We have + * HA = (HA * 33 + C0) * 33 + C1, and we want to ensure + * that dependency chain over HA is just one multiplication + * and one addition, i.e. we want to evaluate this as + * HA = HA * 33 * 33 + (C0 * 33 + C1), and likewise prefer + * (C0 * 32 + (C0 + C1)) for the expression in parenthesis. + */ + ha *= 33 * 33; + c1 += c0; + REASSOC_FENCE(c1, c0); + c1 += c0 * 32; + REASSOC_FENCE(c1, ha); + ha += c1; + + ptr += 2; + } while (ptr < top - 1); + *data = top; + if (ptr < top && (c0 = ptr[0]) != '\n') { + c0 += ha; + REASSOC_FENCE(c0, ha); + ha = ha * 32 + c0; + } +#endif return ha; } diff --git a/xdiff/xutils.h b/xdiff/xutils.h index fd0bba94e8..13f6831047 100644 --- a/xdiff/xutils.h +++ b/xdiff/xutils.h @@ -34,7 +34,15 @@ void *xdl_cha_alloc(chastore_t *cha); long xdl_guess_lines(mmfile_t *mf, long sample); int xdl_blankline(const char *line, long size, long flags); int xdl_recmatch(const char *l1, long s1, const char *l2, long s2, long flags); -unsigned long xdl_hash_record(char const **data, char const *top, long flags); +unsigned long xdl_hash_record_verbatim(char const **data, char const *top); +unsigned long xdl_hash_record_with_whitespace(char const **data, char const *top, long flags); +static inline unsigned long xdl_hash_record(char const **data, char const *top, long flags) +{ + if (flags & XDF_WHITESPACE_FLAGS) + return xdl_hash_record_with_whitespace(data, top, flags); + else + return xdl_hash_record_verbatim(data, top); +} unsigned int xdl_hashbits(unsigned int size); int xdl_num_out(char *out, long val); int xdl_emit_hunk_hdr(long s1, long c1, long s2, long c2, |
