diff options
167 files changed, 14056 insertions, 6111 deletions
diff --git a/.clang-format b/.clang-format index de1c8b5c77..41d4cd23fd 100644 --- a/.clang-format +++ b/.clang-format @@ -149,7 +149,7 @@ Cpp11BracedListStyle: false # A list of macros that should be interpreted as foreach loops instead of as # function calls. -ForEachMacros: ['for_each_string_list_item'] +ForEachMacros: ['for_each_string_list_item', 'for_each_wanted_builtin', 'for_each_builtin', 'for_each_ut'] # The maximum number of consecutive empty lines to keep. MaxEmptyLinesToKeep: 1 diff --git a/.travis.yml b/.travis.yml index 36cbdea7f4..ffb1bc46f2 100644 --- a/.travis.yml +++ b/.travis.yml @@ -21,16 +21,6 @@ matrix: compiler: addons: before_install: - - env: jobname=Windows - os: linux - compiler: - addons: - before_install: - script: - - > - test "$TRAVIS_REPO_SLUG" != "git/git" || - ci/run-windows-build.sh $TRAVIS_BRANCH $(git rev-parse HEAD) - after_failure: - env: jobname=Linux32 os: linux compiler: diff --git a/Documentation/RelNotes/2.22.0.txt b/Documentation/RelNotes/2.22.0.txt new file mode 100644 index 0000000000..16d3110392 --- /dev/null +++ b/Documentation/RelNotes/2.22.0.txt @@ -0,0 +1,101 @@ +Git 2.22 Release Notes +====================== + +Updates since v2.21 +------------------- + +UI, Workflows & Features + + * "git checkout --no-overlay" can be used to trigger a new mode of + checking out paths out of the tree-ish, that allows paths that + match the pathspec that are in the current index and working tree + and are not in the tree-ish. + + * The %(trailers) formatter in "git log --format=..." now allows to + optionally pick trailers selectively by keyword, show only values, + etc. + + * Four new configuration variables {author,committer}.{name,email} + have been introduced to override user.{name,email} in more specific + cases. + + * Command-line completion (in contrib/) learned to tab-complete the + "git submodule absorbgitdirs" subcommand. + + * "git branch" learned a new subcommand "--show-current". + + * Output from "diff --cc" did not show the original paths when the + merge involved renames. A new option adds the paths in the + original trees to the output. + + * The command line completion (in contrib/) has been taught to + complete more subcommand parameters. + + +Performance, Internal Implementation, Development Support etc. + + * The diff machinery, one of the oldest parts of the system, which + long predates the parse-options API, uses fairly long and complex + handcrafted option parser. This is being rewritten to use the + parse-options API. + + * The implementation of pack-redundant has been updated for + performance in a repository with many packfiles. + + * A more structured way to obtain execution trace has been added. + + * "git prune" has been taught to take advantage of reachability + bitmap when able. + + +Fixes since v2.21 +----------------- + + * "git prune-packed" did not notice and complain against excess + arguments given from the command line, which now it does. + (merge 9b0bd87ed2 rj/prune-packed-excess-args later to maint). + + * Split-index fix. + (merge 6e37c8ed3c nd/split-index-null-base-fix later to maint). + + * "git diff --no-index" may still want to access Git goodies like + --ext-diff and --textconv, but so far these have been ignored, + which has been corrected. + (merge 287ab28bfa jk/diff-no-index-initialize later to maint). + + * Unify RPC code for smart http in protocol v0/v1 and v2, which fixes + a bug in the latter (lack of authentication retry) and generally + improves the code base. + (merge a97d00799a jt/http-auth-proto-v2-fix later to maint). + + * The include file compat/bswap.h has been updated so that it is safe + to (accidentally) include it more than once. + (merge 33aa579a55 jk/guard-bswap-header later to maint). + + * The set of header files used by "make hdr-check" unconditionally + included sha256/gcrypt.h, even when it is not used, causing the + make target to fail. We now skip it when GCRYPT_SHA256 is not in + use. + (merge f23aa18e7f rj/hdr-check-gcrypt-fix later to maint). + + * The Makefile uses 'find' utility to enumerate all the *.h header + files, which is expensive on platforms with slow filesystems; it + now optionally uses "ls-files" if working within a repository, + which is a trick similar to how all sources are enumerated to run + ETAGS on. + (merge 92b88eba9f js/find-lib-h-with-ls-files-when-possible later to maint). + + * Code cleanup, docfix, build fix, etc. + (merge 11f470aee7 jc/test-yes-doc later to maint). + (merge 90503a240b js/doc-symref-in-proto-v1 later to maint). + (merge 5c326d1252 jk/unused-params later to maint). + (merge 68cabbfda3 dl/doc-submodule-wo-subcommand later to maint). + (merge 9903623761 ab/receive-pack-use-after-free-fix later to maint). + (merge 1ede45e44b en/merge-options-doc later to maint). + (merge 3e14dd2c8e rd/doc-hook-used-in-sample later to maint). + (merge c271dc28fd nd/no-more-check-racy later to maint). + (merge e6e15194a8 yb/utf-16le-bom-spellfix later to maint). + (merge bb101aaf0c rd/attr.c-comment-typofix later to maint). + (merge 716a5af812 rd/gc-prune-doc-fix later to maint). + (merge 50b206371d js/untravis-windows later to maint). + (merge dbf47215e3 js/rebase-recreate-merge later to maint). diff --git a/Documentation/config/user.txt b/Documentation/config/user.txt index b5b2ba1199..0557cbbceb 100644 --- a/Documentation/config/user.txt +++ b/Documentation/config/user.txt @@ -1,12 +1,19 @@ -user.email:: - Your email address to be recorded in any newly created commits. - Can be overridden by the `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_EMAIL`, and - `EMAIL` environment variables. See linkgit:git-commit-tree[1]. - user.name:: - Your full name to be recorded in any newly created commits. - Can be overridden by the `GIT_AUTHOR_NAME` and `GIT_COMMITTER_NAME` - environment variables. See linkgit:git-commit-tree[1]. +user.email:: +author.name:: +author.email:: +committer.name:: +committer.email:: + The `user.name` and `user.email` variables determine what ends + up in the `author` and `committer` field of commit + objects. + If you need the `author` or `committer` to be different, the + `author.name`, `author.email`, `committer.name` or + `committer.email` variables can be set. + Also, all of these can be overridden by the `GIT_AUTHOR_NAME`, + `GIT_AUTHOR_EMAIL`, `GIT_COMMITTER_NAME`, + `GIT_COMMITTER_EMAIL` and `EMAIL` environment variables. + See linkgit:git-commit-tree[1] for more information. user.useConfigOnly:: Instruct Git to avoid trying to guess defaults for `user.email` diff --git a/Documentation/diff-format.txt b/Documentation/diff-format.txt index cdcc17f0ad..4d846d7346 100644 --- a/Documentation/diff-format.txt +++ b/Documentation/diff-format.txt @@ -95,12 +95,26 @@ from the format described above in the following way: . there are more "src" modes and "src" sha1 . status is concatenated status characters for each parent . no optional "score" number -. single path, only for "dst" +. tab-separated pathname(s) of the file -Example: +For `-c` and `--cc`, only the destination or final path is shown even +if the file was renamed on any side of history. With +`--combined-all-paths`, the name of the path in each parent is shown +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 +::100644 100644 100644 e07d6c5 9042e82 ee91881 RR phooey.c +------------------------------------------------ + +Examples when `--combined-all-paths` added to either `-c` or `--cc`: ------------------------------------------------ -::100644 100644 100644 fabadb8 cc95eb0 4866510 MM describe.c +::100644 100644 100644 fabadb8 cc95eb0 4866510 MM desc.c desc.c desc.c +::100755 100755 100755 52b7a2d 6d1ac04 d2ac7d7 RM foo.sh bar.sh bar.sh +::100644 100644 100644 e07d6c5 9042e82 ee91881 RR fooey.c fuey.c phooey.c ------------------------------------------------ Note that 'combined diff' lists only files which were modified from diff --git a/Documentation/diff-generate-patch.txt b/Documentation/diff-generate-patch.txt index 231105cff4..f10ca410ad 100644 --- a/Documentation/diff-generate-patch.txt +++ b/Documentation/diff-generate-patch.txt @@ -143,6 +143,19 @@ copying detection) are designed to work with diff of two Similar to two-line header for traditional 'unified' diff format, `/dev/null` is used to signal created or deleted files. ++ +However, if the --combined-all-paths option is provided, instead of a +two-line from-file/to-file you get a N+1 line from-file/to-file header, +where N is the number of parents in the merge commit + + --- a/file + --- a/file + --- a/file + +++ b/file ++ +This extended format can be useful if rename or copy detection is +active, to allow you to see the original name of the file in different +parents. 4. Chunk header format is modified to prevent people from accidentally feeding it to `patch -p1`. Combined diff format diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 554a34080d..5ebc56867b 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -36,11 +36,21 @@ endif::git-format-patch[] -U<n>:: --unified=<n>:: Generate diffs with <n> lines of context instead of - the usual three. + the usual three. Implies `--patch`. ifndef::git-format-patch[] Implies `-p`. endif::git-format-patch[] +--output=<file>:: + Output to a specific file instead of stdout. + +--output-indicator-new=<char>:: +--output-indicator-old=<char>:: +--output-indicator-context=<char>:: + Specify the character used to indicate new, old or context + lines in the generated patch. Normally they are '+', '-' and + ' ' respectively. + ifndef::git-format-patch[] --raw:: ifndef::git-log[] @@ -148,6 +158,7 @@ These parameters can also be set individually with `--stat-width=<width>`, number of modified files, as well as number of added and deleted lines. +-X[<param1,param2,...>]:: --dirstat[=<param1,param2,...>]:: Output the distribution of relative amount of changes for each sub-directory. The behavior of `--dirstat` can be customized by @@ -192,6 +203,12 @@ directories with less than 10% of the total amount of changed files, and accumulating child directory counts in the parent directories: `--dirstat=files,10,cumulative`. +--cumulative:: + Synonym for --dirstat=cumulative + +--dirstat-by-file[=<param1,param2>...]:: + Synonym for --dirstat=files,param1,param2... + --summary:: Output a condensed summary of extended header information such as creations, renames and mode changes. @@ -386,6 +403,9 @@ endif::git-format-patch[] Turn off rename detection, even when the configuration file gives the default to do so. +--[no-]rename-empty:: + Whether to use empty blobs as rename source. + ifndef::git-format-patch[] --check:: Warn if changes introduce conflict markers or whitespace errors. diff --git a/Documentation/git-branch.txt b/Documentation/git-branch.txt index 3bd83a7cbd..0cd87ddeff 100644 --- a/Documentation/git-branch.txt +++ b/Documentation/git-branch.txt @@ -9,7 +9,7 @@ SYNOPSIS -------- [verse] 'git branch' [--color[=<when>] | --no-color] [-r | -a] - [--list] [-v [--abbrev=<length> | --no-abbrev]] + [--list] [--show-current] [-v [--abbrev=<length> | --no-abbrev]] [--column[=<options>] | --no-column] [--sort=<key>] [(--merged | --no-merged) [<commit>]] [--contains [<commit]] [--no-contains [<commit>]] @@ -160,6 +160,10 @@ This option is only applicable in non-verbose mode. branch --list 'maint-*'`, list only the branches that match the pattern(s). +--show-current:: + Print the name of the current branch. In detached HEAD state, + nothing is printed. + -v:: -vv:: --verbose:: diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 8c3d4128c2..f179b43732 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -260,6 +260,9 @@ the conflicted merge in the specified paths. This means that you can use `git checkout -p` to selectively discard edits from your current working tree. See the ``Interactive Mode'' 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 +`--[no-]overlay`), and currently doesn't support overlay mode. --ignore-other-worktrees:: `git checkout` refuses when the wanted ref is already checked @@ -280,6 +283,13 @@ section of linkgit:git-add[1] to learn how to operate the `--patch` mode. Do not attempt to create a branch if a remote tracking branch of the same name exists. +--[no-]overlay:: + In the default overlay mode, `git checkout` never + removes files from the index or the working tree. When + specifying `--no-overlay`, files that appear in the index and + working tree, but not in <tree-ish> are removed, to make them + match <tree-ish> exactly. + <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 diff --git a/Documentation/git-diff-tree.txt b/Documentation/git-diff-tree.txt index 43daa7c046..24f32e8c54 100644 --- a/Documentation/git-diff-tree.txt +++ b/Documentation/git-diff-tree.txt @@ -10,8 +10,8 @@ SYNOPSIS -------- [verse] 'git diff-tree' [--stdin] [-m] [-s] [-v] [--no-commit-id] [--pretty] - [-t] [-r] [-c | --cc] [--root] [<common diff options>] - <tree-ish> [<tree-ish>] [<path>...] + [-t] [-r] [-c | --cc] [--combined-all-paths] [--root] + [<common diff options>] <tree-ish> [<tree-ish>] [<path>...] DESCRIPTION ----------- @@ -105,6 +105,13 @@ include::pretty-options.txt[] itself and the commit log message is not shown, just like in any other "empty diff" case. +--combined-all-paths:: + This flag causes combined diffs (used for merge commits) to + list the name of the file from all parents. It thus only has + effect when -c or --cc are specified, and is likely only + useful if filename changes are detected (i.e. when either + rename or copy detection have been requested). + --always:: Show the commit itself and the commit log message even if the diff itself is empty. diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index a7442499f6..a7c1b0f60e 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -76,7 +76,7 @@ be performed as well. --prune=<date>:: Prune loose objects older than date (default is 2 weeks ago, overridable by the config variable `gc.pruneExpire`). - --prune=all prunes loose objects regardless of their age and + --prune=now prunes loose objects regardless of their age and increases the risk of corruption if another process is writing to the repository concurrently; see "NOTES" below. --prune is on by default. diff --git a/Documentation/git-rebase.txt b/Documentation/git-rebase.txt index 5629ba4c5d..6363d674b7 100644 --- a/Documentation/git-rebase.txt +++ b/Documentation/git-rebase.txt @@ -410,7 +410,7 @@ See also INCOMPATIBLE OPTIONS below. + By default, or when `no-rebase-cousins` was specified, commits which do not have `<upstream>` as direct ancestor will keep their original branch point, -i.e. commits that would be excluded by gitlink:git-log[1]'s +i.e. commits that would be excluded by linkgit:git-log[1]'s `--ancestry-path` option will keep their original ancestry by default. If the `rebase-cousins` mode is turned on, such commits are instead rebased onto `<upstream>` (or `<onto>`, if specified). diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index ba3c4df550..2794e29780 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -9,6 +9,7 @@ git-submodule - Initialize, update or inspect submodules SYNOPSIS -------- [verse] +'git submodule' [--quiet] [--cached] 'git submodule' [--quiet] add [<options>] [--] <repository> [<path>] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] @@ -28,6 +29,9 @@ For more information about submodules, see linkgit:gitsubmodules[7]. COMMANDS -------- +With no arguments, shows the status of existing submodules. Several +subcommands are available to perform operations on the submodules. + add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--depth <depth>] [--] <repository> [<path>]:: Add the given repository as a submodule at the given path to the changeset to be committed next to the current diff --git a/Documentation/gitattributes.txt b/Documentation/gitattributes.txt index 9b41f81c06..bdd11a2ddd 100644 --- a/Documentation/gitattributes.txt +++ b/Documentation/gitattributes.txt @@ -346,7 +346,7 @@ automatic line ending conversion based on your platform. Use the following attributes if your '*.ps1' files are UTF-16 little endian encoded without BOM and you want Git to use Windows line endings -in the working directory (use `UTF-16-LE-BOM` instead of `UTF-16LE` if +in the working directory (use `UTF-16LE-BOM` instead of `UTF-16LE` if you want UTF-16 little endian with BOM). Please note, it is highly recommended to explicitly define the line endings with `eol` if the `working-tree-encoding` diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index 959044347e..5bf653c111 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -99,6 +99,10 @@ All the `git commit` hooks are invoked with the environment variable `GIT_EDITOR=:` if the command will not bring up an editor to modify the commit message. +The default 'pre-commit' hook, when enabled--and with the +`hooks.allownonascii` config option unset or set to false--prevents +the use of non-ASCII filenames. + prepare-commit-msg ~~~~~~~~~~~~~~~~~~ diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 63a3fc0954..92a7d936c1 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -3,9 +3,14 @@ Perform the merge and commit the result. This option can be used to override --no-commit. + -With --no-commit perform the merge but pretend the merge -failed and do not autocommit, to give the user a chance to -inspect and further tweak the merge result before committing. +With --no-commit perform the merge and stop just before creating +a merge commit, to give the user a chance to inspect and further +tweak the merge result before committing. ++ +Note that fast-forward updates do not create a merge commit and +therefore there is no way to stop those merges with --no-commit. +Thus, if you want to ensure your branch is not changed or updated +by the merge command, use --no-ff with --no-commit. --edit:: -e:: diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 7bfffae765..079598307a 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -102,120 +102,160 @@ The title was >>t4119: test autocomputing -p<n> for traditional diff input.<< + The placeholders are: -- '%H': commit hash -- '%h': abbreviated commit hash -- '%T': tree hash -- '%t': abbreviated tree hash -- '%P': parent hashes -- '%p': abbreviated parent hashes -- '%an': author name -- '%aN': author name (respecting .mailmap, see linkgit:git-shortlog[1] - or linkgit:git-blame[1]) -- '%ae': author email -- '%aE': author email (respecting .mailmap, see - linkgit:git-shortlog[1] or linkgit:git-blame[1]) -- '%ad': author date (format respects --date= option) -- '%aD': author date, RFC2822 style -- '%ar': author date, relative -- '%at': author date, UNIX timestamp -- '%ai': author date, ISO 8601-like format -- '%aI': author date, strict ISO 8601 format -- '%cn': committer name -- '%cN': committer name (respecting .mailmap, see - linkgit:git-shortlog[1] or linkgit:git-blame[1]) -- '%ce': committer email -- '%cE': committer email (respecting .mailmap, see - linkgit:git-shortlog[1] or linkgit:git-blame[1]) -- '%cd': committer date (format respects --date= option) -- '%cD': committer date, RFC2822 style -- '%cr': committer date, relative -- '%ct': committer date, UNIX timestamp -- '%ci': committer date, ISO 8601-like format -- '%cI': committer date, strict ISO 8601 format -- '%d': ref names, like the --decorate option of linkgit:git-log[1] -- '%D': ref names without the " (", ")" wrapping. -- '%S': ref name given on the command line by which the commit was reached - (like `git log --source`), only works with `git log` -- '%e': encoding -- '%s': subject -- '%f': sanitized subject line, suitable for a filename -- '%b': body -- '%B': raw body (unwrapped subject and body) +- Placeholders that expand to a single literal character: +'%n':: newline +'%%':: a raw '%' +'%x00':: print a byte from a hex code + +- Placeholders that affect formatting of later placeholders: +'%Cred':: switch color to red +'%Cgreen':: switch color to green +'%Cblue':: switch color to blue +'%Creset':: reset color +'%C(...)':: color specification, as described under Values in the + "CONFIGURATION FILE" section of linkgit:git-config[1]. By + default, colors are shown only when enabled for log output + (by `color.diff`, `color.ui`, or `--color`, and respecting + the `auto` settings of the former if we are going to a + terminal). `%C(auto,...)` is accepted as a historical + synonym for the default (e.g., `%C(auto,red)`). Specifying + `%C(always,...)` will show the colors even when color is + not otherwise enabled (though consider just using + `--color=always` to enable color for the whole output, + including this format and anything else git might color). + `auto` alone (i.e. `%C(auto)`) will turn on auto coloring + on the next placeholders until the color is switched + again. +'%m':: left (`<`), right (`>`) or boundary (`-`) mark +'%w([<w>[,<i1>[,<i2>]]])':: switch line wrapping, like the -w option of + linkgit:git-shortlog[1]. +'%<(<N>[,trunc|ltrunc|mtrunc])':: make the next placeholder take at + least N columns, padding spaces on + the right if necessary. Optionally + truncate at the beginning (ltrunc), + the middle (mtrunc) or the end + (trunc) if the output is longer than + N columns. Note that truncating + only works correctly with N >= 2. +'%<|(<N>)':: make the next placeholder take at least until Nth + columns, padding spaces on the right if necessary +'%>(<N>)', '%>|(<N>)':: similar to '%<(<N>)', '%<|(<N>)' respectively, + but padding spaces on the left +'%>>(<N>)', '%>>|(<N>)':: similar to '%>(<N>)', '%>|(<N>)' + respectively, except that if the next + placeholder takes more spaces than given and + there are spaces on its left, use those + spaces +'%><(<N>)', '%><|(<N>)':: similar to '%<(<N>)', '%<|(<N>)' + respectively, but padding both sides + (i.e. the text is centered) + +- Placeholders that expand to information extracted from the commit: +'%H':: commit hash +'%h':: abbreviated commit hash +'%T':: tree hash +'%t':: abbreviated tree hash +'%P':: parent hashes +'%p':: abbreviated parent hashes +'%an':: author name +'%aN':: author name (respecting .mailmap, see linkgit:git-shortlog[1] + or linkgit:git-blame[1]) +'%ae':: author email +'%aE':: author email (respecting .mailmap, see linkgit:git-shortlog[1] + or linkgit:git-blame[1]) +'%ad':: author date (format respects --date= option) +'%aD':: author date, RFC2822 style +'%ar':: author date, relative +'%at':: author date, UNIX timestamp +'%ai':: author date, ISO 8601-like format +'%aI':: author date, strict ISO 8601 format +'%cn':: committer name +'%cN':: committer name (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%ce':: committer email +'%cE':: committer email (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%cd':: committer date (format respects --date= option) +'%cD':: committer date, RFC2822 style +'%cr':: committer date, relative +'%ct':: committer date, UNIX timestamp +'%ci':: committer date, ISO 8601-like format +'%cI':: committer date, strict ISO 8601 format +'%d':: ref names, like the --decorate option of linkgit:git-log[1] +'%D':: ref names without the " (", ")" wrapping. +'%S':: ref name given on the command line by which the commit was reached + (like `git log --source`), only works with `git log` +'%e':: encoding +'%s':: subject +'%f':: sanitized subject line, suitable for a filename +'%b':: body +'%B':: raw body (unwrapped subject and body) ifndef::git-rev-list[] -- '%N': commit notes +'%N':: commit notes endif::git-rev-list[] -- '%GG': raw verification message from GPG for a signed commit -- '%G?': 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 -- '%GS': show the name of the signer for a signed commit -- '%GK': show the key used to sign a signed commit -- '%GF': show the fingerprint of the key used to sign a signed commit -- '%GP': show the fingerprint of the primary key whose subkey was used - to sign a signed commit -- '%gD': reflog selector, e.g., `refs/stash@{1}` or - `refs/stash@{2 minutes ago`}; the format follows the rules described - for the `-g` option. The portion before the `@` is the refname as - given on the command line (so `git log -g refs/heads/master` would - yield `refs/heads/master@{0}`). -- '%gd': shortened reflog selector; same as `%gD`, but the refname - portion is shortened for human readability (so `refs/heads/master` - becomes just `master`). -- '%gn': reflog identity name -- '%gN': reflog identity name (respecting .mailmap, see - linkgit:git-shortlog[1] or linkgit:git-blame[1]) -- '%ge': reflog identity email -- '%gE': reflog identity email (respecting .mailmap, see - linkgit:git-shortlog[1] or linkgit:git-blame[1]) -- '%gs': reflog subject -- '%Cred': switch color to red -- '%Cgreen': switch color to green -- '%Cblue': switch color to blue -- '%Creset': reset color -- '%C(...)': color specification, as described under Values in the - "CONFIGURATION FILE" section of linkgit:git-config[1]. - By default, colors are shown only when enabled for log output (by - `color.diff`, `color.ui`, or `--color`, and respecting the `auto` - settings of the former if we are going to a terminal). `%C(auto,...)` - is accepted as a historical synonym for the default (e.g., - `%C(auto,red)`). Specifying `%C(always,...)` will show the colors - even when color is not otherwise enabled (though consider - just using `--color=always` to enable color for the whole output, - including this format and anything else git might color). `auto` - alone (i.e. `%C(auto)`) will turn on auto coloring on the next - placeholders until the color is switched again. -- '%m': left (`<`), right (`>`) or boundary (`-`) mark -- '%n': newline -- '%%': a raw '%' -- '%x00': print a byte from a hex code -- '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of - linkgit:git-shortlog[1]. -- '%<(<N>[,trunc|ltrunc|mtrunc])': make the next placeholder take at - least N columns, padding spaces on the right if necessary. - Optionally truncate at the beginning (ltrunc), the middle (mtrunc) - or the end (trunc) if the output is longer than N columns. - Note that truncating only works correctly with N >= 2. -- '%<|(<N>)': make the next placeholder take at least until Nth - columns, padding spaces on the right if necessary -- '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)' - respectively, but padding spaces on the left -- '%>>(<N>)', '%>>|(<N>)': similar to '%>(<N>)', '%>|(<N>)' - respectively, except that if the next placeholder takes more spaces - than given and there are spaces on its left, use those spaces -- '%><(<N>)', '%><|(<N>)': similar to '%<(<N>)', '%<|(<N>)' - respectively, but padding both sides (i.e. the text is centered) -- %(trailers[:options]): display the trailers of the body as interpreted - by linkgit:git-interpret-trailers[1]. The `trailers` string may be - followed by a colon and zero or more comma-separated options. If the - `only` option is given, omit non-trailer lines from the trailer block. - If the `unfold` option is given, behave as if interpret-trailer's - `--unfold` option was given. E.g., `%(trailers:only,unfold)` to do - both. +'%GG':: raw verification message from GPG for a signed commit +'%G?':: 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 +'%GS':: show the name of the signer for a signed commit +'%GK':: show the key used to sign a signed commit +'%GF':: show the fingerprint of the key used to sign a signed commit +'%GP':: show the fingerprint of the primary key whose subkey was used + to sign a signed commit +'%gD':: reflog selector, e.g., `refs/stash@{1}` or `refs/stash@{2 + minutes ago`}; the format follows the rules described for the + `-g` option. The portion before the `@` is the refname as + given on the command line (so `git log -g refs/heads/master` + would yield `refs/heads/master@{0}`). +'%gd':: shortened reflog selector; same as `%gD`, but the refname + portion is shortened for human readability (so + `refs/heads/master` becomes just `master`). +'%gn':: reflog identity name +'%gN':: reflog identity name (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%ge':: reflog identity email +'%gE':: reflog identity email (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) +'%gs':: reflog subject +'%(trailers[:options])':: display the trailers of the body as + interpreted by + linkgit:git-interpret-trailers[1]. The + `trailers` string may be followed by a colon + and zero or more comma-separated options: +** 'key=<K>': only show trailers with specified key. Matching is done + case-insensitively and trailing colon is optional. If option is + given multiple times trailer lines matching any of the keys are + shown. This option automatically enables the `only` option so that + non-trailer lines in the trailer block are hidden. If that is not + desired it can be disabled with `only=false`. E.g., + `%(trailers:key=Reviewed-by)` shows trailer lines with key + `Reviewed-by`. +** 'only[=val]': select whether non-trailer lines from the trailer + block should be included. The `only` keyword may optionally be + followed by an equal sign and one of `true`, `on`, `yes` to omit or + `false`, `off`, `no` to show the non-trailer lines. If option is + given without value it is enabled. If given multiple times the last + value is used. +** 'separator=<SEP>': specify a separator inserted between trailer + lines. When this option is not given each trailer line is + terminated with a line feed character. The string SEP may contain + the literal formatting codes described above. To use comma as + separator one must use `%x2C` as it would otherwise be parsed as + next option. If separator option is given multiple times only the + last one is used. E.g., `%(trailers:key=Ticket,separator=%x2C )` + shows all trailer lines whose key is "Ticket" separated by a comma + and a space. +** 'unfold[=val]': make it behave as if interpret-trailer's `--unfold` + option was given. In same way as to for `only` it can be followed + by an equal sign and explicit value. E.g., + `%(trailers:only,unfold=true)` unfolds and shows all trailer lines. +** 'valueonly[=val]': skip over the key part of the trailer line and only + show the value part. Also this optionally allows explicit value. NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will diff --git a/Documentation/rev-list-options.txt b/Documentation/rev-list-options.txt index cad711ce0a..ca959a7286 100644 --- a/Documentation/rev-list-options.txt +++ b/Documentation/rev-list-options.txt @@ -960,6 +960,13 @@ options may be given. See linkgit:git-diff-files[1] for more options. the parents have only two variants and the merge result picks one of them without modification. +--combined-all-paths:: + This flag causes combined diffs (used for merge commits) to + list the name of the file from all parents. It thus only has + effect when -c or --cc are specified, and is likely only + useful if filename changes are detected (i.e. when either + rename or copy detection have been requested). + -m:: This flag makes the merge commits show the full diff like regular commits; for each merge parent, a separate log entry diff --git a/Documentation/technical/api-trace2.txt b/Documentation/technical/api-trace2.txt new file mode 100644 index 0000000000..2de565fa3d --- /dev/null +++ b/Documentation/technical/api-trace2.txt @@ -0,0 +1,1349 @@ += Trace2 API + +The Trace2 API can be used to print debug, performance, and telemetry +information to stderr or a file. The Trace2 feature is inactive unless +explicitly enabled by enabling one or more Trace2 Targets. + +The Trace2 API is intended to replace the existing (Trace1) +printf-style tracing provided by the existing `GIT_TRACE` and +`GIT_TRACE_PERFORMANCE` facilities. During initial implementation, +Trace2 and Trace1 may operate in parallel. + +The Trace2 API defines a set of high-level messages with known fields, +such as (`start`: `argv`) and (`exit`: {`exit-code`, `elapsed-time`}). + +Trace2 instrumentation throughout the Git code base sends Trace2 +messages to the enabled Trace2 Targets. Targets transform these +messages content into purpose-specific formats and write events to +their data streams. In this manner, the Trace2 API can drive +many different types of analysis. + +Targets are defined using a VTable allowing easy extension to other +formats in the future. This might be used to define a binary format, +for example. + +== Trace2 Targets + +Trace2 defines the following set of Trace2 Targets. +Format details are given in a later section. + +`GIT_TR2` (NORMAL):: + + a simple printf format like GIT_TRACE. ++ +------------ +$ export GIT_TR2=~/log.normal +$ git version +git version 2.20.1.155.g426c96fcdb +------------ ++ +------------ +$ cat ~/log.normal +12:28:42.620009 common-main.c:38 version 2.20.1.155.g426c96fcdb +12:28:42.620989 common-main.c:39 start git version +12:28:42.621101 git.c:432 cmd_name version (version) +12:28:42.621215 git.c:662 exit elapsed:0.001227 code:0 +12:28:42.621250 trace2/tr2_tgt_normal.c:124 atexit elapsed:0.001265 code:0 +------------ + +`GIT_TR2_PERF` (PERF):: + + a column-based format to replace GIT_TRACE_PERFORMANCE suitable for + development and testing, possibly to complement tools like gprof. ++ +------------ +$ export GIT_TR2_PERF=~/log.perf +$ git version +git version 2.20.1.155.g426c96fcdb +------------ ++ +------------ +$ cat ~/log.perf +12:28:42.620675 common-main.c:38 | d0 | main | version | | | | | 2.20.1.155.g426c96fcdb +12:28:42.621001 common-main.c:39 | d0 | main | start | | | | | git version +12:28:42.621111 git.c:432 | d0 | main | cmd_name | | | | | version (version) +12:28:42.621225 git.c:662 | d0 | main | exit | | 0.001227 | | | code:0 +12:28:42.621259 trace2/tr2_tgt_perf.c:211 | d0 | main | atexit | | 0.001265 | | | code:0 +------------ + +`GIT_TR2_EVENT` (EVENT):: + + a JSON-based format of event data suitable for telemetry analysis. ++ +------------ +$ export GIT_TR2_EVENT=~/log.event +$ git version +git version 2.20.1.155.g426c96fcdb +------------ ++ +------------ +$ cat ~/log.event +{"event":"version","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.620713","file":"common-main.c","line":38,"evt":"1","exe":"2.20.1.155.g426c96fcdb"} +{"event":"start","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621027","file":"common-main.c","line":39,"argv":["git","version"]} +{"event":"cmd_name","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621122","file":"git.c","line":432,"name":"version","hierarchy":"version"} +{"event":"exit","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621236","file":"git.c","line":662,"t_abs":0.001227,"code":0} +{"event":"atexit","sid":"1547659722619736-11614","thread":"main","time":"2019-01-16 17:28:42.621268","file":"trace2/tr2_tgt_event.c","line":163,"t_abs":0.001265,"code":0} +------------ + +== Enabling a Target + +A Trace2 Target is enabled when the corresponding environment variable +(`GIT_TR2`, `GIT_TR2_PERF`, or `GIT_TR2_EVENT`) is set. The following +values are recognized. + +`0`:: +`false`:: + + Disables the target. + +`1`:: +`true`:: + + Enables the target and writes stream to `STDERR`. + +`[2-9]`:: + + Enables the target and writes to the already opened file descriptor. + +`<absolute-pathname>`:: + + Enables the target, opens and writes to the file in append mode. + +`af_unix:[<socket_type>:]<absolute-pathname>`:: + + Enables the target, opens and writes to a Unix Domain Socket + (on platforms that support them). ++ +Socket type can be either `stream` or `dgram`. If the socket type is +omitted, Git will try both. + +== Trace2 API + +All public Trace2 functions and macros are defined in `trace2.h` and +`trace2.c`. All public symbols are prefixed with `trace2_`. + +There are no public Trace2 data structures. + +The Trace2 code also defines a set of private functions and data types +in the `trace2/` directory. These symbols are prefixed with `tr2_` +and should only be used by functions in `trace2.c`. + +== Conventions for Public Functions and Macros + +The functions defined by the Trace2 API are declared and documented +in `trace2.h`. It defines the API functions and wrapper macros for +Trace2. + +Some functions have a `_fl()` suffix to indicate that they take `file` +and `line-number` arguments. + +Some functions have a `_va_fl()` suffix to indicate that they also +take a `va_list` argument. + +Some functions have a `_printf_fl()` suffix to indicate that they also +take a varargs argument. + +There are CPP wrapper macros and ifdefs to hide most of these details. +See `trace2.h` for more details. The following discussion will only +describe the simplified forms. + +== Public API + +All Trace2 API functions send a messsage to all of the active +Trace2 Targets. This section describes the set of available +messages. + +It helps to divide these functions into groups for discussion +purposes. + +=== Basic Command Messages + +These are concerned with the lifetime of the overall git process. + +`void trace2_initialize()`:: + + Determines if any Trace2 Targets should be enabled and + initializes the Trace2 facility. This includes starting the + elapsed time clocks and thread local storage (TLS). ++ +This function emits a "version" message containing the version of git +and the Trace2 protocol. ++ +This function should be called from `main()` as early as possible in +the life of the process. + +`int trace2_is_enabled()`:: + + Returns 1 if Trace2 is enabled (at least one target is + active). + +`void trace2_cmd_start(int argc, const char **argv)`:: + + Emits a "start" message containing the process command line + arguments. + +`int trace2_cmd_exit(int exit_code)`:: + + Emits an "exit" message containing the process exit-code and + elapsed time. ++ +Returns the exit-code. + +`void trace2_cmd_error(const char *fmt, va_list ap)`:: + + Emits an "error" message containing a formatted error message. + +`void trace2_cmd_path(const char *pathname)`:: + + Emits a "cmd_path" message with the full pathname of the + current process. + +=== Command Detail Messages + +These are concerned with describing the specific Git command +after the command line, config, and environment are inspected. + +`void trace2_cmd_name(const char *name)`:: + + Emits a "cmd_name" message with the canonical name of the + command, for example "status" or "checkout". + +`void trace2_cmd_mode(const char *mode)`:: + + Emits a "cmd_mode" message with a qualifier name to further + describe the current git command. ++ +This message is intended to be used with git commands having multiple +major modes. For example, a "checkout" command can checkout a new +branch or it can checkout a single file, so the checkout code could +emit a cmd_mode message of "branch" or "file". + +`void trace2_cmd_alias(const char *alias, const char **argv_expansion)`:: + + Emits an "alias" message containing the alias used and the + argument expansion. + +`void trace2_def_param(const char *parameter, const char *value)`:: + + Emits a "def_param" message containing a key/value pair. ++ +This message is intended to report some global aspect of the current +command, such as a configuration setting or command line switch that +significantly affects program performance or behavior, such as +`core.abbrev`, `status.showUntrackedFiles`, or `--no-ahead-behind`. + +`void trace2_cmd_list_config()`:: + + Emits a "def_param" messages for "important" configuration + settings. ++ +The environment variable `GIT_TR2_CONFIG_PARAMS` can be set to a +list of patterns of important configuration settings, for example: +`core.*,remote.*.url`. This function will iterate over all config +settings and emit a "def_param" message for each match. + +`void trace2_cmd_set_config(const char *key, const char *value)`:: + + Emits a "def_param" message for a specific configuration + setting IFF it matches the `GIT_TR2_CONFIG_PARAMS` pattern. ++ +This is used to hook into `git_config_set()` and catch any +configuration changes and update a value previously reported by +`trace2_cmd_list_config()`. + +`void trace2_def_repo(struct repository *repo)`:: + + Registers a repository with the Trace2 layer. Assigns a + unique "repo-id" to `repo->trace2_repo_id`. ++ +Emits a "worktree" messages containing the repo-id and the worktree +pathname. ++ +Region and data messages (described later) may refer to this repo-id. ++ +The main/top-level repository will have repo-id value 1 (aka "r1"). ++ +The repo-id field is in anticipation of future in-proc submodule +repositories. + +=== Child Process Messages + +These are concerned with the various spawned child processes, +including shell scripts, git commands, editors, pagers, and hooks. + +`void trace2_child_start(struct child_process *cmd)`:: + + Emits a "child_start" message containing the "child-id", + "child-argv", and "child-classification". ++ +Before calling this, set `cmd->trace2_child_class` to a name +describing the type of child process, for example "editor". ++ +This function assigns a unique "child-id" to `cmd->trace2_child_id`. +This field is used later during the "child_exit" message to associate +it with the "child_start" message. ++ +This function should be called before spawning the child process. + +`void trace2_child_exit(struct child_proess *cmd, int child_exit_code)`:: + + Emits a "child_exit" message containing the "child-id", + the child's elapsed time and exit-code. ++ +The reported elapsed time includes the process creation overhead and +time spend waiting for it to exit, so it may be slightly longer than +the time reported by the child itself. ++ +This function should be called after reaping the child process. + +`int trace2_exec(const char *exe, const char **argv)`:: + + Emits a "exec" message containing the "exec-id" and the + argv of the new process. ++ +This function should be called before calling one of the `exec()` +variants, such as `execvp()`. ++ +This function returns a unique "exec-id". This value is used later +if the exec() fails and a "exec-result" message is necessary. + +`void trace2_exec_result(int exec_id, int error_code)`:: + + Emits a "exec_result" message containing the "exec-id" + and the error code. ++ +On Unix-based systems, `exec()` does not return if successful. +This message is used to indicate that the `exec()` failed and +that the current program is continuing. + +=== Git Thread Messages + +These messages are concerned with Git thread usage. + +`void trace2_thread_start(const char *thread_name)`:: + + Emits a "thread_start" message. ++ +The `thread_name` field should be a descriptive name, such as the +unique name of the thread-proc. A unique "thread-id" will be added +to the name to uniquely identify thread instances. ++ +Region and data messages (described later) may refer to this thread +name. ++ +This function must be called by the thread-proc of the new thread +(so that TLS data is properly initialized) and not by the caller +of `pthread_create()`. + +`void trace2_thread_exit()`:: + + Emits a "thread_exit" message containing the thread name + and the thread elapsed time. ++ +This function must be called by the thread-proc before it returns +(so that the coorect TLS data is used and cleaned up. It should +not be called by the caller of `pthread_join()`. + +=== Region and Data Messages + +These are concerned with recording performance data +over regions or spans of code. + +`void trace2_region_enter(const char *category, const char *label, const struct repository *repo)`:: + +`void trace2_region_enter_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`:: + +`void trace2_region_enter_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`:: + + Emits a thread-relative "region_enter" message with optional + printf string. ++ +This function pushes a new region nesting stack level on the current +thread and starts a clock for the new stack frame. ++ +The `category` field is an arbitrary category name used to classify +regions by feature area, such as "status" or "index". At this time +it is only just printed along with the rest of the message. It may +be used in the future to filter messages. ++ +The `label` field is an arbitrary label used to describe the activity +being started, such as "read_recursive" or "do_read_index". ++ +The `repo` field, if set, will be used to get the "repo-id", so that +recursive oerations can be attributed to the correct repository. + +`void trace2_region_leave(const char *category, const char *label, const struct repository *repo)`:: + +`void trace2_region_leave_printf(const char *category, const char *label, const struct repository *repo, const char *fmt, ...)`:: + +`void trace2_region_leave_printf_va(const char *category, const char *label, const struct repository *repo, const char *fmt, va_list ap)`:: + + Emits a thread-relative "region_leave" message with optional + printf string. ++ +This function pops the region nesting stack on the current thread +and reports the elapsed time of the stack frame. ++ +The `category`, `label`, and `repo` fields are the same as above. +The `category` and `label` do not need to match the correpsonding +"region_enter" message, but it makes the data stream easier to +understand. + +`void trace2_data_string(const char *category, const struct repository *repo, const char *key, const char * value)`:: + +`void trace2_data_intmax(const char *category, const struct repository *repo, const char *key, intmax value)`:: + +`void trace2_data_json(const char *category, const struct repository *repo, const char *key, const struct json_writer *jw)`:: + + Emits a region- and thread-relative "data" or "data_json" message. ++ +This is a key/value pair message containing information about the +current thread, region stack, and repository. This could be used +to print the number of files in a directory during a multi-threaded +recursive tree walk. + +`void trace2_printf(const char *fmt, ...)`:: + +`void trace2_printf_va(const char *fmt, va_list ap)`:: + + Emits a region- and thread-relative "printf" message. + +== Trace2 Target Formats + +=== NORMAL Format + +NORMAL format is enabled when the `GIT_TR2` environment variable is +set. + +Events are written as lines of the form: + +------------ +[<time> SP <filename>:<line> SP+] <event-name> [[SP] <event-message>] LF +------------ + +`<event-name>`:: + + is the event name. + +`<event-message>`:: + is a free-form printf message intended for human consumption. ++ +Note that this may contain embedded LF or CRLF characters that are +not escaped, so the event may spill across multiple lines. + +If `GIT_TR2_BRIEF` is true, the `time`, `filename`, and `line` fields +are omitted. + +This target is intended to be more of a summary (like GIT_TRACE) and +less detailed than the other targets. It ignores thread, region, and +data messages, for example. + +=== PERF Format + +PERF format is enabled when the `GIT_TR2_PERF` environment variable +is set. + +Events are written as lines of the form: + +------------ +[<time> SP <filename>:<line> SP+ + BAR SP] d<depth> SP + BAR SP <thread-name> SP+ + BAR SP <event-name> SP+ + BAR SP [r<repo-id>] SP+ + BAR SP [<t_abs>] SP+ + BAR SP [<t_rel>] SP+ + BAR SP [<category>] SP+ + BAR SP DOTS* <perf-event-message> + LF +------------ + +`<depth>`:: + is the git process depth. This is the number of parent + git processes. A top-level git command has depth value "d0". + A child of it has depth value "d1". A second level child + has depth value "d2" and so on. + +`<thread-name>`:: + is a unique name for the thread. The primary thread + is called "main". Other thread names are of the form "th%d:%s" + and include a unique number and the name of the thread-proc. + +`<event-name>`:: + is the event name. + +`<repo-id>`:: + when present, is a number indicating the repository + in use. A `def_repo` event is emitted when a repository is + opened. This defines the repo-id and associated worktree. + Subsequent repo-specific events will reference this repo-id. ++ +Currently, this is always "r1" for the main repository. +This field is in anticipation of in-proc submodules in the future. + +`<t_abs>`:: + when present, is the absolute time in seconds since the + program started. + +`<t_rel>`:: + when present, is time in seconds relative to the start of + the current region. For a thread-exit event, it is the elapsed + time of the thread. + +`<category>`:: + is present on region and data events and is used to + indicate a broad category, such as "index" or "status". + +`<perf-event-message>`:: + is a free-form printf message intended for human consumption. + +------------ +15:33:33.532712 wt-status.c:2310 | d0 | main | region_enter | r1 | 0.126064 | | status | label:print +15:33:33.532712 wt-status.c:2331 | d0 | main | region_leave | r1 | 0.127568 | 0.001504 | status | label:print +------------ + +If `GIT_TR2_PERF_BRIEF` is true, the `time`, `file`, and `line` +fields are omitted. + +------------ +d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload +------------ + +The PERF target is intended for interactive performance analysis +during development and is quite noisy. + +=== EVENT Format + +EVENT format is enabled when the `GIT_TR2_EVENT` environment +variable is set. + +Each event is a JSON-object containing multiple key/value pairs +written as a single line and followed by a LF. + +------------ +'{' <key> ':' <value> [',' <key> ':' <value>]* '}' LF +------------ + +Some key/value pairs are common to all events and some are +event-specific. + +==== Common Key/Value Pairs + +The following key/value pairs are common to all events: + +------------ +{ + "event":"version", + "sid":"1547659722619736-11614", + "thread":"main", + "time":"2019-01-16 17:28:42.620713", + "file":"common-main.c", + "line":38, + ... +} +------------ + +`"event":<event>`:: + is the event name. + +`"sid":<sid>`:: + is the session-id. This is a unique string to identify the + process instance to allow all events emitted by a process to + be identified. A session-id is used instead of a PID because + PIDs are recycled by the OS. For child git processes, the + session-id is prepended with the session-id of the parent git + process to allow parent-child relationships to be identified + during post-processing. + +`"thread":<thread>`:: + is the thread name. + +`"time":<time>`:: + is the UTC time of the event. + +`"file":<filename>`:: + is source file generating the event. + +`"line":<line-number>`:: + is the integer source line number generating the event. + +`"repo":<repo-id>`:: + when present, is the integer repo-id as described previously. + +If `GIT_TR2_EVENT_BRIEF` is true, the `file` and `line` fields are omitted +from all events and the `time` field is only present on the "start" and +"atexit" events. + +==== Event-Specific Key/Value Pairs + +`"version"`:: + This event gives the version of the executable and the EVENT format. ++ +------------ +{ + "event":"version", + ... + "evt":"1", # EVENT format version + "exe":"2.20.1.155.g426c96fcdb" # git version +} +------------ + +`"start"`:: + This event contains the complete argv received by main(). ++ +------------ +{ + "event":"start", + ... + "argv":["git","version"] +} +------------ + +`"exit"`:: + This event is emitted when git calls `exit()`. ++ +------------ +{ + "event":"exit", + ... + "t_abs":0.001227, # elapsed time in seconds + "code":0 # exit code +} +------------ + +`"atexit"`:: + This event is emitted by the Trace2 `atexit` routine during + final shutdown. It should be the last event emitted by the + process. ++ +(The elapsed time reported here is greater than the time reported in +the "exit" event because it runs after all other atexit tasks have +completed.) ++ +------------ +{ + "event":"atexit", + ... + "t_abs":0.001227, # elapsed time in seconds + "code":0 # exit code +} +------------ + +`"signal"`:: + This event is emitted when the program is terminated by a user + signal. Depending on the platform, the signal event may + prevent the "atexit" event from being generated. ++ +------------ +{ + "event":"signal", + ... + "t_abs":0.001227, # elapsed time in seconds + "signal":13 # SIGTERM, SIGINT, etc. +} +------------ + +`"error"`:: + This event is emitted when one of the `error()`, `die()`, + or `usage()` functions are called. ++ +------------ +{ + "event":"error", + ... + "msg":"invalid option: --cahced", # formatted error message + "fmt":"invalid option: %s" # error format string +} +------------ ++ +The error event may be emitted more than once. The format string +allows post-processors to group errors by type without worrying +about specific error arguments. + +`"cmd_path"`:: + This event contains the discovered full path of the git + executable (on platforms that are configured to resolve it). ++ +------------ +{ + "event":"cmd_path", + ... + "path":"C:/work/gfw/git.exe" +} +------------ + +`"cmd_name"`:: + This event contains the command name for this git process + and the hierarchy of commands from parent git processes. ++ +------------ +{ + "event":"cmd_name", + ... + "name":"pack-objects", + "hierarchy":"push/pack-objects" +} +------------ ++ +Normally, the "name" field contains the canonical name of the +command. When a canonical name is not available, one of +these special values are used: ++ +------------ +"_query_" # "git --html-path" +"_run_dashed_" # when "git foo" tries to run "git-foo" +"_run_shell_alias_" # alias expansion to a shell command +"_run_git_alias_" # alias expansion to a git command +"_usage_" # usage error +------------ + +`"cmd_mode"`:: + This event, when present, describes the command variant This + event may be emitted more than once. ++ +------------ +{ + "event":"cmd_mode", + ... + "name":"branch" +} +------------ ++ +The "name" field is an arbitrary string to describe the command mode. +For example, checkout can checkout a branch or an individual file. +And these variations typically have different performance +characteristics that are not comparable. + +`"alias"`:: + This event is present when an alias is expanded. ++ +------------ +{ + "event":"alias", + ... + "alias":"l", # registered alias + "argv":["log","--graph"] # alias expansion +} +------------ + +`"child_start"`:: + This event describes a child process that is about to be + spawned. ++ +------------ +{ + "event":"child_start", + ... + "child_id":2, + "child_class":"?", + "use_shell":false, + "argv":["git","rev-list","--objects","--stdin","--not","--all","--quiet"] + + "hook_name":"<hook_name>" # present when child_class is "hook" + "cd":"<path>" # present when cd is required +} +------------ ++ +The "child_id" field can be used to match this child_start with the +corresponding child_exit event. ++ +The "child_class" field is a rough classification, such as "editor", +"pager", "transport/*", and "hook". Unclassified children are classified +with "?". + +`"child_exit"`:: + This event is generated after the current process has returned + from the waitpid() and collected the exit information from the + child. ++ +------------ +{ + "event":"child_exit", + ... + "child_id":2, + "pid":14708, # child PID + "code":0, # child exit-code + "t_rel":0.110605 # observed run-time of child process +} +------------ ++ +Note that the session-id of the child process is not available to +the current/spawning process, so the child's PID is reported here as +a hint for post-processing. (But it is only a hint because the child +proces may be a shell script which doesn't have a session-id.) ++ +Note that the `t_rel` field contains the observed run time in seconds +for the child process (starting before the fork/exec/spawn and +stopping after the waitpid() and includes OS process creation overhead). +So this time will be slightly larger than the atexit time reported by +the child process itself. + +`"exec"`:: + This event is generated before git attempts to `exec()` + another command rather than starting a child process. ++ +------------ +{ + "event":"exec", + ... + "exec_id":0, + "exe":"git", + "argv":["foo", "bar"] +} +------------ ++ +The "exec_id" field is a command-unique id and is only useful if the +`exec()` fails and a corresponding exec_result event is generated. + +`"exec_result"`:: + This event is generated if the `exec()` fails and control + returns to the current git command. ++ +------------ +{ + "event":"exec_result", + ... + "exec_id":0, + "code":1 # error code (errno) from exec() +} +------------ + +`"thread_start"`:: + This event is generated when a thread is started. It is + generated from *within* the new thread's thread-proc (for TLS + reasons). ++ +------------ +{ + "event":"thread_start", + ... + "thread":"th02:preload_thread" # thread name +} +------------ + +`"thread_exit"`:: + This event is generated when a thread exits. It is generated + from *within* the thread's thread-proc (for TLS reasons). ++ +------------ +{ + "event":"thread_exit", + ... + "thread":"th02:preload_thread", # thread name + "t_rel":0.007328 # thread elapsed time +} +------------ + +`"def_param"`:: + This event is generated to log a global parameter. ++ +------------ +{ + "event":"def_param", + ... + "param":"core.abbrev", + "value":"7" +} +------------ + +`"def_repo"`:: + This event defines a repo-id and associates it with the root + of the worktree. ++ +------------ +{ + "event":"def_repo", + ... + "repo":1, + "worktree":"/Users/jeffhost/work/gfw" +} +------------ ++ +As stated earlier, the repo-id is currently always 1, so there will +only be one def_repo event. Later, if in-proc submodules are +supported, a def_repo event should be emitted for each submodule +visited. + +`"region_enter"`:: + This event is generated when entering a region. ++ +------------ +{ + "event":"region_enter", + ... + "repo":1, # optional + "nesting":1, # current region stack depth + "category":"index", # optional + "label":"do_read_index", # optional + "msg":".git/index" # optional +} +------------ ++ +The `category` field may be used in a future enhancement to +do category-based filtering. ++ +The `GIT_TR2_EVENT_NESTING` environment variable can be used to +filter deeply nested regions and data events. It defaults to "2". + +`"region_leave"`:: + This event is generated when leaving a region. ++ +------------ +{ + "event":"region_leave", + ... + "repo":1, # optional + "t_rel":0.002876, # time spent in region in seconds + "nesting":1, # region stack depth + "category":"index", # optional + "label":"do_read_index", # optional + "msg":".git/index" # optional +} +------------ + +`"data"`:: + This event is generated to log a thread- and region-local + key/value pair. ++ +------------ +{ + "event":"data", + ... + "repo":1, # optional + "t_abs":0.024107, # absolute elapsed time + "t_rel":0.001031, # elapsed time in region/thread + "nesting":2, # region stack depth + "category":"index", + "key":"read/cache_nr", + "value":"3552" +} +------------ ++ +The "value" field may be an integer or a string. + +`"data-json"`:: + This event is generated to log a pre-formatted JSON string + containing structured data. ++ +------------ +{ + "event":"data_json", + ... + "repo":1, # optional + "t_abs":0.015905, + "t_rel":0.015905, + "nesting":1, + "category":"process", + "key":"windows/ancestry", + "value":["bash.exe","bash.exe"] +} +------------ + +== Example Trace2 API Usage + +Here is a hypothetical usage of the Trace2 API showing the intended +usage (without worrying about the actual Git details). + +Initialization:: + + Initialization happens in `main()`. Behind the scenes, an + `atexit` and `signal` handler are registered. ++ +---------------- +int main(int argc, const char **argv) +{ + int exit_code; + + trace2_initialize(); + trace2_cmd_start(argv); + + exit_code = cmd_main(argc, argv); + + trace2_cmd_exit(exit_code); + + return exit_code; +} +---------------- + +Command Details:: + + After the basics are established, additional command + information can be sent to Trace2 as it is discovered. ++ +---------------- +int cmd_checkout(int argc, const char **argv) +{ + trace2_cmd_name("checkout"); + trace2_cmd_mode("branch"); + trace2_def_repo(the_repository); + + // emit "def_param" messages for "interesting" config settings. + trace2_cmd_list_config(); + + if (do_something()) + trace2_cmd_error("Path '%s': cannot do something", path); + + return 0; +} +---------------- + +Child Processes:: + + Wrap code spawning child processes. ++ +---------------- +void run_child(...) +{ + int child_exit_code; + struct child_process cmd = CHILD_PROCESS_INIT; + ... + cmd.trace2_child_class = "editor"; + + trace2_child_start(&cmd); + child_exit_code = spawn_child_and_wait_for_it(); + trace2_child_exit(&cmd, child_exit_code); +} +---------------- ++ +For example, the following fetch command spawned ssh, index-pack, +rev-list, and gc. This example also shows that fetch took +5.199 seconds and of that 4.932 was in ssh. ++ +---------------- +$ export GIT_TR2_BRIEF=1 +$ export GIT_TR2=~/log.normal +$ git fetch origin +... +---------------- ++ +---------------- +$ cat ~/log.normal +version 2.20.1.vfs.1.1.47.g534dbe1ad1 +start git fetch origin +worktree /Users/jeffhost/work/gfw +cmd_name fetch (fetch) +child_start[0] ssh git@github.com ... +child_start[1] git index-pack ... +... (Trace2 events from child processes omitted) +child_exit[1] pid:14707 code:0 elapsed:0.076353 +child_exit[0] pid:14706 code:0 elapsed:4.931869 +child_start[2] git rev-list ... +... (Trace2 events from child process omitted) +child_exit[2] pid:14708 code:0 elapsed:0.110605 +child_start[3] git gc --auto +... (Trace2 events from child process omitted) +child_exit[3] pid:14709 code:0 elapsed:0.006240 +exit elapsed:5.198503 code:0 +atexit elapsed:5.198541 code:0 +---------------- ++ +When a git process is a (direct or indirect) child of another +git process, it inherits Trace2 context information. This +allows the child to print the command hierarchy. This example +shows gc as child[3] of fetch. When the gc process reports +its name as "gc", it also reports the hierarchy as "fetch/gc". +(In this example, trace2 messages from the child process is +indented for clarity.) ++ +---------------- +$ export GIT_TR2_BRIEF=1 +$ export GIT_TR2=~/log.normal +$ git fetch origin +... +---------------- ++ +---------------- +$ cat ~/log.normal +version 2.20.1.160.g5676107ecd.dirty +start git fetch official +worktree /Users/jeffhost/work/gfw +cmd_name fetch (fetch) +... +child_start[3] git gc --auto + version 2.20.1.160.g5676107ecd.dirty + start /Users/jeffhost/work/gfw/git gc --auto + worktree /Users/jeffhost/work/gfw + cmd_name gc (fetch/gc) + exit elapsed:0.001959 code:0 + atexit elapsed:0.001997 code:0 +child_exit[3] pid:20303 code:0 elapsed:0.007564 +exit elapsed:3.868938 code:0 +atexit elapsed:3.868970 code:0 +---------------- + +Regions:: + + Regions can be use to time an interesting section of code. ++ +---------------- +void wt_status_collect(struct wt_status *s) +{ + trace2_region_enter("status", "worktrees", s->repo); + wt_status_collect_changes_worktree(s); + trace2_region_leave("status", "worktrees", s->repo); + + trace2_region_enter("status", "index", s->repo); + wt_status_collect_changes_index(s); + trace2_region_leave("status", "index", s->repo); + + trace2_region_enter("status", "untracked", s->repo); + wt_status_collect_untracked(s); + trace2_region_leave("status", "untracked", s->repo); +} + +void wt_status_print(struct wt_status *s) +{ + trace2_region_enter("status", "print", s->repo); + switch (s->status_format) { + ... + } + trace2_region_leave("status", "print", s->repo); +} +---------------- ++ +In this example, scanning for untracked files ran from +0.012568 to ++0.027149 (since the process started) and took 0.014581 seconds. ++ +---------------- +$ export GIT_TR2_PERF_BRIEF=1 +$ export GIT_TR2_PERF=~/log.perf +$ git status +... + +$ cat ~/log.perf +d0 | main | version | | | | | 2.20.1.160.g5676107ecd.dirty +d0 | main | start | | | | | git status +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw +d0 | main | cmd_name | | | | | status (status) +... +d0 | main | region_enter | r1 | 0.010988 | | status | label:worktrees +d0 | main | region_leave | r1 | 0.011236 | 0.000248 | status | label:worktrees +d0 | main | region_enter | r1 | 0.011260 | | status | label:index +d0 | main | region_leave | r1 | 0.012542 | 0.001282 | status | label:index +d0 | main | region_enter | r1 | 0.012568 | | status | label:untracked +d0 | main | region_leave | r1 | 0.027149 | 0.014581 | status | label:untracked +d0 | main | region_enter | r1 | 0.027411 | | status | label:print +d0 | main | region_leave | r1 | 0.028741 | 0.001330 | status | label:print +d0 | main | exit | | 0.028778 | | | code:0 +d0 | main | atexit | | 0.028809 | | | code:0 +---------------- ++ +Regions may be nested. This causes messages to be indented in the +PERF target, for example. +Elapsed times are relative to the start of the correpsonding nesting +level as expected. For example, if we add region message to: ++ +---------------- +static enum path_treatment read_directory_recursive(struct dir_struct *dir, + struct index_state *istate, const char *base, int baselen, + struct untracked_cache_dir *untracked, int check_only, + int stop_at_first_file, const struct pathspec *pathspec) +{ + enum path_treatment state, subdir_state, dir_state = path_none; + + trace2_region_enter_printf("dir", "read_recursive", NULL, "%.*s", baselen, base); + ... + trace2_region_leave_printf("dir", "read_recursive", NULL, "%.*s", baselen, base); + return dir_state; +} +---------------- ++ +We can further investigate the time spent scanning for untracked files. ++ +---------------- +$ export GIT_TR2_PERF_BRIEF=1 +$ export GIT_TR2_PERF=~/log.perf +$ git status +... +$ cat ~/log.perf +d0 | main | version | | | | | 2.20.1.162.gb4ccea44db.dirty +d0 | main | start | | | | | git status +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw +d0 | main | cmd_name | | | | | status (status) +... +d0 | main | region_enter | r1 | 0.015047 | | status | label:untracked +d0 | main | region_enter | | 0.015132 | | dir | ..label:read_recursive +d0 | main | region_enter | | 0.016341 | | dir | ....label:read_recursive vcs-svn/ +d0 | main | region_leave | | 0.016422 | 0.000081 | dir | ....label:read_recursive vcs-svn/ +d0 | main | region_enter | | 0.016446 | | dir | ....label:read_recursive xdiff/ +d0 | main | region_leave | | 0.016522 | 0.000076 | dir | ....label:read_recursive xdiff/ +d0 | main | region_enter | | 0.016612 | | dir | ....label:read_recursive git-gui/ +d0 | main | region_enter | | 0.016698 | | dir | ......label:read_recursive git-gui/po/ +d0 | main | region_enter | | 0.016810 | | dir | ........label:read_recursive git-gui/po/glossary/ +d0 | main | region_leave | | 0.016863 | 0.000053 | dir | ........label:read_recursive git-gui/po/glossary/ +... +d0 | main | region_enter | | 0.031876 | | dir | ....label:read_recursive builtin/ +d0 | main | region_leave | | 0.032270 | 0.000394 | dir | ....label:read_recursive builtin/ +d0 | main | region_leave | | 0.032414 | 0.017282 | dir | ..label:read_recursive +d0 | main | region_leave | r1 | 0.032454 | 0.017407 | status | label:untracked +... +d0 | main | exit | | 0.034279 | | | code:0 +d0 | main | atexit | | 0.034322 | | | code:0 +---------------- ++ +Trace2 regions are similar to the existing trace_performance_enter() +and trace_performance_leave() routines, but are thread safe and +maintain per-thread stacks of timers. + +Data Messages:: + + Data messages added to a region. ++ +---------------- +int read_index_from(struct index_state *istate, const char *path, + const char *gitdir) +{ + trace2_region_enter_printf("index", "do_read_index", the_repository, "%s", path); + + ... + + trace2_data_intmax("index", the_repository, "read/version", istate->version); + trace2_data_intmax("index", the_repository, "read/cache_nr", istate->cache_nr); + + trace2_region_leave_printf("index", "do_read_index", the_repository, "%s", path); +} +---------------- ++ +This example shows that the index contained 3552 entries. ++ +---------------- +$ export GIT_TR2_PERF_BRIEF=1 +$ export GIT_TR2_PERF=~/log.perf +$ git status +... +$ cat ~/log.perf +d0 | main | version | | | | | 2.20.1.156.gf9916ae094.dirty +d0 | main | start | | | | | git status +d0 | main | def_repo | r1 | | | | worktree:/Users/jeffhost/work/gfw +d0 | main | cmd_name | | | | | status (status) +d0 | main | region_enter | r1 | 0.001791 | | index | label:do_read_index .git/index +d0 | main | data | r1 | 0.002494 | 0.000703 | index | ..read/version:2 +d0 | main | data | r1 | 0.002520 | 0.000729 | index | ..read/cache_nr:3552 +d0 | main | region_leave | r1 | 0.002539 | 0.000748 | index | label:do_read_index .git/index +... +---------------- + +Thread Events:: + + Thread messages added to a thread-proc. ++ +For example, the multithreaded preload-index code can be +instrumented with a region around the thread pool and then +per-thread start and exit events within the threadproc. ++ +---------------- +static void *preload_thread(void *_data) +{ + // start the per-thread clock and emit a message. + trace2_thread_start("preload_thread"); + + // report which chunk of the array this thread was assigned. + trace2_data_intmax("index", the_repository, "offset", p->offset); + trace2_data_intmax("index", the_repository, "count", nr); + + do { + ... + } while (--nr > 0); + ... + + // report elapsed time taken by this thread. + trace2_thread_exit(); + return NULL; +} + +void preload_index(struct index_state *index, + const struct pathspec *pathspec, + unsigned int refresh_flags) +{ + trace2_region_enter("index", "preload", the_repository); + + for (i = 0; i < threads; i++) { + ... /* create thread */ + } + + for (i = 0; i < threads; i++) { + ... /* join thread */ + } + + trace2_region_leave("index", "preload", the_repository); +} +---------------- ++ +In this example preload_index() was executed by the `main` thread +and started the `preload` region. Seven threads, named +`th01:preload_thread` through `th07:preload_thread`, were started. +Events from each thread are atomically appended to the shared target +stream as they occur so they may appear in random order with respect +other threads. Finally, the main thread waits for the threads to +finish and leaves the region. ++ +Data events are tagged with the active thread name. They are used +to report the per-thread parameters. ++ +---------------- +$ export GIT_TR2_PERF_BRIEF=1 +$ export GIT_TR2_PERF=~/log.perf +$ git status +... +$ cat ~/log.perf +... +d0 | main | region_enter | r1 | 0.002595 | | index | label:preload +d0 | th01:preload_thread | thread_start | | 0.002699 | | | +d0 | th02:preload_thread | thread_start | | 0.002721 | | | +d0 | th01:preload_thread | data | r1 | 0.002736 | 0.000037 | index | offset:0 +d0 | th02:preload_thread | data | r1 | 0.002751 | 0.000030 | index | offset:2032 +d0 | th03:preload_thread | thread_start | | 0.002711 | | | +d0 | th06:preload_thread | thread_start | | 0.002739 | | | +d0 | th01:preload_thread | data | r1 | 0.002766 | 0.000067 | index | count:508 +d0 | th06:preload_thread | data | r1 | 0.002856 | 0.000117 | index | offset:2540 +d0 | th03:preload_thread | data | r1 | 0.002824 | 0.000113 | index | offset:1016 +d0 | th04:preload_thread | thread_start | | 0.002710 | | | +d0 | th02:preload_thread | data | r1 | 0.002779 | 0.000058 | index | count:508 +d0 | th06:preload_thread | data | r1 | 0.002966 | 0.000227 | index | count:508 +d0 | th07:preload_thread | thread_start | | 0.002741 | | | +d0 | th07:preload_thread | data | r1 | 0.003017 | 0.000276 | index | offset:3048 +d0 | th05:preload_thread | thread_start | | 0.002712 | | | +d0 | th05:preload_thread | data | r1 | 0.003067 | 0.000355 | index | offset:1524 +d0 | th05:preload_thread | data | r1 | 0.003090 | 0.000378 | index | count:508 +d0 | th07:preload_thread | data | r1 | 0.003037 | 0.000296 | index | count:504 +d0 | th03:preload_thread | data | r1 | 0.002971 | 0.000260 | index | count:508 +d0 | th04:preload_thread | data | r1 | 0.002983 | 0.000273 | index | offset:508 +d0 | th04:preload_thread | data | r1 | 0.007311 | 0.004601 | index | count:508 +d0 | th05:preload_thread | thread_exit | | 0.008781 | 0.006069 | | +d0 | th01:preload_thread | thread_exit | | 0.009561 | 0.006862 | | +d0 | th03:preload_thread | thread_exit | | 0.009742 | 0.007031 | | +d0 | th06:preload_thread | thread_exit | | 0.009820 | 0.007081 | | +d0 | th02:preload_thread | thread_exit | | 0.010274 | 0.007553 | | +d0 | th07:preload_thread | thread_exit | | 0.010477 | 0.007736 | | +d0 | th04:preload_thread | thread_exit | | 0.011657 | 0.008947 | | +d0 | main | region_leave | r1 | 0.011717 | 0.009122 | index | label:preload +... +d0 | main | exit | | 0.029996 | | | code:0 +d0 | main | atexit | | 0.030027 | | | code:0 +---------------- ++ +In this example, the preload region took 0.009122 seconds. The 7 threads +took between 0.006069 and 0.008947 seconds to work on their portion of +the index. Thread "th01" worked on 508 items at offset 0. Thread "th02" +worked on 508 items at offset 2032. Thread "th04" worked on 508 itemts +at offset 508. ++ +This example also shows that thread names are assigned in a racy manner +as each thread starts and allocates TLS storage. + +== Future Work + +=== Relationship to the Existing Trace Api (api-trace.txt) + +There are a few issues to resolve before we can completely +switch to Trace2. + +* Updating existing tests that assume GIT_TRACE format messages. + +* How to best handle custom GIT_TRACE_<key> messages? + +** The GIT_TRACE_<key> mechanism allows each <key> to write to a +different file (in addition to just stderr). + +** Do we want to maintain that ability or simply write to the existing +Trace2 targets (and convert <key> to a "category"). diff --git a/Documentation/technical/protocol-capabilities.txt b/Documentation/technical/protocol-capabilities.txt index 332d209b58..2b267c0da6 100644 --- a/Documentation/technical/protocol-capabilities.txt +++ b/Documentation/technical/protocol-capabilities.txt @@ -1,6 +1,10 @@ Git Protocol Capabilities ========================= +NOTE: this document describes capabilities for versions 0 and 1 of the pack +protocol. For version 2, please refer to the link:protocol-v2.html[protocol-v2] +doc. + Servers SHOULD support all capabilities defined in this document. On the very first line of the initial server response of either @@ -172,6 +176,20 @@ agent strings are purely informative for statistics and debugging purposes, and MUST NOT be used to programmatically assume the presence or absence of particular features. +symref +------ + +This parameterized capability is used to inform the receiver which symbolic ref +points to which ref; for example, "symref=HEAD:refs/heads/master" tells the +receiver that HEAD points to master. This capability can be repeated to +represent multiple symrefs. + +Servers SHOULD include this capability for the HEAD symref if it is one of the +refs being sent. + +Clients MAY use the parameters from this capability to select the proper initial +branch when cloning a repository. + shallow ------- diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 13f835f9cd..3fc4065da2 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.21.0 +DEF_VER=v2.21.GIT LF=' ' @@ -479,7 +479,11 @@ all:: # # Define DEVELOPER to enable more compiler warnings. Compiler version # and family are auto detected, but could be overridden by defining -# COMPILER_FEATURES (see config.mak.dev) +# COMPILER_FEATURES (see config.mak.dev). You can still set +# CFLAGS="..." in combination with DEVELOPER enables, whether that's +# for tweaking something unrelated (e.g. optimization level), or for +# selectively overriding something DEVELOPER or one of the DEVOPTS +# (see just below) brings in. # # When DEVELOPER is set, DEVOPTS can be used to control compiler # options. This variable contains keywords separated by @@ -506,17 +510,8 @@ GIT-VERSION-FILE: FORCE @$(SHELL_PATH) ./GIT-VERSION-GEN -include GIT-VERSION-FILE -# CFLAGS and LDFLAGS are for the users to override from the command line. - -CFLAGS = -g -O2 -Wall -LDFLAGS = -ALL_CFLAGS = $(CPPFLAGS) $(CFLAGS) -ALL_LDFLAGS = $(LDFLAGS) -STRIP ?= strip - -# Create as necessary, replace existing, make ranlib unneeded. -ARFLAGS = rcs - +# Set our default configuration. +# # Among the variables below, these: # gitexecdir # template_dir @@ -561,6 +556,7 @@ perllibdir_relative = $(patsubst $(prefix)/%,%,$(perllibdir)) export prefix bindir sharedir sysconfdir gitwebdir perllibdir localedir +# Set our default programs CC = cc AR = ar RM = rm -f @@ -573,29 +569,14 @@ TCLTK_PATH = wish XGETTEXT = xgettext MSGFMT = msgfmt CURL_CONFIG = curl-config -PTHREAD_LIBS = -lpthread -PTHREAD_CFLAGS = GCOV = gcov +STRIP = strip SPATCH = spatch export TCL_PATH TCLTK_PATH -# user customisation variable for 'sparse' target -SPARSE_FLAGS ?= -# internal/platform customisation variable for 'sparse' -SP_EXTRA_FLAGS = - -SPATCH_FLAGS = --all-includes --patch . - - - -### --- END CONFIGURATION SECTION --- - -# Those must not be GNU-specific; they are shared with perl/ which may -# be built by a different compiler. (Note that this is an artifact now -# but it still might be nice to keep that distinction.) -BASIC_CFLAGS = -I. -BASIC_LDFLAGS = +# Set our default LIBS variables +PTHREAD_LIBS = -lpthread # Guard against environment variables BUILTIN_OBJS = @@ -773,6 +754,7 @@ TEST_BUILTINS_OBJS += test-string-list.o TEST_BUILTINS_OBJS += test-submodule-config.o TEST_BUILTINS_OBJS += test-submodule-nested-repo-config.o TEST_BUILTINS_OBJS += test-subprocess.o +TEST_BUILTINS_OBJS += test-trace2.o TEST_BUILTINS_OBJS += test-urlmatch-normalization.o TEST_BUILTINS_OBJS += test-xml-encode.o TEST_BUILTINS_OBJS += test-wildmatch.o @@ -841,7 +823,8 @@ VCSSVN_LIB = vcs-svn/lib.a GENERATED_H += command-list.h -LIB_H = $(shell $(FIND) . \ +LIB_H := $(shell git ls-files '*.h' ':!t/' ':!Documentation/' 2>/dev/null || \ + $(FIND) . \ -name .git -prune -o \ -name t -prune -o \ -name Documentation -prune -o \ @@ -1017,6 +1000,16 @@ LIB_OBJS += tempfile.o LIB_OBJS += thread-utils.o LIB_OBJS += tmp-objdir.o LIB_OBJS += trace.o +LIB_OBJS += trace2.o +LIB_OBJS += trace2/tr2_cfg.o +LIB_OBJS += trace2/tr2_cmd_name.o +LIB_OBJS += trace2/tr2_dst.o +LIB_OBJS += trace2/tr2_sid.o +LIB_OBJS += trace2/tr2_tbuf.o +LIB_OBJS += trace2/tr2_tgt_event.o +LIB_OBJS += trace2/tr2_tgt_normal.o +LIB_OBJS += trace2/tr2_tgt_perf.o +LIB_OBJS += trace2/tr2_tls.o LIB_OBJS += trailer.o LIB_OBJS += transport.o LIB_OBJS += transport-helper.o @@ -1165,6 +1158,25 @@ ifeq ($(wildcard sha1collisiondetection/lib/sha1.h),sha1collisiondetection/lib/s DC_SHA1_SUBMODULE = auto endif +# Set CFLAGS, LDFLAGS and other *FLAGS variables. These might be +# tweaked by config.* below as well as the command-line, both of +# which'll override these defaults. +CFLAGS = -g -O2 -Wall +LDFLAGS = +BASIC_CFLAGS = -I. +BASIC_LDFLAGS = + +# library flags +ARFLAGS = rcs +PTHREAD_CFLAGS = + +# For the 'sparse' target +SPARSE_FLAGS ?= +SP_EXTRA_FLAGS = + +# For the 'coccicheck' target +SPATCH_FLAGS = --all-includes --patch . + include config.mak.uname -include config.mak.autogen -include config.mak @@ -1173,6 +1185,9 @@ ifdef DEVELOPER include config.mak.dev endif +ALL_CFLAGS = $(DEVELOPER_CFLAGS) $(CPPFLAGS) $(CFLAGS) +ALL_LDFLAGS = $(LDFLAGS) + comma := , empty := space := $(empty) $(empty) @@ -1596,7 +1611,9 @@ ifdef NO_INET_PTON LIB_OBJS += compat/inet_pton.o BASIC_CFLAGS += -DNO_INET_PTON endif -ifndef NO_UNIX_SOCKETS +ifdef NO_UNIX_SOCKETS + BASIC_CFLAGS += -DNO_UNIX_SOCKETS +else LIB_OBJS += unix-socket.o PROGRAM_OBJS += credential-cache.o PROGRAM_OBJS += credential-cache--daemon.o @@ -2363,7 +2380,7 @@ else # should _not_ be included here, since they are necessary even when # building an object for the first time. -$(OBJECTS): $(LIB_H) +$(OBJECTS): $(LIB_H) $(GENERATED_H) endif exec-cmd.sp exec-cmd.s exec-cmd.o: GIT-PREFIX @@ -2736,7 +2753,10 @@ $(SP_OBJ): %.sp: %.c GIT-CFLAGS FORCE sparse: $(SP_OBJ) GEN_HDRS := command-list.h unicode-width.h -EXCEPT_HDRS := $(GEN_HDRS) compat% xdiff% +EXCEPT_HDRS := $(GEN_HDRS) compat/% xdiff/% +ifndef GCRYPT_SHA256 + EXCEPT_HDRS += sha256/gcrypt.h +endif CHK_HDRS = $(filter-out $(EXCEPT_HDRS),$(patsubst ./%,%,$(LIB_H))) HCO = $(patsubst %.h,%.hco,$(CHK_HDRS)) @@ -1 +1 @@ -Documentation/RelNotes/2.21.0.txt
\ No newline at end of file +Documentation/RelNotes/2.22.0.txt
\ No newline at end of file @@ -56,6 +56,10 @@ static int parse_whitespace_option(struct apply_state *state, const char *option state->ws_error_action = correct_ws_error; return 0; } + /* + * Please update $__git_whitespacelist in git-completion.bash + * when you add new options. + */ return error(_("unrecognized whitespace option '%s'"), option); } @@ -431,14 +431,14 @@ fail_return: * Like info/exclude and .gitignore, the attribute information can * come from many places. * - * (1) .gitattribute file of the same directory; - * (2) .gitattribute file of the parent directory if (1) does not have + * (1) .gitattributes file of the same directory; + * (2) .gitattributes file of the parent directory if (1) does not have * any match; this goes recursively upwards, just like .gitignore. * (3) $GIT_DIR/info/attributes, which overrides both of the above. * * In the same file, later entries override the earlier match, so in the * global list, we would have entries from info/attributes the earliest - * (reading the file from top to bottom), .gitattribute of the root + * (reading the file from top to bottom), .gitattributes of the root * directory (again, reading the file from top to bottom) down to the * current directory, and then scan the list backwards to find the first match. * This is exactly the same as what is_excluded() does in dir.c to deal with @@ -899,7 +899,7 @@ static void prepare_attr_stack(const struct index_state *istate, * set of attribute definitions, followed by the contents * of $(prefix)/etc/gitattributes and a file specified by * core.attributesfile. Then, contents from - * .gitattribute files from directories closer to the + * .gitattributes files from directories closer to the * root to the ones in deeper directories are pushed * to the stack. Finally, at the very top of the stack * we always keep the contents of $GIT_DIR/info/attributes. @@ -204,7 +204,8 @@ static struct commit *fake_working_tree_commit(struct repository *r, origin = make_origin(commit, path); - ident = fmt_ident("Not Committed Yet", "not.committed.yet", NULL, 0); + ident = fmt_ident("Not Committed Yet", "not.committed.yet", + WANT_BLANK_IDENT, NULL, 0); strbuf_addstr(&msg, "tree 0000000000000000000000000000000000000000\n"); for (parent = commit->parents; parent; parent = parent->next) strbuf_addf(&msg, "parent %s\n", diff --git a/builtin/am.c b/builtin/am.c index 58a2aef28b..4fb107a9d1 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -453,6 +453,7 @@ static int run_post_rewrite_hook(const struct am_state *state) cp.in = xopen(am_path(state, "rewritten"), O_RDONLY); cp.stdout_to_stderr = 1; + cp.trace2_hook_name = "post-rewrite"; ret = run_command(&cp); @@ -1579,6 +1580,7 @@ static void do_commit(const struct am_state *state) } author = fmt_ident(state->author_name, state->author_email, + WANT_AUTHOR_IDENT, state->ignore_date ? NULL : state->author_date, IDENT_STRICT); @@ -2119,6 +2121,10 @@ static int parse_opt_patchformat(const struct option *opt, const char *arg, int *opt_value = PATCH_FORMAT_HG; else if (!strcmp(arg, "mboxrd")) *opt_value = PATCH_FORMAT_MBOXRD; + /* + * Please update $__git_patchformat in git-completion.bash + * when you add new options + */ else return error(_("Invalid value for --patch-format: %s"), arg); return 0; diff --git a/builtin/blame.c b/builtin/blame.c index 581de0d832..177c1022a0 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -814,7 +814,7 @@ int cmd_blame(int argc, const char **argv, const char *prefix) * and are only included here to get included in the "-h" * output: */ - { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental heuristic to improve diffs"), PARSE_OPT_NOARG, parse_opt_unknown_cb }, + { OPTION_LOWLEVEL_CALLBACK, 0, "indent-heuristic", NULL, NULL, N_("Use an experimental heuristic to improve diffs"), PARSE_OPT_NOARG, NULL, 0, parse_opt_unknown_cb }, OPT_BIT(0, "minimal", &xdl_opts, N_("Spend extra cycles to find better match"), XDF_NEED_MINIMAL), OPT_STRING('S', NULL, &revs_file, N_("file"), N_("Use revisions from <file> instead of calling git-rev-list")), diff --git a/builtin/branch.c b/builtin/branch.c index 1be727209b..4c83055730 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -443,6 +443,21 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin free(to_free); } +static void print_current_branch_name(void) +{ + int flags; + const char *refname = resolve_ref_unsafe("HEAD", 0, NULL, &flags); + const char *shortname; + if (!refname) + die(_("could not resolve HEAD")); + else if (!(flags & REF_ISSYMREF)) + return; + else if (skip_prefix(refname, "refs/heads/", &shortname)) + puts(shortname); + else + die(_("HEAD (%s) points outside of refs/heads/"), refname); +} + static void reject_rebase_or_bisect_branch(const char *target) { struct worktree **worktrees = get_worktrees(0); @@ -581,6 +596,7 @@ static int edit_branch_description(const char *branch_name) int cmd_branch(int argc, const char **argv, const char *prefix) { int delete = 0, rename = 0, copy = 0, force = 0, list = 0; + int show_current = 0; int reflog = 0, edit_description = 0; int quiet = 0, unset_upstream = 0; const char *new_upstream = NULL; @@ -620,6 +636,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) OPT_BIT('c', "copy", ©, N_("copy a branch and its reflog"), 1), OPT_BIT('C', NULL, ©, N_("copy a branch, even if target exists"), 2), OPT_BOOL('l', "list", &list, N_("list branch names")), + OPT_BOOL(0, "show-current", &show_current, N_("show current branch name")), OPT_BOOL(0, "create-reflog", &reflog, N_("create the branch's reflog")), OPT_BOOL(0, "edit-description", &edit_description, N_("edit the description for the branch")), @@ -662,14 +679,15 @@ int cmd_branch(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, options, builtin_branch_usage, 0); - if (!delete && !rename && !copy && !edit_description && !new_upstream && !unset_upstream && argc == 0) + if (!delete && !rename && !copy && !edit_description && !new_upstream && + !show_current && !unset_upstream && argc == 0) list = 1; if (filter.with_commit || filter.merge != REF_FILTER_MERGED_NONE || filter.points_at.nr || filter.no_commit) list = 1; - if (!!delete + !!rename + !!copy + !!new_upstream + + if (!!delete + !!rename + !!copy + !!new_upstream + !!show_current + list + unset_upstream > 1) usage_with_options(builtin_branch_usage, options); @@ -697,6 +715,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (!argc) die(_("branch name required")); return delete_branches(argc, argv, delete > 1, filter.kind, quiet); + } else if (show_current) { + print_current_branch_name(); + return 0; } else if (list) { /* git branch --local also shows HEAD when it is detached */ if ((filter.kind & FILTER_REFS_BRANCHES) && filter.detached) diff --git a/builtin/checkout.c b/builtin/checkout.c index 24b8593b93..0e6037b296 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -46,6 +46,7 @@ struct checkout_opts { int ignore_other_worktrees; int show_progress; int count_checkout_paths; + int overlay_mode; /* * If new checkout options are added, skip_merge_working_tree * should be updated accordingly. @@ -135,7 +136,8 @@ static int skip_same_name(const struct cache_entry *ce, int pos) return pos; } -static int check_stage(int stage, const struct cache_entry *ce, int pos) +static int check_stage(int stage, const struct cache_entry *ce, int pos, + int overlay_mode) { while (pos < active_nr && !strcmp(active_cache[pos]->name, ce->name)) { @@ -143,6 +145,8 @@ static int check_stage(int stage, const struct cache_entry *ce, int pos) return 0; pos++; } + if (!overlay_mode) + return 0; if (stage == 2) return error(_("path '%s' does not have our version"), ce->name); else @@ -168,7 +172,8 @@ static int check_stages(unsigned stages, const struct cache_entry *ce, int pos) } static int checkout_stage(int stage, const struct cache_entry *ce, int pos, - const struct checkout *state, int *nr_checkouts) + const struct checkout *state, int *nr_checkouts, + int overlay_mode) { while (pos < active_nr && !strcmp(active_cache[pos]->name, ce->name)) { @@ -177,6 +182,10 @@ static int checkout_stage(int stage, const struct cache_entry *ce, int pos, NULL, nr_checkouts); pos++; } + if (!overlay_mode) { + unlink_entry(ce); + return 0; + } if (stage == 2) return error(_("path '%s' does not have our version"), ce->name); else @@ -251,6 +260,59 @@ static int checkout_merged(int pos, const struct checkout *state, int *nr_checko return status; } +static void mark_ce_for_checkout_overlay(struct cache_entry *ce, + char *ps_matched, + const struct checkout_opts *opts) +{ + ce->ce_flags &= ~CE_MATCHED; + if (!opts->ignore_skipworktree && ce_skip_worktree(ce)) + return; + if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) + /* + * "git checkout tree-ish -- path", but this entry + * is in the original index but is not in tree-ish + * or does not match the pathspec; it will not be + * checked out to the working tree. We will not do + * anything to this entry at all. + */ + return; + /* + * Either this entry came from the tree-ish we are + * checking the paths out of, or we are checking out + * of the index. + * + * If it comes from the tree-ish, we already know it + * matches the pathspec and could just stamp + * CE_MATCHED to it from update_some(). But we still + * need ps_matched and read_tree_recursive (and + * eventually tree_entry_interesting) cannot fill + * ps_matched yet. Once it can, we can avoid calling + * match_pathspec() for _all_ entries when + * opts->source_tree != NULL. + */ + if (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched)) + ce->ce_flags |= CE_MATCHED; +} + +static void mark_ce_for_checkout_no_overlay(struct cache_entry *ce, + char *ps_matched, + const struct checkout_opts *opts) +{ + ce->ce_flags &= ~CE_MATCHED; + if (!opts->ignore_skipworktree && ce_skip_worktree(ce)) + return; + if (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched)) { + ce->ce_flags |= CE_MATCHED; + if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) + /* + * In overlay mode, but the path is not in + * tree-ish, which means we should remove it + * from the index and the working tree. + */ + ce->ce_flags |= CE_REMOVE | CE_WT_REMOVE; + } +} + static int checkout_paths(const struct checkout_opts *opts, const char *revision) { @@ -263,6 +325,8 @@ static int checkout_paths(const struct checkout_opts *opts, struct lock_file lock_file = LOCK_INIT; int nr_checkouts = 0, nr_unmerged = 0; + trace2_cmd_mode(opts->patch_mode ? "patch" : "path"); + if (opts->track != BRANCH_TRACK_UNSPECIFIED) die(_("'%s' cannot be used with updating paths"), "--track"); @@ -302,37 +366,15 @@ static int checkout_paths(const struct checkout_opts *opts, * Make sure all pathspecs participated in locating the paths * to be checked out. */ - for (pos = 0; pos < active_nr; pos++) { - struct cache_entry *ce = active_cache[pos]; - ce->ce_flags &= ~CE_MATCHED; - if (!opts->ignore_skipworktree && ce_skip_worktree(ce)) - continue; - if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) - /* - * "git checkout tree-ish -- path", but this entry - * is in the original index; it will not be checked - * out to the working tree and it does not matter - * if pathspec matched this entry. We will not do - * anything to this entry at all. - */ - continue; - /* - * Either this entry came from the tree-ish we are - * checking the paths out of, or we are checking out - * of the index. - * - * If it comes from the tree-ish, we already know it - * matches the pathspec and could just stamp - * CE_MATCHED to it from update_some(). But we still - * need ps_matched and read_tree_recursive (and - * eventually tree_entry_interesting) cannot fill - * ps_matched yet. Once it can, we can avoid calling - * match_pathspec() for _all_ entries when - * opts->source_tree != NULL. - */ - if (ce_path_match(&the_index, ce, &opts->pathspec, ps_matched)) - ce->ce_flags |= CE_MATCHED; - } + for (pos = 0; pos < active_nr; pos++) + if (opts->overlay_mode) + mark_ce_for_checkout_overlay(active_cache[pos], + ps_matched, + opts); + else + mark_ce_for_checkout_no_overlay(active_cache[pos], + ps_matched, + opts); if (report_path_error(ps_matched, &opts->pathspec, opts->prefix)) { free(ps_matched); @@ -353,7 +395,7 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->force) { warning(_("path '%s' is unmerged"), ce->name); } else if (opts->writeout_stage) { - errs |= check_stage(opts->writeout_stage, ce, pos); + errs |= check_stage(opts->writeout_stage, ce, pos, opts->overlay_mode); } else if (opts->merge) { errs |= check_stages((1<<2) | (1<<3), ce, pos); } else { @@ -383,13 +425,16 @@ static int checkout_paths(const struct checkout_opts *opts, if (opts->writeout_stage) errs |= checkout_stage(opts->writeout_stage, ce, pos, - &state, &nr_checkouts); + &state, + &nr_checkouts, opts->overlay_mode); else if (opts->merge) errs |= checkout_merged(pos, &state, &nr_unmerged); pos = skip_same_name(ce, pos) - 1; } } + remove_marked_cache_entries(&the_index, 1); + remove_scheduled_dirs(); errs |= finish_delayed_checkout(&state, &nr_checkouts); if (opts->count_checkout_paths) { @@ -572,6 +617,11 @@ static int skip_merge_working_tree(const struct checkout_opts *opts, */ /* + * opts->overlay_mode cannot be used with switching branches so is + * not tested here + */ + + /* * If we aren't creating a new branch any changes or updates will * happen in the existing branch. Since that could only be updating * the index and working directory, we don't want to skip those steps @@ -966,6 +1016,9 @@ static int switch_branches(const struct checkout_opts *opts, void *path_to_free; struct object_id rev; int flag, writeout_error = 0; + + trace2_cmd_mode("branch"); + memset(&old_branch_info, 0, sizeof(old_branch_info)); old_branch_info.path = path_to_free = resolve_refdup("HEAD", 0, &rev, &flag); if (old_branch_info.path) @@ -1203,6 +1256,8 @@ static int switch_unborn_to_new_branch(const struct checkout_opts *opts) int status; struct strbuf branch_ref = STRBUF_INIT; + trace2_cmd_mode("unborn"); + if (!opts->new_branch) die(_("You are on a branch yet to be born")); strbuf_addf(&branch_ref, "refs/heads/%s", opts->new_branch); @@ -1224,6 +1279,10 @@ static int checkout_branch(struct checkout_opts *opts, die(_("'%s' cannot be used with switching branches"), "--patch"); + if (!opts->overlay_mode) + die(_("'%s' cannot be used with switching branches"), + "--no-overlay"); + if (opts->writeout_stage) die(_("'%s' cannot be used with switching branches"), "--ours/--theirs"); @@ -1312,6 +1371,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) "checkout", "control recursive updating of submodules", PARSE_OPT_OPTARG, option_parse_recurse_submodules_worktree_updater }, OPT_BOOL(0, "progress", &opts.show_progress, N_("force progress reporting")), + OPT_BOOL(0, "overlay", &opts.overlay_mode, N_("use overlay mode (default)")), OPT_END(), }; @@ -1320,6 +1380,7 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) opts.overwrite_ignore = 1; opts.prefix = prefix; opts.show_progress = -1; + opts.overlay_mode = -1; git_config(git_checkout_config, &opts); @@ -1344,6 +1405,9 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) if ((!!opts.new_branch + !!opts.new_branch_force + !!opts.new_orphan_branch) > 1) die(_("-b, -B and --orphan are mutually exclusive")); + if (opts.overlay_mode == 1 && opts.patch_mode) + die(_("-p and --overlay are mutually exclusive")); + /* * From here on, new_branch will contain the branch to be checked out, * and new_branch_force and new_orphan_branch will tell us which one of diff --git a/builtin/commit.c b/builtin/commit.c index 2986553d5f..f17537474a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -609,7 +609,8 @@ static void determine_author_info(struct strbuf *author_ident) set_ident_var(&date, strbuf_detach(&date_buf, NULL)); } - strbuf_addstr(author_ident, fmt_ident(name, email, date, IDENT_STRICT)); + strbuf_addstr(author_ident, fmt_ident(name, email, WANT_AUTHOR_IDENT, date, + IDENT_STRICT)); assert_split_ident(&author, author_ident); export_one("GIT_AUTHOR_NAME", author.name_begin, author.name_end, 0); export_one("GIT_AUTHOR_EMAIL", author.mail_begin, author.mail_end, 0); @@ -1038,6 +1039,10 @@ static void handle_untracked_files_arg(struct wt_status *s) s->show_untracked_files = SHOW_NORMAL_UNTRACKED_FILES; else if (!strcmp(untracked_files_arg, "all")) s->show_untracked_files = SHOW_ALL_UNTRACKED_FILES; + /* + * Please update $__git_untracked_file_modes in + * git-completion.bash when you add new options + */ else die(_("Invalid untracked files mode '%s'"), untracked_files_arg); } @@ -1179,6 +1184,10 @@ static int parse_and_validate_options(int argc, const char *argv[], else if (!strcmp(cleanup_arg, "scissors")) cleanup_mode = use_editor ? COMMIT_MSG_CLEANUP_SCISSORS : COMMIT_MSG_CLEANUP_SPACE; + /* + * Please update _git_commit() in git-completion.bash when you + * add new options. + */ else die(_("Invalid cleanup mode %s"), cleanup_arg); diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index a90681bcba..cb9ea79367 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -83,9 +83,13 @@ static int diff_tree_stdin(char *line) } static const char diff_tree_usage[] = -"git diff-tree [--stdin] [-m] [-c] [--cc] [-s] [-v] [--pretty] [-t] [-r] [--root] " +"git diff-tree [--stdin] [-m] [-c | --cc] [-s] [-v] [--pretty] [-t] [-r] [--root] " "[<common-diff-options>] <tree-ish> [<tree-ish>] [<path>...]\n" " -r diff recursively\n" +" -c show combined diff for merge commits\n" +" --cc show combined diff for merge commits removing uninteresting hunks\n" +" --combined-all-paths\n" +" show name of file in all parents for combined diffs\n" " --root include the initial commit as diff against /dev/null\n" COMMON_DIFF_OPTIONS_HELP; diff --git a/builtin/diff.c b/builtin/diff.c index 9f6109224b..53d4234ff4 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -338,21 +338,23 @@ int cmd_diff(int argc, const char **argv, const char *prefix) "--no-index" : "[--no-index]"); } - if (no_index) - /* If this is a no-index diff, just run it and exit there. */ - diff_no_index(the_repository, &rev, argc, argv); - - /* Otherwise, we are doing the usual "git" diff */ - rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; - /* Scale to real terminal size and respect statGraphWidth config */ + /* Set up defaults that will apply to both no-index and regular diffs. */ rev.diffopt.stat_width = -1; rev.diffopt.stat_graph_width = -1; - - /* Default to let external and textconv be used */ rev.diffopt.flags.allow_external = 1; rev.diffopt.flags.allow_textconv = 1; + /* If this is a no-index diff, just run it and exit there. */ + if (no_index) + diff_no_index(&rev, argc, argv); + + /* + * Otherwise, we are doing the usual "git" diff; set up any + * further defaults that apply to regular diffs. + */ + rev.diffopt.skip_stat_unmatch = !!diff_auto_refresh_index; + /* * Default to intent-to-add entries invisible in the * index. This makes them show up as new files in diff-files diff --git a/builtin/help.c b/builtin/help.c index 7739a5c155..e5590d7787 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -70,6 +70,10 @@ static enum help_format parse_help_format(const char *format) return HELP_FORMAT_INFO; if (!strcmp(format, "web") || !strcmp(format, "html")) return HELP_FORMAT_WEB; + /* + * Please update _git_config() in git-completion.bash when you + * add new help formats. + */ die(_("unrecognized help format '%s'"), format); } diff --git a/builtin/log.c b/builtin/log.c index 57869267d8..ab859f5904 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -84,6 +84,10 @@ static int parse_decoration_style(const char *value) return DECORATE_SHORT_REFS; else if (!strcmp(value, "auto")) return auto_decoration_style(); + /* + * Please update _git_log() in git-completion.bash when you + * add new decoration styles. + */ return -1; } @@ -1228,6 +1232,10 @@ static int thread_callback(const struct option *opt, const char *arg, int unset) *thread = THREAD_SHALLOW; else if (!strcmp(arg, "deep")) *thread = THREAD_DEEP; + /* + * Please update _git_formatpatch() in git-completion.bash + * when you add new options. + */ else return 1; return 0; diff --git a/builtin/merge.c b/builtin/merge.c index e47d77baee..5ce8946d39 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -113,12 +113,15 @@ static int option_parse_message(const struct option *opt, return 0; } -static int option_read_message(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result option_read_message(struct parse_opt_ctx_t *ctx, + const struct option *opt, + const char *arg_not_used, + int unset) { struct strbuf *buf = opt->value; const char *arg; + BUG_ON_OPT_ARG(arg_not_used); if (unset) BUG("-F cannot be negated"); @@ -262,7 +265,7 @@ static struct option builtin_merge_options[] = { option_parse_message), { OPTION_LOWLEVEL_CALLBACK, 'F', "file", &merge_msg, N_("path"), N_("read message from file"), PARSE_OPT_NONEG, - (parse_opt_cb *) option_read_message }, + NULL, 0, option_read_message }, OPT__VERBOSITY(&verbosity), OPT_BOOL(0, "abort", &abort_current_merge, N_("abort the current in-progress merge")), diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index a9fac7c128..a154fc29f6 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -33,6 +33,7 @@ #include "object-store.h" #include "dir.h" #include "midx.h" +#include "trace2.h" #define IN_PACK(obj) oe_in_pack(&to_pack, obj) #define SIZE(obj) oe_size(&to_pack, obj) @@ -3473,6 +3474,8 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) } } + trace2_region_enter("pack-objects", "enumerate-objects", + the_repository); prepare_packing_data(the_repository, &to_pack); if (progress) @@ -3487,12 +3490,23 @@ int cmd_pack_objects(int argc, const char **argv, const char *prefix) if (include_tag && nr_result) for_each_ref(add_ref_tag, NULL); stop_progress(&progress_state); + trace2_region_leave("pack-objects", "enumerate-objects", + the_repository); if (non_empty && !nr_result) return 0; - if (nr_result) + if (nr_result) { + trace2_region_enter("pack-objects", "prepare-pack", + the_repository); prepare_pack(window, depth); + trace2_region_leave("pack-objects", "prepare-pack", + the_repository); + } + + trace2_region_enter("pack-objects", "write-pack-file", the_repository); write_pack_file(); + trace2_region_leave("pack-objects", "write-pack-file", the_repository); + if (progress) fprintf_ln(stderr, _("Total %"PRIu32" (delta %"PRIu32")," diff --git a/builtin/pack-redundant.c b/builtin/pack-redundant.c index 11bc514566..68c1e547c2 100644 --- a/builtin/pack-redundant.c +++ b/builtin/pack-redundant.c @@ -32,14 +32,10 @@ static struct pack_list { struct pack_list *next; struct packed_git *pack; struct llist *unique_objects; - struct llist *all_objects; + struct llist *remaining_objects; + size_t all_objects_size; } *local_packs = NULL, *altodb_packs = NULL; -struct pll { - struct pll *next; - struct pack_list *pl; -}; - static struct llist_item *free_nodes; static inline void llist_item_put(struct llist_item *item) @@ -63,15 +59,6 @@ static inline struct llist_item *llist_item_get(void) return new_item; } -static void llist_free(struct llist *list) -{ - while ((list->back = list->front)) { - list->front = list->front->next; - llist_item_put(list->back); - } - free(list); -} - static inline void llist_init(struct llist **list) { *list = xmalloc(sizeof(struct llist)); @@ -254,6 +241,11 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2) struct llist_item *p1_hint = NULL, *p2_hint = NULL; const unsigned int hashsz = the_hash_algo->rawsz; + if (!p1->unique_objects) + p1->unique_objects = llist_copy(p1->remaining_objects); + if (!p2->unique_objects) + p2->unique_objects = llist_copy(p2->remaining_objects); + p1_base = p1->pack->index_data; p2_base = p2->pack->index_data; p1_base += 256 * 4 + ((p1->pack->index_version < 2) ? 4 : 8); @@ -285,78 +277,6 @@ static void cmp_two_packs(struct pack_list *p1, struct pack_list *p2) } } -static void pll_free(struct pll *l) -{ - struct pll *old; - struct pack_list *opl; - - while (l) { - old = l; - while (l->pl) { - opl = l->pl; - l->pl = opl->next; - free(opl); - } - l = l->next; - free(old); - } -} - -/* all the permutations have to be free()d at the same time, - * since they refer to each other - */ -static struct pll * get_permutations(struct pack_list *list, int n) -{ - struct pll *subset, *ret = NULL, *new_pll = NULL; - - if (list == NULL || pack_list_size(list) < n || n == 0) - return NULL; - - if (n == 1) { - while (list) { - new_pll = xmalloc(sizeof(*new_pll)); - new_pll->pl = NULL; - pack_list_insert(&new_pll->pl, list); - new_pll->next = ret; - ret = new_pll; - list = list->next; - } - return ret; - } - - while (list->next) { - subset = get_permutations(list->next, n - 1); - while (subset) { - new_pll = xmalloc(sizeof(*new_pll)); - new_pll->pl = subset->pl; - pack_list_insert(&new_pll->pl, list); - new_pll->next = ret; - ret = new_pll; - subset = subset->next; - } - list = list->next; - } - return ret; -} - -static int is_superset(struct pack_list *pl, struct llist *list) -{ - struct llist *diff; - - diff = llist_copy(list); - - while (pl) { - llist_sorted_difference_inplace(diff, pl->all_objects); - if (diff->size == 0) { /* we're done */ - llist_free(diff); - return 1; - } - pl = pl->next; - } - llist_free(diff); - return 0; -} - static size_t sizeof_union(struct packed_git *p1, struct packed_git *p2) { size_t ret = 0; @@ -421,14 +341,58 @@ static inline off_t pack_set_bytecount(struct pack_list *pl) return ret; } +static int cmp_remaining_objects(const void *a, const void *b) +{ + struct pack_list *pl_a = *((struct pack_list **)a); + struct pack_list *pl_b = *((struct pack_list **)b); + + if (pl_a->remaining_objects->size == pl_b->remaining_objects->size) { + /* have the same remaining_objects, big pack first */ + if (pl_a->all_objects_size == pl_b->all_objects_size) + return 0; + else if (pl_a->all_objects_size < pl_b->all_objects_size) + return 1; + else + return -1; + } else if (pl_a->remaining_objects->size < pl_b->remaining_objects->size) { + /* sort by remaining objects, more objects first */ + return 1; + } else { + return -1; + } +} + +/* Sort pack_list, greater size of remaining_objects first */ +static void sort_pack_list(struct pack_list **pl) +{ + struct pack_list **ary, *p; + int i; + size_t n = pack_list_size(*pl); + + if (n < 2) + return; + + /* prepare an array of packed_list for easier sorting */ + ary = xcalloc(n, sizeof(struct pack_list *)); + for (n = 0, p = *pl; p; p = p->next) + ary[n++] = p; + + QSORT(ary, n, cmp_remaining_objects); + + /* link them back again */ + for (i = 0; i < n - 1; i++) + ary[i]->next = ary[i + 1]; + ary[n - 1]->next = NULL; + *pl = ary[0]; + + free(ary); +} + + static void minimize(struct pack_list **min) { - struct pack_list *pl, *unique = NULL, - *non_unique = NULL, *min_perm = NULL; - struct pll *perm, *perm_all, *perm_ok = NULL, *new_perm; - struct llist *missing; - off_t min_perm_size = 0, perm_size; - int n; + struct pack_list *pl, *unique = NULL, *non_unique = NULL; + struct llist *missing, *unique_pack_objects; pl = local_packs; while (pl) { @@ -442,53 +406,41 @@ static void minimize(struct pack_list **min) missing = llist_copy(all_objects); pl = unique; while (pl) { - llist_sorted_difference_inplace(missing, pl->all_objects); + llist_sorted_difference_inplace(missing, pl->remaining_objects); pl = pl->next; } + *min = unique; + /* return if there are no objects missing from the unique set */ if (missing->size == 0) { - *min = unique; free(missing); return; } - /* find the permutations which contain all missing objects */ - for (n = 1; n <= pack_list_size(non_unique) && !perm_ok; n++) { - perm_all = perm = get_permutations(non_unique, n); - while (perm) { - if (is_superset(perm->pl, missing)) { - new_perm = xmalloc(sizeof(struct pll)); - memcpy(new_perm, perm, sizeof(struct pll)); - new_perm->next = perm_ok; - perm_ok = new_perm; - } - perm = perm->next; - } - if (perm_ok) - break; - pll_free(perm_all); - } - if (perm_ok == NULL) - die("Internal error: No complete sets found!"); - - /* find the permutation with the smallest size */ - perm = perm_ok; - while (perm) { - perm_size = pack_set_bytecount(perm->pl); - if (!min_perm_size || min_perm_size > perm_size) { - min_perm_size = perm_size; - min_perm = perm->pl; - } - perm = perm->next; - } - *min = min_perm; - /* add the unique packs to the list */ - pl = unique; + unique_pack_objects = llist_copy(all_objects); + llist_sorted_difference_inplace(unique_pack_objects, missing); + + /* remove unique pack objects from the non_unique packs */ + pl = non_unique; while (pl) { - pack_list_insert(min, pl); + llist_sorted_difference_inplace(pl->remaining_objects, unique_pack_objects); pl = pl->next; } + + while (non_unique) { + /* sort the non_unique packs, greater size of remaining_objects first */ + sort_pack_list(&non_unique); + if (non_unique->remaining_objects->size == 0) + break; + + pack_list_insert(min, non_unique); + + for (pl = non_unique->next; pl && pl->remaining_objects->size > 0; pl = pl->next) + llist_sorted_difference_inplace(pl->remaining_objects, non_unique->remaining_objects); + + non_unique = non_unique->next; + } } static void load_all_objects(void) @@ -500,7 +452,7 @@ static void load_all_objects(void) while (pl) { hint = NULL; - l = pl->all_objects->front; + l = pl->remaining_objects->front; while (l) { hint = llist_insert_sorted_unique(all_objects, l->oid, hint); @@ -511,7 +463,7 @@ static void load_all_objects(void) /* remove objects present in remote packs */ pl = altodb_packs; while (pl) { - llist_sorted_difference_inplace(all_objects, pl->all_objects); + llist_sorted_difference_inplace(all_objects, pl->remaining_objects); pl = pl->next; } } @@ -536,11 +488,10 @@ static void scan_alt_odb_packs(void) while (alt) { local = local_packs; while (local) { - llist_sorted_difference_inplace(local->unique_objects, - alt->all_objects); + llist_sorted_difference_inplace(local->remaining_objects, + alt->remaining_objects); local = local->next; } - llist_sorted_difference_inplace(all_objects, alt->all_objects); alt = alt->next; } } @@ -555,7 +506,7 @@ static struct pack_list * add_pack(struct packed_git *p) return NULL; l.pack = p; - llist_init(&l.all_objects); + llist_init(&l.remaining_objects); if (open_pack_index(p)) return NULL; @@ -564,11 +515,11 @@ static struct pack_list * add_pack(struct packed_git *p) base += 256 * 4 + ((p->index_version < 2) ? 4 : 8); step = the_hash_algo->rawsz + ((p->index_version < 2) ? 4 : 0); while (off < p->num_objects * step) { - llist_insert_back(l.all_objects, (const struct object_id *)(base + off)); + llist_insert_back(l.remaining_objects, (const struct object_id *)(base + off)); off += step; } - /* this list will be pruned in cmp_two_packs later */ - l.unique_objects = llist_copy(l.all_objects); + l.all_objects_size = l.remaining_objects->size; + l.unique_objects = NULL; if (p->pack_local) return pack_list_insert(&local_packs, &l); else @@ -603,7 +554,7 @@ static void load_all(void) int cmd_pack_redundant(int argc, const char **argv, const char *prefix) { int i; - struct pack_list *min, *red, *pl; + struct pack_list *min = NULL, *red, *pl; struct llist *ignore; struct object_id *oid; char buf[GIT_MAX_HEXSZ + 2]; /* hex hash + \n + \0 */ @@ -646,7 +597,6 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) load_all_objects(); - cmp_local_packs(); if (alt_odb) scan_alt_odb_packs(); @@ -663,10 +613,12 @@ int cmd_pack_redundant(int argc, const char **argv, const char *prefix) llist_sorted_difference_inplace(all_objects, ignore); pl = local_packs; while (pl) { - llist_sorted_difference_inplace(pl->unique_objects, ignore); + llist_sorted_difference_inplace(pl->remaining_objects, ignore); pl = pl->next; } + cmp_local_packs(); + minimize(&min); if (verbose) { diff --git a/builtin/prune-packed.c b/builtin/prune-packed.c index a9e7b552b9..48c5e78e33 100644 --- a/builtin/prune-packed.c +++ b/builtin/prune-packed.c @@ -63,6 +63,11 @@ int cmd_prune_packed(int argc, const char **argv, const char *prefix) argc = parse_options(argc, argv, prefix, prune_packed_options, prune_packed_usage, 0); + if (argc > 0) + usage_msg_opt(_("too many arguments"), + prune_packed_usage, + prune_packed_options); + prune_packed_objects(opts); return 0; } diff --git a/builtin/prune.c b/builtin/prune.c index 1ec9ddd751..97613eccb5 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -31,16 +31,39 @@ static int prune_tmp_file(const char *fullpath) return 0; } +static void perform_reachability_traversal(struct rev_info *revs) +{ + static int initialized; + struct progress *progress = NULL; + + if (initialized) + return; + + if (show_progress) + progress = start_delayed_progress(_("Checking connectivity"), 0); + mark_reachable_objects(revs, 1, expire, progress); + stop_progress(&progress); + initialized = 1; +} + +static int is_object_reachable(const struct object_id *oid, + struct rev_info *revs) +{ + struct object *obj; + + perform_reachability_traversal(revs); + + obj = lookup_object(the_repository, oid->hash); + return obj && (obj->flags & SEEN); +} + static int prune_object(const struct object_id *oid, const char *fullpath, void *data) { + struct rev_info *revs = data; struct stat st; - /* - * Do we know about this object? - * It must have been reachable - */ - if (lookup_object(the_repository, oid->hash)) + if (is_object_reachable(oid, revs)) return 0; if (lstat(fullpath, &st)) { @@ -102,7 +125,6 @@ static void remove_temporary_files(const char *path) int cmd_prune(int argc, const char **argv, const char *prefix) { struct rev_info revs; - struct progress *progress = NULL; int exclude_promisor_objects = 0; const struct option options[] = { OPT__DRY_RUN(&show_only, N_("do not remove, show only")), @@ -142,17 +164,13 @@ int cmd_prune(int argc, const char **argv, const char *prefix) if (show_progress == -1) show_progress = isatty(2); - if (show_progress) - progress = start_delayed_progress(_("Checking connectivity"), 0); if (exclude_promisor_objects) { fetch_if_missing = 0; revs.exclude_promisor_objects = 1; } - mark_reachable_objects(&revs, 1, expire, progress); - stop_progress(&progress); for_each_loose_file_in_objdir(get_object_directory(), prune_object, - prune_cruft, prune_subdir, NULL); + prune_cruft, prune_subdir, &revs); prune_packed_objects(show_only ? PRUNE_PACKED_DRY_RUN : 0); remove_temporary_files(get_object_directory()); @@ -160,8 +178,10 @@ int cmd_prune(int argc, const char **argv, const char *prefix) remove_temporary_files(s); free(s); - if (is_repository_shallow(the_repository)) + if (is_repository_shallow(the_repository)) { + perform_reachability_traversal(&revs); prune_shallow(show_only ? PRUNE_SHOW_ONLY : 0); + } return 0; } diff --git a/builtin/pull.c b/builtin/pull.c index 701d1473dc..33db889955 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -56,6 +56,10 @@ static enum rebase_type parse_config_rebase(const char *key, const char *value, return REBASE_MERGES; else if (!strcmp(value, "interactive") || !strcmp(value, "i")) return REBASE_INTERACTIVE; + /* + * Please update _git_config() in git-completion.bash when you + * add new rebase modes. + */ if (fatal) die(_("Invalid value for %s: %s"), key, value); diff --git a/builtin/rebase.c b/builtin/rebase.c index 7c7bc13e91..52114cbf0d 100644 --- a/builtin/rebase.c +++ b/builtin/rebase.c @@ -1027,6 +1027,14 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) ACTION_EDIT_TODO, ACTION_SHOW_CURRENT_PATCH, } action = NO_ACTION; + static const char *action_names[] = { N_("undefined"), + N_("continue"), + N_("skip"), + N_("abort"), + N_("quit"), + N_("edit_todo"), + N_("show_current_patch"), + NULL }; const char *gpg_sign = NULL; struct string_list exec = STRING_LIST_INIT_NODUP; const char *rebase_merges = NULL; @@ -1212,6 +1220,15 @@ int cmd_rebase(int argc, const char **argv, const char *prefix) die(_("The --edit-todo action can only be used during " "interactive rebase.")); + if (trace2_is_enabled()) { + if (is_interactive(&options)) + trace2_cmd_mode("interactive"); + else if (exec.nr) + trace2_cmd_mode("interactive-exec"); + else + trace2_cmd_mode(action_names[action]); + } + switch (action) { case ACTION_CONTINUE: { struct object_id head; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index d58b7750b6..29f165d8bd 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -694,6 +694,8 @@ static int run_and_feed_hook(const char *hook_name, feed_fn feed, proc.argv = argv; proc.in = -1; proc.stdout_to_stderr = 1; + proc.trace2_hook_name = hook_name; + if (feed_state->push_options) { int i; for (i = 0; i < feed_state->push_options->nr; i++) @@ -807,6 +809,7 @@ static int run_update_hook(struct command *cmd) proc.stdout_to_stderr = 1; proc.err = use_sideband ? -1 : 0; proc.argv = argv; + proc.trace2_hook_name = "update"; code = start_command(&proc); if (code) @@ -1190,6 +1193,7 @@ static void run_update_post_hook(struct command *commands) proc.no_stdin = 1; proc.stdout_to_stderr = 1; proc.err = use_sideband ? -1 : 0; + proc.trace2_hook_name = "post-update"; if (!start_command(&proc)) { if (use_sideband) @@ -1198,17 +1202,12 @@ static void run_update_post_hook(struct command *commands) } } -static void check_aliased_update(struct command *cmd, struct string_list *list) +static void check_aliased_update_internal(struct command *cmd, + struct string_list *list, + const char *dst_name, int flag) { - struct strbuf buf = STRBUF_INIT; - const char *dst_name; struct string_list_item *item; struct command *dst_cmd; - int flag; - - strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name); - dst_name = resolve_ref_unsafe(buf.buf, 0, NULL, &flag); - strbuf_release(&buf); if (!(flag & REF_ISSYMREF)) return; @@ -1247,6 +1246,18 @@ static void check_aliased_update(struct command *cmd, struct string_list *list) "inconsistent aliased update"; } +static void check_aliased_update(struct command *cmd, struct string_list *list) +{ + struct strbuf buf = STRBUF_INIT; + const char *dst_name; + int flag; + + strbuf_addf(&buf, "%s%s", get_git_namespace(), cmd->ref_name); + dst_name = resolve_ref_unsafe(buf.buf, 0, NULL, &flag); + check_aliased_update_internal(cmd, list, dst_name, flag); + strbuf_release(&buf); +} + static void check_aliased_updates(struct command *commands) { struct command *cmd; diff --git a/builtin/replace.c b/builtin/replace.c index 5b80b7f211..f5701629a8 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -82,6 +82,10 @@ static int list_replace_refs(const char *pattern, const char *format) data.format = REPLACE_FORMAT_MEDIUM; else if (!strcmp(format, "long")) data.format = REPLACE_FORMAT_LONG; + /* + * Please update _git_replace() in git-completion.bash when + * you add new format + */ else return error(_("invalid replace format '%s'\n" "valid formats are 'short', 'medium' and 'long'"), diff --git a/builtin/reset.c b/builtin/reset.c index 4d18a461fa..7882829a95 100644 --- a/builtin/reset.c +++ b/builtin/reset.c @@ -341,6 +341,7 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (patch_mode) { if (reset_type != NONE) die(_("--patch is incompatible with --{hard,mixed,soft}")); + trace2_cmd_mode("patch-interactive"); return run_add_interactive(rev, "--patch=reset", &pathspec); } @@ -357,6 +358,11 @@ int cmd_reset(int argc, const char **argv, const char *prefix) if (reset_type == NONE) reset_type = MIXED; /* by default */ + if (pathspec.nr) + trace2_cmd_mode("path"); + else + trace2_cmd_mode(reset_type_names[reset_type]); + if (reset_type != SOFT && (reset_type != MIXED || get_git_work_tree())) setup_work_tree(); diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index b80fc4ba3d..6bcc4f1bd7 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -1816,11 +1816,10 @@ static int update_submodules(struct submodule_update_clone *suc) { int i; - run_processes_parallel(suc->max_jobs, - update_clone_get_next_task, - update_clone_start_failure, - update_clone_task_finished, - suc); + run_processes_parallel_tr2(suc->max_jobs, update_clone_get_next_task, + update_clone_start_failure, + update_clone_task_finished, suc, "submodule", + "parallel/update"); /* * We saved the output and put it out all at once now. diff --git a/builtin/update-index.c b/builtin/update-index.c index 02ace602b9..1b6c42f748 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -848,14 +848,16 @@ static int parse_new_style_cacheinfo(const char *arg, return 0; } -static int cacheinfo_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result cacheinfo_callback( + struct parse_opt_ctx_t *ctx, const struct option *opt, + const char *arg, int unset) { struct object_id oid; unsigned int mode; const char *path; BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); if (!parse_new_style_cacheinfo(ctx->argv[1], &mode, &oid, &path)) { if (add_cacheinfo(mode, &oid, path, 0)) @@ -874,12 +876,14 @@ static int cacheinfo_callback(struct parse_opt_ctx_t *ctx, return 0; } -static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result stdin_cacheinfo_callback( + struct parse_opt_ctx_t *ctx, const struct option *opt, + const char *arg, int unset) { int *nul_term_line = opt->value; BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); @@ -888,12 +892,14 @@ static int stdin_cacheinfo_callback(struct parse_opt_ctx_t *ctx, return 0; } -static int stdin_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result stdin_callback( + struct parse_opt_ctx_t *ctx, const struct option *opt, + const char *arg, int unset) { int *read_from_stdin = opt->value; BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); if (ctx->argc != 1) return error("option '%s' must be the last argument", opt->long_name); @@ -901,13 +907,15 @@ static int stdin_callback(struct parse_opt_ctx_t *ctx, return 0; } -static int unresolve_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result unresolve_callback( + struct parse_opt_ctx_t *ctx, const struct option *opt, + const char *arg, int unset) { int *has_errors = opt->value; const char *prefix = startup_info->prefix; BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); /* consume remaining arguments. */ *has_errors = do_unresolve(ctx->argc, ctx->argv, @@ -920,13 +928,15 @@ static int unresolve_callback(struct parse_opt_ctx_t *ctx, return 0; } -static int reupdate_callback(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset) +static enum parse_opt_result reupdate_callback( + struct parse_opt_ctx_t *ctx, const struct option *opt, + const char *arg, int unset) { int *has_errors = opt->value; const char *prefix = startup_info->prefix; BUG_ON_OPT_NEG(unset); + BUG_ON_OPT_ARG(arg); /* consume remaining arguments. */ setup_work_tree(); @@ -986,7 +996,8 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) N_("add the specified entry to the index"), PARSE_OPT_NOARG | /* disallow --cacheinfo=<mode> form */ PARSE_OPT_NONEG | PARSE_OPT_LITERAL_ARGHELP, - (parse_opt_cb *) cacheinfo_callback}, + NULL, 0, + cacheinfo_callback}, {OPTION_CALLBACK, 0, "chmod", &set_executable_bit, "(+|-)x", N_("override the executable bit of the listed files"), PARSE_OPT_NONEG, @@ -1012,19 +1023,19 @@ int cmd_update_index(int argc, const char **argv, const char *prefix) {OPTION_LOWLEVEL_CALLBACK, 0, "stdin", &read_from_stdin, NULL, N_("read list of paths to be updated from standard input"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, - (parse_opt_cb *) stdin_callback}, + NULL, 0, stdin_callback}, {OPTION_LOWLEVEL_CALLBACK, 0, "index-info", &nul_term_line, NULL, N_("add entries from standard input to the index"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, - (parse_opt_cb *) stdin_cacheinfo_callback}, + NULL, 0, stdin_cacheinfo_callback}, {OPTION_LOWLEVEL_CALLBACK, 0, "unresolve", &has_errors, NULL, N_("repopulate stages #2 and #3 for the listed paths"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, - (parse_opt_cb *) unresolve_callback}, + NULL, 0, unresolve_callback}, {OPTION_LOWLEVEL_CALLBACK, 'g', "again", &has_errors, NULL, N_("only update entries that differ from HEAD"), PARSE_OPT_NONEG | PARSE_OPT_NOARG, - (parse_opt_cb *) reupdate_callback}, + NULL, 0, reupdate_callback}, OPT_BIT(0, "ignore-missing", &refresh_args.flags, N_("ignore files missing from worktree"), REFRESH_IGNORE_MISSING), diff --git a/builtin/worktree.c b/builtin/worktree.c index 3f9907fcc9..6cc094a453 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -402,6 +402,7 @@ done: cp.dir = path; cp.env = env; cp.argv = NULL; + cp.trace2_hook_name = "post-checkout"; argv_array_pushl(&cp.args, absolute_path(hook), oid_to_hex(&null_oid), oid_to_hex(&commit->object.oid), @@ -9,6 +9,7 @@ #include "gettext.h" #include "convert.h" #include "trace.h" +#include "trace2.h" #include "string-list.h" #include "pack-revindex.h" #include "hash.h" @@ -758,7 +759,7 @@ extern void rename_index_entry_at(struct index_state *, int pos, const char *new /* Remove entry, return true if there are more entries to go. */ extern int remove_index_entry_at(struct index_state *, int pos); -extern void remove_marked_cache_entries(struct index_state *istate); +extern void remove_marked_cache_entries(struct index_state *istate, int invalidate); extern int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_VERBOSE 1 #define ADD_CACHE_PRETEND 2 @@ -1506,10 +1507,19 @@ int date_overflows(timestamp_t date); #define IDENT_STRICT 1 #define IDENT_NO_DATE 2 #define IDENT_NO_NAME 4 + +enum want_ident { + WANT_BLANK_IDENT, + WANT_AUTHOR_IDENT, + WANT_COMMITTER_IDENT +}; + extern const char *git_author_info(int); extern const char *git_committer_info(int); -extern const char *fmt_ident(const char *name, const char *email, const char *date_str, int); -extern const char *fmt_name(const char *name, const char *email); +extern const char *fmt_ident(const char *name, const char *email, + enum want_ident whose_ident, + const char *date_str, int); +extern const char *fmt_name(enum want_ident); extern const char *ident_default_name(void); extern const char *ident_default_email(void); extern const char *git_editor(void); @@ -1569,6 +1579,11 @@ struct checkout { extern int checkout_entry(struct cache_entry *ce, const struct checkout *state, char *topath, int *nr_checkouts); extern void enable_delayed_checkout(struct checkout *state); extern int finish_delayed_checkout(struct checkout *state, int *nr_checkouts); +/* + * Unlink the last component and schedule the leading directories for + * removal, such that empty directories get removed. + */ +extern void unlink_entry(const struct cache_entry *ce); struct cache_def { struct strbuf path; diff --git a/check-racy.c b/check-racy.c deleted file mode 100644 index 24b6542352..0000000000 --- a/check-racy.c +++ /dev/null @@ -1,28 +0,0 @@ -#include "cache.h" - -int main(int ac, char **av) -{ - int i; - int dirty, clean, racy; - - dirty = clean = racy = 0; - read_cache(); - for (i = 0; i < active_nr; i++) { - struct cache_entry *ce = active_cache[i]; - struct stat st; - - if (lstat(ce->name, &st)) { - error_errno("lstat(%s)", ce->name); - continue; - } - - if (ce_match_stat(ce, &st, 0)) - dirty++; - else if (ce_match_stat(ce, &st, CE_MATCH_RACY_IS_DIRTY)) - racy++; - else - clean++; - } - printf("dirty %d, clean %d, racy %d\n", dirty, clean, racy); - return 0; -} diff --git a/ci/run-windows-build.sh b/ci/run-windows-build.sh deleted file mode 100755 index a73a4eca0a..0000000000 --- a/ci/run-windows-build.sh +++ /dev/null @@ -1,103 +0,0 @@ -#!/usr/bin/env bash -# -# Script to trigger the Git for Windows build and test run. -# Set the $GFW_CI_TOKEN as environment variable. -# Pass the branch (only branches on https://github.com/git/git are -# supported) and a commit hash. -# - -. ${0%/*}/lib.sh - -test $# -ne 2 && echo "Unexpected number of parameters" && exit 1 -test -z "$GFW_CI_TOKEN" && echo "GFW_CI_TOKEN not defined" && exit - -BRANCH=$1 -COMMIT=$2 - -gfwci () { - local CURL_ERROR_CODE HTTP_CODE - CONTENT_FILE=$(mktemp -t "git-windows-ci-XXXXXX") - while test -z $HTTP_CODE - do - HTTP_CODE=$(curl \ - -H "Authentication: Bearer $GFW_CI_TOKEN" \ - --silent --retry 5 --write-out '%{HTTP_CODE}' \ - --output >(sed "$(printf '1s/^\xef\xbb\xbf//')" >$CONTENT_FILE) \ - "https://git-for-windows-ci.azurewebsites.net/api/TestNow?$1" \ - ) - CURL_ERROR_CODE=$? - # The GfW CI web app sometimes returns HTTP errors of - # "502 bad gateway" or "503 service unavailable". - # We also need to check the HTTP content because the GfW web - # app seems to pass through (error) results from other Azure - # calls with HTTP code 200. - # Wait a little and retry if we detect this error. More info: - # https://docs.microsoft.com/en-in/azure/app-service-web/app-service-web-troubleshoot-http-502-http-503 - if test $HTTP_CODE -eq 502 || - test $HTTP_CODE -eq 503 || - grep "502 - Web server received an invalid response" $CONTENT_FILE >/dev/null - then - sleep 10 - HTTP_CODE= - fi - done - cat $CONTENT_FILE - rm $CONTENT_FILE - if test $CURL_ERROR_CODE -ne 0 - then - return $CURL_ERROR_CODE - fi - if test "$HTTP_CODE" -ge 400 && test "$HTTP_CODE" -lt 600 - then - return 127 - fi -} - -# Trigger build job -BUILD_ID=$(gfwci "action=trigger&branch=$BRANCH&commit=$COMMIT&skipTests=false") -if test $? -ne 0 -then - echo "Unable to trigger Visual Studio Team Services Build" - echo "$BUILD_ID" - exit 1 -fi - -# Check if the $BUILD_ID contains a number -case $BUILD_ID in -''|*[!0-9]*) echo "Unexpected build number: $BUILD_ID" && exit 1 -esac - -echo "Visual Studio Team Services Build #${BUILD_ID}" - -# Tracing execued commands would produce too much noise in the waiting -# loop below. -set +x - -# Wait until build job finished -STATUS= -RESULT= -while true -do - LAST_STATUS=$STATUS - STATUS=$(gfwci "action=status&buildId=$BUILD_ID") - test "$STATUS" = "$LAST_STATUS" || printf "\nStatus: %s " "$STATUS" - printf "." - - case "$STATUS" in - inProgress|postponed|notStarted) sleep 10 ;; # continue - "completed: succeeded") RESULT="success"; break;; # success - "completed: failed") break;; # failure - *) echo "Unhandled status: $STATUS"; break;; # unknown - esac -done - -# Print log -echo "" -echo "" -set -x -gfwci "action=log&buildId=$BUILD_ID" | cut -c 30- - -# Set exit code for TravisCI -test "$RESULT" = "success" - -save_good_tree diff --git a/combine-diff.c b/combine-diff.c index 23d8fabe75..3e49f3bda8 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -23,11 +23,20 @@ static int compare_paths(const struct combine_diff_path *one, two->path, strlen(two->path), two->mode); } -static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, int n, int num_parent) +static int filename_changed(char status) +{ + return status == 'R' || status == 'C'; +} + +static struct combine_diff_path *intersect_paths( + struct combine_diff_path *curr, + int n, + int num_parent, + int combined_all_paths) { struct diff_queue_struct *q = &diff_queued_diff; struct combine_diff_path *p, **tail = &curr; - int i, cmp; + int i, j, cmp; if (!n) { for (i = 0; i < q->nr; i++) { @@ -50,6 +59,13 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid); p->parent[n].mode = q->queue[i]->one->mode; p->parent[n].status = q->queue[i]->status; + + if (combined_all_paths && + filename_changed(p->parent[n].status)) { + strbuf_init(&p->parent[n].path, 0); + strbuf_addstr(&p->parent[n].path, + q->queue[i]->one->path); + } *tail = p; tail = &p->next; } @@ -68,6 +84,10 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, if (cmp < 0) { /* p->path not in q->queue[]; drop it */ *tail = p->next; + for (j = 0; j < num_parent; j++) + if (combined_all_paths && + filename_changed(p->parent[j].status)) + strbuf_release(&p->parent[j].path); free(p); continue; } @@ -81,6 +101,10 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, oidcpy(&p->parent[n].oid, &q->queue[i]->one->oid); p->parent[n].mode = q->queue[i]->one->mode; p->parent[n].status = q->queue[i]->status; + if (combined_all_paths && + filename_changed(p->parent[n].status)) + strbuf_addstr(&p->parent[n].path, + q->queue[i]->one->path); tail = &p->next; i++; @@ -960,12 +984,25 @@ static void show_combined_header(struct combine_diff_path *elem, if (!show_file_header) return; - if (added) - dump_quoted_path("--- ", "", "/dev/null", - line_prefix, c_meta, c_reset); - else - dump_quoted_path("--- ", a_prefix, elem->path, - line_prefix, c_meta, c_reset); + if (rev->combined_all_paths) { + for (i = 0; i < num_parent; i++) { + char *path = filename_changed(elem->parent[i].status) + ? elem->parent[i].path.buf : elem->path; + if (elem->parent[i].status == DIFF_STATUS_ADDED) + dump_quoted_path("--- ", "", "/dev/null", + line_prefix, c_meta, c_reset); + else + dump_quoted_path("--- ", a_prefix, path, + line_prefix, c_meta, c_reset); + } + } else { + if (added) + dump_quoted_path("--- ", "", "/dev/null", + line_prefix, c_meta, c_reset); + else + dump_quoted_path("--- ", a_prefix, elem->path, + line_prefix, c_meta, c_reset); + } if (deleted) dump_quoted_path("+++ ", "", "/dev/null", line_prefix, c_meta, c_reset); @@ -1227,6 +1264,15 @@ static void show_raw_diff(struct combine_diff_path *p, int num_parent, struct re putchar(inter_name_termination); } + for (i = 0; i < num_parent; i++) + if (rev->combined_all_paths) { + if (filename_changed(p->parent[i].status)) + write_name_quoted(p->parent[i].path.buf, stdout, + inter_name_termination); + else + write_name_quoted(p->path, stdout, + inter_name_termination); + } write_name_quoted(p->path, stdout, line_termination); } @@ -1332,7 +1378,9 @@ static const char *path_path(void *obj) /* find set of paths that every parent touches */ static struct combine_diff_path *find_paths_generic(const struct object_id *oid, - const struct oid_array *parents, struct diff_options *opt) + const struct oid_array *parents, + struct diff_options *opt, + int combined_all_paths) { struct combine_diff_path *paths = NULL; int i, num_parent = parents->nr; @@ -1357,7 +1405,8 @@ static struct combine_diff_path *find_paths_generic(const struct object_id *oid, opt->output_format = DIFF_FORMAT_NO_OUTPUT; diff_tree_oid(&parents->oid[i], oid, "", opt); diffcore_std(opt); - paths = intersect_paths(paths, i, num_parent); + paths = intersect_paths(paths, i, num_parent, + combined_all_paths); /* if showing diff, show it in requested order */ if (opt->output_format != DIFF_FORMAT_NO_OUTPUT && @@ -1467,7 +1516,8 @@ void diff_tree_combined(const struct object_id *oid, * diff(sha1,parent_i) for all i to do the job, specifically * for parent0. */ - paths = find_paths_generic(oid, parents, &diffopts); + paths = find_paths_generic(oid, parents, &diffopts, + rev->combined_all_paths); } else { int stat_opt; @@ -1540,6 +1590,10 @@ void diff_tree_combined(const struct object_id *oid, while (paths) { struct combine_diff_path *tmp = paths; paths = paths->next; + for (i = 0; i < num_parent; i++) + if (rev->combined_all_paths && + filename_changed(tmp->parent[i].status)) + strbuf_release(&tmp->parent[i].path); free(tmp); } diff --git a/common-main.c b/common-main.c index 3728f66b4c..d484aec209 100644 --- a/common-main.c +++ b/common-main.c @@ -25,12 +25,19 @@ static void restore_sigpipe_to_default(void) int main(int argc, const char **argv) { + int result; + /* * Always open file descriptors 0/1/2 to avoid clobbering files * in die(). It also avoids messing up when the pipes are dup'ed * onto stdin/stdout/stderr in the child processes we spawn. */ sanitize_stdfds(); + restore_sigpipe_to_default(); + + trace2_initialize(); + trace2_cmd_start(argv); + trace2_collect_process_info(); git_resolve_executable_dir(argv[0]); @@ -40,7 +47,9 @@ int main(int argc, const char **argv) attr_start(); - restore_sigpipe_to_default(); + result = cmd_main(argc, argv); + + trace2_cmd_exit(result); - return cmd_main(argc, argv); + return result; } diff --git a/compat/bswap.h b/compat/bswap.h index 5078ce5ecc..e4e25735ce 100644 --- a/compat/bswap.h +++ b/compat/bswap.h @@ -1,3 +1,6 @@ +#ifndef COMPAT_BSWAP_H +#define COMPAT_BSWAP_H + /* * Let's make sure we always have a sane definition for ntohl()/htonl(). * Some libraries define those as a function call, just to perform byte @@ -210,3 +213,5 @@ static inline void put_be64(void *ptr, uint64_t value) } #endif + +#endif /* COMPAT_BSWAP_H */ diff --git a/compat/mingw.c b/compat/mingw.c index 8141f77189..6b04514cdc 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -1551,19 +1551,23 @@ static int try_shell_exec(const char *cmd, char *const *argv) return 0; prog = path_lookup(interpr, 1); if (prog) { + int exec_id; int argc = 0; const char **argv2; while (argv[argc]) argc++; ALLOC_ARRAY(argv2, argc + 1); argv2[0] = (char *)cmd; /* full path to the script file */ memcpy(&argv2[1], &argv[1], sizeof(*argv) * argc); + exec_id = trace2_exec(prog, argv2); pid = mingw_spawnv(prog, argv2, 1); if (pid >= 0) { int status; if (waitpid(pid, &status, 0) < 0) status = 255; + trace2_exec_result(exec_id, status); exit(status); } + trace2_exec_result(exec_id, -1); pid = 1; /* indicate that we tried but failed */ free(prog); free(argv2); @@ -1576,12 +1580,17 @@ int mingw_execv(const char *cmd, char *const *argv) /* check if git_command is a shell script */ if (!try_shell_exec(cmd, argv)) { int pid, status; + int exec_id; + exec_id = trace2_exec(cmd, (const char **)argv); pid = mingw_spawnv(cmd, (const char **)argv, 0); - if (pid < 0) + if (pid < 0) { + trace2_exec_result(exec_id, -1); return -1; + } if (waitpid(pid, &status, 0) < 0) status = 255; + trace2_exec_result(exec_id, status); exit(status); } return -1; diff --git a/compat/mingw.h b/compat/mingw.h index 30d9fb3e36..4d73f8aa9d 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -147,8 +147,7 @@ static inline int fcntl(int fd, int cmd, ...) errno = EINVAL; return -1; } -/* bash cannot reliably detect negative return codes as failure */ -#define exit(code) exit((code) & 0xff) + #define sigemptyset(x) (void)0 static inline int sigaddset(sigset_t *set, int signum) { return 0; } diff --git a/compat/win32/trace2_win32_process_info.c b/compat/win32/trace2_win32_process_info.c new file mode 100644 index 0000000000..52bd62034b --- /dev/null +++ b/compat/win32/trace2_win32_process_info.c @@ -0,0 +1,147 @@ +#include "../../cache.h" +#include "../../json-writer.h" +#include <Psapi.h> +#include <tlHelp32.h> + +/* + * An arbitrarily chosen value to limit the size of the ancestor + * array built in git_processes(). + */ +#define NR_PIDS_LIMIT 10 + +/* + * Find the process data for the given PID in the given snapshot + * and update the PROCESSENTRY32 data. + */ +static int find_pid(DWORD pid, HANDLE hSnapshot, PROCESSENTRY32 *pe32) +{ + pe32->dwSize = sizeof(PROCESSENTRY32); + + if (Process32First(hSnapshot, pe32)) { + do { + if (pe32->th32ProcessID == pid) + return 1; + } while (Process32Next(hSnapshot, pe32)); + } + return 0; +} + +/* + * Accumulate JSON array of our parent processes: + * [ + * exe-name-parent, + * exe-name-grand-parent, + * ... + * ] + * + * Note: we only report the filename of the process executable; the + * only way to get its full pathname is to use OpenProcess() + * and GetModuleFileNameEx() or QueryfullProcessImageName() + * and that seems rather expensive (on top of the cost of + * getting the snapshot). + * + * Note: we compute the set of parent processes by walking the PPID + * link in each visited PROCESSENTRY32 record. This search + * stops when an ancestor process is not found in the snapshot + * (because it exited before the current or intermediate parent + * process exited). + * + * This search may compute an incorrect result if the PPID link + * refers to the PID of an exited parent and that PID has been + * recycled and given to a new unrelated process. + * + * Worse, it is possible for a child or descendant of the + * current process to be given the recycled PID and cause a + * PPID-cycle. This would cause an infinite loop building our + * parent process array. + * + * Note: for completeness, the "System Idle" process has PID=0 and + * PPID=0 and could cause another PPID-cycle. We don't expect + * Git to be a descendant of the idle process, but because of + * PID recycling, it might be possible to get a PPID link value + * of 0. This too would cause an infinite loop. + * + * Therefore, we keep an array of the visited PPIDs to guard against + * cycles. + * + * We use a fixed-size array rather than ALLOC_GROW to keep things + * simple and avoid the alloc/realloc overhead. It is OK if we + * truncate the search and return a partial answer. + */ +static void get_processes(struct json_writer *jw, HANDLE hSnapshot) +{ + PROCESSENTRY32 pe32; + DWORD pid; + DWORD pid_list[NR_PIDS_LIMIT]; + int k, nr_pids = 0; + + pid = GetCurrentProcessId(); + while (find_pid(pid, hSnapshot, &pe32)) { + /* Only report parents. Omit self from the JSON output. */ + if (nr_pids) + jw_array_string(jw, pe32.szExeFile); + + /* Check for cycle in snapshot. (Yes, it happened.) */ + for (k = 0; k < nr_pids; k++) + if (pid == pid_list[k]) { + jw_array_string(jw, "(cycle)"); + return; + } + + if (nr_pids == NR_PIDS_LIMIT) { + jw_array_string(jw, "(truncated)"); + return; + } + + pid_list[nr_pids++] = pid; + + pid = pe32.th32ParentProcessID; + } +} + +/* + * Emit JSON data for the current and parent processes. Individual + * trace2 targets can decide how to actually print it. + */ +static void get_ancestry(void) +{ + HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); + + if (hSnapshot != INVALID_HANDLE_VALUE) { + struct json_writer jw = JSON_WRITER_INIT; + + jw_array_begin(&jw, 0); + get_processes(&jw, hSnapshot); + jw_end(&jw); + + trace2_data_json("process", the_repository, "windows/ancestry", + &jw); + + jw_release(&jw); + CloseHandle(hSnapshot); + } +} + +/* + * Is a debugger attached to the current process? + * + * This will catch debug runs (where the debugger started the process). + * This is the normal case. Since this code is called during our startup, + * it will not report instances where a debugger is attached dynamically + * to a running git process, but that is relatively rare. + */ +static void get_is_being_debugged(void) +{ + if (IsDebuggerPresent()) + trace2_data_intmax("process", the_repository, + "windows/debugger_present", 1); +} + +void trace2_collect_process_info(void) +{ + if (!trace2_is_enabled()) + return; + + get_is_being_debugged(); + get_ancestry(); +} @@ -1445,7 +1445,9 @@ int git_default_config(const char *var, const char *value, void *cb) if (starts_with(var, "core.")) return git_default_core_config(var, value, cb); - if (starts_with(var, "user.")) + if (starts_with(var, "user.") || + starts_with(var, "author.") || + starts_with(var, "committer.")) return git_ident_config(var, value, cb); if (starts_with(var, "i18n.")) @@ -2655,6 +2657,8 @@ int git_config_set_gently(const char *key, const char *value) void git_config_set(const char *key, const char *value) { git_config_set_multivar(key, value, NULL, 0); + + trace2_cmd_set_config(key, value); } /* diff --git a/config.mak.dev b/config.mak.dev index 7354fe15b3..bf1f3fcdee 100644 --- a/config.mak.dev +++ b/config.mak.dev @@ -1,41 +1,41 @@ ifeq ($(filter no-error,$(DEVOPTS)),) -CFLAGS += -Werror +DEVELOPER_CFLAGS += -Werror endif ifneq ($(filter pedantic,$(DEVOPTS)),) -CFLAGS += -pedantic +DEVELOPER_CFLAGS += -pedantic # don't warn for each N_ use -CFLAGS += -DUSE_PARENS_AROUND_GETTEXT_N=0 -endif -CFLAGS += -Wall -CFLAGS += -Wdeclaration-after-statement -CFLAGS += -Wformat-security -CFLAGS += -Wno-format-zero-length -CFLAGS += -Wold-style-definition -CFLAGS += -Woverflow -CFLAGS += -Wpointer-arith -CFLAGS += -Wstrict-prototypes -CFLAGS += -Wunused -CFLAGS += -Wvla +DEVELOPER_CFLAGS += -DUSE_PARENS_AROUND_GETTEXT_N=0 +endif +DEVELOPER_CFLAGS += -Wall +DEVELOPER_CFLAGS += -Wdeclaration-after-statement +DEVELOPER_CFLAGS += -Wformat-security +DEVELOPER_CFLAGS += -Wno-format-zero-length +DEVELOPER_CFLAGS += -Wold-style-definition +DEVELOPER_CFLAGS += -Woverflow +DEVELOPER_CFLAGS += -Wpointer-arith +DEVELOPER_CFLAGS += -Wstrict-prototypes +DEVELOPER_CFLAGS += -Wunused +DEVELOPER_CFLAGS += -Wvla ifndef COMPILER_FEATURES COMPILER_FEATURES := $(shell ./detect-compiler $(CC)) endif ifneq ($(filter clang4,$(COMPILER_FEATURES)),) -CFLAGS += -Wtautological-constant-out-of-range-compare +DEVELOPER_CFLAGS += -Wtautological-constant-out-of-range-compare endif ifneq ($(or $(filter gcc6,$(COMPILER_FEATURES)),$(filter clang4,$(COMPILER_FEATURES))),) -CFLAGS += -Wextra +DEVELOPER_CFLAGS += -Wextra # if a function is public, there should be a prototype and the right # header file should be included. If not, it should be static. -CFLAGS += -Wmissing-prototypes +DEVELOPER_CFLAGS += -Wmissing-prototypes ifeq ($(filter extra-all,$(DEVOPTS)),) # These are disabled because we have these all over the place. -CFLAGS += -Wno-empty-body -CFLAGS += -Wno-missing-field-initializers -CFLAGS += -Wno-sign-compare -CFLAGS += -Wno-unused-parameter +DEVELOPER_CFLAGS += -Wno-empty-body +DEVELOPER_CFLAGS += -Wno-missing-field-initializers +DEVELOPER_CFLAGS += -Wno-sign-compare +DEVELOPER_CFLAGS += -Wno-unused-parameter endif endif @@ -43,6 +43,6 @@ endif # not worth fixing since newer compilers correctly stop complaining ifneq ($(filter gcc4,$(COMPILER_FEATURES)),) ifeq ($(filter gcc5,$(COMPILER_FEATURES)),) -CFLAGS += -Wno-uninitialized +DEVELOPER_CFLAGS += -Wno-uninitialized endif endif diff --git a/config.mak.uname b/config.mak.uname index b37fa8424c..41e85fab1c 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -393,6 +393,7 @@ ifeq ($(uname_S),Windows) BASIC_CFLAGS = -nologo -I. -I../zlib -Icompat/vcbuild -Icompat/vcbuild/include -DWIN32 -D_CONSOLE -DHAVE_STRING_H -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE COMPAT_OBJS = compat/msvc.o compat/winansi.o \ compat/win32/pthread.o compat/win32/syslog.o \ + compat/win32/trace2_win32_process_info.o \ compat/win32/dirent.o COMPAT_CFLAGS = -D__USE_MINGW_ACCESS -DNOGDI -DHAVE_STRING_H -Icompat -Icompat/regex -Icompat/win32 -DSTRIP_EXTENSION=\".exe\" BASIC_LDFLAGS = -IGNORE:4217 -IGNORE:4049 -NOLOGO -SUBSYSTEM:CONSOLE @@ -529,7 +530,6 @@ ifneq (,$(findstring MINGW,$(uname_S))) NO_STRTOUMAX = YesPlease NO_MKDTEMP = YesPlease NO_SVN_TESTS = YesPlease - NO_PERL_MAKEMAKER = YesPlease RUNTIME_PREFIX = YesPlease HAVE_WPGMPTR = YesWeDo NO_ST_BLOCKS_IN_STRUCT_STAT = YesPlease @@ -546,6 +546,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) COMPAT_CFLAGS += -DNOGDI -Icompat -Icompat/win32 COMPAT_CFLAGS += -DSTRIP_EXTENSION=\".exe\" COMPAT_OBJS += compat/mingw.o compat/winansi.o \ + compat/win32/trace2_win32_process_info.o \ compat/win32/path-utils.o \ compat/win32/pthread.o compat/win32/syslog.o \ compat/win32/dirent.o @@ -567,7 +568,7 @@ ifneq (,$(wildcard ../THIS_IS_MSYSGIT)) NO_GETTEXT = YesPlease COMPAT_CLFAGS += -D__USE_MINGW_ACCESS else - ifeq ($(shell expr "$(uname_R)" : '2\.'),2) + ifneq ($(shell expr "$(uname_R)" : '1\.'),2) # MSys2 prefix = /usr/ ifeq (MINGW32,$(MSYSTEM)) @@ -1248,6 +1248,7 @@ struct child_process *git_connect(int fd[2], const char *url, conn = NULL; } else if (protocol == PROTO_GIT) { conn = git_connect_git(fd, hostandport, path, prog, version, flags); + conn->trace2_child_class = "transport/git"; } else { struct strbuf cmd = STRBUF_INIT; const char *const *var; @@ -1290,9 +1291,11 @@ struct child_process *git_connect(int fd[2], const char *url, strbuf_release(&cmd); return NULL; } + conn->trace2_child_class = "transport/ssh"; fill_ssh_args(conn, ssh_host, port, version, flags); } else { transport_check_allowed("file"); + conn->trace2_child_class = "transport/file"; if (version > 0) { argv_array_pushf(&conn->env_array, GIT_PROTOCOL_ENVIRONMENT "=version=%d", version); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index 499e56f83d..976e4a6548 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -853,6 +853,11 @@ __git_compute_merge_strategies () __git_merge_strategies=$(__git_list_merge_strategies) } +__git_merge_strategy_options="ours theirs subtree subtree= patience + histogram diff-algorithm= ignore-space-change ignore-all-space + ignore-space-at-eol renormalize no-renormalize no-renames + find-renames find-renames= rename-threshold=" + __git_complete_revlist_file () { local dequoted_word pfx ls ref cur_="$cur" @@ -996,12 +1001,21 @@ __git_complete_strategy () -s|--strategy) __gitcomp "$__git_merge_strategies" return 0 + ;; + -X) + __gitcomp "$__git_merge_strategy_options" + return 0 + ;; esac case "$cur" in --strategy=*) __gitcomp "$__git_merge_strategies" "" "${cur##--strategy=}" return 0 ;; + --strategy-option=*) + __gitcomp "$__git_merge_strategy_options" "" "${cur##--strategy-option=}" + return 0 + ;; esac return 1 } @@ -1163,6 +1177,7 @@ __git_count_arguments () } __git_whitespacelist="nowarn warn error error-all fix" +__git_patchformat="mbox stgit stgit-series hg mboxrd" __git_am_inprogress_options="--skip --continue --resolved --abort --quit --show-current-patch" _git_am () @@ -1177,6 +1192,10 @@ _git_am () __gitcomp "$__git_whitespacelist" "" "${cur##--whitespace=}" return ;; + --patch-format=*) + __gitcomp "$__git_patchformat" "" "${cur##--patch-format=}" + return + ;; --*) __gitcomp_builtin am "" \ "$__git_am_inprogress_options" @@ -1200,6 +1219,10 @@ _git_apply () _git_add () { case "$cur" in + --chmod=*) + __gitcomp "+x -x" "" "${cur##--chmod=}" + return + ;; --*) __gitcomp_builtin add return @@ -1260,6 +1283,8 @@ _git_bisect () esac } +__git_ref_fieldlist="refname objecttype objectsize objectname upstream push HEAD symref" + _git_branch () { local i c=1 only_local_ref="n" has_r="n" @@ -1343,6 +1368,9 @@ _git_cherry_pick () __gitcomp "$__git_cherry_pick_inprogress_options" return fi + + __git_complete_strategy && return + case "$cur" in --*) __gitcomp_builtin cherry-pick "" \ @@ -1506,6 +1534,10 @@ _git_fetch () __gitcomp "$__git_fetch_recurse_submodules" "" "${cur##--recurse-submodules=}" return ;; + --filter=*) + __gitcomp "blob:none blob:limit= sparse:oid= sparse:path=" "" "${cur##--filter=}" + return + ;; --*) __gitcomp_builtin fetch return @@ -1702,8 +1734,8 @@ __git_log_shortlog_options=" --all-match --invert-grep " -__git_log_pretty_formats="oneline short medium full fuller email raw format:" -__git_log_date_formats="relative iso8601 rfc2822 short local default raw" +__git_log_pretty_formats="oneline short medium full fuller email raw format: mboxrd" +__git_log_date_formats="relative iso8601 iso8601-strict rfc2822 short local default raw unix format:" _git_log () { @@ -2221,7 +2253,7 @@ _git_config () return ;; diff.submodule) - __gitcomp "log short" + __gitcomp "$__git_diff_submodule_formats" return ;; help.format) @@ -2388,6 +2420,10 @@ _git_remote () _git_replace () { case "$cur" in + --format=*) + __gitcomp "short medium long" "" "${cur##--format=}" + return + ;; --*) __gitcomp_builtin replace return @@ -2429,6 +2465,7 @@ _git_revert () __gitcomp "$__git_revert_inprogress_options" return fi + __git_complete_strategy && return case "$cur" in --*) __gitcomp_builtin revert "" \ @@ -2573,7 +2610,7 @@ _git_submodule () { __git_has_doubledash && return - local subcommands="add status init deinit update summary foreach sync" + local subcommands="add status init deinit update summary foreach sync absorbgitdirs" local subcommand="$(__git_find_on_cmdline "$subcommands")" if [ -z "$subcommand" ]; then case "$cur" in @@ -921,6 +921,10 @@ static enum date_mode_type parse_date_type(const char *format, const char **end) return DATE_UNIX; if (skip_prefix(format, "format", end)) return DATE_STRFTIME; + /* + * Please update $__git_log_date_formats in + * git-completion.bash when you add new formats. + */ die("unknown date format %s", format); } diff --git a/diff-lib.c b/diff-lib.c index 23c8d351b3..a838c219ec 100644 --- a/diff-lib.c +++ b/diff-lib.c @@ -531,7 +531,7 @@ int run_diff_index(struct rev_info *revs, int cached) exit(128); diff_set_mnemonic_prefix(&revs->diffopt, "c/", cached ? "i/" : "w/"); - diffcore_fix_diff_index(&revs->diffopt); + diffcore_fix_diff_index(); diffcore_std(&revs->diffopt); diff_flush(&revs->diffopt); trace_performance_leave("diff-index"); diff --git a/diff-no-index.c b/diff-no-index.c index 9414e922d1..6001baecd4 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -233,8 +233,7 @@ static void fixup_paths(const char **path, struct strbuf *replacement) } } -void diff_no_index(struct repository *r, - struct rev_info *revs, +void diff_no_index(struct rev_info *revs, int argc, const char **argv) { int i; @@ -242,11 +241,6 @@ void diff_no_index(struct repository *r, struct strbuf replacement = STRBUF_INIT; const char *prefix = revs->prefix; - /* - * FIXME: --no-index should not look at index and we should be - * able to pass NULL repo. Maybe later. - */ - repo_diff_setup(r, &revs->diffopt); for (i = 1; i < argc - 2; ) { int j; if (!strcmp(argv[i], "--no-index")) @@ -23,6 +23,7 @@ #include "argv-array.h" #include "graph.h" #include "packfile.h" +#include "parse-options.h" #include "help.h" #ifdef NO_FAST_WORKING_DIRECTORY @@ -103,11 +104,6 @@ static const char *color_diff_slots[] = { [DIFF_FILE_NEW_BOLD] = "newBold", }; -static NORETURN void die_want_option(const char *option_name) -{ - die(_("option '%s' requires a value"), option_name); -} - define_list_config_array_extra(color_diff_slots, {"plain"}); static int parse_diff_color_slot(const char *var) @@ -178,6 +174,10 @@ static int parse_submodule_params(struct diff_options *options, const char *valu options->submodule_format = DIFF_SUBMODULE_SHORT; else if (!strcmp(value, "diff")) options->submodule_format = DIFF_SUBMODULE_INLINE_DIFF; + /* + * Please update $__git_diff_submodule_formats in + * git-completion.bash when you add new formats. + */ else return -1; return 0; @@ -204,6 +204,10 @@ long parse_algorithm_value(const char *value) return XDF_PATIENCE_DIFF; else if (!strcasecmp(value, "histogram")) return XDF_HISTOGRAM_DIFF; + /* + * Please update $__git_diff_algorithms in git-completion.bash + * when you add new algorithms. + */ return -1; } @@ -1613,8 +1617,7 @@ static int new_blank_line_at_eof(struct emit_callback *ecbdata, const char *line return ws_blank_line(line, len, ecbdata->ws_rule); } -static void emit_add_line(const char *reset, - struct emit_callback *ecbdata, +static void emit_add_line(struct emit_callback *ecbdata, const char *line, int len) { unsigned flags = WSEH_NEW | ecbdata->ws_rule; @@ -1624,16 +1627,14 @@ static void emit_add_line(const char *reset, emit_diff_symbol(ecbdata->opt, DIFF_SYMBOL_PLUS, line, len, flags); } -static void emit_del_line(const char *reset, - struct emit_callback *ecbdata, +static void emit_del_line(struct emit_callback *ecbdata, const char *line, int len) { unsigned flags = WSEH_OLD | ecbdata->ws_rule; emit_diff_symbol(ecbdata->opt, DIFF_SYMBOL_MINUS, line, len, flags); } -static void emit_context_line(const char *reset, - struct emit_callback *ecbdata, +static void emit_context_line(struct emit_callback *ecbdata, const char *line, int len) { unsigned flags = WSEH_CONTEXT | ecbdata->ws_rule; @@ -1742,7 +1743,6 @@ static void emit_rewrite_lines(struct emit_callback *ecb, int prefix, const char *data, int size) { const char *endp = NULL; - const char *reset = diff_get_color(ecb->color_diff, DIFF_RESET); while (0 < size) { int len; @@ -1751,10 +1751,10 @@ static void emit_rewrite_lines(struct emit_callback *ecb, len = endp ? (endp - data + 1) : size; if (prefix != '+') { ecb->lno_in_preimage++; - emit_del_line(reset, ecb, data, len); + emit_del_line(ecb, data, len); } else { ecb->lno_in_postimage++; - emit_add_line(reset, ecb, data, len); + emit_add_line(ecb, data, len); } size -= len; data += len; @@ -2291,7 +2291,7 @@ const char *diff_line_prefix(struct diff_options *opt) return msgbuf->buf; } -static unsigned long sane_truncate_line(struct emit_callback *ecb, char *line, unsigned long len) +static unsigned long sane_truncate_line(char *line, unsigned long len) { const char *cp; unsigned long allot; @@ -2325,7 +2325,6 @@ static void find_lno(const char *line, struct emit_callback *ecbdata) static void fn_out_consume(void *priv, char *line, unsigned long len) { struct emit_callback *ecbdata = priv; - const char *reset = diff_get_color(ecbdata->color_diff, DIFF_RESET); struct diff_options *o = ecbdata->opt; o->found_changes = 1; @@ -2356,7 +2355,7 @@ static void fn_out_consume(void *priv, char *line, unsigned long len) if (line[0] == '@') { if (ecbdata->diff_words) diff_words_flush(ecbdata); - len = sane_truncate_line(ecbdata, line, len); + len = sane_truncate_line(line, len); find_lno(line, ecbdata); emit_hunk_header(ecbdata, line, len); return; @@ -2392,16 +2391,16 @@ static void fn_out_consume(void *priv, char *line, unsigned long len) switch (line[0]) { case '+': ecbdata->lno_in_postimage++; - emit_add_line(reset, ecbdata, line + 1, len - 1); + emit_add_line(ecbdata, line + 1, len - 1); break; case '-': ecbdata->lno_in_preimage++; - emit_del_line(reset, ecbdata, line + 1, len - 1); + emit_del_line(ecbdata, line + 1, len - 1); break; case ' ': ecbdata->lno_in_postimage++; ecbdata->lno_in_preimage++; - emit_context_line(reset, ecbdata, line + 1, len - 1); + emit_context_line(ecbdata, line + 1, len - 1); break; default: /* incomplete line at the end */ @@ -4183,7 +4182,6 @@ static void run_external_diff(const char *pgm, struct diff_filespec *one, struct diff_filespec *two, const char *xfrm_msg, - int complete_rewrite, struct diff_options *o) { struct argv_array argv = ARGV_ARRAY_INIT; @@ -4341,8 +4339,7 @@ static void run_diff_cmd(const char *pgm, } if (pgm) { - run_external_diff(pgm, name, other, one, two, xfrm_msg, - complete_rewrite, o); + run_external_diff(pgm, name, other, one, two, xfrm_msg, o); return; } if (one && two) @@ -4491,6 +4488,8 @@ static void run_checkdiff(struct diff_filepair *p, struct diff_options *o) builtin_checkdiff(name, other, attr_path, p->one, p->two, o); } +static void prep_parse_options(struct diff_options *options); + void repo_diff_setup(struct repository *r, struct diff_options *options) { memcpy(options, &default_diff_options, sizeof(*options)); @@ -4532,6 +4531,8 @@ void repo_diff_setup(struct repository *r, struct diff_options *options) options->color_moved = diff_color_moved_default; options->color_moved_ws_handling = diff_color_moved_ws_default; + + prep_parse_options(options); } void diff_setup_done(struct diff_options *options) @@ -4635,6 +4636,8 @@ void diff_setup_done(struct diff_options *options) if (!options->use_color || external_diff()) options->color_moved = 0; + + FREE_AND_NULL(options->parseopts); } static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *val) @@ -4681,8 +4684,6 @@ static int opt_arg(const char *arg, int arg_short, const char *arg_long, int *va return 1; } -static int diff_scoreopt_parse(const char *opt); - static inline int short_opt(char opt, const char **argv, const char **optarg) { @@ -4720,77 +4721,56 @@ int parse_long_opt(const char *opt, const char **argv, return 2; } -static int stat_opt(struct diff_options *options, const char **av) +static int diff_opt_stat(const struct option *opt, const char *value, int unset) { - const char *arg = av[0]; - char *end; + struct diff_options *options = opt->value; int width = options->stat_width; int name_width = options->stat_name_width; int graph_width = options->stat_graph_width; int count = options->stat_count; - int argcount = 1; + char *end; - if (!skip_prefix(arg, "--stat", &arg)) - BUG("stat option does not begin with --stat: %s", arg); - end = (char *)arg; + BUG_ON_OPT_NEG(unset); - switch (*arg) { - case '-': - if (skip_prefix(arg, "-width", &arg)) { - if (*arg == '=') - width = strtoul(arg + 1, &end, 10); - else if (!*arg && !av[1]) - die_want_option("--stat-width"); - else if (!*arg) { - width = strtoul(av[1], &end, 10); - argcount = 2; - } - } else if (skip_prefix(arg, "-name-width", &arg)) { - if (*arg == '=') - name_width = strtoul(arg + 1, &end, 10); - else if (!*arg && !av[1]) - die_want_option("--stat-name-width"); - else if (!*arg) { - name_width = strtoul(av[1], &end, 10); - argcount = 2; - } - } else if (skip_prefix(arg, "-graph-width", &arg)) { - if (*arg == '=') - graph_width = strtoul(arg + 1, &end, 10); - else if (!*arg && !av[1]) - die_want_option("--stat-graph-width"); - else if (!*arg) { - graph_width = strtoul(av[1], &end, 10); - argcount = 2; - } - } else if (skip_prefix(arg, "-count", &arg)) { - if (*arg == '=') - count = strtoul(arg + 1, &end, 10); - else if (!*arg && !av[1]) - die_want_option("--stat-count"); - else if (!*arg) { - count = strtoul(av[1], &end, 10); - argcount = 2; - } + if (!strcmp(opt->long_name, "stat")) { + if (value) { + width = strtoul(value, &end, 10); + if (*end == ',') + name_width = strtoul(end+1, &end, 10); + if (*end == ',') + count = strtoul(end+1, &end, 10); + if (*end) + return error(_("invalid --stat value: %s"), value); } - break; - case '=': - width = strtoul(arg+1, &end, 10); - if (*end == ',') - name_width = strtoul(end+1, &end, 10); - if (*end == ',') - count = strtoul(end+1, &end, 10); - } + } else if (!strcmp(opt->long_name, "stat-width")) { + width = strtoul(value, &end, 10); + if (*end) + return error(_("%s expects a numerical value"), + opt->long_name); + } else if (!strcmp(opt->long_name, "stat-name-width")) { + name_width = strtoul(value, &end, 10); + if (*end) + return error(_("%s expects a numerical value"), + opt->long_name); + } else if (!strcmp(opt->long_name, "stat-graph-width")) { + graph_width = strtoul(value, &end, 10); + if (*end) + return error(_("%s expects a numerical value"), + opt->long_name); + } else if (!strcmp(opt->long_name, "stat-count")) { + count = strtoul(value, &end, 10); + if (*end) + return error(_("%s expects a numerical value"), + opt->long_name); + } else + BUG("%s should not get here", opt->long_name); - /* Important! This checks all the error cases! */ - if (*end) - return 0; options->output_format |= DIFF_FORMAT_DIFFSTAT; options->stat_name_width = name_width; options->stat_graph_width = graph_width; options->stat_width = width; options->stat_count = count; - return argcount; + return 0; } static int parse_dirstat_opt(struct diff_options *options, const char *params) @@ -4926,6 +4906,308 @@ static int parse_objfind_opt(struct diff_options *opt, const char *arg) return 1; } +static int diff_opt_break_rewrites(const struct option *opt, + const char *arg, int unset) +{ + int *break_opt = opt->value; + int opt1, opt2; + + BUG_ON_OPT_NEG(unset); + if (!arg) + arg = ""; + opt1 = parse_rename_score(&arg); + if (*arg == 0) + opt2 = 0; + else if (*arg != '/') + return error(_("%s expects <n>/<m> form"), opt->long_name); + else { + arg++; + opt2 = parse_rename_score(&arg); + } + if (*arg != 0) + return error(_("%s expects <n>/<m> form"), opt->long_name); + *break_opt = opt1 | (opt2 << 16); + return 0; +} + +static int diff_opt_char(const struct option *opt, + const char *arg, int unset) +{ + char *value = opt->value; + + BUG_ON_OPT_NEG(unset); + if (arg[1]) + return error(_("%s expects a character, got '%s'"), + opt->long_name, arg); + *value = arg[0]; + return 0; +} + +static int diff_opt_compact_summary(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_ARG(arg); + if (unset) { + options->flags.stat_with_summary = 0; + } else { + options->flags.stat_with_summary = 1; + options->output_format |= DIFF_FORMAT_DIFFSTAT; + } + return 0; +} + +static int diff_opt_dirstat(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_NEG(unset); + if (!strcmp(opt->long_name, "cumulative")) { + if (arg) + BUG("how come --cumulative take a value?"); + arg = "cumulative"; + } else if (!strcmp(opt->long_name, "dirstat-by-file")) + parse_dirstat_opt(options, "files"); + parse_dirstat_opt(options, arg ? arg : ""); + return 0; +} + +static int diff_opt_find_copies(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_NEG(unset); + if (!arg) + arg = ""; + options->rename_score = parse_rename_score(&arg); + if (*arg != 0) + return error(_("invalid argument to %s"), opt->long_name); + + if (options->detect_rename == DIFF_DETECT_COPY) + options->flags.find_copies_harder = 1; + else + options->detect_rename = DIFF_DETECT_COPY; + + return 0; +} + +static int diff_opt_find_renames(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_NEG(unset); + if (!arg) + arg = ""; + options->rename_score = parse_rename_score(&arg); + if (*arg != 0) + return error(_("invalid argument to %s"), opt->long_name); + + options->detect_rename = DIFF_DETECT_RENAME; + return 0; +} + +static enum parse_opt_result diff_opt_output(struct parse_opt_ctx_t *ctx, + const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + char *path; + + BUG_ON_OPT_NEG(unset); + path = prefix_filename(ctx->prefix, arg); + options->file = xfopen(path, "w"); + options->close_file = 1; + if (options->use_color != GIT_COLOR_ALWAYS) + options->use_color = GIT_COLOR_NEVER; + free(path); + return 0; +} + +static int diff_opt_relative(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + + BUG_ON_OPT_NEG(unset); + options->flags.relative_name = 1; + if (arg) + options->prefix = arg; + return 0; +} + +static int diff_opt_unified(const struct option *opt, + const char *arg, int unset) +{ + struct diff_options *options = opt->value; + char *s; + + BUG_ON_OPT_NEG(unset); + + options->context = strtol(arg, &s, 10); + if (*s) + return error(_("%s expects a numerical value"), "--unified"); + enable_patch_output(&options->output_format); + + return 0; +} + +static void prep_parse_options(struct diff_options *options) +{ + struct option parseopts[] = { + OPT_GROUP(N_("Diff output format options")), + OPT_BITOP('p', "patch", &options->output_format, + N_("generate patch"), + DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT), + OPT_BIT_F('s', "no-patch", &options->output_format, + N_("suppress diff output"), + DIFF_FORMAT_NO_OUTPUT, PARSE_OPT_NONEG), + OPT_BITOP('u', NULL, &options->output_format, + N_("generate patch"), + DIFF_FORMAT_PATCH, DIFF_FORMAT_NO_OUTPUT), + OPT_CALLBACK_F('U', "unified", options, N_("<n>"), + N_("generate diffs with <n> lines context"), + PARSE_OPT_NONEG, diff_opt_unified), + OPT_BOOL('W', "function-context", &options->flags.funccontext, + N_("generate diffs with <n> lines context")), + OPT_BIT_F(0, "raw", &options->output_format, + N_("generate the diff in raw format"), + DIFF_FORMAT_RAW, PARSE_OPT_NONEG), + OPT_BITOP(0, "patch-with-raw", &options->output_format, + N_("synonym for '-p --raw'"), + DIFF_FORMAT_PATCH | DIFF_FORMAT_RAW, + DIFF_FORMAT_NO_OUTPUT), + OPT_BITOP(0, "patch-with-stat", &options->output_format, + N_("synonym for '-p --stat'"), + DIFF_FORMAT_PATCH | DIFF_FORMAT_DIFFSTAT, + DIFF_FORMAT_NO_OUTPUT), + OPT_BIT_F(0, "numstat", &options->output_format, + N_("machine friendly --stat"), + DIFF_FORMAT_NUMSTAT, PARSE_OPT_NONEG), + OPT_BIT_F(0, "shortstat", &options->output_format, + N_("output only the last line of --stat"), + DIFF_FORMAT_SHORTSTAT, PARSE_OPT_NONEG), + OPT_CALLBACK_F('X', "dirstat", options, N_("<param1,param2>..."), + N_("output the distribution of relative amount of changes for each sub-directory"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_dirstat), + OPT_CALLBACK_F(0, "cumulative", options, NULL, + N_("synonym for --dirstat=cumulative"), + PARSE_OPT_NONEG | PARSE_OPT_NOARG, + diff_opt_dirstat), + OPT_CALLBACK_F(0, "dirstat-by-file", options, N_("<param1,param2>..."), + N_("synonym for --dirstat=files,param1,param2..."), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_dirstat), + OPT_BIT_F(0, "check", &options->output_format, + N_("warn if changes introduce conflict markers or whitespace errors"), + DIFF_FORMAT_CHECKDIFF, PARSE_OPT_NONEG), + OPT_BIT_F(0, "summary", &options->output_format, + N_("condensed summary such as creations, renames and mode changes"), + DIFF_FORMAT_SUMMARY, PARSE_OPT_NONEG), + OPT_BIT_F(0, "name-only", &options->output_format, + N_("show only names of changed files"), + DIFF_FORMAT_NAME, PARSE_OPT_NONEG), + OPT_BIT_F(0, "name-status", &options->output_format, + N_("show only names and status of changed files"), + DIFF_FORMAT_NAME_STATUS, PARSE_OPT_NONEG), + OPT_CALLBACK_F(0, "stat", options, N_("<width>[,<name-width>[,<count>]]"), + N_("generate diffstat"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, diff_opt_stat), + OPT_CALLBACK_F(0, "stat-width", options, N_("<width>"), + N_("generate diffstat with a given width"), + PARSE_OPT_NONEG, diff_opt_stat), + OPT_CALLBACK_F(0, "stat-name-width", options, N_("<width>"), + N_("generate diffstat with a given name width"), + PARSE_OPT_NONEG, diff_opt_stat), + OPT_CALLBACK_F(0, "stat-graph-width", options, N_("<width>"), + N_("generate diffstat with a given graph width"), + PARSE_OPT_NONEG, diff_opt_stat), + OPT_CALLBACK_F(0, "stat-count", options, N_("<count>"), + N_("generate diffstat with limited lines"), + PARSE_OPT_NONEG, diff_opt_stat), + OPT_CALLBACK_F(0, "compact-summary", options, NULL, + N_("generate compact summary in diffstat"), + PARSE_OPT_NOARG, diff_opt_compact_summary), + OPT_CALLBACK_F(0, "output-indicator-new", + &options->output_indicators[OUTPUT_INDICATOR_NEW], + N_("<char>"), + N_("specify the character to indicate a new line instead of '+'"), + PARSE_OPT_NONEG, diff_opt_char), + OPT_CALLBACK_F(0, "output-indicator-old", + &options->output_indicators[OUTPUT_INDICATOR_OLD], + N_("<char>"), + N_("specify the character to indicate an old line instead of '-'"), + PARSE_OPT_NONEG, diff_opt_char), + OPT_CALLBACK_F(0, "output-indicator-context", + &options->output_indicators[OUTPUT_INDICATOR_CONTEXT], + N_("<char>"), + N_("specify the character to indicate a context instead of ' '"), + PARSE_OPT_NONEG, diff_opt_char), + + OPT_GROUP(N_("Diff rename options")), + OPT_CALLBACK_F('B', "break-rewrites", &options->break_opt, N_("<n>[/<m>]"), + N_("break complete rewrite changes into pairs of delete and create"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_break_rewrites), + OPT_CALLBACK_F('M', "find-renames", options, N_("<n>"), + N_("detect renames"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_find_renames), + OPT_SET_INT_F('D', "irreversible-delete", &options->irreversible_delete, + N_("omit the preimage for deletes"), + 1, PARSE_OPT_NONEG), + OPT_CALLBACK_F('C', "find-copies", options, N_("<n>"), + N_("detect copies"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_find_copies), + OPT_BOOL(0, "find-copies-harder", &options->flags.find_copies_harder, + N_("use unmodified files as source to find copies")), + OPT_SET_INT_F(0, "no-renames", &options->detect_rename, + N_("disable rename detection"), + 0, PARSE_OPT_NONEG), + OPT_BOOL(0, "rename-empty", &options->flags.rename_empty, + N_("use empty blobs as rename source")), + + OPT_GROUP(N_("Diff algorithm options")), + OPT_BIT(0, "minimal", &options->xdl_opts, + N_("produce the smallest possible diff"), + XDF_NEED_MINIMAL), + OPT_BIT_F('w', "ignore-all-space", &options->xdl_opts, + N_("ignore whitespace when comparing lines"), + XDF_IGNORE_WHITESPACE, PARSE_OPT_NONEG), + OPT_BIT_F('b', "ignore-space-change", &options->xdl_opts, + N_("ignore changes in amount of whitespace"), + XDF_IGNORE_WHITESPACE_CHANGE, PARSE_OPT_NONEG), + OPT_BIT_F(0, "ignore-space-at-eol", &options->xdl_opts, + N_("ignore changes in whitespace at EOL"), + XDF_IGNORE_WHITESPACE_AT_EOL, PARSE_OPT_NONEG), + OPT_BIT_F(0, "ignore-cr-at-eol", &options->xdl_opts, + N_("ignore carrier-return at the end of line"), + XDF_IGNORE_CR_AT_EOL, PARSE_OPT_NONEG), + OPT_BIT_F(0, "ignore-blank-lines", &options->xdl_opts, + N_("ignore changes whose lines are all blank"), + XDF_IGNORE_BLANK_LINES, PARSE_OPT_NONEG), + + OPT_GROUP(N_("Diff other options")), + OPT_CALLBACK_F(0, "relative", options, N_("<prefix>"), + N_("when run from subdir, exclude changes outside and show relative paths"), + PARSE_OPT_NONEG | PARSE_OPT_OPTARG, + diff_opt_relative), + { OPTION_CALLBACK, 0, "output", options, N_("<file>"), + N_("Output to a specific file"), + PARSE_OPT_NONEG, NULL, 0, diff_opt_output }, + + OPT_END() + }; + + ALLOC_ARRAY(options->parseopts, ARRAY_SIZE(parseopts)); + memcpy(options->parseopts, parseopts, sizeof(parseopts)); +} + int diff_opt_parse(struct diff_options *options, const char **av, int ac, const char *prefix) { @@ -4936,107 +5218,18 @@ int diff_opt_parse(struct diff_options *options, if (!prefix) prefix = ""; - /* Output format options */ - if (!strcmp(arg, "-p") || !strcmp(arg, "-u") || !strcmp(arg, "--patch") - || opt_arg(arg, 'U', "unified", &options->context)) - enable_patch_output(&options->output_format); - else if (!strcmp(arg, "--raw")) - options->output_format |= DIFF_FORMAT_RAW; - else if (!strcmp(arg, "--patch-with-raw")) { - enable_patch_output(&options->output_format); - options->output_format |= DIFF_FORMAT_RAW; - } else if (!strcmp(arg, "--numstat")) - options->output_format |= DIFF_FORMAT_NUMSTAT; - else if (!strcmp(arg, "--shortstat")) - options->output_format |= DIFF_FORMAT_SHORTSTAT; - else if (skip_prefix(arg, "-X", &arg) || - skip_to_optional_arg(arg, "--dirstat", &arg)) - return parse_dirstat_opt(options, arg); - else if (!strcmp(arg, "--cumulative")) - return parse_dirstat_opt(options, "cumulative"); - else if (skip_to_optional_arg(arg, "--dirstat-by-file", &arg)) { - parse_dirstat_opt(options, "files"); - return parse_dirstat_opt(options, arg); - } - else if (!strcmp(arg, "--check")) - options->output_format |= DIFF_FORMAT_CHECKDIFF; - else if (!strcmp(arg, "--summary")) - options->output_format |= DIFF_FORMAT_SUMMARY; - else if (!strcmp(arg, "--patch-with-stat")) { - enable_patch_output(&options->output_format); - options->output_format |= DIFF_FORMAT_DIFFSTAT; - } else if (!strcmp(arg, "--name-only")) - options->output_format |= DIFF_FORMAT_NAME; - else if (!strcmp(arg, "--name-status")) - options->output_format |= DIFF_FORMAT_NAME_STATUS; - else if (!strcmp(arg, "-s") || !strcmp(arg, "--no-patch")) - options->output_format |= DIFF_FORMAT_NO_OUTPUT; - else if (starts_with(arg, "--stat")) - /* --stat, --stat-width, --stat-name-width, or --stat-count */ - return stat_opt(options, av); - else if (!strcmp(arg, "--compact-summary")) { - options->flags.stat_with_summary = 1; - options->output_format |= DIFF_FORMAT_DIFFSTAT; - } else if (!strcmp(arg, "--no-compact-summary")) - options->flags.stat_with_summary = 0; - else if (skip_prefix(arg, "--output-indicator-new=", &arg)) - options->output_indicators[OUTPUT_INDICATOR_NEW] = arg[0]; - else if (skip_prefix(arg, "--output-indicator-old=", &arg)) - options->output_indicators[OUTPUT_INDICATOR_OLD] = arg[0]; - else if (skip_prefix(arg, "--output-indicator-context=", &arg)) - options->output_indicators[OUTPUT_INDICATOR_CONTEXT] = arg[0]; - - /* renames options */ - else if (starts_with(arg, "-B") || - skip_to_optional_arg(arg, "--break-rewrites", NULL)) { - if ((options->break_opt = diff_scoreopt_parse(arg)) == -1) - return error("invalid argument to -B: %s", arg+2); - } - else if (starts_with(arg, "-M") || - skip_to_optional_arg(arg, "--find-renames", NULL)) { - if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) - return error("invalid argument to -M: %s", arg+2); - options->detect_rename = DIFF_DETECT_RENAME; - } - else if (!strcmp(arg, "-D") || !strcmp(arg, "--irreversible-delete")) { - options->irreversible_delete = 1; - } - else if (starts_with(arg, "-C") || - skip_to_optional_arg(arg, "--find-copies", NULL)) { - if (options->detect_rename == DIFF_DETECT_COPY) - options->flags.find_copies_harder = 1; - if ((options->rename_score = diff_scoreopt_parse(arg)) == -1) - return error("invalid argument to -C: %s", arg+2); - options->detect_rename = DIFF_DETECT_COPY; - } - else if (!strcmp(arg, "--no-renames")) - options->detect_rename = 0; - else if (!strcmp(arg, "--rename-empty")) - options->flags.rename_empty = 1; - else if (!strcmp(arg, "--no-rename-empty")) - options->flags.rename_empty = 0; - else if (skip_to_optional_arg_default(arg, "--relative", &arg, NULL)) { - options->flags.relative_name = 1; - if (arg) - options->prefix = arg; - } + ac = parse_options(ac, av, prefix, options->parseopts, NULL, + PARSE_OPT_KEEP_DASHDASH | + PARSE_OPT_KEEP_UNKNOWN | + PARSE_OPT_NO_INTERNAL_HELP | + PARSE_OPT_ONE_SHOT | + PARSE_OPT_STOP_AT_NON_OPTION); + + if (ac) + return ac; /* xdiff options */ - else if (!strcmp(arg, "--minimal")) - DIFF_XDL_SET(options, NEED_MINIMAL); - else if (!strcmp(arg, "--no-minimal")) - DIFF_XDL_CLR(options, NEED_MINIMAL); - else if (!strcmp(arg, "-w") || !strcmp(arg, "--ignore-all-space")) - DIFF_XDL_SET(options, IGNORE_WHITESPACE); - else if (!strcmp(arg, "-b") || !strcmp(arg, "--ignore-space-change")) - DIFF_XDL_SET(options, IGNORE_WHITESPACE_CHANGE); - else if (!strcmp(arg, "--ignore-space-at-eol")) - DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL); - else if (!strcmp(arg, "--ignore-cr-at-eol")) - DIFF_XDL_SET(options, IGNORE_CR_AT_EOL); - else if (!strcmp(arg, "--ignore-blank-lines")) - DIFF_XDL_SET(options, IGNORE_BLANK_LINES); - else if (!strcmp(arg, "--indent-heuristic")) + if (!strcmp(arg, "--indent-heuristic")) DIFF_XDL_SET(options, INDENT_HEURISTIC); else if (!strcmp(arg, "--no-indent-heuristic")) DIFF_XDL_CLR(options, INDENT_HEURISTIC); @@ -5081,8 +5274,6 @@ int diff_opt_parse(struct diff_options *options, options->flags.text = 1; else if (!strcmp(arg, "-R")) options->flags.reverse_diff = 1; - else if (!strcmp(arg, "--find-copies-harder")) - options->flags.find_copies_harder = 1; else if (!strcmp(arg, "--follow")) options->flags.follow_renames = 1; else if (!strcmp(arg, "--no-follow")) { @@ -5230,21 +5421,7 @@ int diff_opt_parse(struct diff_options *options, else if (opt_arg(arg, '\0', "inter-hunk-context", &options->interhunkcontext)) ; - else if (!strcmp(arg, "-W")) - options->flags.funccontext = 1; - else if (!strcmp(arg, "--function-context")) - options->flags.funccontext = 1; - else if (!strcmp(arg, "--no-function-context")) - options->flags.funccontext = 0; - else if ((argcount = parse_long_opt("output", av, &optarg))) { - char *path = prefix_filename(prefix, optarg); - options->file = xfopen(path, "w"); - options->close_file = 1; - if (options->use_color != GIT_COLOR_ALWAYS) - options->use_color = GIT_COLOR_NEVER; - free(path); - return argcount; - } else + else return 0; return 1; } @@ -5285,47 +5462,6 @@ int parse_rename_score(const char **cp_p) return (int)((num >= scale) ? MAX_SCORE : (MAX_SCORE * num / scale)); } -static int diff_scoreopt_parse(const char *opt) -{ - int opt1, opt2, cmd; - - if (*opt++ != '-') - return -1; - cmd = *opt++; - if (cmd == '-') { - /* convert the long-form arguments into short-form versions */ - if (skip_prefix(opt, "break-rewrites", &opt)) { - if (*opt == 0 || *opt++ == '=') - cmd = 'B'; - } else if (skip_prefix(opt, "find-copies", &opt)) { - if (*opt == 0 || *opt++ == '=') - cmd = 'C'; - } else if (skip_prefix(opt, "find-renames", &opt)) { - if (*opt == 0 || *opt++ == '=') - cmd = 'M'; - } - } - if (cmd != 'M' && cmd != 'C' && cmd != 'B') - return -1; /* that is not a -M, -C, or -B option */ - - opt1 = parse_rename_score(&opt); - if (cmd != 'B') - opt2 = 0; - else { - if (*opt == 0) - opt2 = 0; - else if (*opt != '/') - return -1; /* we expect -B80/99 or -B80 */ - else { - opt++; - opt2 = parse_rename_score(&opt); - } - } - if (*opt != 0) - return -1; - return opt1 | (opt2 << 16); -} - struct diff_queue_struct diff_queued_diff; void diff_q(struct diff_queue_struct *queue, struct diff_filepair *dp) @@ -6224,7 +6360,7 @@ static int diffnamecmp(const void *a_, const void *b_) return strcmp(name_a, name_b); } -void diffcore_fix_diff_index(struct diff_options *options) +void diffcore_fix_diff_index(void) { struct diff_queue_struct *q = &diff_queued_diff; QSORT(q->queue, q->nr, diffnamecmp); @@ -9,16 +9,17 @@ #include "object.h" #include "oidset.h" -struct rev_info; +struct combine_diff_path; +struct commit; +struct diff_filespec; struct diff_options; struct diff_queue_struct; -struct strbuf; -struct diff_filespec; -struct userdiff_driver; struct oid_array; -struct commit; -struct combine_diff_path; +struct option; struct repository; +struct rev_info; +struct strbuf; +struct userdiff_driver; typedef int (*pathchange_fn_t)(struct diff_options *options, struct combine_diff_path *path); @@ -64,39 +65,39 @@ typedef struct strbuf *(*diff_prefix_fn_t)(struct diff_options *opt, void *data) #define DIFF_FLAGS_INIT { 0 } struct diff_flags { - unsigned recursive:1; - unsigned tree_in_recursive:1; - unsigned binary:1; - unsigned text:1; - unsigned full_index:1; - unsigned silent_on_remove:1; - unsigned find_copies_harder:1; - unsigned follow_renames:1; - unsigned rename_empty:1; - unsigned has_changes:1; - unsigned quick:1; - unsigned no_index:1; - unsigned allow_external:1; - unsigned exit_with_status:1; - unsigned reverse_diff:1; - unsigned check_failed:1; - unsigned relative_name:1; - unsigned ignore_submodules:1; - unsigned dirstat_cumulative:1; - unsigned dirstat_by_file:1; - unsigned allow_textconv:1; - unsigned textconv_set_via_cmdline:1; - unsigned diff_from_contents:1; - unsigned dirty_submodules:1; - unsigned ignore_untracked_in_submodules:1; - unsigned ignore_dirty_submodules:1; - unsigned override_submodule_config:1; - unsigned dirstat_by_line:1; - unsigned funccontext:1; - unsigned default_follow_renames:1; - unsigned stat_with_summary:1; - unsigned suppress_diff_headers:1; - unsigned dual_color_diffed_diffs:1; + unsigned recursive; + unsigned tree_in_recursive; + unsigned binary; + unsigned text; + unsigned full_index; + unsigned silent_on_remove; + unsigned find_copies_harder; + unsigned follow_renames; + unsigned rename_empty; + unsigned has_changes; + unsigned quick; + unsigned no_index; + unsigned allow_external; + unsigned exit_with_status; + unsigned reverse_diff; + unsigned check_failed; + unsigned relative_name; + unsigned ignore_submodules; + unsigned dirstat_cumulative; + unsigned dirstat_by_file; + unsigned allow_textconv; + unsigned textconv_set_via_cmdline; + unsigned diff_from_contents; + unsigned dirty_submodules; + unsigned ignore_untracked_in_submodules; + unsigned ignore_dirty_submodules; + unsigned override_submodule_config; + unsigned dirstat_by_line; + unsigned funccontext; + unsigned default_follow_renames; + unsigned stat_with_summary; + unsigned suppress_diff_headers; + unsigned dual_color_diffed_diffs; }; static inline void diff_flags_or(struct diff_flags *a, @@ -229,6 +230,7 @@ struct diff_options { unsigned color_moved_ws_handling; struct repository *repo; + struct option *parseopts; }; void diff_emit_submodule_del(struct diff_options *o, const char *line); @@ -294,6 +296,7 @@ struct combine_diff_path { char status; unsigned int mode; struct object_id oid; + struct strbuf path; } parent[FLEX_ARRAY]; }; #define combine_diff_path_size(n, l) \ @@ -367,7 +370,7 @@ int git_config_rename(const char *var, const char *value); #define DIFF_PICKAXE_IGNORE_CASE 32 void diffcore_std(struct diff_options *); -void diffcore_fix_diff_index(struct diff_options *); +void diffcore_fix_diff_index(void); #define COMMON_DIFF_OPTIONS_HELP \ "\ncommon diff options:\n" \ @@ -435,7 +438,7 @@ int diff_flush_patch_id(struct diff_options *, struct object_id *, int); int diff_result_code(struct diff_options *, int); -void diff_no_index(struct repository *, struct rev_info *, int, const char **); +void diff_no_index(struct rev_info *, int, const char **); int index_differs_from(struct repository *r, const char *def, const struct diff_flags *flags, @@ -78,6 +78,7 @@ static int launch_specified_editor(const char *editor, const char *path, p.argv = args; p.env = env; p.use_shell = 1; + p.trace2_child_class = "editor"; if (start_command(&p) < 0) return error("unable to start editor '%s'", editor); @@ -441,6 +441,17 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, static struct strbuf path = STRBUF_INIT; struct stat st; + if (ce->ce_flags & CE_WT_REMOVE) { + if (topath) + /* + * No content and thus no path to create, so we have + * no pathname to return. + */ + BUG("Can't remove entry to a path"); + unlink_entry(ce); + return 0; + } + if (topath) return write_entry(ce, topath, state, 1); @@ -510,3 +521,18 @@ int checkout_entry(struct cache_entry *ce, const struct checkout *state, (*nr_checkouts)++; return write_entry(ce, path.buf, state, 0); } + +void unlink_entry(const struct cache_entry *ce) +{ + const struct submodule *sub = submodule_from_ce(ce); + if (sub) { + /* state.force is set at the caller. */ + submodule_move_head(ce->name, "HEAD", NULL, + SUBMODULE_MOVE_HEAD_FORCE); + } + if (!check_leading_path(ce->name, ce_namelen(ce))) + return; + if (remove_or_warn(ce->ce_mode, ce->name)) + return; + schedule_dir_for_removal(ce->name, ce_namelen(ce)); +} diff --git a/exec-cmd.c b/exec-cmd.c index 4f81f44310..7deeab3039 100644 --- a/exec-cmd.c +++ b/exec-cmd.c @@ -209,6 +209,8 @@ static int git_get_exec_path(struct strbuf *buf, const char *argv0) return -1; } + trace2_cmd_path(buf->buf); + return 0; } diff --git a/git-compat-util.h b/git-compat-util.h index 6573808ebd..31b47932bd 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -1260,6 +1260,13 @@ static inline int is_missing_file_error(int errno_) extern int cmd_main(int, const char **); /* + * Intercept all calls to exit() and route them to trace2 to + * optionally emit a message before calling the real exit(). + */ +int trace2_cmd_exit_fl(const char *file, int line, int code); +#define exit(code) exit(trace2_cmd_exit_fl(__FILE__, __LINE__, (code))) + +/* * You can mark a stack variable with UNLEAK(var) to avoid it being * reported as a leak by tools like LSAN or valgrind. The argument * should generally be the variable itself (not its address and not what diff --git a/git-send-email.perl b/git-send-email.perl index 8eb63b5a2f..8200d58cdc 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -465,6 +465,8 @@ $smtp_encryption = '' unless (defined $smtp_encryption); my(%suppress_cc); if (@suppress_cc) { foreach my $entry (@suppress_cc) { + # Please update $__git_send_email_suppresscc_options + # in git-completion.bash when you add new options. die sprintf(__("Unknown --suppress-cc field: '%s'\n"), $entry) unless $entry =~ /^(?:all|cccmd|cc|author|self|sob|body|bodycc|misc-by)$/; $suppress_cc{$entry} = 1; @@ -494,6 +496,8 @@ my $confirm_unconfigured = !defined $confirm; if ($confirm_unconfigured) { $confirm = scalar %suppress_cc ? 'compose' : 'auto'; }; +# Please update $__git_send_email_confirm_options in +# git-completion.bash when you add new options. die sprintf(__("Unknown --confirm setting: '%s'\n"), $confirm) unless $confirm =~ /^(?:auto|cc|compose|always|never)/; @@ -587,6 +591,8 @@ my %parse_alias = ( if (/\(define-mail-alias\s+"(\S+?)"\s+"(\S+?)"\)/) { $aliases{$1} = [ $2 ]; }}} + # Please update _git_config() in git-completion.bash when you + # add new MUAs. ); if (@alias_files and $aliasfiletype and defined $parse_alias{$aliasfiletype}) { diff --git a/git-submodule.sh b/git-submodule.sh index b5f2beee60..514ede2596 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -5,7 +5,8 @@ # Copyright (c) 2007 Lars Hjemli dashless=$(basename "$0" | sed -e 's/-/ /') -USAGE="[--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>] +USAGE="[--quiet] [--cached] + or: $dashless [--quiet] add [-b <branch>] [-f|--force] [--name <name>] [--reference <repository>] [--] <repository> [<path>] or: $dashless [--quiet] status [--cached] [--recursive] [--] [<path>...] or: $dashless [--quiet] init [--] [<path>...] or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...) @@ -147,16 +147,20 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) git_set_exec_path(cmd + 1); else { puts(git_exec_path()); + trace2_cmd_name("_query_"); exit(0); } } else if (!strcmp(cmd, "--html-path")) { puts(system_path(GIT_HTML_PATH)); + trace2_cmd_name("_query_"); exit(0); } else if (!strcmp(cmd, "--man-path")) { puts(system_path(GIT_MAN_PATH)); + trace2_cmd_name("_query_"); exit(0); } else if (!strcmp(cmd, "--info-path")) { puts(system_path(GIT_INFO_PATH)); + trace2_cmd_name("_query_"); exit(0); } else if (!strcmp(cmd, "-p") || !strcmp(cmd, "--paginate")) { use_pager = 1; @@ -285,6 +289,7 @@ static int handle_options(const char ***argv, int *argc, int *envchanged) (*argv)++; (*argc)--; } else if (skip_prefix(cmd, "--list-cmds=", &cmd)) { + trace2_cmd_name("_query_"); if (!strcmp(cmd, "parseopt")) { struct string_list list = STRING_LIST_INIT_DUP; int i; @@ -332,9 +337,14 @@ static int handle_alias(int *argcp, const char ***argv) commit_pager_choice(); child.use_shell = 1; + child.trace2_child_class = "shell_alias"; argv_array_push(&child.args, alias_string + 1); argv_array_pushv(&child.args, (*argv) + 1); + trace2_cmd_alias(alias_command, child.args.argv); + trace2_cmd_list_config(); + trace2_cmd_name("_run_shell_alias_"); + ret = run_command(&child); if (ret >= 0) /* normal exit */ exit(ret); @@ -369,6 +379,9 @@ static int handle_alias(int *argcp, const char ***argv) /* insert after command name */ memcpy(new_argv + count, *argv + 1, sizeof(char *) * *argcp); + trace2_cmd_alias(alias_command, new_argv); + trace2_cmd_list_config(); + *argv = new_argv; *argcp += count - 1; @@ -417,6 +430,8 @@ static int run_builtin(struct cmd_struct *p, int argc, const char **argv) setup_work_tree(); trace_argv_printf(argv, "trace: built-in: git"); + trace2_cmd_name(p->cmd); + trace2_cmd_list_config(); validate_cache_entries(the_repository->index); status = p->fn(argc, argv, prefix); @@ -666,7 +681,14 @@ static void execv_dashed_external(const char **argv) cmd.clean_on_exit = 1; cmd.wait_after_clean = 1; cmd.silent_exec_failure = 1; + cmd.trace2_child_class = "dashed"; + trace2_cmd_name("_run_dashed_"); + + /* + * The code in run_command() logs trace2 child_start/child_exit + * events, so we do not need to report exec/exec_result events here. + */ trace_argv_printf(cmd.args.argv, "trace: exec:"); /* @@ -676,6 +698,12 @@ static void execv_dashed_external(const char **argv) * the program. */ status = run_command(&cmd); + + /* + * If the child process ran and we are now going to exit, emit a + * generic string as our trace2 command verb to indicate that we + * launched a dashed command. + */ if (status >= 0) exit(status); else if (errno != ENOENT) @@ -701,6 +729,43 @@ static int run_argv(int *argcp, const char ***argv) if (!done_alias) handle_builtin(*argcp, *argv); +#if 0 // TODO In GFW, need to amend a7924b655e940b06cb547c235d6bed9767929673 to include trace2_ and _tr2 lines. + else if (get_builtin(**argv)) { + struct argv_array args = ARGV_ARRAY_INIT; + int i; + + /* + * The current process is committed to launching a + * child process to run the command named in (**argv) + * and exiting. Log a generic string as the trace2 + * command verb to indicate this. Note that the child + * process will log the actual verb when it runs. + */ + trace2_cmd_name("_run_git_alias_"); + + if (get_super_prefix()) + die("%s doesn't support --super-prefix", **argv); + + commit_pager_choice(); + + argv_array_push(&args, "git"); + for (i = 0; i < *argcp; i++) + argv_array_push(&args, (*argv)[i]); + + trace_argv_printf(args.argv, "trace: exec:"); + + /* + * if we fail because the command is not found, it is + * OK to return. Otherwise, we just pass along the status code. + */ + i = run_command_v_opt_tr2(args.argv, RUN_SILENT_EXEC_FAILURE | + RUN_CLEAN_ON_EXIT, "git_alias"); + if (i >= 0 || errno != ENOENT) + exit(i); + die("could not execute builtin %s", **argv); + } +#endif // a7924b655e940b06cb547c235d6bed9767929673 + /* .. then try the external ones */ execv_dashed_external(*argv); diff --git a/gitk-git/po/bg.po b/gitk-git/po/bg.po index 407d5550b1..87ab1fac24 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 Alexander Shopov <ash@kambanaria.org>. +# Copyright (C) 2014, 2015, 2019 Alexander Shopov <ash@kambanaria.org>. # This file is distributed under the same license as the git package. -# Alexander Shopov <ash@kambanaria.org>, 2014, 2015. +# Alexander Shopov <ash@kambanaria.org>, 2014, 2015, 2019. # # msgid "" msgstr "" "Project-Id-Version: gitk master\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2015-12-19 11:48+0200\n" -"PO-Revision-Date: 2015-12-19 11:49+0200\n" +"POT-Creation-Date: 2019-03-04 11:27+0100\n" +"PO-Revision-Date: 2019-03-04 11:39+0100\n" "Last-Translator: Alexander Shopov <ash@kambanaria.org>\n" "Language-Team: Bulgarian <dict@fsa-bg.org>\n" "Language: bg\n" @@ -22,17 +22,17 @@ msgstr "" msgid "Couldn't get list of unmerged files:" msgstr "СпиÑъкът Ñ Ð½ÐµÑлети файлове не може да бъде получен:" -#: gitk:212 gitk:2399 +#: gitk:212 gitk:2403 msgid "Color words" msgstr "ОцветÑване на думите" -#: gitk:217 gitk:2399 gitk:8239 gitk:8272 +#: gitk:217 gitk:2403 gitk:8249 gitk:8282 msgid "Markup words" msgstr "ОтбелÑзване на думите" #: gitk:324 msgid "Error parsing revisions:" -msgstr "Грешка при разбор на верÑиите:" +msgstr "Грешка при анализ на верÑиите:" #: gitk:380 msgid "Error executing --argscmd command:" @@ -59,314 +59,318 @@ msgstr "Грешка при изпълнение на „git log“:" msgid "Reading" msgstr "Прочитане" -#: gitk:496 gitk:4544 +#: gitk:496 gitk:4549 msgid "Reading commits..." msgstr "Прочитане на подаваниÑта…" -#: gitk:499 gitk:1637 gitk:4547 +#: gitk:499 gitk:1641 gitk:4552 msgid "No commits selected" msgstr "Ðе Ñа избрани подаваниÑ" -#: gitk:1445 gitk:4064 gitk:12469 +#: gitk:1449 gitk:4069 gitk:12583 msgid "Command line" msgstr "Команден ред" -#: gitk:1511 +#: gitk:1515 msgid "Can't parse git log output:" msgstr "Изходът от „git log“ не може да Ñе анализира:" -#: gitk:1740 +#: gitk:1744 msgid "No commit information available" msgstr "ЛипÑва Ð¸Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° подаваниÑ" -#: gitk:1903 gitk:1932 gitk:4334 gitk:9702 gitk:11274 gitk:11554 +#: gitk:1907 gitk:1936 gitk:4339 gitk:9789 gitk:11388 gitk:11668 msgid "OK" msgstr "Добре" -#: gitk:1934 gitk:4336 gitk:9215 gitk:9294 gitk:9424 gitk:9473 gitk:9704 -#: gitk:11275 gitk:11555 +#: gitk:1938 gitk:4341 gitk:9225 gitk:9304 gitk:9434 gitk:9520 gitk:9791 +#: gitk:11389 gitk:11669 msgid "Cancel" msgstr "Отказ" -#: gitk:2083 +#: gitk:2087 msgid "&Update" msgstr "&ОбновÑване" -#: gitk:2084 +#: gitk:2088 msgid "&Reload" msgstr "&Презареждане" -#: gitk:2085 +#: gitk:2089 msgid "Reread re&ferences" -msgstr "&Ðаново прочитане на наÑтройките" +msgstr "&Ðаново прочитане" -#: gitk:2086 +#: gitk:2090 msgid "&List references" msgstr "&ИзброÑване на указателите" -#: gitk:2088 +#: gitk:2092 msgid "Start git &gui" msgstr "&Стартиране на „git gui“" -#: gitk:2090 +#: gitk:2094 msgid "&Quit" msgstr "&Спиране на програмата" -#: gitk:2082 +#: gitk:2086 msgid "&File" msgstr "&Файл" -#: gitk:2094 +#: gitk:2098 msgid "&Preferences" msgstr "&ÐаÑтройки" -#: gitk:2093 +#: gitk:2097 msgid "&Edit" msgstr "&Редактиране" -#: gitk:2098 +#: gitk:2102 msgid "&New view..." msgstr "&Ðов изглед…" -#: gitk:2099 +#: gitk:2103 msgid "&Edit view..." msgstr "&Редактиране на изгледа…" -#: gitk:2100 +#: gitk:2104 msgid "&Delete view" msgstr "&Изтриване на изгледа" -#: gitk:2102 +#: gitk:2106 msgid "&All files" msgstr "&Ð’Ñички файлове" -#: gitk:2097 +#: gitk:2101 msgid "&View" msgstr "&Изглед" -#: gitk:2107 gitk:2117 +#: gitk:2111 gitk:2121 msgid "&About gitk" msgstr "&ОтноÑно gitk" -#: gitk:2108 gitk:2122 +#: gitk:2112 gitk:2126 msgid "&Key bindings" msgstr "&Клавишни комбинации" -#: gitk:2106 gitk:2121 +#: gitk:2110 gitk:2125 msgid "&Help" msgstr "Помо&щ" -#: gitk:2199 gitk:8671 +#: gitk:2203 gitk:8681 msgid "SHA1 ID:" msgstr "SHA1:" -#: gitk:2243 +#: gitk:2247 msgid "Row" msgstr "Ред" -#: gitk:2281 +#: gitk:2285 msgid "Find" msgstr "ТърÑене" -#: gitk:2309 +#: gitk:2313 msgid "commit" msgstr "подаване" -#: gitk:2313 gitk:2315 gitk:4706 gitk:4729 gitk:4753 gitk:6774 gitk:6846 -#: gitk:6931 +#: gitk:2317 gitk:2319 gitk:4711 gitk:4734 gitk:4758 gitk:6779 gitk:6851 +#: gitk:6936 msgid "containing:" msgstr "Ñъдържащо:" -#: gitk:2316 gitk:3545 gitk:3550 gitk:4782 +#: gitk:2320 gitk:3550 gitk:3555 gitk:4787 msgid "touching paths:" -msgstr "заÑÑгащо пътищата:" +msgstr "в пътищата:" -#: gitk:2317 gitk:4796 +#: gitk:2321 gitk:4801 msgid "adding/removing string:" msgstr "добавÑщо/премахващо низ" -#: gitk:2318 gitk:4798 +#: gitk:2322 gitk:4803 msgid "changing lines matching:" msgstr "променÑщо редове напаÑващи:" -#: gitk:2327 gitk:2329 gitk:4785 +#: gitk:2331 gitk:2333 gitk:4790 msgid "Exact" msgstr "Точно" -#: gitk:2329 gitk:4873 gitk:6742 +#: gitk:2333 gitk:4878 gitk:6747 msgid "IgnCase" msgstr "Без региÑÑ‚ÑŠÑ€" -#: gitk:2329 gitk:4755 gitk:4871 gitk:6738 +#: gitk:2333 gitk:4760 gitk:4876 gitk:6743 msgid "Regexp" msgstr "Рег. израз" -#: gitk:2331 gitk:2332 gitk:4893 gitk:4923 gitk:4930 gitk:6867 gitk:6935 +#: gitk:2335 gitk:2336 gitk:4898 gitk:4928 gitk:4935 gitk:6872 gitk:6940 msgid "All fields" msgstr "Ð’Ñички полета" -#: gitk:2332 gitk:4890 gitk:4923 gitk:6805 +#: gitk:2336 gitk:4895 gitk:4928 gitk:6810 msgid "Headline" msgstr "Първи ред" -#: gitk:2333 gitk:4890 gitk:6805 gitk:6935 gitk:7408 +#: gitk:2337 gitk:4895 gitk:6810 gitk:6940 gitk:7413 msgid "Comments" msgstr "Коментари" -#: gitk:2333 gitk:4890 gitk:4895 gitk:4930 gitk:6805 gitk:7343 gitk:8849 -#: gitk:8864 +#: gitk:2337 gitk:4895 gitk:4900 gitk:4935 gitk:6810 gitk:7348 gitk:8859 +#: gitk:8874 msgid "Author" msgstr "Ðвтор" -#: gitk:2333 gitk:4890 gitk:6805 gitk:7345 +#: gitk:2337 gitk:4895 gitk:6810 gitk:7350 msgid "Committer" msgstr "Подаващ" -#: gitk:2367 +#: gitk:2371 msgid "Search" msgstr "ТърÑене" -#: gitk:2375 +#: gitk:2379 msgid "Diff" msgstr "Разлики" -#: gitk:2377 +#: gitk:2381 msgid "Old version" msgstr "Стара верÑиÑ" -#: gitk:2379 +#: gitk:2383 msgid "New version" msgstr "Ðова верÑиÑ" -#: gitk:2382 +#: gitk:2386 msgid "Lines of context" msgstr "КонтекÑÑ‚ в редове" -#: gitk:2392 +#: gitk:2396 msgid "Ignore space change" msgstr "Празните знаци без значение" -#: gitk:2396 gitk:2398 gitk:7978 gitk:8225 +#: gitk:2400 gitk:2402 gitk:7983 gitk:8235 msgid "Line diff" msgstr "Поредови разлики" -#: gitk:2463 +#: gitk:2467 msgid "Patch" msgstr "Кръпка" -#: gitk:2465 +#: gitk:2469 msgid "Tree" msgstr "Дърво" -#: gitk:2635 gitk:2656 +#: gitk:2639 gitk:2660 msgid "Diff this -> selected" msgstr "Разлики между това и избраното" -#: gitk:2636 gitk:2657 +#: gitk:2640 gitk:2661 msgid "Diff selected -> this" msgstr "Разлики между избраното и това" -#: gitk:2637 gitk:2658 +#: gitk:2641 gitk:2662 msgid "Make patch" msgstr "Създаване на кръпка" -#: gitk:2638 gitk:9273 +#: gitk:2642 gitk:9283 msgid "Create tag" msgstr "Създаване на етикет" -#: gitk:2639 +#: gitk:2643 msgid "Copy commit summary" msgstr "Копиране на информациÑта за подаване" -#: gitk:2640 gitk:9404 +#: gitk:2644 gitk:9414 msgid "Write commit to file" msgstr "Запазване на подаването във файл" -#: gitk:2641 gitk:9461 +#: gitk:2645 msgid "Create new branch" msgstr "Създаване на нов клон" -#: gitk:2642 +#: gitk:2646 msgid "Cherry-pick this commit" msgstr "Отбиране на това подаване" -#: gitk:2643 +#: gitk:2647 msgid "Reset HEAD branch to here" msgstr "Привеждане на върха на клона към текущото подаване" -#: gitk:2644 +#: gitk:2648 msgid "Mark this commit" msgstr "ОтбелÑзване на това подаване" -#: gitk:2645 +#: gitk:2649 msgid "Return to mark" msgstr "Връщане към отбелÑзаното подаване" -#: gitk:2646 +#: gitk:2650 msgid "Find descendant of this and mark" msgstr "Откриване и отбелÑзване на наÑледниците" -#: gitk:2647 +#: gitk:2651 msgid "Compare with marked commit" msgstr "Сравнение Ñ Ð¾Ñ‚Ð±ÐµÐ»Ñзаното подаване" -#: gitk:2648 gitk:2659 +#: gitk:2652 gitk:2663 msgid "Diff this -> marked commit" msgstr "Разлики между това и отбелÑзаното" -#: gitk:2649 gitk:2660 +#: gitk:2653 gitk:2664 msgid "Diff marked commit -> this" msgstr "Разлики между отбелÑзаното и това" -#: gitk:2650 +#: gitk:2654 msgid "Revert this commit" msgstr "ОтмÑна на това подаване" -#: gitk:2666 +#: gitk:2670 msgid "Check out this branch" msgstr "ИзтеглÑне на този клон" -#: gitk:2667 +#: gitk:2671 +msgid "Rename this branch" +msgstr "Преименуване на този клон" + +#: gitk:2672 msgid "Remove this branch" msgstr "Изтриване на този клон" -#: gitk:2668 +#: gitk:2673 msgid "Copy branch name" msgstr "Копиране на името на клона" -#: gitk:2675 +#: gitk:2680 msgid "Highlight this too" msgstr "ОтбелÑзване и на това" -#: gitk:2676 +#: gitk:2681 msgid "Highlight this only" msgstr "ОтбелÑзване Ñамо на това" -#: gitk:2677 +#: gitk:2682 msgid "External diff" msgstr "Външна програма за разлики" -#: gitk:2678 +#: gitk:2683 msgid "Blame parent commit" msgstr "Ðнотиране на родителÑкото подаване" -#: gitk:2679 +#: gitk:2684 msgid "Copy path" msgstr "Копиране на пътÑ" -#: gitk:2686 +#: gitk:2691 msgid "Show origin of this line" msgstr "Показване на произхода на този ред" -#: gitk:2687 +#: gitk:2692 msgid "Run git gui blame on this line" msgstr "Изпълнение на „git gui blame“ върху този ред" -#: gitk:3031 +#: gitk:3036 msgid "About gitk" msgstr "ОтноÑно gitk" -#: gitk:3033 +#: gitk:3038 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -382,324 +386,324 @@ msgstr "" "\n" "Използвайте и разпроÑтранÑвайте при уÑловиÑта на ОПЛ на ГÐУ" -#: gitk:3041 gitk:3108 gitk:9890 +#: gitk:3046 gitk:3113 gitk:10004 msgid "Close" msgstr "ЗатварÑне" -#: gitk:3062 +#: gitk:3067 msgid "Gitk key bindings" msgstr "Клавишни комбинации" -#: gitk:3065 +#: gitk:3070 msgid "Gitk key bindings:" msgstr "Клавишни комбинации:" -#: gitk:3067 +#: gitk:3072 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tСпиране на програмата" -#: gitk:3068 +#: gitk:3073 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tЗатварÑне на прозореца" -#: gitk:3069 +#: gitk:3074 msgid "<Home>\t\tMove to first commit" msgstr "<Home>\t\tКъм първото подаване" -#: gitk:3070 +#: gitk:3075 msgid "<End>\t\tMove to last commit" msgstr "<End>\t\tКъм поÑледното подаване" -#: gitk:3071 +#: gitk:3076 msgid "<Up>, p, k\tMove up one commit" msgstr "<Up>, p, k\tЕдно подаване нагоре" -#: gitk:3072 +#: gitk:3077 msgid "<Down>, n, j\tMove down one commit" msgstr "<Down>, n, j\tЕдно подаване надолу" -#: gitk:3073 +#: gitk:3078 msgid "<Left>, z, h\tGo back in history list" msgstr "<Left>, z, h\tÐазад в иÑториÑта" -#: gitk:3074 +#: gitk:3079 msgid "<Right>, x, l\tGo forward in history list" msgstr "<Right>, x, l\tÐапред в иÑториÑта" -#: gitk:3075 +#: gitk:3080 #, tcl-format msgid "<%s-n>\tGo to n-th parent of current commit in history list" msgstr "<%s-n>\tКъм n-Ñ‚Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ» на текущото подаване в иÑториÑта" -#: gitk:3076 +#: gitk:3081 msgid "<PageUp>\tMove up one page in commit list" msgstr "<PageUp>\tСтраница нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3077 +#: gitk:3082 msgid "<PageDown>\tMove down one page in commit list" msgstr "<PageDown>\tСтраница надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3078 +#: gitk:3083 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tКъм началото на ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3079 +#: gitk:3084 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tКъм ÐºÑ€Ð°Ñ Ð½Ð° ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñта" -#: gitk:3080 +#: gitk:3085 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Up>\tРед нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3081 +#: gitk:3086 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Down>\tРед надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3082 +#: gitk:3087 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tСтраница нагоре в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3083 +#: gitk:3088 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tСтраница надолу в ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:3084 +#: gitk:3089 msgid "<Shift-Up>\tFind backwards (upwards, later commits)" msgstr "<Shift-Up>\tТърÑене назад (визуално нагоре, иÑторичеÑки — поÑледващи)" -#: gitk:3085 +#: gitk:3090 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)" msgstr "" "<Shift-Down>\tТърÑене напред (визуално надолу, иÑторичеÑки — предхождащи)" -#: gitk:3086 +#: gitk:3091 msgid "<Delete>, b\tScroll diff view up one page" msgstr "<Delete>, b\tСтраница нагоре в изгледа за разлики" -#: gitk:3087 +#: gitk:3092 msgid "<Backspace>\tScroll diff view up one page" msgstr "<Backspace>\tСтраница надолу в изгледа за разлики" -#: gitk:3088 +#: gitk:3093 msgid "<Space>\t\tScroll diff view down one page" msgstr "<Space>\t\tСтраница надолу в изгледа за разлики" -#: gitk:3089 +#: gitk:3094 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\t18 реда нагоре в изгледа за разлики" -#: gitk:3090 +#: gitk:3095 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\t18 реда надолу в изгледа за разлики" -#: gitk:3091 +#: gitk:3096 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tТърÑене" -#: gitk:3092 +#: gitk:3097 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tКъм Ñледващата поÑва" -#: gitk:3093 +#: gitk:3098 msgid "<Return>\tMove to next find hit" msgstr "<Return>\tКъм Ñледващата поÑва" -#: gitk:3094 +#: gitk:3099 msgid "g\t\tGo to commit" msgstr "g\t\tКъм поÑледното подаване" -#: gitk:3095 +#: gitk:3100 msgid "/\t\tFocus the search box" msgstr "/\t\tÐ¤Ð¾ÐºÑƒÑ Ð²ÑŠÑ€Ñ…Ñƒ полето за Ñ‚ÑŠÑ€Ñене" -#: gitk:3096 +#: gitk:3101 msgid "?\t\tMove to previous find hit" msgstr "?\t\tКъм предишната поÑва" -#: gitk:3097 +#: gitk:3102 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tСледващ файл в изгледа за разлики" -#: gitk:3098 +#: gitk:3103 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tТърÑене на Ñледващата поÑва в изгледа за разлики" -#: gitk:3099 +#: gitk:3104 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tТърÑене на предишната поÑва в изгледа за разлики" -#: gitk:3100 +#: gitk:3105 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-KP+>\tПо-голÑм размер на шрифта" -#: gitk:3101 +#: gitk:3106 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tПо-голÑм размер на шрифта" -#: gitk:3102 +#: gitk:3107 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-KP->\tПо-малък размер на шрифта" -#: gitk:3103 +#: gitk:3108 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tПо-малък размер на шрифта" -#: gitk:3104 +#: gitk:3109 msgid "<F5>\t\tUpdate" msgstr "<F5>\t\tОбновÑване" -#: gitk:3569 gitk:3578 +#: gitk:3574 gitk:3583 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Грешка при Ñъздаването на временната Ð´Ð¸Ñ€ÐµÐºÑ‚Ð¾Ñ€Ð¸Ñ â€ž%s“:" -#: gitk:3591 +#: gitk:3596 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Грешка при получаването на „%s“ от %s:" -#: gitk:3654 +#: gitk:3659 msgid "command failed:" msgstr "неуÑпешно изпълнение на команда:" -#: gitk:3803 +#: gitk:3808 msgid "No such commit" msgstr "Такова подаване нÑма" -#: gitk:3817 +#: gitk:3822 msgid "git gui blame: command failed:" msgstr "„git gui blame“: неуÑпешно изпълнение на команда:" -#: gitk:3848 +#: gitk:3853 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Върхът за Ñливане не може да бъде прочетен: %s" -#: gitk:3856 +#: gitk:3861 #, tcl-format msgid "Error reading index: %s" msgstr "Грешка при прочитане на индекÑа: %s" -#: gitk:3881 +#: gitk:3886 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Командата „git blame“ не може да бъде Ñтартирана: %s" -#: gitk:3884 gitk:6773 +#: gitk:3889 gitk:6778 msgid "Searching" msgstr "ТърÑене" -#: gitk:3916 +#: gitk:3921 #, tcl-format msgid "Error running git blame: %s" msgstr "Грешка при изпълнението на „git blame“: %s" -#: gitk:3944 +#: gitk:3949 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Този ред идва от подаването %s, което не е в изгледа" -#: gitk:3958 +#: gitk:3963 msgid "External diff viewer failed:" msgstr "ÐеуÑпешно изпълнение на външната програма за разлики:" -#: gitk:4062 +#: gitk:4067 msgid "All files" msgstr "Ð’Ñички файлове" -#: gitk:4086 +#: gitk:4091 msgid "View" msgstr "Изглед" -#: gitk:4089 +#: gitk:4094 msgid "Gitk view definition" msgstr "Ð”ÐµÑ„Ð¸Ð½Ð¸Ñ†Ð¸Ñ Ð½Ð° изглед в Gitk" -#: gitk:4093 +#: gitk:4098 msgid "Remember this view" msgstr "Запазване на този изглед" -#: gitk:4094 +#: gitk:4099 msgid "References (space separated list):" msgstr "Указатели (ÑпиÑък Ñ Ñ€Ð°Ð·Ð´ÐµÐ»Ð¸Ñ‚ÐµÐ» интервал):" -#: gitk:4095 +#: gitk:4100 msgid "Branches & tags:" msgstr "Клони и етикети:" -#: gitk:4096 +#: gitk:4101 msgid "All refs" msgstr "Ð’Ñички указатели" -#: gitk:4097 +#: gitk:4102 msgid "All (local) branches" msgstr "Ð’Ñички (локални) клони" -#: gitk:4098 +#: gitk:4103 msgid "All tags" msgstr "Ð’Ñички етикети" -#: gitk:4099 +#: gitk:4104 msgid "All remote-tracking branches" msgstr "Ð’Ñички ÑледÑщи клони" -#: gitk:4100 +#: gitk:4105 msgid "Commit Info (regular expressions):" msgstr "Ð˜Ð½Ñ„Ð¾Ñ€Ð¼Ð°Ñ†Ð¸Ñ Ð·Ð° подаване (рег. изр.):" -#: gitk:4101 +#: gitk:4106 msgid "Author:" msgstr "Ðвтор:" -#: gitk:4102 +#: gitk:4107 msgid "Committer:" msgstr "Подал:" -#: gitk:4103 +#: gitk:4108 msgid "Commit Message:" msgstr "Съобщение при подаване:" -#: gitk:4104 +#: gitk:4109 msgid "Matches all Commit Info criteria" msgstr "Съвпадение по вÑички характериÑтики на подаването" -#: gitk:4105 +#: gitk:4110 msgid "Matches no Commit Info criteria" msgstr "Ðе Ñъвпада по Ð½Ð¸ÐºÐ¾Ñ Ð¾Ñ‚ характериÑтиките на подаването" -#: gitk:4106 +#: gitk:4111 msgid "Changes to Files:" msgstr "Промени по файловете:" -#: gitk:4107 +#: gitk:4112 msgid "Fixed String" msgstr "ДоÑловен низ" -#: gitk:4108 +#: gitk:4113 msgid "Regular Expression" msgstr "РегулÑрен израз" -#: gitk:4109 +#: gitk:4114 msgid "Search string:" msgstr "Ðиз за Ñ‚ÑŠÑ€Ñене:" -#: gitk:4110 +#: gitk:4115 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -707,204 +711,204 @@ msgstr "" "Дата на подаване („2 weeks ago“ (преди 2 Ñедмици), „2009-03-17 15:27:38“, " "„March 17, 2009 15:27:38“):" -#: gitk:4111 +#: gitk:4116 msgid "Since:" msgstr "От:" -#: gitk:4112 +#: gitk:4117 msgid "Until:" msgstr "До:" -#: gitk:4113 +#: gitk:4118 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "" "Ограничаване и/или преÑкачане на определен брой верÑии (неотрицателно цÑло " "чиÑло):" -#: gitk:4114 +#: gitk:4119 msgid "Number to show:" msgstr "Брой показани:" -#: gitk:4115 +#: gitk:4120 msgid "Number to skip:" msgstr "Брой преÑкочени:" -#: gitk:4116 +#: gitk:4121 msgid "Miscellaneous options:" msgstr "Разни:" -#: gitk:4117 +#: gitk:4122 msgid "Strictly sort by date" msgstr "Подреждане по дата" -#: gitk:4118 +#: gitk:4123 msgid "Mark branch sides" msgstr "ОтбелÑзване на Ñтраните по клона" -#: gitk:4119 +#: gitk:4124 msgid "Limit to first parent" msgstr "Само Ð¿ÑŠÑ€Ð²Ð¸Ñ Ñ€Ð¾Ð´Ð¸Ñ‚ÐµÐ»" -#: gitk:4120 +#: gitk:4125 msgid "Simple history" msgstr "ОпроÑтена иÑториÑ" -#: gitk:4121 +#: gitk:4126 msgid "Additional arguments to git log:" msgstr "Допълнителни аргументи към „git log“:" -#: gitk:4122 +#: gitk:4127 msgid "Enter files and directories to include, one per line:" msgstr "Въведете файловете и директориите за включване, по елемент на ред" -#: gitk:4123 +#: gitk:4128 msgid "Command to generate more commits to include:" msgstr "" "Команда за генерирането на допълнителни подаваниÑ, които да бъдат включени:" -#: gitk:4247 +#: gitk:4252 msgid "Gitk: edit view" msgstr "Gitk: редактиране на изглед" -#: gitk:4255 +#: gitk:4260 msgid "-- criteria for selecting revisions" msgstr "— критерии за избор на верÑии" -#: gitk:4260 +#: gitk:4265 msgid "View Name" msgstr "Име на изглед" -#: gitk:4335 +#: gitk:4340 msgid "Apply (F5)" msgstr "Прилагане (F5)" -#: gitk:4373 +#: gitk:4378 msgid "Error in commit selection arguments:" msgstr "Грешка в аргументите за избор на подаваниÑ:" -#: gitk:4428 gitk:4481 gitk:4943 gitk:4957 gitk:6227 gitk:12410 gitk:12411 +#: gitk:4433 gitk:4486 gitk:4948 gitk:4962 gitk:6232 gitk:12524 gitk:12525 msgid "None" msgstr "ÐÑма" -#: gitk:5040 gitk:5045 +#: gitk:5045 gitk:5050 msgid "Descendant" msgstr "ÐаÑледник" -#: gitk:5041 +#: gitk:5046 msgid "Not descendant" msgstr "Ðе е наÑледник" -#: gitk:5048 gitk:5053 +#: gitk:5053 gitk:5058 msgid "Ancestor" msgstr "ПредшеÑтвеник" -#: gitk:5049 +#: gitk:5054 msgid "Not ancestor" msgstr "Ðе е предшеÑтвеник" -#: gitk:5343 +#: gitk:5348 msgid "Local changes checked in to index but not committed" msgstr "Локални промени добавени към индекÑа, но неподадени" -#: gitk:5379 +#: gitk:5384 msgid "Local uncommitted changes, not checked in to index" msgstr "Локални промени извън индекÑа" -#: gitk:7153 +#: gitk:7158 msgid "and many more" msgstr "и още много" -#: gitk:7156 +#: gitk:7161 msgid "many" msgstr "много" -#: gitk:7347 +#: gitk:7352 msgid "Tags:" msgstr "Етикети:" -#: gitk:7364 gitk:7370 gitk:8844 +#: gitk:7369 gitk:7375 gitk:8854 msgid "Parent" msgstr "Родител" -#: gitk:7375 +#: gitk:7380 msgid "Child" msgstr "Дете" -#: gitk:7384 +#: gitk:7389 msgid "Branch" msgstr "Клон" -#: gitk:7387 +#: gitk:7392 msgid "Follows" msgstr "Следва" -#: gitk:7390 +#: gitk:7395 msgid "Precedes" msgstr "ПредшеÑтва" -#: gitk:7985 +#: gitk:7990 #, tcl-format msgid "Error getting diffs: %s" msgstr "Грешка при получаването на разликите: %s" -#: gitk:8669 +#: gitk:8679 msgid "Goto:" msgstr "Към ред:" -#: gitk:8690 +#: gitk:8700 #, tcl-format msgid "Short SHA1 id %s is ambiguous" msgstr "Съкратената Ñума по SHA1 %s не е еднозначна" -#: gitk:8697 +#: gitk:8707 #, tcl-format msgid "Revision %s is not known" msgstr "Ðепозната верÑÐ¸Ñ %s" -#: gitk:8707 +#: gitk:8717 #, tcl-format msgid "SHA1 id %s is not known" msgstr "Ðепозната Ñума по SHA1 %s" -#: gitk:8709 +#: gitk:8719 #, tcl-format msgid "Revision %s is not in the current view" msgstr "ВерÑÐ¸Ñ %s не е в Ñ‚ÐµÐºÑƒÑ‰Ð¸Ñ Ð¸Ð·Ð³Ð»ÐµÐ´" -#: gitk:8851 gitk:8866 +#: gitk:8861 gitk:8876 msgid "Date" msgstr "Дата" -#: gitk:8854 +#: gitk:8864 msgid "Children" msgstr "Деца" -#: gitk:8917 +#: gitk:8927 #, tcl-format msgid "Reset %s branch to here" msgstr "ЗанулÑване на клона „%s“ към текущото подаване" -#: gitk:8919 +#: gitk:8929 msgid "Detached head: can't reset" msgstr "ÐеÑвързан връх: невъзможно занулÑване" -#: gitk:9024 gitk:9030 +#: gitk:9034 gitk:9040 msgid "Skipping merge commit " msgstr "ПропуÑкане на подаването на Ñливането" -#: gitk:9039 gitk:9044 +#: gitk:9049 gitk:9054 msgid "Error getting patch ID for " msgstr "Грешка при получаването на идентификатора на " -#: gitk:9040 gitk:9045 +#: gitk:9050 gitk:9055 msgid " - stopping\n" msgstr " — Ñпиране\n" -#: gitk:9050 gitk:9053 gitk:9061 gitk:9075 gitk:9084 +#: gitk:9060 gitk:9063 gitk:9071 gitk:9085 gitk:9094 msgid "Commit " msgstr "Подаване" -#: gitk:9054 +#: gitk:9064 msgid "" " is the same patch as\n" " " @@ -912,7 +916,7 @@ msgstr "" " е Ñъщата кръпка като\n" " " -#: gitk:9062 +#: gitk:9072 msgid "" " differs from\n" " " @@ -920,7 +924,7 @@ msgstr "" " Ñе различава от\n" " " -#: gitk:9064 +#: gitk:9074 msgid "" "Diff of commits:\n" "\n" @@ -928,130 +932,147 @@ msgstr "" "Разлика между подаваниÑта:\n" "\n" -#: gitk:9076 gitk:9085 +#: gitk:9086 gitk:9095 #, tcl-format msgid " has %s children - stopping\n" msgstr " има %s деца — Ñпиране\n" -#: gitk:9104 +#: gitk:9114 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Грешка при запазването на подаването във файл: %s" -#: gitk:9110 +#: gitk:9120 #, tcl-format msgid "Error diffing commits: %s" msgstr "Грешка при изчиÑлÑването на разликите между подаваниÑта: %s" -#: gitk:9156 +#: gitk:9166 msgid "Top" msgstr "Ðай-горе" -#: gitk:9157 +#: gitk:9167 msgid "From" msgstr "От" -#: gitk:9162 +#: gitk:9172 msgid "To" msgstr "До" -#: gitk:9186 +#: gitk:9196 msgid "Generate patch" msgstr "Генериране на кръпка" -#: gitk:9188 +#: gitk:9198 msgid "From:" msgstr "От:" -#: gitk:9197 +#: gitk:9207 msgid "To:" msgstr "До:" -#: gitk:9206 +#: gitk:9216 msgid "Reverse" msgstr "Обръщане" -#: gitk:9208 gitk:9418 +#: gitk:9218 gitk:9428 msgid "Output file:" msgstr "Запазване във файла:" -#: gitk:9214 +#: gitk:9224 msgid "Generate" msgstr "Генериране" -#: gitk:9252 +#: gitk:9262 msgid "Error creating patch:" msgstr "Грешка при Ñъздаването на кръпка:" -#: gitk:9275 gitk:9406 gitk:9463 +#: gitk:9285 gitk:9416 gitk:9504 msgid "ID:" msgstr "Идентификатор:" -#: gitk:9284 +#: gitk:9294 msgid "Tag name:" msgstr "Име на етикет:" -#: gitk:9287 +#: gitk:9297 msgid "Tag message is optional" msgstr "Съобщението за етикет е незадължително" -#: gitk:9289 +#: gitk:9299 msgid "Tag message:" msgstr "Съобщение за етикет:" -#: gitk:9293 gitk:9472 +#: gitk:9303 gitk:9474 msgid "Create" msgstr "Създаване" -#: gitk:9311 +#: gitk:9321 msgid "No tag name specified" msgstr "ЛипÑва име на етикет" -#: gitk:9315 +#: gitk:9325 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Етикетът „%s“ вече ÑъщеÑтвува" -#: gitk:9325 +#: gitk:9335 msgid "Error creating tag:" msgstr "Грешка при Ñъздаването на етикет:" -#: gitk:9415 +#: gitk:9425 msgid "Command:" msgstr "Команда:" -#: gitk:9423 +#: gitk:9433 msgid "Write" msgstr "Запазване" -#: gitk:9441 +#: gitk:9451 msgid "Error writing commit:" msgstr "Грешка при запазването на подаването:" -#: gitk:9468 +#: gitk:9473 +msgid "Create branch" +msgstr "Създаване на клон" + +#: gitk:9489 +#, tcl-format +msgid "Rename branch %s" +msgstr "Преименуване на клона „%s“" + +#: gitk:9490 +msgid "Rename" +msgstr "Преименуване" + +#: gitk:9514 msgid "Name:" msgstr "Име:" -#: gitk:9491 +#: gitk:9538 msgid "Please specify a name for the new branch" msgstr "Укажете име за Ð½Ð¾Ð²Ð¸Ñ ÐºÐ»Ð¾Ð½" -#: gitk:9496 +#: gitk:9543 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "Клонът „%s“ вече ÑъщеÑтвува. Да бъде ли презапиÑан?" -#: gitk:9563 +#: gitk:9587 +msgid "Please specify a new name for the branch" +msgstr "Укажете ново име за клона" + +#: gitk:9650 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Подаването „%s“ вече е включено в клона „%s“ — да бъде ли приложено отново?" -#: gitk:9568 +#: gitk:9655 msgid "Cherry-picking" msgstr "Отбиране" -#: gitk:9577 +#: gitk:9664 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1060,7 +1081,7 @@ msgstr "" "ÐеуÑпешно отбиране, защото във файла „%s“ има локални промени.\n" "Подайте, занулете или ги Ñкатайте и пробвайте отново." -#: gitk:9583 +#: gitk:9670 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1068,29 +1089,29 @@ msgstr "" "ÐеуÑпешно отбиране поради конфликти при Ñливане.\n" "ИÑкате ли да ги коригирате чрез „git citool“?" -#: gitk:9599 gitk:9657 +#: gitk:9686 gitk:9744 msgid "No changes committed" msgstr "Ðе Ñа подадени промени" -#: gitk:9626 +#: gitk:9713 #, tcl-format msgid "Commit %s is not included in branch %s -- really revert it?" msgstr "Подаването „%s“ не е включено в клона „%s“. Да бъде ли отменено?" -#: gitk:9631 +#: gitk:9718 msgid "Reverting" msgstr "ОтмÑна" -#: gitk:9639 +#: gitk:9726 #, tcl-format msgid "" "Revert failed because of local changes to the following files:%s Please " "commit, reset or stash your changes and try again." msgstr "" "ÐеуÑпешна отмÑна, защото във файла „%s“ има локални промени.\n" -"Подайте, занулете или ги Ñкатайте и пробвайте отново.<" +"Подайте, занулете или ги Ñкатайте и пробвайте отново." -#: gitk:9643 +#: gitk:9730 msgid "" "Revert failed because of merge conflict.\n" " Do you wish to run git citool to resolve it?" @@ -1098,66 +1119,71 @@ msgstr "" "ÐеуÑпешно отмÑна поради конфликти при Ñливане.\n" "ИÑкате ли да ги коригирате чрез „git citool“?" -#: gitk:9686 +#: gitk:9773 msgid "Confirm reset" msgstr "Потвърждаване на занулÑването" -#: gitk:9688 +#: gitk:9775 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Да Ñе занули ли клонът „%s“ към „%s“?" -#: gitk:9690 +#: gitk:9777 msgid "Reset type:" msgstr "Вид занулÑване:" -#: gitk:9693 +#: gitk:9780 msgid "Soft: Leave working tree and index untouched" msgstr "Слабо: работното дърво и индекÑа оÑтават Ñъщите" -#: gitk:9696 +#: gitk:9783 msgid "Mixed: Leave working tree untouched, reset index" msgstr "СмеÑено: работното дърво оÑтава Ñъщото, индекÑÑŠÑ‚ Ñе занулÑва" -#: gitk:9699 +#: gitk:9786 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" msgstr "" "Силно: занулÑване и на работното дърво, и на индекÑа\n" -"(*ВСИЧКИ* локални промени ще бъдат безвъзвратно загубени)" +"(ВСИЧКИ локални промени ще бъдат безвъзвратно загубени)" -#: gitk:9716 +#: gitk:9803 msgid "Resetting" msgstr "ЗанулÑване" -#: gitk:9776 +#: gitk:9876 +#, tcl-format +msgid "A local branch named %s exists already" +msgstr "Вече ÑъщеÑтвува локален клон „%s“." + +#: gitk:9884 msgid "Checking out" msgstr "ИзтеглÑне" -#: gitk:9829 +#: gitk:9943 msgid "Cannot delete the currently checked-out branch" msgstr "Текущо изтеглениÑÑ‚ клон не може да бъде изтрит" -#: gitk:9835 +#: gitk:9949 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" "Really delete branch %s?" msgstr "" "ПодаваниÑта на клона „%s“ не Ñа на никой друг клон.\n" -"ÐаиÑтина ли да Ñе изтрие клонът „%s“?" +"ÐаиÑтина ли иÑкате да изтриете клона „%s“?" -#: gitk:9866 +#: gitk:9980 #, tcl-format msgid "Tags and heads: %s" msgstr "Етикети и върхове: %s" -#: gitk:9883 +#: gitk:9997 msgid "Filter" msgstr "Филтриране" -#: gitk:10179 +#: gitk:10293 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1165,201 +1191,201 @@ msgstr "" "Грешка при прочитането на топологиÑта на подаваниÑта. ИнформациÑта за клона " "и предшеÑтващите/Ñледващите етикети ще е непълна." -#: gitk:11156 +#: gitk:11270 msgid "Tag" msgstr "Етикет" -#: gitk:11160 +#: gitk:11274 msgid "Id" msgstr "Идентификатор" -#: gitk:11243 +#: gitk:11357 msgid "Gitk font chooser" msgstr "Избор на шрифт за Gitk" -#: gitk:11260 +#: gitk:11374 msgid "B" msgstr "Ч" -#: gitk:11263 +#: gitk:11377 msgid "I" msgstr "К" -#: gitk:11381 +#: gitk:11495 msgid "Commit list display options" msgstr "ÐаÑтройки на ÑпиÑъка Ñ Ð¿Ð¾Ð´Ð°Ð²Ð°Ð½Ð¸Ñ" -#: gitk:11384 +#: gitk:11498 msgid "Maximum graph width (lines)" msgstr "МакÑимална широчина на графа (в редове)" -#: gitk:11388 +#: gitk:11502 #, no-tcl-format msgid "Maximum graph width (% of pane)" msgstr "МакÑимална широчина на графа (% от панела)" -#: gitk:11391 +#: gitk:11505 msgid "Show local changes" msgstr "Показване на локалните промени" -#: gitk:11394 +#: gitk:11508 msgid "Auto-select SHA1 (length)" msgstr "Ðвтоматично избиране на SHA1 (дължина)" -#: gitk:11398 +#: gitk:11512 msgid "Hide remote refs" msgstr "Скриване на отдалечените указатели" -#: gitk:11402 +#: gitk:11516 msgid "Diff display options" msgstr "ÐаÑтройки на показването на разликите" -#: gitk:11404 +#: gitk:11518 msgid "Tab spacing" msgstr "Широчина на табулатора" -#: gitk:11407 +#: gitk:11521 msgid "Display nearby tags/heads" msgstr "Извеждане на близките етикети и върхове" -#: gitk:11410 +#: gitk:11524 msgid "Maximum # tags/heads to show" msgstr "МакÑимален брой етикети/върхове за показване" -#: gitk:11413 +#: gitk:11527 msgid "Limit diffs to listed paths" msgstr "Разлика Ñамо в избраните пътища" -#: gitk:11416 +#: gitk:11530 msgid "Support per-file encodings" msgstr "Поддръжка на различни ÐºÐ¾Ð´Ð¸Ñ€Ð°Ð½Ð¸Ñ Ð·Ð° вÑеки файл" -#: gitk:11422 gitk:11569 +#: gitk:11536 gitk:11683 msgid "External diff tool" msgstr "Външен инÑтрумент за разлики" -#: gitk:11423 +#: gitk:11537 msgid "Choose..." msgstr "Избор…" -#: gitk:11428 +#: gitk:11542 msgid "General options" msgstr "Общи наÑтройки" -#: gitk:11431 +#: gitk:11545 msgid "Use themed widgets" msgstr "Използване на тема за графичните обекти" -#: gitk:11433 +#: gitk:11547 msgid "(change requires restart)" msgstr "(промÑната изиÑква реÑтартиране на Gitk)" -#: gitk:11435 +#: gitk:11549 msgid "(currently unavailable)" msgstr "(в момента недоÑтъпно)" -#: gitk:11446 +#: gitk:11560 msgid "Colors: press to choose" msgstr "Цветове: избира Ñе Ñ Ð½Ð°Ñ‚Ð¸Ñкане" -#: gitk:11449 +#: gitk:11563 msgid "Interface" msgstr "ИнтерфейÑ" -#: gitk:11450 +#: gitk:11564 msgid "interface" msgstr "интерфейÑ" -#: gitk:11453 +#: gitk:11567 msgid "Background" msgstr "Фон" -#: gitk:11454 gitk:11484 +#: gitk:11568 gitk:11598 msgid "background" msgstr "фон" -#: gitk:11457 +#: gitk:11571 msgid "Foreground" msgstr "Знаци" -#: gitk:11458 +#: gitk:11572 msgid "foreground" msgstr "знаци" -#: gitk:11461 +#: gitk:11575 msgid "Diff: old lines" msgstr "Разлика: Ñтари редове" -#: gitk:11462 +#: gitk:11576 msgid "diff old lines" msgstr "разлика, Ñтари редове" -#: gitk:11466 +#: gitk:11580 msgid "Diff: new lines" msgstr "Разлика: нови редове" -#: gitk:11467 +#: gitk:11581 msgid "diff new lines" msgstr "разлика, нови редове" -#: gitk:11471 +#: gitk:11585 msgid "Diff: hunk header" msgstr "Разлика: начало на парче" -#: gitk:11473 +#: gitk:11587 msgid "diff hunk header" msgstr "разлика, начало на парче" -#: gitk:11477 +#: gitk:11591 msgid "Marked line bg" msgstr "Фон на отбелÑзан ред" -#: gitk:11479 +#: gitk:11593 msgid "marked line background" msgstr "фон на отбелÑзан ред" -#: gitk:11483 +#: gitk:11597 msgid "Select bg" msgstr "Избор на фон" -#: gitk:11492 +#: gitk:11606 msgid "Fonts: press to choose" msgstr "Шрифтове: избира Ñе Ñ Ð½Ð°Ñ‚Ð¸Ñкане" -#: gitk:11494 +#: gitk:11608 msgid "Main font" msgstr "ОÑновен шрифт" -#: gitk:11495 +#: gitk:11609 msgid "Diff display font" msgstr "Шрифт за разликите" -#: gitk:11496 +#: gitk:11610 msgid "User interface font" msgstr "Шрифт на интерфейÑа" -#: gitk:11518 +#: gitk:11632 msgid "Gitk preferences" msgstr "ÐаÑтройки на Gitk" -#: gitk:11527 +#: gitk:11641 msgid "General" msgstr "Общи" -#: gitk:11528 +#: gitk:11642 msgid "Colors" msgstr "Цветове" -#: gitk:11529 +#: gitk:11643 msgid "Fonts" msgstr "Шрифтове" -#: gitk:11579 +#: gitk:11693 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: избор на цвÑÑ‚ на „%s“" -#: gitk:12092 +#: gitk:12206 msgid "" "Sorry, gitk cannot run with this version of Tcl/Tk.\n" " Gitk requires at least Tcl/Tk 8.4." @@ -1367,15 +1393,15 @@ msgstr "" "Тази верÑÐ¸Ñ Ð½Ð° Tcl/Tk не Ñе поддържа от Gitk.\n" " Ðеобходима ви е поне Tcl/Tk 8.4." -#: gitk:12302 +#: gitk:12416 msgid "Cannot find a git repository here." msgstr "Тук липÑва хранилище на Git." -#: gitk:12349 +#: gitk:12463 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Ðееднозначен аргумент „%s“: има и такава верÑиÑ, и такъв файл" -#: gitk:12361 +#: gitk:12475 msgid "Bad arguments to gitk:" msgstr "Ðеправилни аргументи на gitk:" @@ -11,6 +11,10 @@ static struct strbuf git_default_name = STRBUF_INIT; static struct strbuf git_default_email = STRBUF_INIT; static struct strbuf git_default_date = STRBUF_INIT; +static struct strbuf git_author_name = STRBUF_INIT; +static struct strbuf git_author_email = STRBUF_INIT; +static struct strbuf git_committer_name = STRBUF_INIT; +static struct strbuf git_committer_email = STRBUF_INIT; static int default_email_is_bogus; static int default_name_is_bogus; @@ -355,7 +359,7 @@ N_("\n" "\n"); const char *fmt_ident(const char *name, const char *email, - const char *date_str, int flag) + enum want_ident whose_ident, const char *date_str, int flag) { static struct strbuf ident = STRBUF_INIT; int strict = (flag & IDENT_STRICT); @@ -363,6 +367,12 @@ const char *fmt_ident(const char *name, const char *email, int want_name = !(flag & IDENT_NO_NAME); if (!email) { + if (whose_ident == WANT_AUTHOR_IDENT && git_author_email.len) + email = git_author_email.buf; + else if (whose_ident == WANT_COMMITTER_IDENT && git_committer_email.len) + email = git_committer_email.buf; + } + if (!email) { if (strict && ident_use_config_only && !(ident_config_given & IDENT_MAIL_GIVEN)) { fputs(_(env_hint), stderr); @@ -378,6 +388,13 @@ const char *fmt_ident(const char *name, const char *email, if (want_name) { int using_default = 0; if (!name) { + if (whose_ident == WANT_AUTHOR_IDENT && git_author_name.len) + name = git_author_name.buf; + else if (whose_ident == WANT_COMMITTER_IDENT && + git_committer_name.len) + name = git_committer_name.buf; + } + if (!name) { if (strict && ident_use_config_only && !(ident_config_given & IDENT_NAME_GIVEN)) { fputs(_(env_hint), stderr); @@ -425,9 +442,25 @@ const char *fmt_ident(const char *name, const char *email, return ident.buf; } -const char *fmt_name(const char *name, const char *email) +const char *fmt_name(enum want_ident whose_ident) { - return fmt_ident(name, email, NULL, IDENT_STRICT | IDENT_NO_DATE); + char *name = NULL; + char *email = NULL; + + switch (whose_ident) { + case WANT_BLANK_IDENT: + break; + case WANT_AUTHOR_IDENT: + name = getenv("GIT_AUTHOR_NAME"); + email = getenv("GIT_AUTHOR_EMAIL"); + break; + case WANT_COMMITTER_IDENT: + name = getenv("GIT_COMMITTER_NAME"); + email = getenv("GIT_COMMITTER_EMAIL"); + break; + } + return fmt_ident(name, email, whose_ident, NULL, + IDENT_STRICT | IDENT_NO_DATE); } const char *git_author_info(int flag) @@ -438,6 +471,7 @@ const char *git_author_info(int flag) author_ident_explicitly_given |= IDENT_MAIL_GIVEN; return fmt_ident(getenv("GIT_AUTHOR_NAME"), getenv("GIT_AUTHOR_EMAIL"), + WANT_AUTHOR_IDENT, getenv("GIT_AUTHOR_DATE"), flag); } @@ -450,6 +484,7 @@ const char *git_committer_info(int flag) committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; return fmt_ident(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"), + WANT_COMMITTER_IDENT, getenv("GIT_COMMITTER_DATE"), flag); } @@ -473,10 +508,45 @@ int author_ident_sufficiently_given(void) return ident_is_sufficient(author_ident_explicitly_given); } -int git_ident_config(const char *var, const char *value, void *data) +static int set_ident(const char *var, const char *value) { - if (!strcmp(var, "user.useconfigonly")) { - ident_use_config_only = git_config_bool(var, value); + if (!strcmp(var, "author.name")) { + if (!value) + return config_error_nonbool(var); + strbuf_reset(&git_author_name); + strbuf_addstr(&git_author_name, value); + author_ident_explicitly_given |= IDENT_NAME_GIVEN; + ident_config_given |= IDENT_NAME_GIVEN; + return 0; + } + + if (!strcmp(var, "author.email")) { + if (!value) + return config_error_nonbool(var); + strbuf_reset(&git_author_email); + strbuf_addstr(&git_author_email, value); + author_ident_explicitly_given |= IDENT_MAIL_GIVEN; + ident_config_given |= IDENT_MAIL_GIVEN; + return 0; + } + + if (!strcmp(var, "committer.name")) { + if (!value) + return config_error_nonbool(var); + strbuf_reset(&git_committer_name); + strbuf_addstr(&git_committer_name, value); + committer_ident_explicitly_given |= IDENT_NAME_GIVEN; + ident_config_given |= IDENT_NAME_GIVEN; + return 0; + } + + if (!strcmp(var, "committer.email")) { + if (!value) + return config_error_nonbool(var); + strbuf_reset(&git_committer_email); + strbuf_addstr(&git_committer_email, value); + committer_ident_explicitly_given |= IDENT_MAIL_GIVEN; + ident_config_given |= IDENT_MAIL_GIVEN; return 0; } @@ -505,6 +575,16 @@ int git_ident_config(const char *var, const char *value, void *data) return 0; } +int git_ident_config(const char *var, const char *value, void *data) +{ + if (!strcmp(var, "user.useconfigonly")) { + ident_use_config_only = git_config_bool(var, value); + return 0; + } + + return set_ident(var, value); +} + static int buf_cmp(const char *a_begin, const char *a_end, const char *b_begin, const char *b_end) { diff --git a/list-objects-filter-options.c b/list-objects-filter-options.c index b71bd1fb65..c0036f7378 100644 --- a/list-objects-filter-options.c +++ b/list-objects-filter-options.c @@ -82,6 +82,10 @@ static int gently_parse_list_objects_filter( filter_options->sparse_path_value = strdup(v0); return 0; } + /* + * Please update _git_fetch() in git-completion.bash when you + * add new filters + */ if (errbuf) strbuf_addf(errbuf, "invalid filter-spec '%s'", arg); diff --git a/log-tree.c b/log-tree.c index 3cb14256ec..1e56df62a7 100644 --- a/log-tree.c +++ b/log-tree.c @@ -687,8 +687,7 @@ void show_log(struct rev_info *opt) */ if (ctx.need_8bit_cte >= 0 && opt->add_signoff) ctx.need_8bit_cte = - has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"), - getenv("GIT_COMMITTER_EMAIL"))); + has_non_ascii(fmt_name(WANT_COMMITTER_IDENT)); ctx.date_mode = opt->date_mode; ctx.date_mode_explicit = opt->date_mode_explicit; ctx.abbrev = opt->diffopt.abbrev; diff --git a/merge-recursive.c b/merge-recursive.c index 4851825aeb..6c40c61c47 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -1402,8 +1402,7 @@ static int merge_mode_and_contents(struct merge_options *o, static int handle_rename_via_dir(struct merge_options *o, struct diff_filepair *pair, - const char *rename_branch, - const char *other_branch) + const char *rename_branch) { /* * Handle file adds that need to be renamed due to directory rename @@ -2213,8 +2212,7 @@ static void handle_directory_level_conflicts(struct merge_options *o, remove_hashmap_entries(dir_re_merge, &remove_from_merge); } -static struct hashmap *get_directory_renames(struct diff_queue_struct *pairs, - struct tree *tree) +static struct hashmap *get_directory_renames(struct diff_queue_struct *pairs) { struct hashmap *dir_renames; struct hashmap_iter iter; @@ -2460,8 +2458,7 @@ static void apply_directory_rename_modifications(struct merge_options *o, struct tree *o_tree, struct tree *a_tree, struct tree *b_tree, - struct string_list *entries, - int *clean) + struct string_list *entries) { struct string_list_item *item; int stage = (tree == a_tree ? 2 : 3); @@ -2632,8 +2629,7 @@ static struct string_list *get_renames(struct merge_options *o, apply_directory_rename_modifications(o, pair, new_path, re, tree, o_tree, a_tree, b_tree, - entries, - clean_merge); + entries); } hashmap_iter_init(&collisions, &iter); @@ -2944,8 +2940,8 @@ static int detect_and_process_renames(struct merge_options *o, merge_pairs = get_diffpairs(o, common, merge); if (o->detect_directory_renames) { - dir_re_head = get_directory_renames(head_pairs, head); - dir_re_merge = get_directory_renames(merge_pairs, merge); + dir_re_head = get_directory_renames(head_pairs); + dir_re_merge = get_directory_renames(merge_pairs); handle_directory_level_conflicts(o, dir_re_head, head, @@ -3268,8 +3264,7 @@ static int process_entry(struct merge_options *o, clean_merge = 1; if (handle_rename_via_dir(o, conflict_info->pair1, - conflict_info->branch1, - conflict_info->branch2)) + conflict_info->branch1)) clean_merge = -1; break; case RENAME_ADD: @@ -3764,6 +3759,10 @@ int parse_merge_opt(struct merge_options *o, const char *s) return -1; o->merge_detect_rename = 1; } + /* + * Please update $__git_merge_strategy_options in + * git-completion.bash when you add new options + */ else return -1; return 0; diff --git a/pack-objects.c b/pack-objects.c index e7cd337bee..ce33b8906e 100644 --- a/pack-objects.c +++ b/pack-objects.c @@ -119,8 +119,7 @@ static void prepare_in_pack_by_idx(struct packing_data *pdata) * this fall back code, just stay simple and fall back to using * in_pack[] array. */ -void oe_map_new_pack(struct packing_data *pack, - struct packed_git *p) +void oe_map_new_pack(struct packing_data *pack) { uint32_t i; diff --git a/pack-objects.h b/pack-objects.h index 6bfacc7d2c..6fde7ce27c 100644 --- a/pack-objects.h +++ b/pack-objects.h @@ -247,14 +247,14 @@ static inline struct packed_git *oe_in_pack(const struct packing_data *pack, return pack->in_pack[e - pack->objects]; } -void oe_map_new_pack(struct packing_data *pack, - struct packed_git *p); +void oe_map_new_pack(struct packing_data *pack); + static inline void oe_set_in_pack(struct packing_data *pack, struct object_entry *e, struct packed_git *p) { if (!p->index) - oe_map_new_pack(pack, p); + oe_map_new_pack(pack); if (pack->in_pack_by_idx) e->in_pack_idx = p->index; else @@ -100,6 +100,7 @@ void prepare_pager_args(struct child_process *pager_process, const char *pager) argv_array_push(&pager_process->args, pager); pager_process->use_shell = 1; setup_pager_env(&pager_process->env_array); + pager_process->trace2_child_class = "pager"; } void setup_pager(void) diff --git a/parse-options-cb.c b/parse-options-cb.c index e2f3eaed07..2733393546 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -170,9 +170,12 @@ int parse_opt_noop_cb(const struct option *opt, const char *arg, int unset) * "-h" output even if it's not being handled directly by * parse_options(). */ -int parse_opt_unknown_cb(const struct option *opt, const char *arg, int unset) +enum parse_opt_result parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, + const struct option *opt, + const char *arg, int unset) { - return -2; + BUG_ON_OPT_ARG(arg); + return PARSE_OPT_UNKNOWN; } /** diff --git a/parse-options.c b/parse-options.c index 9f84bacce6..cec74522e5 100644 --- a/parse-options.c +++ b/parse-options.c @@ -20,8 +20,9 @@ int optbug(const struct option *opt, const char *reason) return error("BUG: switch '%c' %s", opt->short_name, reason); } -static int get_arg(struct parse_opt_ctx_t *p, const struct option *opt, - int flags, const char **arg) +static enum parse_opt_result get_arg(struct parse_opt_ctx_t *p, + const struct option *opt, + int flags, const char **arg) { if (p->opt) { *arg = p->opt; @@ -44,9 +45,10 @@ static void fix_filename(const char *prefix, const char **file) *file = prefix_filename(prefix, *file); } -static int opt_command_mode_error(const struct option *opt, - const struct option *all_opts, - int flags) +static enum parse_opt_result opt_command_mode_error( + const struct option *opt, + const struct option *all_opts, + int flags) { const struct option *that; struct strbuf that_name = STRBUF_INIT; @@ -69,16 +71,16 @@ static int opt_command_mode_error(const struct option *opt, error(_("%s is incompatible with %s"), optname(opt, flags), that_name.buf); strbuf_release(&that_name); - return -1; + return PARSE_OPT_ERROR; } return error(_("%s : incompatible with something else"), optname(opt, flags)); } -static int get_value(struct parse_opt_ctx_t *p, - const struct option *opt, - const struct option *all_opts, - int flags) +static enum parse_opt_result get_value(struct parse_opt_ctx_t *p, + const struct option *opt, + const struct option *all_opts, + int flags) { const char *s, *arg; const int unset = flags & OPT_UNSET; @@ -93,7 +95,7 @@ static int get_value(struct parse_opt_ctx_t *p, switch (opt->type) { case OPTION_LOWLEVEL_CALLBACK: - return (*(parse_opt_ll_cb *)opt->callback)(p, opt, unset); + return opt->ll_callback(p, opt, NULL, unset); case OPTION_BIT: if (unset) @@ -109,6 +111,13 @@ static int get_value(struct parse_opt_ctx_t *p, *(int *)opt->value &= ~opt->defval; return 0; + case OPTION_BITOP: + if (unset) + BUG("BITOP can't have unset form"); + *(int *)opt->value &= ~opt->extra; + *(int *)opt->value |= opt->defval; + return 0; + case OPTION_COUNTUP: if (*(int *)opt->value < 0) *(int *)opt->value = 0; @@ -152,16 +161,27 @@ static int get_value(struct parse_opt_ctx_t *p, return err; case OPTION_CALLBACK: + { + const char *p_arg = NULL; + int p_unset; + if (unset) - return (*opt->callback)(opt, NULL, 1) ? (-1) : 0; - if (opt->flags & PARSE_OPT_NOARG) - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; - if (opt->flags & PARSE_OPT_OPTARG && !p->opt) - return (*opt->callback)(opt, NULL, 0) ? (-1) : 0; - if (get_arg(p, opt, flags, &arg)) + p_unset = 1; + else if (opt->flags & PARSE_OPT_NOARG) + p_unset = 0; + else if (opt->flags & PARSE_OPT_OPTARG && !p->opt) + p_unset = 0; + else if (get_arg(p, opt, flags, &arg)) return -1; - return (*opt->callback)(opt, arg, 0) ? (-1) : 0; - + else { + p_unset = 0; + p_arg = arg; + } + if (opt->callback) + return (*opt->callback)(opt, p_arg, p_unset) ? (-1) : 0; + else + return (*opt->ll_callback)(p, opt, p_arg, p_unset); + } case OPTION_INTEGER: if (unset) { *(int *)opt->value = 0; @@ -201,7 +221,8 @@ static int get_value(struct parse_opt_ctx_t *p, } } -static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *options) +static enum parse_opt_result parse_short_opt(struct parse_opt_ctx_t *p, + const struct option *options) { const struct option *all_opts = options; const struct option *numopt = NULL; @@ -228,15 +249,19 @@ static int parse_short_opt(struct parse_opt_ctx_t *p, const struct option *optio len++; arg = xmemdupz(p->opt, len); p->opt = p->opt[len] ? p->opt + len : NULL; - rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0; + if (numopt->callback) + rc = (*numopt->callback)(numopt, arg, 0) ? (-1) : 0; + else + rc = (*numopt->ll_callback)(p, numopt, arg, 0); free(arg); return rc; } - return -2; + return PARSE_OPT_UNKNOWN; } -static int parse_long_opt(struct parse_opt_ctx_t *p, const char *arg, - const struct option *options) +static enum parse_opt_result parse_long_opt( + struct parse_opt_ctx_t *p, const char *arg, + const struct option *options) { const struct option *all_opts = options; const char *arg_end = strchrnul(arg, '='); @@ -262,11 +287,12 @@ again: if (*rest) continue; p->out[p->cpidx++] = arg - 2; - return 0; + return PARSE_OPT_DONE; } if (!rest) { /* abbreviated? */ - if (!strncmp(long_name, arg, arg_end - arg)) { + if (!(p->flags & PARSE_OPT_KEEP_UNKNOWN) && + !strncmp(long_name, arg, arg_end - arg)) { is_abbreviated: if (abbrev_option) { /* @@ -326,11 +352,11 @@ is_abbreviated: ambiguous_option->long_name, (abbrev_flags & OPT_UNSET) ? "no-" : "", abbrev_option->long_name); - return -3; + return PARSE_OPT_HELP; } if (abbrev_option) return get_value(p, abbrev_option, all_opts, abbrev_flags); - return -2; + return PARSE_OPT_UNKNOWN; } static int parse_nodash_opt(struct parse_opt_ctx_t *p, const char *arg, @@ -400,6 +426,19 @@ static void parse_options_check(const struct option *opts) if ((opts->flags & PARSE_OPT_OPTARG) || !(opts->flags & PARSE_OPT_NOARG)) err |= optbug(opts, "should not accept an argument"); + break; + case OPTION_CALLBACK: + if (!opts->callback && !opts->ll_callback) + BUG("OPTION_CALLBACK needs one callback"); + if (opts->callback && opts->ll_callback) + BUG("OPTION_CALLBACK can't have two callbacks"); + break; + case OPTION_LOWLEVEL_CALLBACK: + if (!opts->ll_callback) + BUG("OPTION_LOWLEVEL_CALLBACK needs a callback"); + if (opts->callback) + BUG("OPTION_LOWLEVEL_CALLBACK needs no high level callback"); + break; default: ; /* ok. (usually accepts an argument) */ } @@ -416,15 +455,24 @@ void parse_options_start(struct parse_opt_ctx_t *ctx, const struct option *options, int flags) { memset(ctx, 0, sizeof(*ctx)); - ctx->argc = ctx->total = argc - 1; - ctx->argv = argv + 1; - ctx->out = argv; + ctx->argc = argc; + ctx->argv = argv; + if (!(flags & PARSE_OPT_ONE_SHOT)) { + ctx->argc--; + ctx->argv++; + } + ctx->total = ctx->argc; + ctx->out = argv; ctx->prefix = prefix; ctx->cpidx = ((flags & PARSE_OPT_KEEP_ARGV0) != 0); ctx->flags = flags; if ((flags & PARSE_OPT_KEEP_UNKNOWN) && - (flags & PARSE_OPT_STOP_AT_NON_OPTION)) + (flags & PARSE_OPT_STOP_AT_NON_OPTION) && + !(flags & PARSE_OPT_ONE_SHOT)) BUG("STOP_AT_NON_OPTION and KEEP_UNKNOWN don't go together"); + if ((flags & PARSE_OPT_ONE_SHOT) && + (flags & PARSE_OPT_KEEP_ARGV0)) + BUG("Can't keep argv0 if you don't have it"); parse_options_check(options); } @@ -536,6 +584,10 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, for (; ctx->argc; ctx->argc--, ctx->argv++) { const char *arg = ctx->argv[0]; + if (ctx->flags & PARSE_OPT_ONE_SHOT && + ctx->argc != ctx->total) + break; + if (*arg != '-' || !arg[1]) { if (parse_nodash_opt(ctx, arg, options) == 0) continue; @@ -556,22 +608,28 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, if (arg[1] != '-') { ctx->opt = arg + 1; switch (parse_short_opt(ctx, options)) { - case -1: + case PARSE_OPT_ERROR: return PARSE_OPT_ERROR; - case -2: + case PARSE_OPT_UNKNOWN: if (ctx->opt) check_typos(arg + 1, options); if (internal_help && *ctx->opt == 'h') goto show_usage; goto unknown; + case PARSE_OPT_NON_OPTION: + case PARSE_OPT_HELP: + case PARSE_OPT_COMPLETE: + BUG("parse_short_opt() cannot return these"); + case PARSE_OPT_DONE: + break; } if (ctx->opt) check_typos(arg + 1, options); while (ctx->opt) { switch (parse_short_opt(ctx, options)) { - case -1: + case PARSE_OPT_ERROR: return PARSE_OPT_ERROR; - case -2: + case PARSE_OPT_UNKNOWN: if (internal_help && *ctx->opt == 'h') goto show_usage; @@ -583,6 +641,12 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, ctx->argv[0] = xstrdup(ctx->opt - 1); *(char *)ctx->argv[0] = '-'; goto unknown; + case PARSE_OPT_NON_OPTION: + case PARSE_OPT_COMPLETE: + case PARSE_OPT_HELP: + BUG("parse_short_opt() cannot return these"); + case PARSE_OPT_DONE: + break; } } continue; @@ -601,15 +665,22 @@ int parse_options_step(struct parse_opt_ctx_t *ctx, if (internal_help && !strcmp(arg + 2, "help")) goto show_usage; switch (parse_long_opt(ctx, arg + 2, options)) { - case -1: + case PARSE_OPT_ERROR: return PARSE_OPT_ERROR; - case -2: + case PARSE_OPT_UNKNOWN: goto unknown; - case -3: + case PARSE_OPT_HELP: goto show_usage; + case PARSE_OPT_NON_OPTION: + case PARSE_OPT_COMPLETE: + BUG("parse_long_opt() cannot return these"); + case PARSE_OPT_DONE: + break; } continue; unknown: + if (ctx->flags & PARSE_OPT_ONE_SHOT) + break; if (!(ctx->flags & PARSE_OPT_KEEP_UNKNOWN)) return PARSE_OPT_UNKNOWN; ctx->out[ctx->cpidx++] = ctx->argv[0]; @@ -623,6 +694,9 @@ unknown: int parse_options_end(struct parse_opt_ctx_t *ctx) { + if (ctx->flags & PARSE_OPT_ONE_SHOT) + return ctx->total - ctx->argc; + MOVE_ARRAY(ctx->out + ctx->cpidx, ctx->argv, ctx->argc); ctx->out[ctx->cpidx + ctx->argc] = NULL; return ctx->cpidx + ctx->argc; diff --git a/parse-options.h b/parse-options.h index 14fe32428e..7d83e2971d 100644 --- a/parse-options.h +++ b/parse-options.h @@ -10,6 +10,7 @@ enum parse_opt_type { /* options with no arguments */ OPTION_BIT, OPTION_NEGBIT, + OPTION_BITOP, OPTION_COUNTUP, OPTION_SET_INT, OPTION_CMDMODE, @@ -27,7 +28,8 @@ enum parse_opt_flags { PARSE_OPT_STOP_AT_NON_OPTION = 2, PARSE_OPT_KEEP_ARGV0 = 4, PARSE_OPT_KEEP_UNKNOWN = 8, - PARSE_OPT_NO_INTERNAL_HELP = 16 + PARSE_OPT_NO_INTERNAL_HELP = 16, + PARSE_OPT_ONE_SHOT = 32 }; enum parse_opt_option_flags { @@ -47,8 +49,9 @@ struct option; typedef int parse_opt_cb(const struct option *, const char *arg, int unset); struct parse_opt_ctx_t; -typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx, - const struct option *opt, int unset); +typedef enum parse_opt_result parse_opt_ll_cb(struct parse_opt_ctx_t *ctx, + const struct option *opt, + const char *arg, int unset); /* * `type`:: @@ -98,13 +101,16 @@ typedef int parse_opt_ll_cb(struct parse_opt_ctx_t *ctx, * the option takes optional argument. * * `callback`:: - * pointer to the callback to use for OPTION_CALLBACK or - * OPTION_LOWLEVEL_CALLBACK. + * pointer to the callback to use for OPTION_CALLBACK * * `defval`:: * default value to fill (*->value) with for PARSE_OPT_OPTARG. * OPTION_{BIT,SET_INT} store the {mask,integer} to put in the value when met. * CALLBACKS can use it like they want. + * + * `ll_callback`:: + * pointer to the callback to use for OPTION_LOWLEVEL_CALLBACK + * */ struct option { enum parse_opt_type type; @@ -117,6 +123,8 @@ struct option { int flags; parse_opt_cb *callback; intptr_t defval; + parse_opt_ll_cb *ll_callback; + intptr_t extra; }; #define OPT_BIT_F(s, l, v, h, b, f) { OPTION_BIT, (s), (l), (v), NULL, (h), \ @@ -126,12 +134,17 @@ struct option { #define OPT_SET_INT_F(s, l, v, h, i, f) { OPTION_SET_INT, (s), (l), (v), NULL, \ (h), PARSE_OPT_NOARG | (f), NULL, (i) } #define OPT_BOOL_F(s, l, v, h, f) OPT_SET_INT_F(s, l, v, h, 1, f) +#define OPT_CALLBACK_F(s, l, v, a, h, f, cb) \ + { OPTION_CALLBACK, (s), (l), (v), (a), (h), (f), (cb) } #define OPT_END() { OPTION_END } #define OPT_ARGUMENT(l, h) { OPTION_ARGUMENT, 0, (l), NULL, NULL, \ (h), PARSE_OPT_NOARG} #define OPT_GROUP(h) { OPTION_GROUP, 0, NULL, NULL, NULL, (h) } #define OPT_BIT(s, l, v, h, b) OPT_BIT_F(s, l, v, h, b, 0) +#define OPT_BITOP(s, l, v, h, set, clear) { OPTION_BITOP, (s), (l), (v), NULL, (h), \ + PARSE_OPT_NOARG|PARSE_OPT_NONEG, NULL, \ + (set), NULL, (clear) } #define OPT_NEGBIT(s, l, v, h, b) { OPTION_NEGBIT, (s), (l), (v), NULL, \ (h), PARSE_OPT_NOARG, NULL, (b) } #define OPT_COUNTUP(s, l, v, h) OPT_COUNTUP_F(s, l, v, h, 0) @@ -153,8 +166,7 @@ struct option { #define OPT_EXPIRY_DATE(s, l, v, h) \ { OPTION_CALLBACK, (s), (l), (v), N_("expiry-date"),(h), 0, \ parse_opt_expiry_date_cb } -#define OPT_CALLBACK(s, l, v, a, h, f) \ - { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } +#define OPT_CALLBACK(s, l, v, a, h, f) OPT_CALLBACK_F(s, l, v, a, h, 0, f) #define OPT_NUMBER_CALLBACK(v, h, f) \ { OPTION_NUMBER, 0, NULL, (v), NULL, (h), \ PARSE_OPT_NOARG | PARSE_OPT_NONEG, (f) } @@ -169,23 +181,31 @@ struct option { N_("no-op (backward compatibility)"), \ PARSE_OPT_HIDDEN | PARSE_OPT_NOARG, parse_opt_noop_cb } -/* parse_options() will filter out the processed options and leave the - * non-option arguments in argv[]. usagestr strings should be marked - * for translation with N_(). +/* + * parse_options() will filter out the processed options and leave the + * non-option arguments in argv[]. argv0 is assumed program name and + * skipped. + * + * usagestr strings should be marked for translation with N_(). + * * Returns the number of arguments left in argv[]. + * + * In one-shot mode, argv0 is not a program name, argv[] is left + * untouched and parse_options() returns the number of options + * processed. */ -extern int parse_options(int argc, const char **argv, const char *prefix, - const struct option *options, - const char * const usagestr[], int flags); +int parse_options(int argc, const char **argv, const char *prefix, + const struct option *options, + const char * const usagestr[], int flags); -extern NORETURN void usage_with_options(const char * const *usagestr, - const struct option *options); +NORETURN void usage_with_options(const char * const *usagestr, + const struct option *options); -extern NORETURN void usage_msg_opt(const char *msg, - const char * const *usagestr, - const struct option *options); +NORETURN void usage_msg_opt(const char *msg, + const char * const *usagestr, + const struct option *options); -extern int optbug(const struct option *opt, const char *reason); +int optbug(const struct option *opt, const char *reason); const char *optname(const struct option *opt, int flags); /* @@ -204,12 +224,12 @@ const char *optname(const struct option *opt, int flags); /*----- incremental advanced APIs -----*/ -enum { - PARSE_OPT_COMPLETE = -2, - PARSE_OPT_HELP = -1, - PARSE_OPT_DONE, +enum parse_opt_result { + PARSE_OPT_COMPLETE = -3, + PARSE_OPT_HELP = -2, + PARSE_OPT_ERROR = -1, /* must be the same as error() */ + PARSE_OPT_DONE = 0, /* fixed so that "return 0" works */ PARSE_OPT_NON_OPTION, - PARSE_OPT_ERROR, PARSE_OPT_UNKNOWN }; @@ -227,31 +247,31 @@ struct parse_opt_ctx_t { const char *prefix; }; -extern void parse_options_start(struct parse_opt_ctx_t *ctx, - int argc, const char **argv, const char *prefix, - const struct option *options, int flags); +void parse_options_start(struct parse_opt_ctx_t *ctx, + int argc, const char **argv, const char *prefix, + const struct option *options, int flags); -extern int parse_options_step(struct parse_opt_ctx_t *ctx, - const struct option *options, - const char * const usagestr[]); +int parse_options_step(struct parse_opt_ctx_t *ctx, + const struct option *options, + const char * const usagestr[]); -extern int parse_options_end(struct parse_opt_ctx_t *ctx); +int parse_options_end(struct parse_opt_ctx_t *ctx); -extern struct option *parse_options_concat(struct option *a, struct option *b); +struct option *parse_options_concat(struct option *a, struct option *b); /*----- some often used options -----*/ -extern int parse_opt_abbrev_cb(const struct option *, const char *, int); -extern int parse_opt_expiry_date_cb(const struct option *, const char *, int); -extern int parse_opt_color_flag_cb(const struct option *, const char *, int); -extern int parse_opt_verbosity_cb(const struct option *, const char *, int); -extern int parse_opt_object_name(const struct option *, const char *, int); -extern int parse_opt_commits(const struct option *, const char *, int); -extern int parse_opt_tertiary(const struct option *, const char *, int); -extern int parse_opt_string_list(const struct option *, const char *, int); -extern int parse_opt_noop_cb(const struct option *, const char *, int); -extern int parse_opt_unknown_cb(const struct option *, const char *, int); -extern int parse_opt_passthru(const struct option *, const char *, int); -extern int parse_opt_passthru_argv(const struct option *, const char *, int); +int parse_opt_abbrev_cb(const struct option *, const char *, int); +int parse_opt_expiry_date_cb(const struct option *, const char *, int); +int parse_opt_color_flag_cb(const struct option *, const char *, int); +int parse_opt_verbosity_cb(const struct option *, const char *, int); +int parse_opt_object_name(const struct option *, const char *, int); +int parse_opt_commits(const struct option *, const char *, int); +int parse_opt_tertiary(const struct option *, const char *, int); +int parse_opt_string_list(const struct option *, const char *, int); +int parse_opt_noop_cb(const struct option *, const char *, int); +int parse_opt_unknown_cb(struct parse_opt_ctx_t *ctx, const struct option *, const char *, int); +int parse_opt_passthru(const struct option *, const char *, int); +int parse_opt_passthru_argv(const struct option *, const char *, int); #define OPT__VERBOSE(var, h) OPT_COUNTUP('v', "verbose", (var), (h)) #define OPT__QUIET(var, h) OPT_COUNTUP('q', "quiet", (var), (h)) diff --git a/pkt-line.c b/pkt-line.c index d4b71d3e82..60329b301b 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -117,7 +117,7 @@ void packet_buf_delim(struct strbuf *buf) strbuf_add(buf, "0001", 4); } -static void set_packet_header(char *buf, const int size) +void set_packet_header(char *buf, const int size) { static char hexchar[] = "0123456789abcdef"; diff --git a/pkt-line.h b/pkt-line.h index ad9a4a2cd7..c36cb788ed 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -25,6 +25,7 @@ void packet_delim(int fd); void packet_write_fmt(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3))); void packet_buf_flush(struct strbuf *buf); void packet_buf_delim(struct strbuf *buf); +void set_packet_header(char *buf, int size); void packet_write(int fd_out, const char *buf, size_t size); void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); void packet_buf_write_len(struct strbuf *buf, const char *data, size_t len); @@ -1,7 +1,7 @@ # Catalan translations for Git. # This file is distributed under the same license as the Git package. # Alex Henrie <alexhenrie24@gmail.com>, 2014-2016. -# Jordi Mas i Hernà ndez <jmas@softcatala.org>, 2016-2018 +# Jordi Mas i Hernà ndez <jmas@softcatala.org>, 2016-2019 # # Terminologia i criteris utilitzats # @@ -3284,7 +3284,7 @@ msgid "Adding %s" msgstr "S'està afegint %s" #: merge-recursive.c:3300 -#y, c-format +#, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" " %s" @@ -6758,7 +6758,7 @@ msgstr "" #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" msgstr "" -" (useu \"git %s <fitxer>...\" per a incloure-ho en el qual es cometrà )" +" (useu \"git %s <fitxer>...\" per a incloure-ho en el que es cometrà )" #: wt-status.c:256 msgid "both deleted:" @@ -22474,1503 +22474,3 @@ msgstr "%s sauté avec un suffix de sauvegarde '%s'.\n" #, perl-format msgid "Do you really want to send %s? [y|N]: " msgstr "Souhaitez-vous réellement envoyer %s ?[y|N] : " - -#~ msgid "--reschedule-failed-exec requires an interactive rebase" -#~ msgstr "--reschedule-failed-exec requiert un rebasage interactif" - -#, fuzzy -#~| msgid "git archive [<options>] <tree-ish> [<path>...]" -#~ msgid "git diff --no-index [<options>] <path> <path>" -#~ msgstr "git archive [<options>] <arbre ou apparenté> [<chemin>...]" - -#, fuzzy -#~| msgid "invalid sparse value '%s'" -#~ msgid "invalid --stat value: %s" -#~ msgstr "valeur invalide de 'sparse' '%s'" - -#, fuzzy -#~| msgid "unable to create '%s'" -#~ msgid "unable to resolve '%s'" -#~ msgstr "impossible de créer '%s'" - -#, fuzzy -#~| msgid "expected wanted-ref, got '%s'" -#~ msgid "%s expects a character, got '%s'" -#~ msgstr "wanted-ref attendu, '%s' trouvé" - -#, fuzzy -#~| msgid "invalid color '%s' in color.blame.repeatedLines" -#~ msgid "invalid mode '%s' in --color-moved-ws" -#~ msgstr "couleur invalide '%s' dans color.blame.repeatedlines" - -#, fuzzy -#~| msgid "invalid value for %s" -#~ msgid "invalid argument to %s" -#~ msgstr "Valeur invalide pour %s" - -#, fuzzy -#~| msgid "bad number of arguments" -#~ msgid "bad --word-diff argument: %s" -#~ msgstr "mauvais nombre d'arguments" - -#, fuzzy -#~| msgid "Generating patches" -#~ msgid "generate patch" -#~ msgstr "Génération des patchs" - -#, fuzzy -#~| msgid "ensure at least <n> lines of context match" -#~ msgid "generate diffs with <n> lines context" -#~ msgstr "s'assurer d'au moins <n> lignes de correspondance de contexte" - -#, fuzzy -#~| msgid "(synonym to --stat)" -#~ msgid "synonym for '-p --raw'" -#~ msgstr "(synonyme de --stat)" - -#, fuzzy -#~| msgid "(synonym to --stat)" -#~ msgid "synonym for '-p --stat'" -#~ msgstr "(synonyme de --stat)" - -#, fuzzy -#~| msgid "machine-readable output" -#~ msgid "machine friendly --stat" -#~ msgstr "sortie pour traitement automatique" - -#, fuzzy -#~| msgid "output only the trailers" -#~ msgid "output only the last line of --stat" -#~ msgstr "éliminer les lignes terminales vides" - -#, fuzzy -#~| msgid "synonym for --files-with-matches" -#~ msgid "synonym for --dirstat=cumulative" -#~ msgstr "synonyme pour --files-with-matches" - -#, fuzzy -#~| msgid "show only filenames instead of matching lines" -#~ msgid "show only names of changed files" -#~ msgstr "" -#~ "n'afficher que les noms de fichiers au lieu des lignes correspondant" - -#, fuzzy -#~| msgid "show only filenames instead of matching lines" -#~ msgid "show only names and status of changed files" -#~ msgstr "" -#~ "n'afficher que les noms de fichiers au lieu des lignes correspondant" - -#, fuzzy -#~| msgid "failed to generate diff" -#~ msgid "generate diffstat" -#~ msgstr "échec de la génération de diff" - -#, fuzzy -#~| msgid "show ignored files" -#~ msgid "show colored diff" -#~ msgstr "afficher les fichiers ignorés" - -#, fuzzy -#~| msgid "<prefix>/" -#~ msgid "<prefix>" -#~ msgstr "<préfixe>/" - -#, fuzzy -#~| msgid "prepend parent project's basename to output" -#~ msgid "prepend an additional prefix to every line of output" -#~ msgstr "préfixer le nom de base du projet parent à la sortie" - -#, fuzzy -#~| msgid "" -#~| "Create a shallow clone truncated to the specified number of revisions" -#~ msgid "show context between diff hunks up to the specified number of lines" -#~ msgstr "Créer un clone superficiel tronqué au nombre de révisions spécifié" - -#, fuzzy -#~| msgid "Generic options" -#~ msgid "Diff rename options" -#~ msgstr "Options génériques" - -#, fuzzy -#~| msgid "<n>[,<base>]" -#~ msgid "<n>[/<m>]" -#~ msgstr "<n>[,<base>]" - -#, fuzzy -#~| msgid "do not detect renames" -#~ msgid "detect renames" -#~ msgstr "ne pas détecter les renommages" - -#, fuzzy -#~| msgid "Updated preimage for '%s'" -#~ msgid "omit the preimage for deletes" -#~ msgstr "Pré-image mise à jour pour '%s'" - -#, fuzzy -#~| msgid "Performing inexact rename detection" -#~ msgid "disable rename detection" -#~ msgstr "Détection de renommage inexact en cours" - -#, fuzzy -#~| msgid "invalid option: %s" -#~ msgid "Diff algorithm options" -#~ msgstr "option invalide : %s" - -#, fuzzy -#~| msgid "ignore changes in whitespace when finding context" -#~ msgid "ignore whitespace when comparing lines" -#~ msgstr "ignorer des modifications d'espace lors de la recherche de contexte" - -#, fuzzy -#~| msgid "ignore changes in whitespace when finding context" -#~ msgid "ignore changes in amount of whitespace" -#~ msgstr "ignorer des modifications d'espace lors de la recherche de contexte" - -#, fuzzy -#~| msgid "ignore changes in whitespace when finding context" -#~ msgid "ignore changes in whitespace at EOL" -#~ msgstr "ignorer des modifications d'espace lors de la recherche de contexte" - -#, fuzzy -#~| msgid "text" -#~ msgid "<text>" -#~ msgstr "texte" - -#, fuzzy -#~| msgid "mode" -#~ msgid "<mode>" -#~ msgstr "mode" - -#, fuzzy -#~| msgid "decorate options" -#~ msgid "Diff other options" -#~ msgstr "décorer les options" - -#, fuzzy -#~| msgid "process binary files as text" -#~ msgid "treat all files as text" -#~ msgstr "traiter les fichiers binaires comme texte" - -#, fuzzy -#~| msgid "when" -#~ msgid "<when>" -#~ msgstr "quand" - -#, fuzzy -#~| msgid "" -#~| "ignore changes to submodules, optional when: all, dirty, untracked. " -#~| "(Default: all)" -#~ msgid "ignore changes to submodules in the diff generation" -#~ msgstr "" -#~ "ignorer les modifications dans les sous-modules, \"quand\" facultatif : " -#~ "all (tous), dirty (sale), untracked (non suivi). (Défaut : all)" - -#, fuzzy -#~| msgid "format" -#~ msgid "<format>" -#~ msgstr "format" - -#, fuzzy -#~| msgid "use .gitattributes only from the index" -#~ msgid "hide 'git add -N' entries from the index" -#~ msgstr "utiliser .gitattributes seulement depuis l'index" - -#, fuzzy -#~| msgid "string" -#~ msgid "<string>" -#~ msgstr "chaîne" - -#, fuzzy -#~| msgid "show matching files in the pager" -#~ msgid "show all changes in the changeset with -S or -G" -#~ msgstr "afficher les fichiers correspondant dans le pagineur" - -#, fuzzy -#~| msgid "use extended POSIX regular expressions" -#~ msgid "treat <string> in -S as extended POSIX regular expression" -#~ msgstr "utiliser des expressions régulières étendues POSIX" - -#, fuzzy -#~| msgid "print all configuration variable names" -#~ msgid "override diff.orderFile configuration variable" -#~ msgstr "afficher tous les noms de variables de configuration" - -#, fuzzy -#~| msgid "object" -#~ msgid "<object-id>" -#~ msgstr "objet" - -#, fuzzy -#~| msgid "file" -#~ msgid "<file>" -#~ msgstr "fichier" - -#, fuzzy -#~| msgid "commit only specified files" -#~ msgid "Output to a specific file" -#~ msgstr "valider seulement les fichiers spécifiés" - -#, fuzzy -#~| msgid "Could not spawn pack-objects" -#~ msgid "could not start pack-objects" -#~ msgstr "Impossible de créer des objets groupés" - -#, fuzzy -#~| msgid "Could not spawn pack-objects" -#~ msgid "could not finish pack-objects" -#~ msgstr "Impossible de créer des objets groupés" - -#, fuzzy -#~| msgid "unrecognized position:%s" -#~ msgid "Unrecognized protocol version" -#~ msgstr "position non reconnue : %s" - -#, fuzzy -#~| msgid "unrecognized position:%s" -#~ msgid "Unrecognized protocol_version" -#~ msgstr "position non reconnue : %s" - -#, fuzzy -#~| msgid "could not write '%s'" -#~ msgid "could not write '%s'." -#~ msgstr "impossible d'écrire '%s'" - -#~ msgid "unable to write sha1 filename %s" -#~ msgstr "impossible d'écrire le fichier sha1 %s" - -#~ msgid "unable to write sha1 file" -#~ msgstr "impossible d'écrire le fichier sha1" - -#~ msgid "cannot read sha1_file for %s" -#~ msgstr "impossible de lire le fichier sha1 pour %s" - -#, fuzzy -#~| msgid "bad revision '%s'" -#~ msgid "Can't find revision '%s' to ignore" -#~ msgstr "mauvaise révision '%s'" - -#, fuzzy -#~| msgid "ignore index when checking" -#~ msgid "Ignore <rev> when blaming" -#~ msgstr "ignorer l'index pendant la vérification" - -#, fuzzy -#~| msgid "read message from file" -#~ msgid "Ignore revisions from <file>" -#~ msgstr "lire le message depuis un fichier" - -#, fuzzy -#~| msgid "could not resolve HEAD commit" -#~ msgid "could not resolve HEAD" -#~ msgstr "impossible de résoudre le commit HEAD" - -#, fuzzy -#~| msgid "HEAD not found below refs/heads!" -#~ msgid "HEAD (%s) points outside of refs/heads/" -#~ msgstr "HEAD non trouvée sous refs/heads !" - -#, fuzzy -#~| msgid "No current branch." -#~ msgid "show current branch name" -#~ msgstr "Pas de branche courante." - -#, fuzzy -#~| msgid "prune loose refs (default)" -#~ msgid "use overlay mode (default)" -#~ msgstr "éliminer les références perdues (défaut)" - -#, fuzzy -#~| msgid "-n and -k are mutually exclusive" -#~ msgid "-p and --overlay are mutually exclusive" -#~ msgstr "-n et -k sont mutuellement exclusifs" - -#, fuzzy -#~| msgid "unable to read config file '%s'" -#~ msgid "move a variable to a different config file" -#~ msgstr "lecture du fichier de configuration '%s' impossible" - -#, fuzzy -#~| msgid "Unknown commit %s" -#~ msgid "unknown config source" -#~ msgstr "Commit inconnu %s" - -#~ msgid "" -#~ "error: cannot combine interactive options (--interactive, --exec, --" -#~ "rebase-merges, --preserve-merges, --keep-empty, --root + --onto) with am " -#~ "options (%s)" -#~ msgstr "" -#~ "erreur: impossible de combiner des options interactives (--interactive, --" -#~ "exec, --rebase-merges, --preserve-merges, --keep-empty, --root + --onto) " -#~ "avec les options am (%s)" - -#, fuzzy -#~| msgid "git remote set-url --delete <name> <url>" -#~ msgid "git remote set-url --save-to-push <name> <url>" -#~ msgstr "git remote set-url --delete <nom> <URL>" - -#, fuzzy -#~| msgid "The --cached option cannot be used with the --files option" -#~ msgid "--save-to-push cannot be used with other options" -#~ msgstr "L'option --cached ne peut pas être utilisée avec l'option --files" - -#, fuzzy -#~| msgid "--format cannot be used when not listing" -#~ msgid "--save-to-push can only be used when only one url is defined" -#~ msgstr "--format ne peut pas être utilisé sans lister" - -#, fuzzy -#~| msgid "git worktree list [<options>]" -#~ msgid "git stash list [<options>]" -#~ msgstr "git worktree list [<options>]" - -#, fuzzy -#~| msgid "git remote show [<options>] <name>" -#~ msgid "git stash show [<options>] [<stash>]" -#~ msgstr "git remote show [<options>] <nom>" - -#, fuzzy -#~| msgid "git branch [<options>] [-l] [-f] <branch-name> [<start-point>]" -#~ msgid "git stash branch <branchname> [<stash>]" -#~ msgstr "" -#~ "git branch [<options] [-l] [-f] <nom-de-branche> [<point-de-départ>]" - -#, fuzzy -#~| msgid "'$args' is not a stash-like commit" -#~ msgid "'%s' is not a stash-like commit" -#~ msgstr "'$args' n'est pas une validation de type remisage" - -#, fuzzy -#~| msgid "Too many revisions specified: $REV" -#~ msgid "Too many revisions specified:%s" -#~ msgstr "Trop de révisions spécifiées : $REV" - -#, fuzzy -#~| msgid "'%s' is not a valid ref name" -#~ msgid "%s is not a valid reference" -#~ msgstr "'%s' n'est pas un nom valide de référence" - -#, fuzzy -#~| msgid "Cannot apply a stash in the middle of a merge" -#~ msgid "cannot apply a stash in the middle of a merge" -#~ msgstr "Impossible d'appliquer un remisage en cours de fusion" - -#, fuzzy -#~| msgid "could not generate todo list" -#~ msgid "could not generate diff %s^!." -#~ msgstr "impossible de générer la liste à -faire" - -#, fuzzy -#~| msgid "Conflicts in index. Try without --index." -#~ msgid "conflicts in index.Try without --index." -#~ msgstr "Conflits dans l'index. Essayez sans --index." - -#, fuzzy -#~| msgid "Could not save index tree" -#~ msgid "could not save index tree" -#~ msgstr "Impossible de sauvegarder l'arbre d'index" - -#, fuzzy -#~| msgid "Could not restore untracked files from stash entry" -#~ msgid "could not restore untracked files from stash" -#~ msgstr "" -#~ "Impossible de restaurer les fichiers non-suivis depuis l'entrée de " -#~ "remisage" - -#, fuzzy -#~| msgid "Merging %s with %s\n" -#~ msgid "Merging %s with %s" -#~ msgstr "Fusion de %s avec %s\n" - -#, fuzzy -#~| msgid "failed to read the index" -#~ msgid "attempt to recreate the index" -#~ msgstr "échec à la lecture de l'index" - -#, fuzzy -#~| msgid "Dropped ${REV} ($s)" -#~ msgid "Dropped %s (%s)" -#~ msgstr "${REV} supprimé ($s)" - -#, fuzzy -#~| msgid "${REV}: Could not drop stash entry" -#~ msgid "%s: Could not drop stash entry" -#~ msgstr "${REV}: Impossible de supprimer l'élément de stash" - -#, fuzzy -#~| msgid "'$args' is not a stash reference" -#~ msgid "'%s' is not a stash reference" -#~ msgstr "'$args' n'est pas une référence de remisage" - -#, fuzzy -#~| msgid "Cannot update $ref_stash with $w_commit" -#~ msgid "Cannot update %s with %s" -#~ msgstr "Impossible de mettre à jour $ref_stash avec $w_commit" - -#, fuzzy -#~| msgid "tag message" -#~ msgid "stash message" -#~ msgstr "message pour l'étiquette" - -#, fuzzy -#~| msgid "--bisect-clean-state requires no arguments" -#~ msgid "\"git stash store\" requires one <commit> argument" -#~ msgstr "--bisect-clean-state ne supporte aucun argument" - -#, fuzzy -#~| msgid "Maybe you wanted to say 'git add .'?\n" -#~ msgid "Did you forget to 'git add'?" -#~ msgstr "Vous vouliez sûrement dire 'git add .' ?\n" - -#, fuzzy -#~| msgid "Saved working directory and index state $stash_msg" -#~ msgid "Saved working directory and index state %s" -#~ msgstr "Copie de travail et état de l'index sauvegardés dans $stash_msg" - -#, fuzzy -#~| msgid "Refresh index" -#~ msgid "keep index" -#~ msgstr "Rafraîchir l'index" - -#, fuzzy -#~| msgid "quiet" -#~ msgid "quiet mode" -#~ msgstr "quiet" - -#, fuzzy -#~| msgid "list untracked files in columns" -#~ msgid "include untracked files in stash" -#~ msgstr "afficher les fichiers non suivis en colonnes" - -#, fuzzy -#~| msgid "show ignored files" -#~ msgid "include ignore files" -#~ msgstr "afficher les fichiers ignorés" - -#, fuzzy -#~| msgid "expiry-date" -#~ msgid "expiry date" -#~ msgstr "date-d'expiration" - -#, fuzzy -#~| msgid "Use binary search to find the commit that introduced a bug" -#~ msgid "Find by binary search the change that introduced a bug" -#~ msgstr "" -#~ "Trouver par recherche binaire la modification qui a introduit un bogue" - -#, fuzzy -#~| msgid "path into the working tree" -#~ msgid "Checkout a branch or paths to the working tree" -#~ msgstr "chemin dans la copie de travail" - -#~ msgid "Forward-port local commits to the updated upstream head" -#~ msgstr "" -#~ "Reporter les validations locales sur le sommet mis à jour d'une branche " -#~ "amont" - -#, fuzzy -#~| msgid "invalid ident line: %s" -#~ msgid "invalid hunk line '%d'\n" -#~ msgstr "ligne d'identification invalide : %s" - -#, fuzzy -#~| msgid "invalid ident line: %s" -#~ msgid "invalid hunk line '%s'\n" -#~ msgstr "ligne d'identification invalide : %s" - -#, fuzzy -#~| msgid "select mainline parent" -#~ msgid "select lines? " -#~ msgstr "sélectionner le parent principal" - -#, fuzzy -#~| msgid "cannot store index file" -#~ msgid "Cannot select line by line\n" -#~ msgstr "impossible de stocker le fichier d'index" - -#~ msgid "ignoring unknown color-moved-ws mode '%s'" -#~ msgstr "mode color-moved-ws inconnu '%s' ignoré" - -#~ msgid "only 'tree:0' is supported" -#~ msgstr "seul 'tree:0' est supporté" - -#~ msgid "Renaming %s to %s and %s to %s instead" -#~ msgstr "Renommage de %s en %s et de %s en %s à la place" - -#~ msgid "Adding merged %s" -#~ msgstr "Ajout de %s fusionné" - -#~ msgid "Internal error" -#~ msgstr "Erreur interne" - -#~ msgid "mainline was specified but commit %s is not a merge." -#~ msgstr "" -#~ "une branche principale a été spécifiée mais le commit %s n'est pas une " -#~ "fusion." - -#~ msgid "" -#~ "error: cannot combine merge options (--merge, --strategy, --strategy-" -#~ "option) with am options (%s)" -#~ msgstr "" -#~ "erreur : impossible de combiner les options de fusion (--merge, --" -#~ "strategy, --strategy-option) avec les options am (%s)" - -#~ msgid "unrecognised option: '$arg'" -#~ msgstr "option inconnue : '$arg'" - -#~ msgid "'$invalid' is not a valid commit" -#~ msgstr "'$invalid' n'est pas une validation valide" - -#~ msgid "could not parse '%s' (looking for '%s')" -#~ msgstr "impossible d'analyser '%s' (à la recherche de '%s')" - -#~ msgid "bad quoting on %s value in '%s'" -#~ msgstr "Mauvaise citation sur la valeur %s dans '%s'" - -#~ msgid "deprecated synonym for --create-reflog" -#~ msgstr "synonyme déconseillé de --create-reflog" - -#~ msgid "Can't stat %s" -#~ msgstr "impossible de faire un stat de %s" - -#~ msgid "abort rebase" -#~ msgstr "abandonner le rebasage" - -#~ msgid "make rebase script" -#~ msgstr "créer les script de rebasage" - -#~ msgid "No such remote: %s" -#~ msgstr "Distante inconnue : %s" - -#~ msgid "cannot move a locked working tree" -#~ msgstr "impossible de déplacer un arbre de travail verrouillé" - -#~ msgid "cannot remove a locked working tree" -#~ msgstr "impossible de supprimer un arbre de travail verrouillé" - -#~ msgid "Applied autostash." -#~ msgstr "Autoremisage appliqué." - -#~ msgid "Cannot store $stash_sha1" -#~ msgstr "Impossible de stocker $stash_sha1" - -#~ msgid "" -#~ "\n" -#~ "\tHowever, if you remove everything, the rebase will be aborted.\n" -#~ "\n" -#~ "\t" -#~ msgstr "" -#~ "\n" -#~ "Cependant, si vous effacez tout, le rebasage sera annulé.\n" -#~ "\n" -#~ "\t" - -#~ msgid "could not parse '%s' (looking for '%s'" -#~ msgstr "impossible d'analyser '%s' (à la recherche de '%s')" - -#~ msgid "color both diff and diff-between-diffs" -#~ msgstr "colorer à la fois les diffs et le diff-between-diffs" - -#~ msgid "push|fetch" -#~ msgstr "push|fetch" - -#~ msgid "Dirty index: cannot merge (dirty: %s)" -#~ msgstr "Index sale : fusion impossible (sales : %s)" - -#~ msgid "(+/-)x" -#~ msgstr "(+/-)x" - -#~ msgid "<command>" -#~ msgstr "<commande>" - -#~ msgid "w[,i1[,i2]]" -#~ msgstr "w[,i1[,i2]]" - -#~ msgid "Entering '$displaypath'" -#~ msgstr "Entrée dans '$displaypath'" - -#~ msgid "Stopping at '$displaypath'; script returned non-zero status." -#~ msgstr "Arrêt sur '$displaypath' ; le script a retourné un état non nul." - -#~ msgid "Everyday Git With 20 Commands Or So" -#~ msgstr "Git de tous les jours avec à peu près 20 commandes" - -#~ msgid "Could not open '%s' for writing" -#~ msgstr "Impossible d'ouvrir '%s' en écriture" - -#~ msgid "" -#~ "unexpected 1st line of squash message:\n" -#~ "\n" -#~ "\t%.*s" -#~ msgstr "" -#~ "première ligne de message de compression inattendue :\n" -#~ "\n" -#~ "\t%.*s" - -#~ msgid "" -#~ "invalid 1st line of squash message:\n" -#~ "\n" -#~ "\t%.*s" -#~ msgstr "" -#~ "première ligne de message de compression invalide :\n" -#~ "\n" -#~ "\t%.*s" - -#~ msgid "BUG: returned path string doesn't match cwd?" -#~ msgstr "BUG : le chemin renvoyé ne correspond pas à cwd ?" - -#~ msgid "Error in object" -#~ msgstr "Erreur dans l'objet" - -#~ msgid "git fetch-pack: expected ACK/NAK, got EOF" -#~ msgstr "git fetch-pack : ACK/NACK attendu, EOF reçu" - -#~ msgid "invalid filter-spec expression '%s'" -#~ msgstr "expression de filtre invalide : '%s'" - -#~ msgid "The copy of the patch that failed is found in: %s" -#~ msgstr "La copie du patch qui a échoué se trouve dans : %s" - -#~ msgid "pathspec and --all are incompatible" -#~ msgstr "un spécificateur de chemin et --all sont incompatibles" - -#~ msgid "Submodule '$name' ($url) unregistered for path '$displaypath'" -#~ msgstr "" -#~ "Le sous-module '$name' ($url) n'est pas enregistré pour le chemin " -#~ "'$displaypath'" - -#~ msgid "To/Cc/Bcc fields are not interpreted yet, they have been ignored\n" -#~ msgstr "" -#~ "Les champs To/CC/Bcc ne sont pas encore interprétés, ils ont été ignorés\n" - -#~ msgid "" -#~ "empty strings as pathspecs will be made invalid in upcoming releases. " -#~ "please use . instead if you meant to match all paths" -#~ msgstr "" -#~ "les chaines de caractères vides comme spécificateurs de chemin seront " -#~ "invalides dans les prochaines versions. Veuillez utiliser . à la place " -#~ "pour correspondre à tous le chemins" - -#~ msgid "could not truncate '%s'" -#~ msgstr "impossible de tronquer '%s'" - -#~ msgid "could not close %s" -#~ msgstr "impossible de fermer %s" - -#~ msgid "Copied a misnamed branch '%s' away" -#~ msgstr "Copie d'une branche mal nommée '%s'" - -#~ msgid "it does not make sense to create 'HEAD' manually" -#~ msgstr "créer manuellement 'HEAD' n'a pas de sens" - -#~ msgid "Don't know how to clone %s" -#~ msgstr "Je ne sais pas cloner %s" - -#~ msgid "Don't know how to fetch from %s" -#~ msgstr "Je ne sais pas récupérer depuis %s" - -#~ msgid "'$term' is not a valid term" -#~ msgstr "'$term' n'est pas un terme valide" - -#~ msgid "" -#~ "error: unknown option for 'stash save': $option\n" -#~ " To provide a message, use git stash save -- '$option'" -#~ msgstr "" -#~ "erreur: option inconnue pour 'stash save': $option\n" -#~ " Pour fournir un message, utilisez git stash save -- '$option'" - -#~ msgid "Failed to recurse into submodule path '$sm_path'" -#~ msgstr "Échec de parcours dans le chemin du sous-module '$sm_path'" - -#~ msgid "%%(trailers) does not take arguments" -#~ msgstr "%%(trailers) n'accepte pas d'argument" - -#~ msgid "submodule update strategy not supported for submodule '%s'" -#~ msgstr "" -#~ "stratégie de mise à jour de sous-module non supportée pour le sous-module " -#~ "'%s'" - -#~ msgid "change upstream info" -#~ msgstr "modifier l'information amont" - -#~ msgid "" -#~ "\n" -#~ "If you wanted to make '%s' track '%s', do this:\n" -#~ "\n" -#~ msgstr "" -#~ "\n" -#~ "Si vous vouliez que '%s' suive '%s', faites ceci :\n" -#~ "\n" - -#~ msgid "basename" -#~ msgstr "nom de base" - -#~ msgid "" -#~ "Warning: the SHA-1 is missing or isn't a commit in the following line:\n" -#~ " - $line" -#~ msgstr "" -#~ "Attention : le SHA-1 manque ou n'est pas un commit dans la ligne " -#~ "suivante :\n" -#~ " - $line" - -#~ msgid "" -#~ "Warning: the command isn't recognized in the following line:\n" -#~ " - $line" -#~ msgstr "" -#~ "Attention : la commande n'est pas reconnue dans le ligne suivante :\n" -#~ " - $line" - -#~ msgid "Or you can abort the rebase with 'git rebase --abort'." -#~ msgstr "" -#~ "Ou bien vous pouvez abandonner le rebasage avec 'git rebase --abort'." - -#~ msgid "in %0.1f seconds automatically..." -#~ msgstr "dans %0.1f secondes automatiquement..." - -#~ msgid "dup2(%d,%d) failed" -#~ msgstr "échec de dup2(%d,%d)" - -#~ msgid "Initial commit on " -#~ msgstr "Validation initiale sur " - -#~ msgid "Patch is empty. Was it split wrong?" -#~ msgstr "Le patch est vide. Le découpage était-il bon ?" - -#~ msgid "" -#~ "You still have unmerged paths in your index.\n" -#~ "Did you forget to use 'git add'?" -#~ msgstr "" -#~ "Vous avez toujours des chemins non fusionnés dans votre index\n" -#~ "Auriez-vous oublié de faire 'git add' ?" - -#~ msgid "" -#~ "Cannot update paths and switch to branch '%s' at the same time.\n" -#~ "Did you intend to checkout '%s' which can not be resolved as commit?" -#~ msgstr "" -#~ "Impossible de mettre à jour les chemins et de basculer sur la branche " -#~ "'%s' en même temps.\n" -#~ "Souhaitiez-vous extraire '%s' qui ne peut être résolu comme commit ?" - -#~ msgid "Explicit paths specified without -i or -o; assuming --only paths..." -#~ msgstr "Chemins explicites spécifiés sans -i ni -o ; --only supposé..." - -#~ msgid "default mode for recursion" -#~ msgstr "mode par défaut pour la récursion" - -#~ msgid "submodule--helper subcommand must be called with a subcommand" -#~ msgstr "" -#~ "la sous-commande submodule--helper doit être appelée avec une sous-" -#~ "commande" - -#~ msgid "could not stat '%s" -#~ msgstr "stat impossible de '%s'" - -#~ msgid "tag: tagging " -#~ msgstr "étiquette: étiquetage de " - -#~ msgid "commit object" -#~ msgstr "objet commit" - -#~ msgid "tree object" -#~ msgstr "objet arbre" - -#~ msgid "blob object" -#~ msgstr "objet blob" - -#~ msgid "" -#~ "There is nothing to exclude from by :(exclude) patterns.\n" -#~ "Perhaps you forgot to add either ':/' or '.' ?" -#~ msgstr "" -#~ "Il n'y a rien dont il faut exclure par des motifs :(exclure).\n" -#~ "Peut-être avez-vous oublié d'ajouter ':/' ou '.' ?" - -#~ msgid "unrecognized format: %%(%s)" -#~ msgstr "format non reconnu %%(%s)" - -#~ msgid ":strip= requires a positive integer argument" -#~ msgstr ":strip= requiert un argument entier positif" - -#~ msgid "ref '%s' does not have %ld components to :strip" -#~ msgstr "la réf '%s' n'a pas %ld composants à :strip" - -# féminin pour une branche -#~ msgid "[%s: gone]" -#~ msgstr "[%s: disparue]" - -#~ msgid "[%s]" -#~ msgstr "[%s]" - -#~ msgid "[%s: behind %d]" -#~ msgstr "[%s: en retard de %d]" - -#~ msgid "[%s: ahead %d]" -#~ msgstr "[%s : en avance de %d]" - -#~ msgid "[%s: ahead %d, behind %d]" -#~ msgstr "[%s : en avance de %d, en retard de %d]" - -#~ msgid " **** invalid ref ****" -#~ msgstr " **** référence invalide ****" - -#~ msgid "insanely long object directory %.*s" -#~ msgstr "objet répertoire démentiellement long %.*s" - -#~ msgid "git merge [<options>] <msg> HEAD <commit>" -#~ msgstr "git merge [<options>] <message> HEAD <commit>" - -#~ msgid "tag name too long: %.*s..." -#~ msgstr "nom d'étiquette trop long : %.*s..." - -#~ msgid "tag header too big." -#~ msgstr "en-tête d'étiquette trop gros." - -#~ msgid "" -#~ "If the patch applies cleanly, the edited hunk will immediately be\n" -#~ "marked for discarding" -#~ msgstr "" -#~ "Si le patch s'applique proprement, la section éditée sera\n" -#~ "immediatement marquée comme éliminée" - -#~ msgid "Use an experimental blank-line-based heuristic to improve diffs" -#~ msgstr "" -#~ "Utiliser une heuristique expérimentale reposant sur les lignes vides pour " -#~ "améliorer le diffs" - -#~ msgid "Clever... amending the last one with dirty index." -#~ msgstr "Malin... correction du dernier avec un index sale." - -#~ msgid "" -#~ "the following submodule (or one of its nested submodules)\n" -#~ "uses a .git directory:" -#~ msgid_plural "" -#~ "the following submodules (or one of their nested submodules)\n" -#~ "use a .git directory:" -#~ msgstr[0] "" -#~ "le sous-module suivant (ou un de ses sous-modules imbriqués)\n" -#~ "utilise un répertoire .git :" -#~ msgstr[1] "" -#~ "les sous-modules suivants (ou un de leurs sous-modules imbriqués)\n" -#~ "utilisent un répertoire .git :" - -#~ msgid "" -#~ "\n" -#~ "(use 'rm -rf' if you really want to remove it including all of its " -#~ "history)" -#~ msgstr "" -#~ "\n" -#~ "(utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout " -#~ "son historique)" - -#~ msgid "Error wrapping up %s." -#~ msgstr "Erreur lors de l'emballage de %s." - -#~ msgid "Your local changes would be overwritten by cherry-pick." -#~ msgstr "Vos modifications locales seraient écrasées par cherry-pick." - -#~ msgid "Cannot revert during another revert." -#~ msgstr "Impossible d'annuler un commit pendant l'annulation d'un commit." - -#~ msgid "Cannot cherry-pick during another cherry-pick." -#~ msgstr "Impossible de picorer pendant un autre picorage." - -#~ msgid "Could not parse line %d." -#~ msgstr "Impossible d'analyser la ligne %d." - -#~ msgid "Could not open %s" -#~ msgstr "Impossible d'ouvrir %s" - -#~ msgid "Could not format %s." -#~ msgstr "Impossible de formater %s." - -#~ msgid "%s: %s" -#~ msgstr "%s : %s" - -#~ msgid "You need to set your committer info first" -#~ msgstr "Vous devez d'abord définir vos informations de validateur" - -#~ msgid "This is the 2nd commit message:" -#~ msgstr "Ceci est le deuxième message de validation :" - -#~ msgid "This is the 3rd commit message:" -#~ msgstr "Ceci est le troisième message de validation :" - -#~ msgid "This is the 4th commit message:" -#~ msgstr "Ceci est le quatrième message de validation :" - -#~ msgid "This is the 5th commit message:" -#~ msgstr "Ceci est le cinquième message de validation :" - -#~ msgid "This is the 6th commit message:" -#~ msgstr "Ceci est le sixième message de validation :" - -#~ msgid "This is the 7th commit message:" -#~ msgstr "Ceci est le septième message de validation :" - -#~ msgid "This is the 8th commit message:" -#~ msgstr "Ceci est le huitième message de validation :" - -#~ msgid "This is the 9th commit message:" -#~ msgstr "Ceci est le neuvième message de validation :" - -#~ msgid "This is the 10th commit message:" -#~ msgstr "Ceci est le dixième message de validation :" - -#~ msgid "This is the ${n}th commit message:" -#~ msgstr "Ceci est le ${n}ième message de validation :" - -#~ msgid "This is the ${n}st commit message:" -#~ msgstr "Ceci est le ${n}ième message de validation :" - -#~ msgid "This is the ${n}nd commit message:" -#~ msgstr "Ceci est le ${n}ième message de validation :" - -#~ msgid "This is the ${n}rd commit message:" -#~ msgstr "Ceci est le ${n}ième message de validation :" - -#~ msgid "The 1st commit message will be skipped:" -#~ msgstr "Le premier message de validation sera ignoré :" - -#~ msgid "The 2nd commit message will be skipped:" -#~ msgstr "Le deuxième message de validation sera ignoré :" - -#~ msgid "The 3rd commit message will be skipped:" -#~ msgstr "Le troisième message de validation sera ignoré :" - -#~ msgid "The 4th commit message will be skipped:" -#~ msgstr "Le quatrième message de validation sera ignoré :" - -#~ msgid "The 5th commit message will be skipped:" -#~ msgstr "Le cinquième message de validation sera ignoré :" - -#~ msgid "The 6th commit message will be skipped:" -#~ msgstr "Le sixième message de validation sera ignoré :" - -#~ msgid "The 7th commit message will be skipped:" -#~ msgstr "Le septième message de validation sera ignoré :" - -#~ msgid "The 8th commit message will be skipped:" -#~ msgstr "Le huitième message de validation sera ignoré :" - -#~ msgid "The 9th commit message will be skipped:" -#~ msgstr "Le neuvième message de validation sera ignoré :" - -#~ msgid "The 10th commit message will be skipped:" -#~ msgstr "Le dixième message de validation sera ignoré :" - -#~ msgid "The ${n}th commit message will be skipped:" -#~ msgstr "le ${n}ième message de validation sera ignoré :" - -#~ msgid "The ${n}st commit message will be skipped:" -#~ msgstr "Le message de validation ${n} sera ignoré :" - -#~ msgid "The ${n}nd commit message will be skipped:" -#~ msgstr "Le message de validation ${n} sera ignoré :" - -#~ msgid "The ${n}rd commit message will be skipped:" -#~ msgstr "Le message de validation ${n} sera ignoré :" - -#~ msgid "could not run gpg." -#~ msgstr "impossible de lancer gpg." - -#~ msgid "gpg did not accept the data" -#~ msgstr "gpg n'a pas accepté les données" - -#~ msgid "unsupported object type in the tree" -#~ msgstr "type d'objet non supporté dans l'arbre" - -#~ msgid "Fatal merge failure, shouldn't happen." -#~ msgstr "Échec fatal de fusion, qui ne devrait jamais arriver." - -#~ msgid "Unprocessed path??? %s" -#~ msgstr "Chemin non traité ??? %s" - -#~ msgid "Cannot %s during a %s" -#~ msgstr "Impossible de %s pendant un %s" - -#~ msgid "Can't cherry-pick into empty head" -#~ msgstr "Impossible de picorer vers une HEAD vide" - -#~ msgid "could not open %s for writing" -#~ msgstr "Impossible d'ouvrir '%s' en écriture" - -#~ msgid "bug: unhandled unmerged status %x" -#~ msgstr "bogue : état de non-fusion non géré %x" - -#~ msgid "bug: unhandled diff status %c" -#~ msgstr "bogue : état de diff non géré %c" - -#~ msgid "could not write branch description template" -#~ msgstr "impossible d'écrire le modèle de description de branche" - -#~ msgid "corrupt index file" -#~ msgstr "fichier d'index corrompu" - -#~ msgid "detach the HEAD at named commit" -#~ msgstr "détacher la HEAD à la validation nommée" - -#~ msgid "Checking connectivity... " -#~ msgstr "Vérification de la connectivité... " - -#~ msgid " (unable to update local ref)" -#~ msgstr " (impossible de mettre à jour la référence locale)" - -#~ msgid "Reinitialized existing" -#~ msgstr "existant réinitialisé" - -#~ msgid "Initialized empty" -#~ msgstr "vide initialisé" - -#~ msgid " shared" -#~ msgstr " partagé" - -#~ msgid "Verify that the named commit has a valid GPG signature" -#~ msgstr "Vérifier que la validation a une signature GPG valide" - -#~ msgid "Writing SQUASH_MSG" -#~ msgstr "Écriture de SQUASH_MSG" - -#~ msgid "Finishing SQUASH_MSG" -#~ msgstr "Finition de SQUASH_MSG" - -#~ msgid " and with remote" -#~ msgstr " et avec la distante" - -#~ msgid "removing '%s' failed" -#~ msgstr "la suppression de '%s' a échoué" - -#~ msgid "Please call 'bisect_state' with at least one argument." -#~ msgstr "Veuillez appeler 'bisect_state' avec au moins un argument." - -#~ msgid "" -#~ "If you want to reuse this local git directory instead of cloning again " -#~ "from" -#~ msgstr "" -#~ "Si vous voulez réutiliser ce répertoire git local au lieu de cloner à " -#~ "nouveau depuis" - -#~ msgid "" -#~ "use the '--force' option. If the local git directory is not the correct " -#~ "repo" -#~ msgstr "" -#~ "utilisez l'option '--force'. Si le répertoire local git n'est pas le " -#~ "dépôt correct" - -#~ msgid "" -#~ "or you are unsure what this means choose another name with the '--name' " -#~ "option." -#~ msgstr "" -#~ "ou si vous ne savez pas ce que cela signifie, choisissez un autre nom " -#~ "avec l'option '--name'." - -#~ msgid "Submodule work tree '$displaypath' contains a .git directory" -#~ msgstr "" -#~ "La copie de travail du sous-module '$displaypath' contient un répertoire ." -#~ "git" - -#~ msgid "" -#~ "(use 'rm -rf' if you really want to remove it including all of its " -#~ "history)" -#~ msgstr "" -#~ "(utilisez 'rm -rf' si vous voulez vraiment le supprimer en incluant tout " -#~ "son historique)" - -#~ msgid "'%s': %s" -#~ msgstr "'%s' : %s" - -#~ msgid "unable to access '%s': %s" -#~ msgstr "impossible d'accéder à '%s' : %s" - -#~ msgid " git branch -d %s\n" -#~ msgstr " git branch -d %s\n" - -#~ msgid " git branch --set-upstream-to %s\n" -#~ msgstr " git branch --set-upstream-to %s\n" - -#~ msgid "cannot open %s: %s\n" -#~ msgstr "impossible d'ouvrir %s : %s\n" - -#~ msgid "Please, stage your changes to .gitmodules or stash them to proceed" -#~ msgstr "" -#~ "Veuillez indexer vos modifications de .gitmodules ou remisez-les pour " -#~ "continuer" - -#~ msgid "failed to remove: %s" -#~ msgstr "échec de la suppression de %s" - -#~ msgid "" -#~ "Submodule path '$displaypath' not initialized\n" -#~ "Maybe you want to use 'update --init'?" -#~ msgstr "" -#~ "Chemin de sous-module '$displaypath' non initialisé\n" -#~ "Peut-être souhaitez-vous utiliser 'update --init' ?" - -#~ msgid "improper format entered align:%s" -#~ msgstr "format non convenable align:%s" - -#~ msgid "" -#~ "push.default is unset; its implicit value has changed in\n" -#~ "Git 2.0 from 'matching' to 'simple'. To squelch this message\n" -#~ "and maintain the traditional behavior, use:\n" -#~ "\n" -#~ " git config --global push.default matching\n" -#~ "\n" -#~ "To squelch this message and adopt the new behavior now, use:\n" -#~ "\n" -#~ " git config --global push.default simple\n" -#~ "\n" -#~ "When push.default is set to 'matching', git will push local branches\n" -#~ "to the remote branches that already exist with the same name.\n" -#~ "\n" -#~ "Since Git 2.0, Git defaults to the more conservative 'simple'\n" -#~ "behavior, which only pushes the current branch to the corresponding\n" -#~ "remote branch that 'git pull' uses to update the current branch.\n" -#~ "\n" -#~ "See 'git help config' and search for 'push.default' for further " -#~ "information.\n" -#~ "(the 'simple' mode was introduced in Git 1.7.11. Use the similar mode\n" -#~ "'current' instead of 'simple' if you sometimes use older versions of Git)" -#~ msgstr "" -#~ "push.default n'est pas défini ; sa valeur implicite a changé dans Git " -#~ "2.0\n" -#~ "de 'matching' vers 'simple'. Pour supprimer ce message et maintenir\n" -#~ "le comportement actuel après la modification de la valeur de défaut, " -#~ "utilisez :\n" -#~ "\n" -#~ " git config --global push.default matching\n" -#~ "\n" -#~ "Pour supprimer ce message et adopter le nouveau comportement maintenant, " -#~ "utilisez :\n" -#~ "\n" -#~ " git config --global push.default simple\n" -#~ "\n" -#~ "Quand push.default vaudra 'matching', git poussera les branches locales\n" -#~ "sur les branches distantes qui existent déjà avec le même nom.\n" -#~ "\n" -#~ "Depuis Git 2.0, Git utilise par défaut le comportement plus conservatif " -#~ "'simple'\n" -#~ "qui ne pousse la branche courante que vers la branche distante " -#~ "correspondante\n" -#~ "que 'git pull' utilise pour mettre à jour la branche courante.\n" -#~ " \n" -#~ "Voir 'git help config' et chercher 'push.default' pour plus " -#~ "d'information.\n" -#~ "(le mode 'simple' a été introduit dans Git 1.7.11. Utilisez le mode " -#~ "similaire\n" -#~ "'current' au lieu de 'simple' si vous utilisez de temps en temps " -#~ "d'anciennes versions de Git)" - -#~ msgid "check|on-demand|no" -#~ msgstr "check|on-demand|no" - -#~ msgid "Could not append '%s'" -#~ msgstr "Impossible d'ajouter '%s'" - -#~ msgid "Missing author: %s" -#~ msgstr "Auteur manquant : %s" - -#~ msgid "Testing " -#~ msgstr "Test en cours " - -#~ msgid "unable to look up current user in the passwd file: %s" -#~ msgstr "" -#~ "impossible de rechercher l'utilisateur actuel dans le fichier de mots de " -#~ "passe : %s" - -#~ msgid "no such user" -#~ msgstr "utilisateur inconnu" - -#~ msgid "branch '%s' does not point at a commit" -#~ msgstr "la branche '%s' ne pointe pas sur un commit" - -#~ msgid "print only merged branches" -#~ msgstr "afficher seulement les branches fusionnées" - -#~ msgid "--dissociate given, but there is no --reference" -#~ msgstr "--dissociate est spécifié, mais --reference est absent" - -#~ msgid "show usage" -#~ msgstr "afficher l'usage" - -#~ msgid "insanely long template name %s" -#~ msgstr "nom de modèle démentiellement long %s" - -#~ msgid "insanely long symlink %s" -#~ msgstr "lien symbolique démentiellement long %s" - -#~ msgid "insanely long template path %s" -#~ msgstr "chemin de modèle %s démentiellement long" - -#~ msgid "unsupported sort specification '%s'" -#~ msgstr "spécification de tri non supportée '%s'" - -#~ msgid "unsupported sort specification '%s' in variable '%s'" -#~ msgstr "spécification de tri non supportée '%s' dans le variable '%s'" - -#~ msgid "switch 'points-at' requires an object" -#~ msgstr "le commutateur 'points-at' a besoin d'un objet" - -#~ msgid "--sort and -n are incompatible" -#~ msgstr "--sort et -n sont incompatibles" - -#~ msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" -#~ msgstr "" -#~ "Le répertoire Git '$a' fait partie du chemin de sous-module '$b' ou vice-" -#~ "versa" - -#~ msgid "false|true|preserve" -#~ msgstr "false|true|preserve" - -#~ msgid "BUG: reopen a lockfile that is still open" -#~ msgstr "BUG: réouverture d'un fichier verrou déjà ouvert" - -#~ msgid "BUG: reopen a lockfile that has been committed" -#~ msgstr "BUG: réouverture d'un fichier verrou validé" - -#~ msgid "option %s does not accept negative form" -#~ msgstr "l'option %s n'accepte pas de valeur négative" - -#~ msgid "unable to parse value '%s' for option %s" -#~ msgstr "impossible d'analyser la valeur '%s' pour l'option %s" - -#~ msgid "-b and -B are mutually exclusive" -#~ msgstr "-b et -B sont mutuellement exclusifs" - -#~ msgid "" -#~ "When you have resolved this problem, run \"$cmdline --continue\".\n" -#~ "If you prefer to skip this patch, run \"$cmdline --skip\" instead.\n" -#~ "To restore the original branch and stop patching, run \"$cmdline --abort" -#~ "\"." -#~ msgstr "" -#~ "Lorsque vous aurez résolu ce problème, lancez \"$cmdline --continue\".\n" -#~ "Si vous préférez sauter ce patch, lancez \"$cmdline --skip\" à la place.\n" -#~ "Pour restaurer la branche d'origine et stopper le patchage, lancez " -#~ "\"$cmdline --abort\"." - -#~ msgid "Patch format $patch_format is not supported." -#~ msgstr "Le format de patch $patch_format n'est pas supporté." - -#~ msgid "Please make up your mind. --skip or --abort?" -#~ msgstr "Décidez-vous. --skip ou --abort ?" - -#~ msgid "" -#~ "Patch is empty. Was it split wrong?\n" -#~ "If you would prefer to skip this patch, instead run \"$cmdline --skip\".\n" -#~ "To restore the original branch and stop patching run \"$cmdline --abort\"." -#~ msgstr "" -#~ "Le patch est vide. Était-il mal découpé ?\n" -#~ "Si vous préférez sauter ce patch, lancez plutôt \"$cmdline --skip\".\n" -#~ "Pour restaurer la branche d'origine et stopper le patchage, lancez " -#~ "\"$cmdline --abort\"." - -#~ msgid "Patch does not have a valid courriel address." -#~ msgstr "Le patch n'a pas d'adresse courriel valide." - -#~ msgid "Applying: $FIRSTLINE" -#~ msgstr "Application : $FIRSTLINE" - -#~ msgid "Patch failed at $msgnum $FIRSTLINE" -#~ msgstr "Le patch a échoué à $msgnum $FIRSTLINE" - -#~ msgid "" -#~ "Pull is not possible because you have unmerged files.\n" -#~ "Please, fix them up in the work tree, and then use 'git add/rm <file>'\n" -#~ "as appropriate to mark resolution and make a commit." -#~ msgstr "" -#~ "Le tirage n'est pas possible car vous avez des fichiers non fusionnés.\n" -#~ "Veuillez les corriger dans votre copie de travail, utiliser alors 'git " -#~ "add/rm <fichier>'\n" -#~ "si nécessaire pour marquer comme résolu et valider." - -#~ msgid "no branch specified" -#~ msgstr "aucune branche spécifiée" - -#~ msgid "prune .git/worktrees" -#~ msgstr "éliminer .git/worktrees" - -#~ msgid "The most commonly used git commands are:" -#~ msgstr "Les commandes git les plus utilisées sont :" - -#~ msgid "No such branch: '%s'" -#~ msgstr "Branche inconnue : '%s'" - -#~ msgid "Could not create git link %s" -#~ msgstr "Impossible de créer le lien git %s" - -#~ msgid "Invalid gc.pruneexpire: '%s'" -#~ msgstr "gc.pruneexpire invalide : '%s'" - -#~ msgid "(detached from %s)" -#~ msgstr "(détaché de %s)" - -#~ msgid "No existing author found with '%s'" -#~ msgstr "Aucun auteur existant trouvé avec '%s'" - -#~ msgid "search also in ignored files" -#~ msgstr "rechercher aussi dans les fichiers ignorés" - -#~ msgid "git remote set-head <name> (-a | --auto | -d | --delete |<branch>)" -#~ msgstr "git remote set-head <nom> (-a | --auto | -d | --delete |<branche>)" - -#~ msgid "no files added" -#~ msgstr "aucun fichier ajouté" - -#~ msgid "slot" -#~ msgstr "emplacement" - -#~ msgid "Failed to lock ref for update" -#~ msgstr "Échec du verrouillage de la référence pour mise à jour" - -#~ msgid "Failed to write ref" -#~ msgstr "Échec de l'écriture de la référence" - -#~ msgid "Failed to lock HEAD during fast_forward_to" -#~ msgstr "Échec du verrouillage de HEAD pendant l'avance rapide" - -#~ msgid "cannot lock HEAD ref" -#~ msgstr "impossible de verrouiller la référence HEAD" - -#~ msgid "cannot update HEAD ref" -#~ msgstr "impossible de mettre à jour la référence HEAD" - -#~ msgid "%s: cannot lock the ref" -#~ msgstr "%s : impossible de verrouiller la référence" - -#~ msgid "commit has empty message" -#~ msgstr "le commit a un message vide" - -#~ msgid "Failed to chdir: %s" -#~ msgstr "Échec de chdir: %s" - -#~ msgid "Tracking not set up: name too long: %s" -#~ msgstr "Suivi de branche non paramétré : le nom est trop long : %s" - -#~ msgid "could not find .gitmodules in index" -#~ msgstr "impossible de trouver .gitmodules dans l'index" - -#~ msgid "reading updated .gitmodules failed" -#~ msgstr "échec de la lecture du .gitmodules mis à jour" - -#~ msgid "unable to stat updated .gitmodules" -#~ msgstr "échec de stat du .gitmodules mis à jour" - -#~ msgid "unable to remove .gitmodules from index" -#~ msgstr "suppression du .gitmodules dans l'index impossible" - -#~ msgid "adding updated .gitmodules failed" -#~ msgstr "échec de l'ajout du .gitmodules mis à jour" - -#~ msgid "bug" -#~ msgstr "bogue" - -#~ msgid ", behind " -#~ msgstr ", derrière " - -#~ msgid "" -#~ "The behavior of 'git add %s (or %s)' with no path argument from a\n" -#~ "subdirectory of the tree will change in Git 2.0 and should not be used " -#~ "anymore.\n" -#~ "To add content for the whole tree, run:\n" -#~ "\n" -#~ " git add %s :/\n" -#~ " (or git add %s :/)\n" -#~ "\n" -#~ "To restrict the command to the current directory, run:\n" -#~ "\n" -#~ " git add %s .\n" -#~ " (or git add %s .)\n" -#~ "\n" -#~ "With the current Git version, the command is restricted to the current " -#~ "directory.\n" -#~ msgstr "" -#~ "Le comportement de 'git add %s (ou %s)' sans argument de chemin depuis " -#~ "un\n" -#~ "sous-répertoire du projet va changer dans Git 2.0 et ne doit plus être " -#~ "utilisé.\n" -#~ "Pour ajouter le contenu de toute l'arborescence, lancez :\n" -#~ "\n" -#~ " git add %s :/\n" -#~ " (ou git add %s :/)\n" -#~ "\n" -#~ "Pour restreindre la commande au répertoire courant, lancez :\n" -#~ "\n" -#~ " git add %s .\n" -#~ " (ou git add %s .)\n" -#~ "\n" -#~ "Avec la version actuelle de Git, la commande est restreinte au répertoire " -#~ "courant.\n" - -#~ msgid "" -#~ "You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" -#~ "whose behaviour will change in Git 2.0 with respect to paths you " -#~ "removed.\n" -#~ "Paths like '%s' that are\n" -#~ "removed from your working tree are ignored with this version of Git.\n" -#~ "\n" -#~ "* 'git add --ignore-removal <pathspec>', which is the current default,\n" -#~ " ignores paths you removed from your working tree.\n" -#~ "\n" -#~ "* 'git add --all <pathspec>' will let you also record the removals.\n" -#~ "\n" -#~ "Run 'git status' to check the paths you removed from your working tree.\n" -#~ msgstr "" -#~ "Vous avez lancé 'git add' sans '-A (--all)' ni '--ignore-removal',\n" -#~ "dont le comportement va changer dans Git 2.0 avec le respect des chemins " -#~ "que vous supprimez.\n" -#~ "Les chemins tels que '%s' qui ont été\n" -#~ "retirés de votre copie de travail sont ignorés avec cette version de " -#~ "Git.\n" -#~ "\n" -#~ "* 'git add --ignore-removal <chemin>', qui est l'option par défaut " -#~ "actuelle,\n" -#~ " ignore les chemins que vous avez supprimés de votre copie de travail.\n" -#~ "\n" -#~ "* 'git add --all <chemin>' permet d'enregistrer aussi les suppressions.\n" -#~ "\n" -#~ "Lancez 'git status' pour vérifier les chemins que vous avez supprimés de " -#~ "votre copie de travail.\n" - -#~ msgid "key id" -#~ msgstr "identifiant de clé" - -#~ msgid "" -#~ "Auto packing the repository for optimum performance. You may also\n" -#~ "run \"git gc\" manually. See \"git help gc\" for more information.\n" -#~ msgstr "" -#~ "Compression automatique du dépôt pour une performance optimum. Vous " -#~ "pouvez aussi\n" -#~ "lancer \"git gc\" manuellement. Voir \"git help gc\" pour plus " -#~ "d'information.\n" - -#~ msgid "" -#~ "Updates were rejected because a pushed branch tip is behind its remote\n" -#~ "counterpart. If you did not intend to push that branch, you may want to\n" -#~ "specify branches to push or set the 'push.default' configuration " -#~ "variable\n" -#~ "to 'simple', 'current' or 'upstream' to push only the current branch." -#~ msgstr "" -#~ "Les mises à jour ont été rejetées car la pointe de la branche poussée est " -#~ "derrière\n" -#~ "son homologue distant. Si vous ne vouliez pas pousser cette branche, vous " -#~ "pourriez\n" -#~ "vouloir spécifier les branches à pousser ou définir la variable de " -#~ "configuration\n" -#~ "'push.default' à 'simple', 'current' ou 'upstream' pour pousser seulement " -#~ "la branche courante." - -#~ msgid "deleted: %s" -#~ msgstr "supprimé : %s" - -#~ msgid "modified: %s" -#~ msgstr "modifié : %s" - -#~ msgid "renamed: %s -> %s" -#~ msgstr "renommé : %s -> %s" - -#~ msgid "unmerged: %s" -#~ msgstr "non fus. : %s" - -#~ msgid "input paths are terminated by a null character" -#~ msgstr "les chemins en entrée sont terminés par le caractère nul" - -#~ msgid "" -#~ "Aborting. Consider using either the --force or --include-untracked option." -#~ msgstr "Abandon. Utilisez l'option --force ou --include-untracked." @@ -2,14 +2,14 @@ # Bản dịch tiếng Việt dà nh cho GIT-CORE. # This file is distributed under the same license as the git-core package. # Nguyá»…n Thái Ngá»c Duy <pclouds@gmail.com>, 2012. -# Trần Ngá»c Quân <vnwildman@gmail.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018. +# Trần Ngá»c Quân <vnwildman@gmail.com>, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019. # msgid "" msgstr "" -"Project-Id-Version: git v2.20.0 round 3\n" +"Project-Id-Version: git v2.21 round 2\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2018-12-02 10:55+0800\n" -"PO-Revision-Date: 2018-12-02 14:12+0700\n" +"POT-Creation-Date: 2019-02-15 10:09+0800\n" +"PO-Revision-Date: 2019-02-26 14:49+0700\n" "Last-Translator: Trần Ngá»c Quân <vnwildman@gmail.com>\n" "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n" "Language: vi\n" @@ -19,48 +19,48 @@ msgstr "" "Plural-Forms: nplurals=1; plural=0;\n" "X-Language-Team-Website: <http://translationproject.org/team/vi.html>\n" "X-Poedit-SourceCharset: UTF-8\n" -"X-Poedit-Basepath: ../\n" +"X-Poedit-Basepath: ..\n" "X-Generator: Gtranslator 2.91.7\n" -#: advice.c:99 +#: advice.c:101 #, c-format msgid "%shint: %.*s%s\n" msgstr "%sgợi ý: %.*s%s\n" -#: advice.c:152 +#: advice.c:154 msgid "Cherry-picking is not possible because you have unmerged files." msgstr "" "Cherry-picking là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được " "hòa trá»™n." -#: advice.c:154 +#: advice.c:156 msgid "Committing is not possible because you have unmerged files." msgstr "" "Commit là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n." -#: advice.c:156 +#: advice.c:158 msgid "Merging is not possible because you have unmerged files." msgstr "" "Merge là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n." -#: advice.c:158 +#: advice.c:160 msgid "Pulling is not possible because you have unmerged files." msgstr "" "Pull là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n." -#: advice.c:160 +#: advice.c:162 msgid "Reverting is not possible because you have unmerged files." msgstr "" "Revert là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n." -#: advice.c:162 +#: advice.c:164 #, c-format msgid "It is not possible to %s because you have unmerged files." msgstr "" "Nó là không thể thá»±c hiện vá»›i %s bởi vì bạn có những táºp tin chÆ°a được hòa " "trá»™n." -#: advice.c:170 +#: advice.c:172 msgid "" "Fix them up in the work tree, and then use 'git add/rm <file>'\n" "as appropriate to mark resolution and make a commit." @@ -68,23 +68,23 @@ msgstr "" "Sá»a chúng trong cây là m việc, và sau đó dùng lệnh “git add/rm <táºp-tin>â€\n" "dà nh riêng cho việc đánh dấu cần giải quyết và tạo lần chuyển giao." -#: advice.c:178 +#: advice.c:180 msgid "Exiting because of an unresolved conflict." msgstr "Thoát ra bởi vì xung Ä‘á»™t không thể giải quyết." -#: advice.c:183 builtin/merge.c:1289 +#: advice.c:185 builtin/merge.c:1290 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Bạn chÆ°a kết thúc việc hòa trá»™n (MERGE_HEAD vẫn tồn tại)." -#: advice.c:185 +#: advice.c:187 msgid "Please, commit your changes before merging." msgstr "Vui lòng chuyển giao các thay đổi trÆ°á»›c khi hòa trá»™n." -#: advice.c:186 +#: advice.c:188 msgid "Exiting because of unfinished merge." msgstr "Thoát ra bởi vì việc hòa trá»™n không hoà n tất." -#: advice.c:192 +#: advice.c:194 #, c-format msgid "" "Note: checking out '%s'.\n" @@ -113,6 +113,14 @@ msgstr "" " git checkout -b <tên-nhánh-má»›i>\n" "\n" +#: alias.c:50 +msgid "cmdline ends with \\" +msgstr "cmdline kết thúc vá»›i \\" + +#: alias.c:51 +msgid "unclosed quote" +msgstr "chÆ°a đóng trÃch dẫn" + #: apply.c:59 #, c-format msgid "unrecognized whitespace option '%s'" @@ -143,65 +151,65 @@ msgstr "--index ở ngoà i má»™t kho chứa" msgid "--cached outside a repository" msgstr "--cached ở ngoà i má»™t kho chứa" -#: apply.c:826 +#: apply.c:825 #, c-format msgid "Cannot prepare timestamp regexp %s" msgstr "" "Không thể chuẩn bị biểu thức chÃnh qui dấu vết thá»i gian (timestamp regexp) " "%s" -#: apply.c:835 +#: apply.c:834 #, c-format msgid "regexec returned %d for input: %s" msgstr "thi hà nh biểu thức chÃnh quy trả vá» %d cho đầu và o: %s" -#: apply.c:909 +#: apply.c:908 #, c-format msgid "unable to find filename in patch at line %d" msgstr "không thể tìm thấy tên táºp tin trong miếng vá tại dòng %d" -#: apply.c:947 +#: apply.c:946 #, c-format msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" msgstr "" "git apply: git-diff sai - cần /dev/null, nhÆ°ng lại nháºn được %s trên dòng %d" -#: apply.c:953 +#: apply.c:952 #, c-format msgid "git apply: bad git-diff - inconsistent new filename on line %d" msgstr "git apply: git-diff sai - tên táºp tin má»›i không nhất quán trên dòng %d" -#: apply.c:954 +#: apply.c:953 #, c-format msgid "git apply: bad git-diff - inconsistent old filename on line %d" msgstr "git apply: git-diff sai - tên táºp tin cÅ© không nhất quán trên dòng %d" -#: apply.c:959 +#: apply.c:958 #, c-format msgid "git apply: bad git-diff - expected /dev/null on line %d" msgstr "git apply: git-diff sai - cần “/dev/null†trên dòng %d" -#: apply.c:988 +#: apply.c:987 #, c-format msgid "invalid mode on line %d: %s" msgstr "chế Ä‘á»™ không hợp lệ trên dòng %d: %s" -#: apply.c:1307 +#: apply.c:1306 #, c-format msgid "inconsistent header lines %d and %d" msgstr "phần đầu mâu thuẫn dòng %d và %d" -#: apply.c:1479 +#: apply.c:1478 #, c-format msgid "recount: unexpected line: %.*s" msgstr "chi tiết: dòng không cần: %.*s" -#: apply.c:1548 +#: apply.c:1547 #, c-format msgid "patch fragment without header at line %d: %.*s" msgstr "miếng vá phân mảnh mà không có phần đầu tại dòng %d: %.*s" -#: apply.c:1568 +#: apply.c:1567 #, c-format msgid "" "git diff header lacks filename information when removing %d leading pathname " @@ -213,81 +221,81 @@ msgstr[0] "" "phần đầu diff cho git thiếu thông tin tên táºp tin khi gỡ bá» Ä‘i %d trong " "thà nh phần dẫn đầu tên của Ä‘Æ°á»ng dẫn (dòng %d)" -#: apply.c:1581 +#: apply.c:1580 #, c-format msgid "git diff header lacks filename information (line %d)" msgstr "phần đầu diff cho git thiếu thông tin tên táºp tin (dòng %d)" -#: apply.c:1769 +#: apply.c:1768 msgid "new file depends on old contents" msgstr "táºp tin má»›i phụ thuá»™c và o ná»™i dung cÅ©" -#: apply.c:1771 +#: apply.c:1770 msgid "deleted file still has contents" msgstr "táºp tin đã xóa vẫn còn ná»™i dung" -#: apply.c:1805 +#: apply.c:1804 #, c-format msgid "corrupt patch at line %d" msgstr "miếng vá há»ng tại dòng %d" -#: apply.c:1842 +#: apply.c:1841 #, c-format msgid "new file %s depends on old contents" msgstr "táºp tin má»›i %s phụ thuá»™c và o ná»™i dung cÅ©" -#: apply.c:1844 +#: apply.c:1843 #, c-format msgid "deleted file %s still has contents" msgstr "táºp tin đã xóa %s vẫn còn ná»™i dung" -#: apply.c:1847 +#: apply.c:1846 #, c-format msgid "** warning: file %s becomes empty but is not deleted" msgstr "** cảnh báo: táºp tin %s trở nên trống rá»—ng nhÆ°ng không bị xóa" -#: apply.c:1994 +#: apply.c:1993 #, c-format msgid "corrupt binary patch at line %d: %.*s" msgstr "miếng vá định dạng nhị phân sai há»ng tại dòng %d: %.*s" -#: apply.c:2031 +#: apply.c:2030 #, c-format msgid "unrecognized binary patch at line %d" msgstr "miếng vá định dạng nhị phân không được nháºn ra tại dòng %d" -#: apply.c:2193 +#: apply.c:2192 #, c-format msgid "patch with only garbage at line %d" msgstr "vá chỉ vá»›i “rác†tại dòng %d" -#: apply.c:2279 +#: apply.c:2278 #, c-format msgid "unable to read symlink %s" msgstr "không thể Ä‘á»c liên kết má»m %s" -#: apply.c:2283 +#: apply.c:2282 #, c-format msgid "unable to open or read %s" msgstr "không thể mở hay Ä‘á»c %s" -#: apply.c:2942 +#: apply.c:2941 #, c-format msgid "invalid start of line: '%c'" msgstr "sai khởi đầu dòng: “%câ€" -#: apply.c:3063 +#: apply.c:3062 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." msgstr[0] "Khối dữ liệu #%d thà nh công tại %d (offset %d dòng)." -#: apply.c:3075 +#: apply.c:3074 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "Ná»™i dung bị giảm xuống còn (%ld/%ld) để áp dụng mảnh dữ liệu tại %d" -#: apply.c:3081 +#: apply.c:3080 #, c-format msgid "" "while searching for:\n" @@ -296,55 +304,55 @@ msgstr "" "trong khi Ä‘ang tìm kiếm cho:\n" "%.*s" -#: apply.c:3103 +#: apply.c:3102 #, c-format msgid "missing binary patch data for '%s'" msgstr "thiếu dữ liệu của miếng vá định dạng nhị phân cho “%sâ€" -#: apply.c:3111 +#: apply.c:3110 #, c-format msgid "cannot reverse-apply a binary patch without the reverse hunk to '%s'" msgstr "" "không thể reverse-apply má»™t miếng vá nhị phân mà không đảo ngược hunk thà nh " "“%sâ€" -#: apply.c:3158 +#: apply.c:3157 #, c-format msgid "cannot apply binary patch to '%s' without full index line" msgstr "" "không thể áp dụng miếng vá nhị phân thà nh “%s†mà không có dòng chỉ mục đầy " "đủ" -#: apply.c:3168 +#: apply.c:3167 #, c-format msgid "" "the patch applies to '%s' (%s), which does not match the current contents." msgstr "" "miếng vá áp dụng cho “%s†(%s), cái mà không khá»›p vá»›i các ná»™i dung hiện tại." -#: apply.c:3176 +#: apply.c:3175 #, c-format msgid "the patch applies to an empty '%s' but it is not empty" msgstr "miếng vá áp dụng cho má»™t “%s†trống rá»—ng nhÆ°ng nó lại không trống" -#: apply.c:3194 +#: apply.c:3193 #, c-format msgid "the necessary postimage %s for '%s' cannot be read" msgstr "không thể Ä‘á»c postimage %s cần thiết cho “%sâ€" -#: apply.c:3207 +#: apply.c:3206 #, c-format msgid "binary patch does not apply to '%s'" msgstr "miếng vá định dạng nhị phân không được áp dụng cho “%sâ€" -#: apply.c:3213 +#: apply.c:3212 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" "vá nhị phân cho “%s†tạo ra kết quả không chÃnh xác (mong chá» %s, lại nháºn " "%s)" -#: apply.c:3234 +#: apply.c:3233 #, c-format msgid "patch failed: %s:%ld" msgstr "gặp lá»—i khi vá: %s:%ld" @@ -381,7 +389,7 @@ msgstr "%s: không khá»›p trong mục lục" #: apply.c:3575 msgid "repository lacks the necessary blob to fall back on 3-way merge." -msgstr "Kho thiếu đối tượng blob cần thiết để trở vá» trên “3-way mergeâ€." +msgstr "kho thiếu đối tượng blob cần thiết để trở vá» trên “3-way mergeâ€." #: apply.c:3578 #, c-format @@ -422,7 +430,8 @@ msgstr "%s: sai kiểu" msgid "%s has type %o, expected %o" msgstr "%s có kiểu %o, cần %o" -#: apply.c:3881 apply.c:3883 +#: apply.c:3881 apply.c:3883 read-cache.c:820 read-cache.c:846 +#: read-cache.c:1299 #, c-format msgid "invalid path '%s'" msgstr "Ä‘Æ°á»ng dẫn không hợp lệ “%sâ€" @@ -477,7 +486,7 @@ msgstr "thay đổi chế Ä‘á»™ cho %s, cái mà không phải là HEAD hiện t msgid "sha1 information is lacking or useless (%s)." msgstr "thông tin sha1 còn thiếu hay không dùng được(%s)." -#: apply.c:4113 builtin/checkout.c:244 builtin/reset.c:142 +#: apply.c:4113 builtin/checkout.c:248 builtin/reset.c:143 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry gặp lá»—i đối vá»›i Ä‘Æ°á»ng dẫn “%sâ€" @@ -552,7 +561,7 @@ msgstr[0] "Äang áp dụng miếng vá %%s vá»›i %d lần từ chối…" msgid "truncating .rej filename to %.*s.rej" msgstr "Ä‘ang cắt ngắn tên táºp tin .rej thà nh %.*s.rej" -#: apply.c:4564 builtin/fetch.c:843 builtin/fetch.c:1122 +#: apply.c:4564 builtin/fetch.c:837 builtin/fetch.c:1118 #, c-format msgid "cannot open %s" msgstr "không mở được “%sâ€" @@ -565,184 +574,184 @@ msgstr "Khối nhá»› #%d được áp dụng gá»n gà ng." #: apply.c:4582 #, c-format msgid "Rejected hunk #%d." -msgstr "Ä‘oạn dữ liệu #%d bị từ chối." +msgstr "Äoạn dữ liệu #%d bị từ chối." #: apply.c:4692 #, c-format msgid "Skipped patch '%s'." -msgstr "bá» qua Ä‘Æ°á»ng dẫn “%sâ€." +msgstr "Bá» qua Ä‘Æ°á»ng dẫn “%sâ€." #: apply.c:4700 msgid "unrecognized input" msgstr "không thừa nháºn đầu và o" -#: apply.c:4719 +#: apply.c:4720 msgid "unable to read index file" msgstr "không thể Ä‘á»c táºp tin lÆ°u bảng mục lục" -#: apply.c:4874 +#: apply.c:4875 #, c-format msgid "can't open patch '%s': %s" msgstr "không thể mở miếng vá “%sâ€: %s" -#: apply.c:4901 +#: apply.c:4902 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "đã chấm dứt %d lá»—i khoảng trắng" -#: apply.c:4907 apply.c:4922 +#: apply.c:4908 apply.c:4923 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." msgstr[0] "%d dòng thêm khoảng trắng lá»—i." -#: apply.c:4915 +#: apply.c:4916 #, c-format msgid "%d line applied after fixing whitespace errors." msgid_plural "%d lines applied after fixing whitespace errors." msgstr[0] "%d dòng được áp dụng sau khi sá»a các lá»—i khoảng trắng." -#: apply.c:4931 builtin/add.c:538 builtin/mv.c:300 builtin/rm.c:389 +#: apply.c:4932 builtin/add.c:539 builtin/mv.c:301 builtin/rm.c:390 msgid "Unable to write new index file" msgstr "Không thể ghi táºp tin lÆ°u bảng mục lục má»›i" -#: apply.c:4958 apply.c:4961 builtin/am.c:2209 builtin/am.c:2212 -#: builtin/clone.c:121 builtin/fetch.c:118 builtin/merge.c:262 -#: builtin/pull.c:199 builtin/submodule--helper.c:406 -#: builtin/submodule--helper.c:1362 builtin/submodule--helper.c:1365 -#: builtin/submodule--helper.c:1846 builtin/submodule--helper.c:1849 -#: builtin/submodule--helper.c:2088 git-add--interactive.perl:197 +#: apply.c:4959 apply.c:4962 builtin/am.c:2203 builtin/am.c:2206 +#: builtin/clone.c:122 builtin/fetch.c:118 builtin/merge.c:263 +#: builtin/pull.c:200 builtin/submodule--helper.c:407 +#: builtin/submodule--helper.c:1366 builtin/submodule--helper.c:1369 +#: builtin/submodule--helper.c:1850 builtin/submodule--helper.c:1853 +#: builtin/submodule--helper.c:2092 git-add--interactive.perl:197 msgid "path" msgstr "Ä‘Æ°á»ng-dẫn" -#: apply.c:4959 +#: apply.c:4960 msgid "don't apply changes matching the given path" msgstr "không áp dụng các thay đổi khá»›p vá»›i Ä‘Æ°á»ng dẫn đã cho" -#: apply.c:4962 +#: apply.c:4963 msgid "apply changes matching the given path" msgstr "áp dụng các thay đổi khá»›p vá»›i Ä‘Æ°á»ng dẫn đã cho" -#: apply.c:4964 builtin/am.c:2218 +#: apply.c:4965 builtin/am.c:2212 msgid "num" msgstr "số" -#: apply.c:4965 +#: apply.c:4966 msgid "remove <num> leading slashes from traditional diff paths" msgstr "gỡ bá» <số> dấu gạch chéo dẫn đầu từ Ä‘Æ°á»ng dẫn diff cổ Ä‘iển" -#: apply.c:4968 +#: apply.c:4969 msgid "ignore additions made by the patch" msgstr "lá» Ä‘i phần bổ xung được tạo ra bởi miếng vá" -#: apply.c:4970 +#: apply.c:4971 msgid "instead of applying the patch, output diffstat for the input" msgstr "" "thay vì áp dụng má»™t miếng vá, kết xuất kết quả từ lệnh diffstat cho đầu ra" -#: apply.c:4974 +#: apply.c:4975 msgid "show number of added and deleted lines in decimal notation" msgstr "" "hiển thị số lượng các dòng được thêm và o và xóa Ä‘i theo ký hiệu tháºp phân" -#: apply.c:4976 +#: apply.c:4977 msgid "instead of applying the patch, output a summary for the input" msgstr "thay vì áp dụng má»™t miếng vá, kết xuất kết quả cho đầu và o" -#: apply.c:4978 +#: apply.c:4979 msgid "instead of applying the patch, see if the patch is applicable" msgstr "thay vì áp dụng miếng vá, hãy xem xem miếng vá có thÃch hợp không" -#: apply.c:4980 +#: apply.c:4981 msgid "make sure the patch is applicable to the current index" msgstr "hãy chắc chắn là miếng vá thÃch hợp vá»›i bảng mục lục hiện hà nh" -#: apply.c:4982 +#: apply.c:4983 msgid "mark new files with `git add --intent-to-add`" msgstr "đánh dấu các táºp tin má»›i vá»›i “git add --intent-to-addâ€" -#: apply.c:4984 +#: apply.c:4985 msgid "apply a patch without touching the working tree" msgstr "áp dụng má»™t miếng vá mà không Ä‘á»™ng chạm đến cây là m việc" -#: apply.c:4986 +#: apply.c:4987 msgid "accept a patch that touches outside the working area" msgstr "chấp nháºn má»™t miếng vá mà không Ä‘á»™ng chạm đến cây là m việc" -#: apply.c:4989 +#: apply.c:4990 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "" "đồng thá»i áp dụng miếng vá (dùng vá»›i tùy chá»n --stat/--summary/--check)" -#: apply.c:4991 +#: apply.c:4992 msgid "attempt three-way merge if a patch does not apply" msgstr "thá» hòa trá»™n kiểu three-way nếu việc vá không thể thá»±c hiện được" -#: apply.c:4993 +#: apply.c:4994 msgid "build a temporary index based on embedded index information" msgstr "" "xây dá»±ng bảng mục lục tạm thá»i trên cÆ¡ sở thông tin bảng mục lục được nhúng" -#: apply.c:4996 builtin/checkout-index.c:170 builtin/ls-files.c:523 +#: apply.c:4997 builtin/checkout-index.c:173 builtin/ls-files.c:524 msgid "paths are separated with NUL character" msgstr "các Ä‘Æ°á»ng dẫn bị ngăn cách bởi ký tá»± NULL" -#: apply.c:4998 +#: apply.c:4999 msgid "ensure at least <n> lines of context match" msgstr "đảm bảo rằng có Ãt nhất <n> dòng ná»™i dung khá»›p" -#: apply.c:4999 builtin/am.c:2197 builtin/interpret-trailers.c:97 +#: apply.c:5000 builtin/am.c:2191 builtin/interpret-trailers.c:97 #: builtin/interpret-trailers.c:99 builtin/interpret-trailers.c:101 -#: builtin/pack-objects.c:3312 builtin/rebase.c:857 +#: builtin/pack-objects.c:3314 builtin/rebase.c:1065 msgid "action" msgstr "hà nh Ä‘á»™ng" -#: apply.c:5000 +#: apply.c:5001 msgid "detect new or modified lines that have whitespace errors" msgstr "tìm thấy má»™t dòng má»›i hoặc bị sá»a đổi mà nó có lá»—i do khoảng trắng" -#: apply.c:5003 apply.c:5006 +#: apply.c:5004 apply.c:5007 msgid "ignore changes in whitespace when finding context" msgstr "lá» Ä‘i sá»± thay đổi do khoảng trắng gây ra khi quét ná»™i dung" -#: apply.c:5009 +#: apply.c:5010 msgid "apply the patch in reverse" msgstr "áp dụng miếng vá theo chiá»u ngược" -#: apply.c:5011 +#: apply.c:5012 msgid "don't expect at least one line of context" msgstr "đừng hy vá»ng có Ãt nhất má»™t dòng ná»™i dung" -#: apply.c:5013 +#: apply.c:5014 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "để lại khối dữ liệu bị từ chối trong các táºp tin *.rej tÆ°Æ¡ng ứng" -#: apply.c:5015 +#: apply.c:5016 msgid "allow overlapping hunks" msgstr "cho phép chồng khối nhá»›" -#: apply.c:5016 builtin/add.c:290 builtin/check-ignore.c:21 -#: builtin/commit.c:1309 builtin/count-objects.c:98 builtin/fsck.c:698 -#: builtin/log.c:2023 builtin/mv.c:122 builtin/read-tree.c:127 -#: builtin/rebase--interactive.c:157 +#: apply.c:5017 builtin/add.c:291 builtin/check-ignore.c:22 +#: builtin/commit.c:1312 builtin/count-objects.c:98 builtin/fsck.c:724 +#: builtin/log.c:2037 builtin/mv.c:123 builtin/read-tree.c:128 +#: builtin/rebase--interactive.c:159 msgid "be verbose" msgstr "chi tiết" -#: apply.c:5018 +#: apply.c:5019 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "" "đã dò tìm thấy dung sai không chÃnh xác thiếu dòng má»›i tại cuối táºp tin" -#: apply.c:5021 +#: apply.c:5022 msgid "do not trust the line counts in the hunk headers" msgstr "không tin số lượng dòng trong phần đầu khối dữ liệu" -#: apply.c:5023 builtin/am.c:2206 +#: apply.c:5024 builtin/am.c:2200 msgid "root" msgstr "gốc" -#: apply.c:5024 +#: apply.c:5025 msgid "prepend <root> to all filenames" msgstr "treo thêm <root> và o tất cả các tên táºp tin" @@ -765,99 +774,118 @@ msgstr "" msgid "git archive --remote <repo> [--exec <cmd>] --list" msgstr "git archive --remote <kho> [--exec <lệnh>] --list" -#: archive.c:370 builtin/add.c:176 builtin/add.c:514 builtin/rm.c:298 +#: archive.c:372 builtin/add.c:177 builtin/add.c:515 builtin/rm.c:299 #, c-format msgid "pathspec '%s' did not match any files" msgstr "đặc tả Ä‘Æ°á»ng dẫn “%s†không khá»›p vá»›i bất kỳ táºp tin nà o" -#: archive.c:453 +#: archive.c:396 +#, c-format +msgid "no such ref: %.*s" +msgstr "không có tham chiếu nà o nhÆ° thế: %.*s" + +#: archive.c:401 +#, c-format +msgid "not a valid object name: %s" +msgstr "không phải là tên đối tượng hợp lệ: “%sâ€" + +#: archive.c:414 +#, c-format +msgid "not a tree object: %s" +msgstr "không phải là đối tượng cây: “%sâ€" + +#: archive.c:424 +msgid "current working directory is untracked" +msgstr "thÆ° mục là m việc hiện hà nh chÆ°a được theo dõi" + +#: archive.c:455 msgid "fmt" msgstr "định_dạng" -#: archive.c:453 +#: archive.c:455 msgid "archive format" msgstr "định dạng lÆ°u trữ" -#: archive.c:454 builtin/log.c:1536 +#: archive.c:456 builtin/log.c:1549 msgid "prefix" msgstr "tiá»n_tố" -#: archive.c:455 +#: archive.c:457 msgid "prepend prefix to each pathname in the archive" msgstr "nối thêm tiá»n tố và o từng Ä‘Æ°á»ng dẫn táºp tin trong kho lÆ°u" -#: archive.c:456 builtin/blame.c:820 builtin/blame.c:821 builtin/config.c:129 -#: builtin/fast-export.c:1013 builtin/fast-export.c:1015 builtin/grep.c:884 -#: builtin/hash-object.c:104 builtin/ls-files.c:559 builtin/ls-files.c:562 -#: builtin/notes.c:412 builtin/notes.c:575 builtin/read-tree.c:122 +#: archive.c:458 builtin/blame.c:820 builtin/blame.c:821 builtin/config.c:129 +#: builtin/fast-export.c:1091 builtin/fast-export.c:1093 builtin/grep.c:895 +#: builtin/hash-object.c:105 builtin/ls-files.c:560 builtin/ls-files.c:563 +#: builtin/notes.c:412 builtin/notes.c:578 builtin/read-tree.c:123 #: parse-options.h:162 msgid "file" msgstr "táºp_tin" -#: archive.c:457 builtin/archive.c:89 +#: archive.c:459 builtin/archive.c:90 msgid "write the archive to this file" msgstr "ghi kho lÆ°u và o táºp tin nà y" -#: archive.c:459 +#: archive.c:461 msgid "read .gitattributes in working directory" msgstr "Ä‘á»c .gitattributes trong thÆ° mục là m việc" -#: archive.c:460 +#: archive.c:462 msgid "report archived files on stderr" msgstr "liệt kê các táºp tin được lÆ°u trữ và o stderr (đầu ra lá»—i tiêu chuẩn)" -#: archive.c:461 +#: archive.c:463 msgid "store only" msgstr "chỉ lÆ°u (không nén)" -#: archive.c:462 +#: archive.c:464 msgid "compress faster" msgstr "nén nhanh hÆ¡n" -#: archive.c:470 +#: archive.c:472 msgid "compress better" msgstr "nén nhá» hÆ¡n" -#: archive.c:473 +#: archive.c:475 msgid "list supported archive formats" msgstr "liệt kê các kiểu nén được há»— trợ" -#: archive.c:475 builtin/archive.c:90 builtin/clone.c:111 builtin/clone.c:114 -#: builtin/submodule--helper.c:1374 builtin/submodule--helper.c:1855 +#: archive.c:477 builtin/archive.c:91 builtin/clone.c:112 builtin/clone.c:115 +#: builtin/submodule--helper.c:1378 builtin/submodule--helper.c:1859 msgid "repo" msgstr "kho" -#: archive.c:476 builtin/archive.c:91 +#: archive.c:478 builtin/archive.c:92 msgid "retrieve the archive from remote repository <repo>" msgstr "nháºn kho nén từ kho chứa <kho> trên máy chủ" -#: archive.c:477 builtin/archive.c:92 builtin/difftool.c:714 -#: builtin/notes.c:496 +#: archive.c:479 builtin/archive.c:93 builtin/difftool.c:715 +#: builtin/notes.c:498 msgid "command" msgstr "lệnh" -#: archive.c:478 builtin/archive.c:93 +#: archive.c:480 builtin/archive.c:94 msgid "path to the remote git-upload-archive command" msgstr "Ä‘Æ°á»ng dẫn đến lệnh git-upload-pack trên máy chủ" -#: archive.c:485 +#: archive.c:487 msgid "Unexpected option --remote" msgstr "Gặp tùy chá»n --remote không cần" -#: archive.c:487 +#: archive.c:489 msgid "Option --exec can only be used together with --remote" msgstr "Tùy chá»n --exec chỉ có thể được dùng cùng vá»›i --remote" -#: archive.c:489 +#: archive.c:491 msgid "Unexpected option --output" msgstr "Gặp tùy chá»n không cần --output" -#: archive.c:511 +#: archive.c:513 #, c-format msgid "Unknown archive format '%s'" msgstr "Không hiểu định dạng “%sâ€" -#: archive.c:518 +#: archive.c:520 #, c-format msgid "Argument not supported for format '%s': -%d" msgstr "Tham số không được há»— trợ cho định dạng “%sâ€: -%d" @@ -901,7 +929,7 @@ msgstr "Ä‘Æ°á»ng dẫn không hợp lệ UTF-8: %s" msgid "path too long (%d chars, SHA1: %s): %s" msgstr "Ä‘Æ°á»ng dẫn quá dà i (%d ký tá»±, SHA1: %s): %s" -#: archive-zip.c:474 builtin/pack-objects.c:224 builtin/pack-objects.c:227 +#: archive-zip.c:474 builtin/pack-objects.c:225 builtin/pack-objects.c:228 #, c-format msgid "deflate error (%d)" msgstr "lá»—i giải nén (%d)" @@ -911,12 +939,17 @@ msgstr "lá»—i giải nén (%d)" msgid "timestamp too large for this system: %<PRIuMAX>" msgstr "dấu vết thá»i gian là quá lá»›n cho hệ thống nà y: %<PRIuMAX>" -#: attr.c:212 +#: attr.c:211 #, c-format msgid "%.*s is not a valid attribute name" msgstr "%.*s không phải tên thuá»™c tÃnh hợp lệ" -#: attr.c:409 +#: attr.c:368 +#, c-format +msgid "%s not allowed: %s:%d" +msgstr "%s không được phép: %s:%d" + +#: attr.c:408 msgid "" "Negative patterns are ignored in git attributes\n" "Use '\\!' for literal leading exclamation." @@ -927,19 +960,19 @@ msgstr "" #: bisect.c:468 #, c-format msgid "Badly quoted content in file '%s': %s" -msgstr "ná»™i dung được trÃch dẫn sai táºp tin “%sâ€: %s" +msgstr "Ná»™i dung được trÃch dẫn sai trong táºp tin “%sâ€: %s" -#: bisect.c:676 +#: bisect.c:678 #, c-format msgid "We cannot bisect more!\n" msgstr "Chúng tôi không bisect thêm nữa!\n" -#: bisect.c:730 +#: bisect.c:733 #, c-format msgid "Not a valid commit name %s" msgstr "Không phải tên đối tượng commit %s hợp lệ" -#: bisect.c:754 +#: bisect.c:758 #, c-format msgid "" "The merge base %s is bad.\n" @@ -948,7 +981,7 @@ msgstr "" "Hòa trá»™n trên %s là sai.\n" "Äiá»u đó có nghÄ©a là lá»—i đã được sá»a chữa giữa %s và [%s].\n" -#: bisect.c:759 +#: bisect.c:763 #, c-format msgid "" "The merge base %s is new.\n" @@ -957,7 +990,7 @@ msgstr "" "Hòa trá»™n trên %s là má»›i.\n" "Gần nhÆ° chắc chắn là có thay đổi giữa %s và [%s].\n" -#: bisect.c:764 +#: bisect.c:768 #, c-format msgid "" "The merge base %s is %s.\n" @@ -966,7 +999,7 @@ msgstr "" "Hòa trá»™n trên %s là %s.\n" "Äiá»u đó có nghÄ©a là lần chuyển giao “%s†đầu tiên là giữa %s và [%s].\n" -#: bisect.c:772 +#: bisect.c:776 #, c-format msgid "" "Some %s revs are not ancestors of the %s rev.\n" @@ -977,7 +1010,7 @@ msgstr "" "git bisect không thể là m việc đúng đắn trong trÆ°á»ng hợp nà y.\n" "Liệu có phải bạn nhầm lẫn các Ä‘iểm %s và %s không?\n" -#: bisect.c:785 +#: bisect.c:789 #, c-format msgid "" "the merge base between %s and [%s] must be skipped.\n" @@ -989,45 +1022,45 @@ msgstr "" "%s.\n" "Chúng tôi vẫn cứ tiếp tục." -#: bisect.c:818 +#: bisect.c:822 #, c-format msgid "Bisecting: a merge base must be tested\n" msgstr "Bisecting: ná»n hòa trá»™n cần phải được kiểm tra\n" -#: bisect.c:858 +#: bisect.c:865 #, c-format msgid "a %s revision is needed" msgstr "cần má»™t Ä‘iểm xét duyệt %s" -#: bisect.c:877 builtin/notes.c:177 builtin/tag.c:237 +#: bisect.c:884 builtin/notes.c:177 builtin/tag.c:237 #, c-format msgid "could not create file '%s'" msgstr "không thể tạo táºp tin “%sâ€" -#: bisect.c:928 builtin/merge.c:138 +#: bisect.c:937 builtin/merge.c:139 #, c-format msgid "could not read file '%s'" msgstr "không thể Ä‘á»c táºp tin “%sâ€" -#: bisect.c:958 +#: bisect.c:967 msgid "reading bisect refs failed" msgstr "việc Ä‘á»c tham chiếu bisect gặp lá»—i" -#: bisect.c:977 +#: bisect.c:986 #, c-format msgid "%s was both %s and %s\n" msgstr "%s là cả %s và %s\n" -#: bisect.c:985 +#: bisect.c:994 #, c-format msgid "" "No testable commit found.\n" "Maybe you started with bad path parameters?\n" msgstr "" -"không tìm thấy lần chuyển giao kiểm tra được nà o.\n" +"Không tìm thấy lần chuyển giao kiểm tra được nà o.\n" "Có lẽ bạn bắt đầu vá»›i các tham số Ä‘Æ°á»ng dẫn sai?\n" -#: bisect.c:1004 +#: bisect.c:1013 #, c-format msgid "(roughly %d step)" msgid_plural "(roughly %d steps)" @@ -1036,46 +1069,46 @@ msgstr[0] "(Æ°á»›c chừng %d bÆ°á»›c)" #. TRANSLATORS: the last %s will be replaced with "(roughly %d #. steps)" translation. #. -#: bisect.c:1010 +#: bisect.c:1019 #, c-format msgid "Bisecting: %d revision left to test after this %s\n" msgid_plural "Bisecting: %d revisions left to test after this %s\n" msgstr[0] "Bisecting: còn %d Ä‘iểm xét duyệt để kiểm sau %s nà y\n" -#: blame.c:1787 +#: blame.c:1792 msgid "--contents and --reverse do not blend well." msgstr "tùy chá»n--contents và --reverse không được trá»™n và o nhau." -#: blame.c:1801 +#: blame.c:1806 msgid "cannot use --contents with final commit object name" msgstr "không thể dùng --contents vá»›i tên đối tượng chuyển giao cuối cùng" -#: blame.c:1822 +#: blame.c:1827 msgid "--reverse and --first-parent together require specified latest commit" msgstr "" "--reverse và --first-parent cùng nhau cần chỉ định lần chuyển giao cuối" -#: blame.c:1831 bundle.c:162 ref-filter.c:2046 sequencer.c:1963 -#: sequencer.c:4002 builtin/commit.c:1001 builtin/log.c:377 builtin/log.c:932 -#: builtin/log.c:1407 builtin/log.c:1783 builtin/log.c:2072 builtin/merge.c:406 +#: blame.c:1836 bundle.c:164 ref-filter.c:2071 remote.c:1948 sequencer.c:1993 +#: sequencer.c:4064 builtin/commit.c:1004 builtin/log.c:378 builtin/log.c:936 +#: builtin/log.c:1420 builtin/log.c:1796 builtin/log.c:2086 builtin/merge.c:407 #: builtin/pack-objects.c:3137 builtin/pack-objects.c:3152 #: builtin/shortlog.c:192 msgid "revision walk setup failed" msgstr "cà i đặt việc di chuyển qua các Ä‘iểm xét duyệt gặp lá»—i" -#: blame.c:1849 +#: blame.c:1854 msgid "" "--reverse --first-parent together require range along first-parent chain" msgstr "" "--reverse --first-parent cùng nhau yêu cầu vùng cùng vá»›i chuá»—i cha-mẹ-đầu-" "tiên" -#: blame.c:1860 +#: blame.c:1865 #, c-format msgid "no such path %s in %s" msgstr "không có Ä‘Æ°á»ng dẫn %s trong “%sâ€" -#: blame.c:1871 +#: blame.c:1876 #, c-format msgid "cannot read blob %s for path %s" msgstr "không thể Ä‘á»c blob %s cho Ä‘Æ°á»ng dẫn “%sâ€" @@ -1196,27 +1229,27 @@ msgstr "" "sẽ theo dõi bản đối chiếu máy chủ của nó, bạn cần dùng lệnh\n" "\"git push -u\" để đặt cấu hình thượng nguồn bạn muốn push." -#: branch.c:279 +#: branch.c:280 #, c-format msgid "Not a valid object name: '%s'." msgstr "Không phải tên đối tượng hợp lệ: “%sâ€." -#: branch.c:299 +#: branch.c:300 #, c-format msgid "Ambiguous object name: '%s'." msgstr "Tên đối tượng chÆ°a rõ rà ng: “%sâ€." -#: branch.c:304 +#: branch.c:305 #, c-format msgid "Not a valid branch point: '%s'." msgstr "Nhánh không hợp lệ: “%sâ€." -#: branch.c:358 +#: branch.c:359 #, c-format msgid "'%s' is already checked out at '%s'" msgstr "“%s†đã được lấy ra tại “%s†rồi" -#: branch.c:381 +#: branch.c:382 #, c-format msgid "HEAD of working tree %s is not updated" msgstr "HEAD của cây là m việc %s chÆ°a được cáºp nháºt" @@ -1231,68 +1264,68 @@ msgstr "“%s†không giống nhÆ° táºp tin v2 bundle (định dạng dump cá msgid "unrecognized header: %s%s (%d)" msgstr "phần đầu không được thừa nháºn: %s%s (%d)" -#: bundle.c:90 rerere.c:480 rerere.c:690 sequencer.c:2182 sequencer.c:2722 -#: builtin/commit.c:774 +#: bundle.c:90 rerere.c:480 rerere.c:690 sequencer.c:2215 sequencer.c:2763 +#: builtin/commit.c:776 #, c-format msgid "could not open '%s'" msgstr "không thể mở “%sâ€" -#: bundle.c:141 +#: bundle.c:143 msgid "Repository lacks these prerequisite commits:" msgstr "Kho chứa thiếu những lần chuyển giao tiên quyết nà y:" -#: bundle.c:192 +#: bundle.c:194 #, c-format msgid "The bundle contains this ref:" msgid_plural "The bundle contains these %d refs:" msgstr[0] "Bó dữ liệu chứa %d tham chiếu:" -#: bundle.c:199 +#: bundle.c:201 msgid "The bundle records a complete history." msgstr "Lệnh bundle ghi lại toà n bá»™ lịch sá»." -#: bundle.c:201 +#: bundle.c:203 #, c-format msgid "The bundle requires this ref:" msgid_plural "The bundle requires these %d refs:" msgstr[0] "Lệnh bundle yêu cầu %d tham chiếu nà y:" -#: bundle.c:267 +#: bundle.c:269 msgid "unable to dup bundle descriptor" msgstr "không thể nhân đôi bá»™ mô tả bundle" -#: bundle.c:274 +#: bundle.c:276 msgid "Could not spawn pack-objects" msgstr "Không thể sản sinh đối tượng gói" -#: bundle.c:285 +#: bundle.c:287 msgid "pack-objects died" msgstr "đối tượng gói đã chết" -#: bundle.c:327 +#: bundle.c:329 msgid "rev-list died" msgstr "rev-list đã chết" -#: bundle.c:376 +#: bundle.c:378 #, c-format msgid "ref '%s' is excluded by the rev-list options" msgstr "th.chiếu “%s†bị loại trừ bởi các tùy chá»n rev-list" -#: bundle.c:456 builtin/log.c:192 builtin/log.c:1688 builtin/shortlog.c:304 +#: bundle.c:457 builtin/log.c:193 builtin/log.c:1701 builtin/shortlog.c:306 #, c-format msgid "unrecognized argument: %s" msgstr "đối số không được thừa nháºn: %s" -#: bundle.c:464 +#: bundle.c:465 msgid "Refusing to create empty bundle." msgstr "Từ chối tạo má»™t bó dữ liệu trống rá»—ng." -#: bundle.c:474 +#: bundle.c:475 #, c-format msgid "cannot create '%s'" msgstr "không thể tạo “%sâ€" -#: bundle.c:498 +#: bundle.c:500 msgid "index-pack died" msgstr "mục lục gói đã chết" @@ -1301,8 +1334,8 @@ msgstr "mục lục gói đã chết" msgid "invalid color value: %.*s" msgstr "giá trị mà u không hợp lệ: %.*s" -#: commit.c:50 sequencer.c:2528 builtin/am.c:370 builtin/am.c:414 -#: builtin/am.c:1390 builtin/am.c:2025 builtin/replace.c:376 +#: commit.c:50 sequencer.c:2567 builtin/am.c:355 builtin/am.c:399 +#: builtin/am.c:1375 builtin/am.c:2019 builtin/replace.c:376 #: builtin/replace.c:448 #, c-format msgid "could not parse %s" @@ -1333,28 +1366,28 @@ msgstr "" "Tắt lá»i nhắn nà y bằng cách chạy\n" "\"git config advice.graftFileDeprecated false\"" -#: commit.c:1115 +#: commit.c:1122 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" "Lần chuyển giao %s có má»™t chữ ký GPG không đáng tin, được cho là bởi %s." -#: commit.c:1118 +#: commit.c:1125 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "Lần chuyển giao %s có má»™t chữ ký GPG sai, được cho là bởi %s." -#: commit.c:1121 +#: commit.c:1128 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "Lần chuyển giao %s không có chữ ký GPG." -#: commit.c:1124 +#: commit.c:1131 #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "Lần chuyển giao %s có má»™t chữ ký GPG tốt bởi %s\n" -#: commit.c:1378 +#: commit.c:1385 msgid "" "Warning: commit message did not conform to UTF-8.\n" "You may want to amend it after fixing the message, or set the config\n" @@ -1364,92 +1397,138 @@ msgstr "" "Bạn có lẽ muốn tu bổ nó sau khi sá»a lá»i chú thÃch, hoặc là đặt biến\n" "cấu hình i18n.commitencoding thà nh bảng mã mà dá»± án của bạn muốn dùng.\n" -#: commit-graph.c:108 +#: commit-graph.c:101 #, c-format msgid "graph file %s is too small" msgstr "táºp tin đồ thị %s quá nhá»" -#: commit-graph.c:115 +#: commit-graph.c:136 #, c-format msgid "graph signature %X does not match signature %X" msgstr "chữ ký đồ há»a %X không khá»›p chữ ký %X" -#: commit-graph.c:122 +#: commit-graph.c:143 #, c-format msgid "graph version %X does not match version %X" msgstr "phiên bản đồ há»a %X không khá»›p phiên bản %X" -#: commit-graph.c:129 +#: commit-graph.c:150 #, c-format msgid "hash version %X does not match version %X" msgstr "phiên bản băm “%X†không có phiên bản khá»›p %X" -#: commit-graph.c:153 +#: commit-graph.c:173 +msgid "chunk lookup table entry missing; graph file may be incomplete" +msgstr "" +"mục tin bảng tìm kiếm mảnh còn thiếu; táºp tin đồ thị có thể sẽ không hoà n " +"thiện" + +#: commit-graph.c:184 #, c-format msgid "improper chunk offset %08x%08x" msgstr "bù mảnh không đúng chá»— %08x%08x" -#: commit-graph.c:189 +#: commit-graph.c:221 #, c-format msgid "chunk id %08x appears multiple times" msgstr "mã mảnh %08x xuất hiện nhiá»u lần" -#: commit-graph.c:308 +#: commit-graph.c:334 #, c-format msgid "could not find commit %s" msgstr "không thể tìm thấy lần chuyển giao %s" -#: commit-graph.c:617 builtin/pack-objects.c:2652 +#: commit-graph.c:671 builtin/pack-objects.c:2646 #, c-format msgid "unable to get type of object %s" msgstr "không thể lấy kiểu của đối tượng “%sâ€" -#: commit-graph.c:651 -msgid "Annotating commits in commit graph" -msgstr "Diá»…n giải các lần chuyển giao trong đồ thị lần chuyển giao" +#: commit-graph.c:704 +msgid "Loading known commits in commit graph" +msgstr "Äang tải các lần chuyển giao chÆ°a biết trong đồ thị lần chuyển giao" + +#: commit-graph.c:720 +msgid "Expanding reachable commits in commit graph" +msgstr "" +"Mở rá»™ng các lần chuyển giao có thể tiếp cáºn được trong trong đồ thị lần " +"chuyển giao" + +#: commit-graph.c:732 +msgid "Clearing commit marks in commit graph" +msgstr "Äang dá»n dẹp các đánh dấu lần chuyển giao trong đồ thị lần chuyển giao" -#: commit-graph.c:691 +#: commit-graph.c:752 msgid "Computing commit graph generation numbers" msgstr "Äang tÃnh toán số tạo sÆ¡ đồ các lần chuyển giao" -#: commit-graph.c:803 commit-graph.c:826 commit-graph.c:852 -msgid "Finding commits for commit graph" -msgstr "Äang tìm các lần chuyển giao cho đồ thị lần chuyển giao" +#: commit-graph.c:869 +#, c-format +msgid "Finding commits for commit graph in %d pack" +msgid_plural "Finding commits for commit graph in %d packs" +msgstr[0] "" +"Äang tìm các lần chuyển giao cho đồ thị lần chuyển giao trong %d gói" -#: commit-graph.c:812 +#: commit-graph.c:882 #, c-format msgid "error adding pack %s" msgstr "gặp lá»—i thêm gói %s" -#: commit-graph.c:814 +#: commit-graph.c:884 #, c-format msgid "error opening index for %s" msgstr "gặp lá»—i khi mở mục lục cho “%sâ€" -#: commit-graph.c:868 +#: commit-graph.c:898 +#, c-format +msgid "Finding commits for commit graph from %d ref" +msgid_plural "Finding commits for commit graph from %d refs" +msgstr[0] "" +"Äang tìm các lần chuyển giao cho đồ thị lần chuyển giao từ %d tham chiếu" + +#: commit-graph.c:930 +msgid "Finding commits for commit graph among packed objects" +msgstr "" +"Äang tìm các lần chuyển giao cho đồ thị lần chuyển giao trong số các đối " +"tượng đã đóng gói" + +#: commit-graph.c:943 +msgid "Counting distinct commits in commit graph" +msgstr "Äang đếm các lần chuyển giao khác nhau trong đồ thị lần chuyển giao" + +#: commit-graph.c:956 #, c-format msgid "the commit graph format cannot write %d commits" msgstr "định dạng đồ há»a các lần chuyển giao không thể ghi %d lần chuyển giao" -#: commit-graph.c:895 +#: commit-graph.c:965 +msgid "Finding extra edges in commit graph" +msgstr "Äang tìm các cạnh mở tá»™ng trong đồ thị lần chuyển giao" + +#: commit-graph.c:989 msgid "too many commits to write graph" msgstr "có quá nhiá»u lần chuyển giao để ghi đồ thị" -#: commit-graph.c:902 midx.c:769 +#: commit-graph.c:996 midx.c:769 #, c-format msgid "unable to create leading directories of %s" msgstr "không thể tạo các thÆ° mục dẫn đầu của “%sâ€" -#: commit-graph.c:1002 +#: commit-graph.c:1036 +#, c-format +msgid "Writing out commit graph in %d pass" +msgid_plural "Writing out commit graph in %d passes" +msgstr[0] "Äang ghi ra đồ thị các lần chuyển giao trong lần %d" + +#: commit-graph.c:1109 msgid "the commit-graph file has incorrect checksum and is likely corrupt" msgstr "" "táºp tin sÆ¡ đồ chuyển giao có tổng kiểm không đúng và có vẻ nhÆ° là đã há»ng" -#: commit-graph.c:1046 +#: commit-graph.c:1153 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" -#: compat/obstack.c:405 compat/obstack.c:407 +#: compat/obstack.c:406 compat/obstack.c:408 msgid "memory exhausted" msgstr "hết bá»™ nhá»›" @@ -1491,7 +1570,7 @@ msgstr "khóa không chứa má»™t phần: %s" msgid "key does not contain variable name: %s" msgstr "khóa không chứa bất kỳ má»™t tên biến nà o: %s" -#: config.c:378 sequencer.c:2296 +#: config.c:378 sequencer.c:2330 #, c-format msgid "invalid key: %s" msgstr "khóa không đúng: %s" @@ -1629,7 +1708,7 @@ 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" -#: config.c:1481 builtin/pack-objects.c:3391 +#: config.c:1481 builtin/pack-objects.c:3394 #, c-format msgid "bad pack compression level %d" msgstr "mức nén gói %d không hợp lệ" @@ -1703,62 +1782,62 @@ msgstr "%s có Ä‘a giá trị" msgid "failed to write new configuration file %s" msgstr "gặp lá»—i khi ghi táºp tin cấu hình “%sâ€" -#: config.c:2717 config.c:3041 +#: config.c:2716 config.c:3040 #, c-format msgid "could not lock config file %s" msgstr "không thể khóa táºp tin cấu hình %s" -#: config.c:2728 +#: config.c:2727 #, c-format msgid "opening %s" msgstr "Ä‘ang mở “%sâ€" -#: config.c:2763 builtin/config.c:327 +#: config.c:2762 builtin/config.c:328 #, c-format msgid "invalid pattern: %s" msgstr "mẫu không hợp lệ: %s" -#: config.c:2788 +#: config.c:2787 #, c-format msgid "invalid config file %s" msgstr "táºp tin cấu hình “%s†không hợp lệ" -#: config.c:2801 config.c:3054 +#: config.c:2800 config.c:3053 #, c-format msgid "fstat on %s failed" msgstr "fstat trên %s gặp lá»—i" -#: config.c:2812 +#: config.c:2811 #, c-format msgid "unable to mmap '%s'" msgstr "không thể mmap “%sâ€" -#: config.c:2821 config.c:3059 +#: config.c:2820 config.c:3058 #, c-format msgid "chmod on %s failed" msgstr "chmod trên %s gặp lá»—i" -#: config.c:2906 config.c:3156 +#: config.c:2905 config.c:3155 #, c-format msgid "could not write config file %s" msgstr "không thể ghi táºp tin cấu hình “%sâ€" -#: config.c:2940 +#: config.c:2939 #, c-format msgid "could not set '%s' to '%s'" msgstr "không thể đặt “%s†thà nh “%sâ€" -#: config.c:2942 builtin/remote.c:782 +#: config.c:2941 builtin/remote.c:782 #, c-format msgid "could not unset '%s'" msgstr "không thể thôi đặt “%sâ€" -#: config.c:3032 +#: config.c:3031 #, c-format msgid "invalid section name: %s" msgstr "tên của phần không hợp lệ: %s" -#: config.c:3199 +#: config.c:3198 #, c-format msgid "missing value for '%s'" msgstr "thiếu giá trị cho cho “%sâ€" @@ -1811,50 +1890,45 @@ msgstr "lá»—i giao thức: cần sha-1 shallow, nhÆ°ng lại nháºn được “ msgid "repository on the other end cannot be shallow" msgstr "kho đã ở Ä‘iểm cuối khoác nên không thể được shallow" -#: connect.c:310 fetch-pack.c:182 builtin/archive.c:63 -#, c-format -msgid "remote error: %s" -msgstr "lá»—i máy chủ: %s" - -#: connect.c:316 +#: connect.c:313 msgid "invalid packet" msgstr "gói không hợp lệ" -#: connect.c:336 +#: connect.c:333 #, c-format msgid "protocol error: unexpected '%s'" msgstr "lá»—i giao thức: không cần “%sâ€" -#: connect.c:444 +#: connect.c:441 #, c-format msgid "invalid ls-refs response: %s" msgstr "trả vá» của ls-refs không hợp lệ: %s" -#: connect.c:448 +#: connect.c:445 msgid "expected flush after ref listing" msgstr "cần đẩy dữ liệu lên Ä‘Ä©a sau khi liệt kê tham chiếu" -#: connect.c:547 +#: connect.c:544 #, c-format msgid "protocol '%s' is not supported" msgstr "giao thức “%s†chÆ°a được há»— trợ" -#: connect.c:598 +#: connect.c:595 msgid "unable to set SO_KEEPALIVE on socket" msgstr "không thể đặt SO_KEEPALIVE trên ổ cắm" -#: connect.c:638 connect.c:701 +#: connect.c:635 connect.c:698 #, c-format msgid "Looking up %s ... " -msgstr "Äang tìm kiếm %s …" +msgstr "Äang tìm kiếm %s … " -#: connect.c:642 +#: connect.c:639 #, c-format msgid "unable to look up %s (port %s) (%s)" msgstr "không tìm được %s (cổng %s) (%s)" #. TRANSLATORS: this is the end of "Looking up %s ... " -#: connect.c:646 connect.c:717 +#: connect.c:643 connect.c:714 #, c-format msgid "" "done.\n" @@ -1863,7 +1937,7 @@ msgstr "" "xong.\n" "Äang kết nối đến %s (cổng %s) … " -#: connect.c:668 connect.c:745 +#: connect.c:665 connect.c:742 #, c-format msgid "" "unable to connect to %s:\n" @@ -1873,61 +1947,61 @@ msgstr "" "%s" #. TRANSLATORS: this is the end of "Connecting to %s (port %s) ... " -#: connect.c:674 connect.c:751 +#: connect.c:671 connect.c:748 msgid "done." msgstr "hoà n tất." -#: connect.c:705 +#: connect.c:702 #, c-format msgid "unable to look up %s (%s)" msgstr "không thể tìm thấy %s (%s)" -#: connect.c:711 +#: connect.c:708 #, c-format msgid "unknown port %s" msgstr "không hiểu cổng %s" -#: connect.c:848 connect.c:1174 +#: connect.c:845 connect.c:1171 #, c-format msgid "strange hostname '%s' blocked" msgstr "đã khóa tên máy lạ “%sâ€" -#: connect.c:850 +#: connect.c:847 #, c-format msgid "strange port '%s' blocked" msgstr "đã khóa cổng lạ “%sâ€" -#: connect.c:860 +#: connect.c:857 #, c-format msgid "cannot start proxy %s" msgstr "không thể khởi chạy ủy nhiệm “%sâ€" -#: connect.c:927 +#: connect.c:924 msgid "no path specified; see 'git help pull' for valid url syntax" msgstr "chÆ°a chỉ định Ä‘Æ°á»ng dẫn; xem'git help pull†để biết cú pháp url hợp lệ" -#: connect.c:1122 +#: connect.c:1119 msgid "ssh variant 'simple' does not support -4" msgstr "ssh biến thể “simple†không há»— trợ -4" -#: connect.c:1134 +#: connect.c:1131 msgid "ssh variant 'simple' does not support -6" msgstr "ssh biến thể “simple†không há»— trợ -6" -#: connect.c:1151 +#: connect.c:1148 msgid "ssh variant 'simple' does not support setting port" msgstr "ssh biến thể “simple†không há»— trợ đặt cổng" -#: connect.c:1262 +#: connect.c:1259 #, c-format msgid "strange pathname '%s' blocked" msgstr "đã khóa tên Ä‘Æ°á»ng dẫn lạ “%sâ€" -#: connect.c:1307 +#: connect.c:1304 msgid "unable to fork" msgstr "không thể rẽ nhánh tiến trình con" -#: connected.c:68 builtin/fsck.c:202 builtin/prune.c:147 +#: connected.c:68 builtin/fsck.c:221 builtin/prune.c:146 msgid "Checking connectivity" msgstr "Äang kiểm tra kết nối" @@ -1943,17 +2017,17 @@ msgstr "gặp lá»—i khi ghi và o rev-list" msgid "failed to close rev-list's stdin" msgstr "gặp lá»—i khi đóng đầu và o chuẩn stdin của rev-list" -#: convert.c:194 +#: convert.c:193 #, c-format msgid "illegal crlf_action %d" msgstr "crlf_action %d không hợp lệ" -#: convert.c:207 +#: convert.c:206 #, c-format msgid "CRLF would be replaced by LF in %s" msgstr "CRLF nên được thay bằng LF trong %s" -#: convert.c:209 +#: convert.c:208 #, c-format msgid "" "CRLF will be replaced by LF in %s.\n" @@ -1962,12 +2036,12 @@ msgstr "" "CRLF sẽ bị thay thế bằng LF trong %s.\n" "Táºp tin sẽ có kiểu xuống dòng nhÆ° bản gốc trong thÆ° mục là m việc của bạn" -#: convert.c:217 +#: convert.c:216 #, c-format msgid "LF would be replaced by CRLF in %s" msgstr "LF nên thay bằng CRLF trong %s" -#: convert.c:219 +#: convert.c:218 #, c-format msgid "" "LF will be replaced by CRLF in %s.\n" @@ -1976,12 +2050,12 @@ msgstr "" "LF sẽ bị thay thế bằng CRLF trong %s.\n" "Táºp tin sẽ có kiểu xuống dòng nhÆ° bản gốc trong thÆ° mục là m việc của bạn" -#: convert.c:280 +#: convert.c:279 #, c-format msgid "BOM is prohibited in '%s' if encoded as %s" msgstr "BOM bị cấm trong “%s†nếu được mã hóa là %s" -#: convert.c:287 +#: convert.c:286 #, c-format msgid "" "The file '%s' contains a byte order mark (BOM). Please use UTF-%s as working-" @@ -1990,12 +2064,12 @@ msgstr "" "Táºp tin “%s†có chứa ký hiệu thứ tá»± byte (BOM). Vui lòng dùng UTF-%s nhÆ° là " "bảng mã cây là m việc." -#: convert.c:305 +#: convert.c:304 #, c-format msgid "BOM is required in '%s' if encoded as %s" msgstr "BOM là bắt buá»™c trong “%s†nếu được mã hóa là %s" -#: convert.c:307 +#: convert.c:306 #, c-format msgid "" "The file '%s' is missing a byte order mark (BOM). Please use UTF-%sBE or UTF-" @@ -2004,37 +2078,37 @@ msgstr "" "Táºp tin “%s†còn thiếu ký hiệu thứ tá»± byte (BOM). Vui lòng dùng UTF-%sBE hay " "UTF-%sLE (còn phục thuá»™c và o thứ tá»± byte) nhÆ° là bảng mã cây là m việc." -#: convert.c:425 convert.c:496 +#: convert.c:424 convert.c:495 #, c-format msgid "failed to encode '%s' from %s to %s" msgstr "gặp lá»—i khi mã hóa “%s†từ “%s†sang “%sâ€" -#: convert.c:468 +#: convert.c:467 #, c-format msgid "encoding '%s' from %s to %s and back is not the same" msgstr "mã hóa “%s†từ %s thà nh %s và ngược trở lại không phải là cùng" -#: convert.c:674 +#: convert.c:673 #, c-format msgid "cannot fork to run external filter '%s'" msgstr "không thể rẽ nhánh tiến trình để chạy bá»™ lá»c bên ngoà i “%sâ€" -#: convert.c:694 +#: convert.c:693 #, c-format msgid "cannot feed the input to external filter '%s'" msgstr "không thể cấp đầu và o cho bá»™ lá»c bên ngoà i “%sâ€" -#: convert.c:701 +#: convert.c:700 #, c-format msgid "external filter '%s' failed %d" msgstr "chạy bá»™ lá»c bên ngoà i “%s†gặp lá»—i %d" -#: convert.c:736 convert.c:739 +#: convert.c:735 convert.c:738 #, c-format msgid "read from external filter '%s' failed" msgstr "Ä‘á»c từ bá»™ lá»c bên ngoà i “%s†gặp lá»—i" -#: convert.c:742 convert.c:796 +#: convert.c:741 convert.c:796 #, c-format msgid "external filter '%s' failed" msgstr "gặp lá»—i khi chạy bá»™ lá»c bên ngoà i “%sâ€" @@ -2058,7 +2132,7 @@ msgstr "" #: convert.c:1228 msgid "true/false are no valid working-tree-encodings" -msgstr "true/false là không phải bảng mã cây là m việc hợp lệ " +msgstr "true/false là không phải bảng-mã-cây-là m-việc hợp lệ" #: convert.c:1398 convert.c:1432 #, c-format @@ -2070,86 +2144,86 @@ msgstr "%s: gặp lá»—i khi xóa bá»™ lá»c “%sâ€" msgid "%s: smudge filter %s failed" msgstr "%s: smudge bá»™ lá»c %s gặp lá»—i" -#: date.c:116 +#: date.c:137 msgid "in the future" msgstr "ở thá»i tÆ°Æ¡ng lai" -#: date.c:122 +#: date.c:143 #, c-format msgid "%<PRIuMAX> second ago" msgid_plural "%<PRIuMAX> seconds ago" msgstr[0] "%<PRIuMAX> giây trÆ°á»›c" -#: date.c:129 +#: date.c:150 #, c-format msgid "%<PRIuMAX> minute ago" msgid_plural "%<PRIuMAX> minutes ago" msgstr[0] "%<PRIuMAX> phút trÆ°á»›c" -#: date.c:136 +#: date.c:157 #, c-format msgid "%<PRIuMAX> hour ago" msgid_plural "%<PRIuMAX> hours ago" msgstr[0] "%<PRIuMAX> giá» trÆ°á»›c" -#: date.c:143 +#: date.c:164 #, c-format msgid "%<PRIuMAX> day ago" msgid_plural "%<PRIuMAX> days ago" msgstr[0] "%<PRIuMAX> ngà y trÆ°á»›c" -#: date.c:149 +#: date.c:170 #, c-format msgid "%<PRIuMAX> week ago" msgid_plural "%<PRIuMAX> weeks ago" msgstr[0] "%<PRIuMAX> tuần trÆ°á»›c" -#: date.c:156 +#: date.c:177 #, c-format msgid "%<PRIuMAX> month ago" msgid_plural "%<PRIuMAX> months ago" msgstr[0] "%<PRIuMAX> tháng trÆ°á»›c" -#: date.c:167 +#: date.c:188 #, c-format msgid "%<PRIuMAX> year" msgid_plural "%<PRIuMAX> years" msgstr[0] "%<PRIuMAX> năm" #. TRANSLATORS: "%s" is "<n> years" -#: date.c:170 +#: date.c:191 #, c-format msgid "%s, %<PRIuMAX> month ago" msgid_plural "%s, %<PRIuMAX> months ago" msgstr[0] "%s, %<PRIuMAX> tháng trÆ°á»›c" -#: date.c:175 date.c:180 +#: date.c:196 date.c:201 #, c-format msgid "%<PRIuMAX> year ago" msgid_plural "%<PRIuMAX> years ago" msgstr[0] "%<PRIuMAX> năm trÆ°á»›c" -#: delta-islands.c:268 +#: delta-islands.c:272 msgid "Propagating island marks" msgstr "Äang lan truyá»n các đánh dấu island" -#: delta-islands.c:286 +#: delta-islands.c:290 #, c-format msgid "bad tree object %s" msgstr "đối tượng cây sai “%sâ€" -#: delta-islands.c:330 +#: delta-islands.c:334 #, c-format msgid "failed to load island regex for '%s': %s" msgstr "gặp lá»—i khi tải biểu thức chÃnh quy island cho “%sâ€: %s" -#: delta-islands.c:386 +#: delta-islands.c:390 #, c-format msgid "island regex from config has too many capture groups (max=%d)" msgstr "" "biểu thức chÃnh quy island từ cấu hình có quá nhiá»u nhóm chụp (tối Ä‘a=%d)" -#: delta-islands.c:462 +#: delta-islands.c:466 #, c-format msgid "Marked %d islands, done.\n" msgstr "Äã đánh dấu %d island, xong.\n" @@ -2186,25 +2260,30 @@ msgstr "" "cà i đặt mà u đã di chuyển phải là má»™t trong “noâ€, “defaultâ€, “blocksâ€, " "“zebraâ€, “dimmed_zebraâ€, “plainâ€" -#: diff.c:316 +#: diff.c:319 #, c-format -msgid "ignoring unknown color-moved-ws mode '%s'" -msgstr "bá» qua chế Ä‘á»™ color-moved-ws chÆ°a biết “%sâ€" +msgid "" +"unknown color-moved-ws mode '%s', possible values are 'ignore-space-change', " +"'ignore-space-at-eol', 'ignore-all-space', 'allow-indentation-change'" +msgstr "" +"không hiểu chế Ä‘á»™ color-moved-ws “%sâ€, các giá trị có thể là “ignore-space-" +"changeâ€, “ignore-space-at-eolâ€, “ignore-all-spaceâ€, “allow-indentation-" +"changeâ€" -#: diff.c:323 +#: diff.c:327 msgid "" -"color-moved-ws: allow-indentation-change cannot be combined with other white " -"space modes" +"color-moved-ws: allow-indentation-change cannot be combined with other " +"whitespace modes" msgstr "" "color-moved-ws: allow-indentation-change không thể tổ hợp cùng vá»›i các chế " "Ä‘á»™ khoảng trắng khác" -#: diff.c:394 +#: diff.c:400 #, c-format msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "Không hiểu giá trị cho biến cấu hình “diff.submoduleâ€: “%sâ€" -#: diff.c:454 +#: diff.c:460 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -2213,24 +2292,24 @@ msgstr "" "Tìm thấy các lá»—i trong biến cấu hình “diff.dirstatâ€:\n" "%s" -#: diff.c:4140 +#: diff.c:4211 #, c-format msgid "external diff died, stopping at %s" msgstr "phần má»m diff ở bên ngoà i đã chết, dừng tại %s" -#: diff.c:4482 +#: diff.c:4553 msgid "--name-only, --name-status, --check and -s are mutually exclusive" msgstr "--name-only, --name-status, --check và -s loại từ lẫn nhau" -#: diff.c:4485 +#: diff.c:4556 msgid "-G, -S and --find-object are mutually exclusive" msgstr "Các tùy chá»n -G, -S, và --find-object loại từ lẫn nhau" -#: diff.c:4563 +#: diff.c:4634 msgid "--follow requires exactly one pathspec" msgstr "--follow cần chÃnh xác má»™t đặc tả Ä‘Æ°á»ng dẫn" -#: diff.c:4729 +#: diff.c:4800 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -2239,22 +2318,22 @@ msgstr "" "Gặp lá»—i khi phân tÃch đối số tùy chá»n --dirstat/-X:\n" "%s" -#: diff.c:4743 +#: diff.c:4814 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Gặp lá»—i khi phân tÃch đối số tùy chá»n --submodule: “%sâ€" -#: diff.c:5823 +#: diff.c:5900 msgid "inexact rename detection was skipped due to too many files." msgstr "" "nháºn thấy đổi tên không chÃnh xác đã bị bá» qua bởi có quá nhiá»u táºp tin." -#: diff.c:5826 +#: diff.c:5903 msgid "only found copies from modified paths due to too many files." msgstr "" "chỉ tìm thấy các bản sao từ Ä‘Æ°á»ng dẫn đã sá»a đổi bởi vì có quá nhiá»u táºp tin." -#: diff.c:5829 +#: diff.c:5906 #, c-format msgid "" "you may want to set your %s variable to at least %d and retry the command." @@ -2262,40 +2341,40 @@ msgstr "" "bạn có lẽ muốn đặt biến %s của bạn thà nh Ãt nhất là %d và thá» lại lệnh lần " "nữa." -#: dir.c:576 +#: dir.c:538 #, c-format msgid "pathspec '%s' did not match any file(s) known to git" msgstr "đặc tả Ä‘Æ°á»ng dẫn “%s†không khá»›p vá»›i bất kỳ táºp tin nà o mà git biết" -#: dir.c:965 +#: dir.c:927 #, c-format msgid "cannot use %s as an exclude file" msgstr "không thể dùng %s nhÆ° là má»™t táºp tin loại trừ" -#: dir.c:1880 +#: dir.c:1842 #, c-format msgid "could not open directory '%s'" msgstr "không thể mở thÆ° mục “%sâ€" -#: dir.c:2122 +#: dir.c:2084 msgid "failed to get kernel name and information" msgstr "gặp lá»—i khi lấy tên và thông tin của nhân" -#: dir.c:2246 +#: dir.c:2208 msgid "untracked cache is disabled on this system or location" -msgstr "bá»™ nhá»› tạm không theo vết bị tắt trên hệ thống hay vị trà nà y." +msgstr "bá»™ nhá»› tạm không theo vết bị tắt trên hệ thống hay vị trà nà y" -#: dir.c:3047 +#: dir.c:3009 #, c-format msgid "index file corrupt in repo %s" msgstr "táºp tin ghi bảng mục lục bị há»ng trong kho %s" -#: dir.c:3092 dir.c:3097 +#: dir.c:3054 dir.c:3059 #, c-format msgid "could not create directories for %s" msgstr "không thể tạo thÆ° mục cho %s" -#: dir.c:3126 +#: dir.c:3088 #, c-format msgid "could not migrate git directory from '%s' to '%s'" msgstr "không thể di cÆ° thÆ° mục git từ “%s†sang “%sâ€" @@ -2337,235 +2416,239 @@ msgstr "Máy chủ không có địa chỉ URL" msgid "git fetch-pack: expected shallow list" msgstr "git fetch-pack: cần danh sách shallow" -#: fetch-pack.c:163 +#: fetch-pack.c:154 +msgid "git fetch-pack: expected a flush packet after shallow list" +msgstr "git fetch-pack: cần má»™t gói đẩy sau danh sách shallow" + +#: fetch-pack.c:165 msgid "git fetch-pack: expected ACK/NAK, got a flush packet" msgstr "git fetch-pack: cần ACK/NAK, nhÆ°ng lại nháºn được má»™t gói flush" -#: fetch-pack.c:183 +#: fetch-pack.c:185 #, c-format msgid "git fetch-pack: expected ACK/NAK, got '%s'" msgstr "git fetch-pack: cần ACK/NAK, nhÆ°ng lại nháºn được “%sâ€" -#: fetch-pack.c:253 +#: fetch-pack.c:256 msgid "--stateless-rpc requires multi_ack_detailed" msgstr "--stateless-rpc cần multi_ack_detailed" -#: fetch-pack.c:347 fetch-pack.c:1277 +#: fetch-pack.c:358 fetch-pack.c:1264 #, c-format msgid "invalid shallow line: %s" msgstr "dòng shallow không hợp lệ: %s" -#: fetch-pack.c:353 fetch-pack.c:1283 +#: fetch-pack.c:364 fetch-pack.c:1271 #, c-format msgid "invalid unshallow line: %s" msgstr "dòng unshallow không hợp lệ: %s" -#: fetch-pack.c:355 fetch-pack.c:1285 +#: fetch-pack.c:366 fetch-pack.c:1273 #, c-format msgid "object not found: %s" -msgstr "Không tìm thấy đối tượng: %s" +msgstr "không tìm thấy đối tượng: %s" -#: fetch-pack.c:358 fetch-pack.c:1288 +#: fetch-pack.c:369 fetch-pack.c:1276 #, c-format msgid "error in object: %s" msgstr "lá»—i trong đối tượng: %s" -#: fetch-pack.c:360 fetch-pack.c:1290 +#: fetch-pack.c:371 fetch-pack.c:1278 #, c-format msgid "no shallow found: %s" msgstr "không tìm shallow nà o: %s" -#: fetch-pack.c:363 fetch-pack.c:1293 +#: fetch-pack.c:374 fetch-pack.c:1282 #, c-format msgid "expected shallow/unshallow, got %s" msgstr "cần shallow/unshallow, nhÆ°ng lại nháºn được %s" -#: fetch-pack.c:404 +#: fetch-pack.c:415 #, c-format msgid "got %s %d %s" msgstr "nháºn %s %d - %s" -#: fetch-pack.c:421 +#: fetch-pack.c:432 #, c-format msgid "invalid commit %s" msgstr "lần chuyển giao %s không hợp lệ" -#: fetch-pack.c:452 +#: fetch-pack.c:463 msgid "giving up" msgstr "chịu thua" -#: fetch-pack.c:464 progress.c:229 +#: fetch-pack.c:475 progress.c:229 msgid "done" msgstr "xong" -#: fetch-pack.c:476 +#: fetch-pack.c:487 #, c-format msgid "got %s (%d) %s" msgstr "nháºn %s (%d) %s" -#: fetch-pack.c:522 +#: fetch-pack.c:533 #, c-format msgid "Marking %s as complete" msgstr "Äánh dấu %s là đã hoà n thà nh" -#: fetch-pack.c:764 +#: fetch-pack.c:740 #, c-format msgid "already have %s (%s)" msgstr "đã sẵn có %s (%s)" -#: fetch-pack.c:803 +#: fetch-pack.c:779 msgid "fetch-pack: unable to fork off sideband demultiplexer" msgstr "fetch-pack: không thể rẽ nhánh sideband demultiplexer" -#: fetch-pack.c:811 +#: fetch-pack.c:787 msgid "protocol error: bad pack header" msgstr "lá»—i giao thức: phần đầu gói bị sai" -#: fetch-pack.c:879 +#: fetch-pack.c:855 #, c-format msgid "fetch-pack: unable to fork off %s" msgstr "fetch-pack: không thể rẽ nhánh %s" -#: fetch-pack.c:895 +#: fetch-pack.c:871 #, c-format msgid "%s failed" msgstr "%s gặp lá»—i" -#: fetch-pack.c:897 +#: fetch-pack.c:873 msgid "error in sideband demultiplexer" msgstr "có lá»—i trong sideband demultiplexer" -#: fetch-pack.c:926 +#: fetch-pack.c:902 msgid "Server does not support shallow clients" msgstr "Máy chủ không há»— trợ máy khách shallow" -#: fetch-pack.c:930 +#: fetch-pack.c:906 msgid "Server supports multi_ack_detailed" msgstr "Máy chủ há»— trợ multi_ack_detailed" -#: fetch-pack.c:933 +#: fetch-pack.c:909 msgid "Server supports no-done" msgstr "Máy chủ há»— trợ no-done" -#: fetch-pack.c:939 +#: fetch-pack.c:915 msgid "Server supports multi_ack" msgstr "Máy chủ há»— trợ multi_ack" -#: fetch-pack.c:943 +#: fetch-pack.c:919 msgid "Server supports side-band-64k" msgstr "Máy chủ há»— trợ side-band-64k" -#: fetch-pack.c:947 +#: fetch-pack.c:923 msgid "Server supports side-band" msgstr "Máy chủ há»— trợ side-band" -#: fetch-pack.c:951 +#: fetch-pack.c:927 msgid "Server supports allow-tip-sha1-in-want" msgstr "Máy chủ há»— trợ allow-tip-sha1-in-want" -#: fetch-pack.c:955 +#: fetch-pack.c:931 msgid "Server supports allow-reachable-sha1-in-want" msgstr "Máy chủ há»— trợ allow-reachable-sha1-in-want" -#: fetch-pack.c:965 +#: fetch-pack.c:941 msgid "Server supports ofs-delta" msgstr "Máy chủ há»— trợ ofs-delta" -#: fetch-pack.c:971 fetch-pack.c:1158 +#: fetch-pack.c:947 fetch-pack.c:1140 msgid "Server supports filter" msgstr "Máy chủ há»— trợ bá»™ lá»c" -#: fetch-pack.c:979 +#: fetch-pack.c:955 #, c-format msgid "Server version is %.*s" msgstr "Phiên bản máy chủ là %.*s" -#: fetch-pack.c:985 +#: fetch-pack.c:961 msgid "Server does not support --shallow-since" msgstr "Máy chủ không há»— trợ --shallow-since" -#: fetch-pack.c:989 +#: fetch-pack.c:965 msgid "Server does not support --shallow-exclude" msgstr "Máy chủ không há»— trợ --shallow-exclude" -#: fetch-pack.c:991 +#: fetch-pack.c:967 msgid "Server does not support --deepen" msgstr "Máy chủ không há»— trợ --deepen" -#: fetch-pack.c:1008 +#: fetch-pack.c:984 msgid "no common commits" msgstr "không có lần chuyển giao chung nà o" -#: fetch-pack.c:1020 fetch-pack.c:1418 +#: fetch-pack.c:996 fetch-pack.c:1419 msgid "git fetch-pack: fetch failed." msgstr "git fetch-pack: fetch gặp lá»—i." -#: fetch-pack.c:1153 +#: fetch-pack.c:1134 msgid "Server does not support shallow requests" msgstr "Máy chủ không há»— trợ yêu cầu shallow" -#: fetch-pack.c:1199 +#: fetch-pack.c:1184 #, c-format msgid "error reading section header '%s'" msgstr "gặp lá»—i khi Ä‘á»c phần đầu của Ä‘oạn %s" -#: fetch-pack.c:1205 +#: fetch-pack.c:1190 #, c-format msgid "expected '%s', received '%s'" msgstr "cần “%sâ€, nhÆ°ng lại nháºn “%sâ€" -#: fetch-pack.c:1244 +#: fetch-pack.c:1229 #, c-format msgid "unexpected acknowledgment line: '%s'" msgstr "gặp dòng không được thừa nháºn: “%sâ€" -#: fetch-pack.c:1249 +#: fetch-pack.c:1234 #, c-format msgid "error processing acks: %d" msgstr "gặp lá»—i khi xá» lý tÃn hiệu trả lá»i: %d" -#: fetch-pack.c:1259 +#: fetch-pack.c:1244 msgid "expected packfile to be sent after 'ready'" msgstr "cần táºp tin gói để gá»i sau “readyâ€" -#: fetch-pack.c:1261 +#: fetch-pack.c:1246 msgid "expected no other sections to be sent after no 'ready'" msgstr "không cần thêm phần nà o để gá»i sau “readyâ€" -#: fetch-pack.c:1298 +#: fetch-pack.c:1287 #, c-format msgid "error processing shallow info: %d" msgstr "lá»—i xá» lý thông tin shallow: %d" -#: fetch-pack.c:1314 +#: fetch-pack.c:1308 #, c-format msgid "expected wanted-ref, got '%s'" msgstr "cần wanted-ref, nhÆ°ng lại nháºn được “%sâ€" -#: fetch-pack.c:1324 +#: fetch-pack.c:1318 #, c-format msgid "unexpected wanted-ref: '%s'" msgstr "không cần wanted-ref: “%sâ€" -#: fetch-pack.c:1328 +#: fetch-pack.c:1322 #, c-format msgid "error processing wanted refs: %d" msgstr "lá»—i khi xá» lý wanted refs: %d" -#: fetch-pack.c:1642 +#: fetch-pack.c:1646 msgid "no matching remote head" msgstr "không khá»›p phần đầu máy chủ" -#: fetch-pack.c:1660 builtin/clone.c:664 +#: fetch-pack.c:1664 builtin/clone.c:671 msgid "remote did not send all necessary objects" msgstr "máy chủ đã không gá»i tất cả các đối tượng cần thiết" -#: fetch-pack.c:1686 +#: fetch-pack.c:1690 #, c-format msgid "no such remote ref %s" -msgstr "Không có máy chủ tham chiếu nà o nhÆ° %s" +msgstr "không có máy chủ tham chiếu nà o nhÆ° %s" -#: fetch-pack.c:1689 +#: fetch-pack.c:1693 #, c-format msgid "Server does not allow request for unadvertised object %s" msgstr "" @@ -2594,8 +2677,8 @@ msgstr "bá» qua mà u không hợp lệ “%.*s†trong log.graphColors" msgid "'%s': unable to read %s" msgstr "“%sâ€: không thể Ä‘á»c %s" -#: grep.c:2130 setup.c:164 builtin/clone.c:410 builtin/diff.c:81 -#: builtin/rm.c:134 +#: grep.c:2130 setup.c:164 builtin/clone.c:411 builtin/diff.c:82 +#: builtin/rm.c:135 #, c-format msgid "failed to stat '%s'" msgstr "gặp lá»—i khi lấy thống kê vỠ“%sâ€" @@ -2657,41 +2740,41 @@ msgstr "Lệnh/Äồng bá»™ kho ở mức thấp" msgid "Low-level Commands / Internal Helpers" msgstr "Lệnh/Há»— trợ ná»™i tại ở mức thấp" -#: help.c:296 +#: help.c:298 #, c-format msgid "available git commands in '%s'" msgstr "các lệnh git sẵn có trong thÆ° mục “%sâ€:" -#: help.c:303 +#: help.c:305 msgid "git commands available from elsewhere on your $PATH" msgstr "các lệnh git sẵn có từ má»™t nÆ¡i khác trong $PATH của bạn" -#: help.c:312 +#: help.c:314 msgid "These are common Git commands used in various situations:" msgstr "Có các lệnh Git chung được sá» dụng trong các tình huống khác nhau:" -#: help.c:361 git.c:90 +#: help.c:363 git.c:90 #, c-format msgid "unsupported command listing type '%s'" msgstr "không há»— trợ liệt kê lệnh kiểu “%sâ€" -#: help.c:408 +#: help.c:410 msgid "The common Git guides are:" msgstr "Các chỉ dẫn chung vá» Git là :" -#: help.c:517 +#: help.c:519 msgid "See 'git help <command>' to read about a specific subcommand" msgstr "Xem “git help <lệnh>†để Ä‘á»c các đặc tả của lệnh con" -#: help.c:522 +#: help.c:524 msgid "External commands" msgstr "Các lệnh bên ngoà i" -#: help.c:530 +#: help.c:539 msgid "Command aliases" msgstr "Các bà danh lệnh" -#: help.c:594 +#: help.c:603 #, c-format msgid "" "'%s' appears to be a git command, but we were not\n" @@ -2700,31 +2783,31 @@ msgstr "" "“%s†trông nhÆ° là má»™t lệnh git, nhÆ°ng chúng tôi không\n" "thể thá»±c thi nó. Có lẽ là lệnh git-%s đã bị há»ng?" -#: help.c:653 +#: help.c:662 msgid "Uh oh. Your system reports no Git commands at all." msgstr "á»i chà . Hệ thống của bạn báo rằng chẳng có lệnh Git nà o cả." -#: help.c:675 +#: help.c:684 #, c-format msgid "WARNING: You called a Git command named '%s', which does not exist." msgstr "CẢNH BÃO: Bạn đã gá»i lệnh Git có tên “%sâ€, mà nó lại không có sẵn." -#: help.c:680 +#: help.c:689 #, c-format msgid "Continuing under the assumption that you meant '%s'." msgstr "Tiếp tục và coi rằng ý bạn là “%sâ€." -#: help.c:685 +#: help.c:694 #, c-format msgid "Continuing in %0.1f seconds, assuming that you meant '%s'." msgstr "Tiếp tục trong %0.1f giây,và coi rằng ý bạn là “%sâ€." -#: help.c:693 +#: help.c:702 #, c-format msgid "git: '%s' is not a git command. See 'git --help'." msgstr "git: “%s†không phải là má»™t lệnh của git. Xem “git --helpâ€." -#: help.c:697 +#: help.c:706 msgid "" "\n" "The most similar command is" @@ -2735,16 +2818,16 @@ msgstr[0] "" "\n" "Những lệnh giống nhất là " -#: help.c:712 +#: help.c:721 msgid "git version [<options>]" msgstr "git version [<các-tùy-chá»n>]" -#: help.c:780 +#: help.c:789 #, c-format msgid "%s: %s - %s" msgstr "%s: %s - %s" -#: help.c:784 +#: help.c:793 msgid "" "\n" "Did you mean this?" @@ -2809,20 +2892,20 @@ 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" -#: ident.c:419 builtin/commit.c:606 +#: ident.c:419 builtin/commit.c:608 #, c-format msgid "invalid date format: %s" msgstr "ngà y tháng không hợp lệ: %s" -#: list-objects-filter-options.c:35 +#: list-objects-filter-options.c:36 msgid "multiple filter-specs cannot be combined" msgstr "không thể tổ hợp nhiá»u đặc tả kiểu lá»c" #: list-objects-filter-options.c:58 -msgid "only 'tree:0' is supported" -msgstr "chỉ “tree:0†là được há»— trợ" +msgid "expected 'tree:<depth>'" +msgstr "cần “tree:<depth>â€" -#: list-objects-filter-options.c:137 +#: list-objects-filter-options.c:152 msgid "cannot change partial clone promisor remote" msgstr "không thể thay đổi nhân bản từng phần máy chủ promisor" @@ -2854,98 +2937,98 @@ msgstr "Không thể tạo “%s.lockâ€: %s" msgid "failed to read the cache" msgstr "gặp lá»—i khi Ä‘á»c bá»™ nhá»› đệm" -#: merge.c:107 rerere.c:720 builtin/am.c:1899 builtin/am.c:1933 -#: builtin/checkout.c:387 builtin/checkout.c:708 builtin/clone.c:764 +#: merge.c:107 rerere.c:720 builtin/am.c:1884 builtin/am.c:1918 +#: builtin/checkout.c:416 builtin/checkout.c:745 builtin/clone.c:771 msgid "unable to write new index file" msgstr "không thể ghi táºp tin lÆ°u bảng mục lục má»›i" -#: merge-recursive.c:323 +#: merge-recursive.c:332 msgid "(bad commit)\n" msgstr "(commit sai)\n" -#: merge-recursive.c:345 +#: merge-recursive.c:355 #, c-format msgid "add_cacheinfo failed for path '%s'; merge aborting." msgstr "addinfo_cache gặp lá»—i đối vá»›i Ä‘Æ°á»ng dẫn “%sâ€; việc hòa trá»™n bị bãi bá»." -#: merge-recursive.c:353 +#: merge-recursive.c:364 #, c-format msgid "add_cacheinfo failed to refresh for path '%s'; merge aborting." msgstr "" "addinfo_cache gặp lá»—i khi là m má»›i đối vá»›i Ä‘Æ°á»ng dẫn “%sâ€; việc hòa trá»™n bị " "bãi bá»." -#: merge-recursive.c:435 +#: merge-recursive.c:447 msgid "error building trees" msgstr "gặp lá»—i khi xây dá»±ng cây" -#: merge-recursive.c:906 +#: merge-recursive.c:902 #, c-format msgid "failed to create path '%s'%s" msgstr "gặp lá»—i khi tạo Ä‘Æ°á»ng dẫn “%sâ€%s" -#: merge-recursive.c:917 +#: merge-recursive.c:913 #, 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" -#: merge-recursive.c:931 merge-recursive.c:950 +#: merge-recursive.c:927 merge-recursive.c:946 msgid ": perhaps a D/F conflict?" msgstr ": có lẽ là má»™t xung Ä‘á»™t D/F?" -#: merge-recursive.c:940 +#: merge-recursive.c:936 #, 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â€" -#: merge-recursive.c:982 builtin/cat-file.c:39 +#: merge-recursive.c:978 builtin/cat-file.c:40 #, c-format msgid "cannot read object %s '%s'" msgstr "không thể Ä‘á»c đối tượng %s “%sâ€" -#: merge-recursive.c:984 +#: merge-recursive.c:980 #, c-format msgid "blob expected for %s '%s'" msgstr "mong đợi đối tượng blob cho %s “%sâ€" -#: merge-recursive.c:1008 +#: merge-recursive.c:1004 #, c-format msgid "failed to open '%s': %s" msgstr "gặp lá»—i khi mở “%sâ€: %s" -#: merge-recursive.c:1019 +#: merge-recursive.c:1015 #, 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" -#: merge-recursive.c:1024 +#: merge-recursive.c:1020 #, 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â€" -#: merge-recursive.c:1212 +#: merge-recursive.c:1211 #, 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 lấy ra được)" -#: merge-recursive.c:1219 +#: merge-recursive.c:1218 #, c-format msgid "Failed to merge submodule %s (commits not present)" msgstr "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con “%s†(lần chuyển giao không hiện diện)" -#: merge-recursive.c:1226 +#: merge-recursive.c:1225 #, c-format msgid "Failed to merge submodule %s (commits don't follow merge-base)" msgstr "" "Gặp lá»—i khi hòa trá»™n mô-Ä‘un-con “%s†(lần chuyển giao không theo sau ná»n-hòa-" "trá»™n)" -#: merge-recursive.c:1234 merge-recursive.c:1246 +#: merge-recursive.c:1233 merge-recursive.c:1245 #, 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:" -#: merge-recursive.c:1237 merge-recursive.c:1249 +#: merge-recursive.c:1236 merge-recursive.c:1248 #, c-format msgid "Fast-forwarding submodule %s" msgstr "Chuyển-tiếp-nhanh mô-Ä‘un-con “%sâ€" @@ -2988,28 +3071,28 @@ msgstr "" 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)" -#: merge-recursive.c:1358 +#: merge-recursive.c:1361 msgid "Failed to execute internal merge" msgstr "Gặp lá»—i khi thá»±c hiện trá»™n ná»™i bá»™" -#: merge-recursive.c:1363 +#: merge-recursive.c:1366 #, c-format msgid "Unable to add %s to database" msgstr "Không thể thêm %s và o cÆ¡ sở dữ liệu" -#: merge-recursive.c:1395 +#: merge-recursive.c:1398 #, c-format msgid "Auto-merging %s" msgstr "Tá»±-Ä‘á»™ng-hòa-trá»™n %s" -#: merge-recursive.c:1416 +#: merge-recursive.c:1419 #, 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." -#: merge-recursive.c:1483 +#: merge-recursive.c:1486 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -3018,7 +3101,7 @@ 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)." -#: merge-recursive.c:1488 +#: merge-recursive.c:1491 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -3027,7 +3110,7 @@ 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)." -#: merge-recursive.c:1495 +#: merge-recursive.c:1498 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s in %s. Version %s of %s left " @@ -3036,7 +3119,7 @@ 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." -#: merge-recursive.c:1500 +#: merge-recursive.c:1503 #, c-format msgid "" "CONFLICT (%s/delete): %s deleted in %s and %s to %s in %s. Version %s of %s " @@ -3045,33 +3128,45 @@ 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." -#: merge-recursive.c:1534 +#: merge-recursive.c:1537 msgid "rename" msgstr "đổi tên" -#: merge-recursive.c:1534 +#: merge-recursive.c:1537 msgid "renamed" msgstr "đã đổi tên" -#: merge-recursive.c:1588 merge-recursive.c:1737 merge-recursive.c:2369 -#: merge-recursive.c:3124 +#: merge-recursive.c:1633 merge-recursive.c:2481 merge-recursive.c:3213 #, 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â€" -#: merge-recursive.c:1602 +#: merge-recursive.c:1643 +#, 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." + +#: merge-recursive.c:1706 +#, 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" + +#: merge-recursive.c:1734 #, 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" -#: merge-recursive.c:1607 +#: merge-recursive.c:1739 #, 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" -#: merge-recursive.c:1633 +#: merge-recursive.c:1759 #, c-format msgid "" "CONFLICT (rename/rename): Rename \"%s\"->\"%s\" in branch \"%s\" rename \"%s" @@ -3080,29 +3175,17 @@ 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" -#: merge-recursive.c:1638 +#: merge-recursive.c:1764 msgid " (left unresolved)" msgstr " (cần giải quyết)" -#: merge-recursive.c:1699 +#: merge-recursive.c:1868 #, 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" -#: merge-recursive.c:1734 -#, c-format -msgid "Renaming %s to %s and %s to %s instead" -msgstr "Äang đổi tên %s thà nh %s thay vì %s thà nh %s" - -#: merge-recursive.c:1746 -#, 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." - -#: merge-recursive.c:1952 +#: merge-recursive.c:2064 #, c-format msgid "" "CONFLICT (directory rename split): Unclear where to place %s because " @@ -3113,7 +3196,7 @@ msgstr "" "vì thÆ° mục %s đã bị đổi tên thà nh nhiá»u thÆ° mục khác, vá»›i không Ä‘Ãch đến " "nháºn má»™t phần nhiá»u của các táºp tin." -#: merge-recursive.c:1984 +#: merge-recursive.c:2096 #, c-format msgid "" "CONFLICT (implicit dir rename): Existing file/dir at %s in the way of " @@ -3122,16 +3205,16 @@ msgstr "" "XUNG ÄỘT: (ngầm đổi tên thÆ° mục): Táºp tin/thÆ° mục đã sẵn có tại %s theo cách " "của các đổi tên thÆ° mục ngầm đặt (các) Ä‘Æ°á»ng dẫn sau ở đây: %s." -#: merge-recursive.c:1994 +#: merge-recursive.c:2106 #, c-format msgid "" "CONFLICT (implicit dir rename): Cannot map more than one path to %s; " "implicit directory renames tried to put these paths there: %s" msgstr "" "XUNG ÄỘT: (ngầm đổi tên thÆ° mục): Không thể ánh xạ má»™t Ä‘Æ°á»ng dẫn thà nh %s; " -"các đổi tên thÆ° mục ngầm cố đặt các Ä‘Æ°á»ng dẫn ở đây: %s." +"các đổi tên thÆ° mục ngầm cố đặt các Ä‘Æ°á»ng dẫn ở đây: %s" -#: merge-recursive.c:2086 +#: merge-recursive.c:2198 #, c-format msgid "" "CONFLICT (rename/rename): Rename directory %s->%s in %s. Rename directory %s-" @@ -3140,7 +3223,7 @@ 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" -#: merge-recursive.c:2331 +#: merge-recursive.c:2443 #, c-format msgid "" "WARNING: Avoiding applying %s -> %s rename to %s, because %s itself was " @@ -3149,88 +3232,82 @@ msgstr "" "CẢNH BÃO: tránh áp dụng %s -> %s đổi thên thà nh %s, bởi vì bản thân %s cÅ©ng " "bị đổi tên." -#: merge-recursive.c:2737 -#, c-format -msgid "CONFLICT (rename/add): Rename %s->%s in %s. %s added in %s" -msgstr "" -"XUNG ÄỘT (đổi-tên/thêm): Äổi tên %s->%s trong %s. %s được thêm và o trong %s" - -#: merge-recursive.c:2763 -#, c-format -msgid "Adding merged %s" -msgstr "Thêm hòa trá»™n %s" - -#: merge-recursive.c:2770 merge-recursive.c:3127 -#, c-format -msgid "Adding as %s instead" -msgstr "Thay và o đó thêm và o %s" - -#: merge-recursive.c:2934 +#: merge-recursive.c:3022 #, c-format msgid "cannot read object %s" msgstr "không thể Ä‘á»c đối tượng %s" -#: merge-recursive.c:2937 +#: merge-recursive.c:3025 #, c-format msgid "object %s is not a blob" msgstr "đối tượng %s không phải là má»™t blob" -#: merge-recursive.c:3006 +#: merge-recursive.c:3094 msgid "modify" msgstr "sá»a đổi" -#: merge-recursive.c:3006 +#: merge-recursive.c:3094 msgid "modified" msgstr "đã sá»a" -#: merge-recursive.c:3017 +#: merge-recursive.c:3105 msgid "content" msgstr "ná»™i dung" -#: merge-recursive.c:3024 +#: merge-recursive.c:3112 msgid "add/add" msgstr "thêm/thêm" -#: merge-recursive.c:3071 +#: merge-recursive.c:3160 #, c-format msgid "Skipped %s (merged same as existing)" msgstr "Äã bá» qua %s (đã có sẵn lần hòa trá»™n nà y)" -#: merge-recursive.c:3093 git-submodule.sh:858 +#: merge-recursive.c:3182 git-submodule.sh:861 msgid "submodule" msgstr "mô-Ä‘un-con" -#: merge-recursive.c:3094 +#: merge-recursive.c:3183 #, c-format msgid "CONFLICT (%s): Merge conflict in %s" msgstr "XUNG ÄỘT (%s): Xung Ä‘á»™t hòa trá»™n trong %s" #: merge-recursive.c:3216 #, c-format +msgid "Adding as %s instead" +msgstr "Thay và o đó thêm và o %s" + +#: merge-recursive.c:3319 +#, c-format msgid "Removing %s" msgstr "Äang xóa %s" -#: merge-recursive.c:3242 +#: merge-recursive.c:3345 msgid "file/directory" msgstr "táºp-tin/thÆ°-mục" -#: merge-recursive.c:3248 +#: merge-recursive.c:3351 msgid "directory/file" msgstr "thÆ°-mục/táºp-tin" -#: merge-recursive.c:3255 +#: merge-recursive.c:3358 #, 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" -#: merge-recursive.c:3264 +#: merge-recursive.c:3367 #, c-format msgid "Adding %s" msgstr "Thêm \"%s\"" -#: merge-recursive.c:3300 +#: merge-recursive.c:3376 +#, 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" + +#: merge-recursive.c:3417 #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -3240,37 +3317,37 @@ msgstr "" "hòa trá»™n:\n" " %s" -#: merge-recursive.c:3311 +#: merge-recursive.c:3428 msgid "Already up to date!" msgstr "Äã cáºp nháºt rồi!" -#: merge-recursive.c:3320 +#: merge-recursive.c:3437 #, 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" -#: merge-recursive.c:3419 +#: merge-recursive.c:3536 msgid "Merging:" msgstr "Äang trá»™n:" -#: merge-recursive.c:3432 +#: merge-recursive.c:3549 #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "tìm thấy %u tổ tiên chung:" -#: merge-recursive.c:3471 +#: merge-recursive.c:3588 msgid "merge returned no commit" msgstr "hòa trá»™n không trả vá» lần chuyển giao nà o" -#: merge-recursive.c:3537 +#: merge-recursive.c:3654 #, c-format msgid "Could not parse object '%s'" msgstr "Không thể phân tÃch đối tượng “%sâ€" -#: merge-recursive.c:3553 builtin/merge.c:691 builtin/merge.c:849 +#: merge-recursive.c:3670 builtin/merge.c:692 builtin/merge.c:850 msgid "Unable to write index." -msgstr "Không thể ghi bảng mục lục" +msgstr "Không thể ghi bảng mục lục." #: midx.c:65 #, c-format @@ -3385,22 +3462,22 @@ msgid "incorrect object offset for oid[%d] = %s: %<PRIx64> != %<PRIx64>" msgstr "" "khoảng bù đối tượng không đúng cho oid[%d] = %s: %<PRIx64> != %<PRIx64>" -#: name-hash.c:532 +#: name-hash.c:531 #, c-format msgid "unable to create lazy_dir thread: %s" msgstr "không thể tạo tuyến lazy_dir: %s" -#: name-hash.c:554 +#: name-hash.c:553 #, c-format msgid "unable to create lazy_name thread: %s" msgstr "không thể tạo tuyến lazy_name: %s" -#: name-hash.c:560 +#: name-hash.c:559 #, c-format msgid "unable to join lazy_name thread: %s" msgstr "không thể gia nháºp tuyến lazy_name: %s" -#: notes-merge.c:275 +#: notes-merge.c:277 #, c-format msgid "" "You have not concluded your previous notes merge (%s exists).\n" @@ -3412,23 +3489,23 @@ msgstr "" "chuyển giao hay bãi bá» lần hòa trá»™n trÆ°á»›c đây và bắt đầu má»™t hòa trá»™n ghi " "chú má»›i." -#: notes-merge.c:282 +#: notes-merge.c:284 #, c-format msgid "You have not concluded your notes merge (%s exists)." msgstr "Bạn chÆ°a kết thúc việc hòa trá»™n ghi chú (%s vẫn tồn tại)." -#: notes-utils.c:45 +#: notes-utils.c:46 msgid "Cannot commit uninitialized/unreferenced notes tree" msgstr "" "Không thể chuyển giao cây ghi chú chÆ°a được khởi tạo hoặc không được tham " "chiếu" -#: notes-utils.c:104 +#: notes-utils.c:105 #, c-format msgid "Bad notes.rewriteMode value: '%s'" msgstr "Giá trị notes.rewriteMode sai: “%sâ€" -#: notes-utils.c:114 +#: notes-utils.c:115 #, c-format msgid "Refusing to rewrite notes in %s (outside of refs/notes/)" msgstr "Từ chối ghi đè ghi chú trong %s (nằm ngoà i refs/notes/)" @@ -3437,7 +3514,7 @@ msgstr "Từ chối ghi đè ghi chú trong %s (nằm ngoà i refs/notes/)" #. the environment variable, the second %s is #. its value. #. -#: notes-utils.c:144 +#: notes-utils.c:145 #, c-format msgid "Bad %s value: '%s'" msgstr "Giá trị %s sai: “%sâ€" @@ -3447,46 +3524,106 @@ msgstr "Giá trị %s sai: “%sâ€" msgid "invalid object type \"%s\"" msgstr "kiểu đối tượng \"%s\" không hợp lệ" -#: object.c:173 +#: object.c:174 #, c-format msgid "object %s is a %s, not a %s" msgstr "đối tượng %s là má»™t %s, không phải là má»™t %s" -#: object.c:233 +#: object.c:234 #, c-format msgid "object %s has unknown type id %d" msgstr "đối tượng %s có mã kiểu %d chÆ°a biết" -#: object.c:246 +#: object.c:247 #, c-format msgid "unable to parse object: %s" msgstr "không thể phân tÃch đối tượng: “%sâ€" -#: object.c:266 object.c:277 +#: object.c:267 object.c:278 #, c-format -msgid "sha1 mismatch %s" -msgstr "sha1 không khá»›p %s" +msgid "hash mismatch %s" +msgstr "mã băm không khá»›p %s" #: packfile.c:607 msgid "offset before end of packfile (broken .idx?)" msgstr "vị trà tÆ°Æ¡ng đối trÆ°á»›c Ä‘iểm kết thúc của táºp tin gói (.idx há»ng à ?)" -#: packfile.c:1864 +#: packfile.c:1870 #, c-format msgid "offset before start of pack index for %s (corrupt index?)" msgstr "vị trà tÆ°Æ¡ng đối nằm trÆ°á»›c chỉ mục gói cho %s (mục lục bị há»ng à ?)" -#: packfile.c:1868 +#: packfile.c:1874 #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" msgstr "" "vị trà tÆ°Æ¡ng đối vượt quá cuối của chỉ mục gói cho %s (mục lục bị cắt cụt à ?)" -#: parse-options.c:672 +#: parse-options.c:35 +#, c-format +msgid "%s requires a value" +msgstr "“%s†yêu cầu má»™t giá trị" + +#: parse-options.c:69 +#, c-format +msgid "%s is incompatible with %s" +msgstr "%s là xung khắc vá»›i %s" + +#: parse-options.c:74 +#, c-format +msgid "%s : incompatible with something else" +msgstr "%s : xung khắc vá»›i các cái khác" + +#: parse-options.c:88 parse-options.c:92 parse-options.c:260 +#, c-format +msgid "%s takes no value" +msgstr "%s k nháºn giá trị" + +#: parse-options.c:90 +#, c-format +msgid "%s isn't available" +msgstr "%s không sẵn có" + +#: parse-options.c:178 +#, c-format +msgid "%s expects a numerical value" +msgstr "tùy chá»n “%s†cần má»™t giá trị bằng số" + +#: parse-options.c:194 +#, 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" + +#: parse-options.c:322 +#, c-format +msgid "ambiguous option: %s (could be --%s%s or --%s%s)" +msgstr "tùy chá»n chÆ°a rõ rang: %s (nên là --%s%s hay --%s%s)" + +#: parse-options.c:356 parse-options.c:364 +#, c-format +msgid "did you mean `--%s` (with two dashes ?)" +msgstr "có phải ý bạn là “--%s“ (vá»›i hai dấu gạch ngang?)" + +#: parse-options.c:649 +#, c-format +msgid "unknown option `%s'" +msgstr "không hiểu tùy chá»n “%sâ€" + +#: parse-options.c:651 +#, c-format +msgid "unknown switch `%c'" +msgstr "không hiểu tùy chá»n “%câ€" + +#: parse-options.c:653 +#, c-format +msgid "unknown non-ascii option in string: `%s'" +msgstr "không hiểu tùy chá»n non-ascii trong chuá»—i: “%sâ€" + +#: parse-options.c:675 msgid "..." msgstr "…" -#: parse-options.c:691 +#: parse-options.c:694 #, c-format msgid "usage: %s" msgstr "cách dùng: %s" @@ -3494,26 +3631,36 @@ msgstr "cách dùng: %s" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation. #. -#: parse-options.c:697 +#: parse-options.c:700 #, c-format msgid " or: %s" msgstr " hoặc: %s" -#: parse-options.c:700 +#: parse-options.c:703 #, c-format msgid " %s" msgstr " %s" -#: parse-options.c:739 +#: parse-options.c:742 msgid "-NUM" msgstr "-Sá»" -#: parse-options-cb.c:37 +#: parse-options-cb.c:21 +#, c-format +msgid "option `%s' expects a numerical value" +msgstr "tùy chá»n “%s†cần má»™t giá trị bằng số" + +#: parse-options-cb.c:38 #, c-format msgid "malformed expiration date '%s'" msgstr "ngà y tháng hết hạn dị hình “%sâ€" -#: parse-options-cb.c:109 +#: parse-options-cb.c:51 +#, c-format +msgid "option `%s' expects \"always\", \"auto\", or \"never\"" +msgstr "tùy chá»n “%s†cần \"always\", \"auto\", hoặc \"never\"" + +#: parse-options-cb.c:110 #, c-format msgid "malformed object name '%s'" msgstr "tên đối tượng dị hình “%sâ€" @@ -3523,30 +3670,30 @@ msgstr "tên đối tượng dị hình “%sâ€" msgid "Could not make %s writable by group" msgstr "Không thể là m %s được ghi bởi nhóm" -#: pathspec.c:129 +#: pathspec.c:128 msgid "Escape character '\\' not allowed as last character in attr value" msgstr "" "Ký tá»± thoát chuá»—i “\\†không được phép là ký tá»± cuối trong giá trị thuá»™c tÃnh" -#: pathspec.c:147 +#: pathspec.c:146 msgid "Only one 'attr:' specification is allowed." -msgstr "chỉ có má»™t đặc tả “attr:†là được phép." +msgstr "Chỉ có má»™t đặc tả “attr:†là được phép." -#: pathspec.c:150 +#: pathspec.c:149 msgid "attr spec must not be empty" msgstr "đặc tả attr phải không được để trống" -#: pathspec.c:193 +#: pathspec.c:192 #, c-format msgid "invalid attribute name %s" msgstr "tên thuá»™c tÃnh không hợp lệ %s" -#: pathspec.c:258 +#: pathspec.c:257 msgid "global 'glob' and 'noglob' pathspec settings are incompatible" msgstr "" "các cà i đặt đặc tả Ä‘Æ°á»ng dẫn “glob†và “noglob†toà n cục là xung khắc nhau" -#: pathspec.c:265 +#: pathspec.c:264 msgid "" "global 'literal' pathspec setting is incompatible with all other global " "pathspec settings" @@ -3554,46 +3701,46 @@ msgstr "" "cà i đặt đặc tả Ä‘Æ°á»ng dẫn “literal†toà n cục là xung khắc vá»›i các cà i đặt đặc " "tả Ä‘Æ°á»ng dẫn toà n cục khác" -#: pathspec.c:305 +#: pathspec.c:304 msgid "invalid parameter for pathspec magic 'prefix'" msgstr "tham số không hợp lệ cho “tiá»n tố†mà u nhiệm đặc tả Ä‘Æ°á»ng đẫn" -#: pathspec.c:326 +#: pathspec.c:325 #, c-format msgid "Invalid pathspec magic '%.*s' in '%s'" msgstr "Số mà u nhiệm đặc tả Ä‘Æ°á»ng dẫn không hợp lệ “%.*s†trong “%sâ€" -#: pathspec.c:331 +#: pathspec.c:330 #, c-format msgid "Missing ')' at the end of pathspec magic in '%s'" msgstr "Thiếu “)†tại cuối của số mà u nhiệm đặc tả Ä‘Æ°á»ng dẫn trong “%sâ€" -#: pathspec.c:369 +#: pathspec.c:368 #, c-format msgid "Unimplemented pathspec magic '%c' in '%s'" msgstr "ChÆ°a viết mã cho số mà u nhiệm đặc tả Ä‘Æ°á»ng dẫn “%c†trong “%sâ€" -#: pathspec.c:428 +#: pathspec.c:427 #, c-format msgid "%s: 'literal' and 'glob' are incompatible" msgstr "%s: “literal†và “glob†xung khắc nhau" -#: pathspec.c:441 +#: pathspec.c:440 #, c-format msgid "%s: '%s' is outside repository" msgstr "%s: “%s†ngoà i má»™t kho chứa" -#: pathspec.c:515 +#: pathspec.c:514 #, c-format msgid "'%s' (mnemonic: '%c')" msgstr "“%s†(mnemonic: “%câ€)" -#: pathspec.c:525 +#: pathspec.c:524 #, c-format msgid "%s: pathspec magic not supported by this command: %s" msgstr "%s: số mầu nhiệm đặc tả Ä‘Æ°á»ng dẫn chÆ°a được há»— trợ bởi lệnh nà y: %s" -#: pathspec.c:592 +#: pathspec.c:591 #, c-format msgid "pathspec '%s' is beyond a symbolic link" msgstr "đặc tả Ä‘Æ°á»ng dẫn “%s†vượt ra ngoà i liên kết má»m" @@ -3602,50 +3749,55 @@ msgstr "đặc tả Ä‘Æ°á»ng dẫn “%s†vượt ra ngoà i liên kết má»m msgid "flush packet write failed" msgstr "gặp lá»—i khi ghi và o táºp tin gói lúc đẩy dữ liệu lên bá»™ nhá»›" -#: pkt-line.c:142 pkt-line.c:228 +#: pkt-line.c:144 pkt-line.c:230 msgid "protocol error: impossibly long line" msgstr "lá»—i giao thức: không thể là m được dòng dà i" -#: pkt-line.c:158 pkt-line.c:160 +#: pkt-line.c:160 pkt-line.c:162 msgid "packet write with format failed" msgstr "gặp lá»—i khi ghi gói có định dạng" -#: pkt-line.c:192 +#: pkt-line.c:194 msgid "packet write failed - data exceeds max packet size" msgstr "gặp lá»—i khi ghi gói - dữ liệu vượt quá cỡ vói tối Ä‘a" -#: pkt-line.c:199 pkt-line.c:206 +#: pkt-line.c:201 pkt-line.c:208 msgid "packet write failed" msgstr "gặp lá»—i khi ghi gói" -#: pkt-line.c:291 +#: pkt-line.c:293 msgid "read error" msgstr "lá»—i Ä‘á»c" -#: pkt-line.c:299 +#: pkt-line.c:301 msgid "the remote end hung up unexpectedly" msgstr "máy chủ bị treo bất ngá»" -#: pkt-line.c:327 +#: pkt-line.c:329 #, c-format msgid "protocol error: bad line length character: %.4s" msgstr "lá»—i giao thức: ký tá»± chiá»u dà i dòng bị sai: %.4s" -#: pkt-line.c:337 pkt-line.c:342 +#: pkt-line.c:339 pkt-line.c:344 #, c-format msgid "protocol error: bad line length %d" msgstr "lá»—i giao thức: chiá»u dà i dòng bị sai %d" -#: preload-index.c:118 +#: pkt-line.c:353 +#, c-format +msgid "remote error: %s" +msgstr "lá»—i máy chủ: %s" + +#: preload-index.c:119 msgid "Refreshing index" msgstr "Là m má»›i bảng mục lục" -#: preload-index.c:137 +#: preload-index.c:138 #, c-format msgid "unable to create threaded lstat: %s" msgstr "không thể tạo tuyến trình lstat: %s" -#: pretty.c:962 +#: pretty.c:963 msgid "unable to parse --pretty format" msgstr "không thể phân tÃch định dạng --pretty" @@ -3657,7 +3809,7 @@ msgstr "không thể lấy thông tin thống kê vỠ“log“" msgid "could not read `log` output" msgstr "không thể Ä‘á»c kết xuất “logâ€" -#: range-diff.c:74 sequencer.c:4764 +#: range-diff.c:74 sequencer.c:4828 #, c-format msgid "could not parse commit '%s'" msgstr "không thể phân tÃch lần chuyển giao “%sâ€" @@ -3671,11 +3823,47 @@ msgstr "gặp lá»—i khi tạo khác biệt" msgid "could not parse log for '%s'" msgstr "không thể phân tÃch nháºt ký cho “%sâ€" -#: read-cache.c:1490 +#: read-cache.c:673 +#, c-format +msgid "will not add file alias '%s' ('%s' already exists in index)" +msgstr "" +"sẽ không thêm các bà danh “%s†(“%s†đã có từ trÆ°á»›c trong bảng mục lục)" + +#: read-cache.c:689 +msgid "cannot create an empty blob in the object database" +msgstr "không thể tạo má»™t blob rá»—ng trong cÆ¡ sở dữ liệu đối tượng" + +#: read-cache.c:710 +#, c-format +msgid "%s: can only add regular files, symbolic links or git-directories" +msgstr "" +"%s: chỉ có thể thêm táºp tin thông thÆ°á»ng, liên kết má»m hoặc git-directories" + +#: read-cache.c:765 +#, c-format +msgid "unable to index file '%s'" +msgstr "không thể đánh mục lục táºp tin “%sâ€" + +#: read-cache.c:784 +#, c-format +msgid "unable to add '%s' to index" +msgstr "không thể thêm %s và o bảng mục lục" + +#: read-cache.c:795 +#, c-format +msgid "unable to stat '%s'" +msgstr "không thể lấy thống kê “%sâ€" + +#: read-cache.c:1304 +#, c-format +msgid "'%s' appears as both a file and as a directory" +msgstr "%s có vẻ không phải là táºp tin và cÅ©ng chẳng phải là má»™t thÆ° mục" + +#: read-cache.c:1489 msgid "Refresh index" msgstr "Là m tÆ°Æ¡i má»›i bảng mục lục" -#: read-cache.c:1604 +#: read-cache.c:1603 #, c-format msgid "" "index.version set, but the value is invalid.\n" @@ -3684,7 +3872,7 @@ msgstr "" "index.version được đặt, nhÆ°ng giá trị của nó lại không hợp lệ.\n" "Dùng phiên bản %i" -#: read-cache.c:1614 +#: read-cache.c:1613 #, c-format msgid "" "GIT_INDEX_VERSION set, but the value is invalid.\n" @@ -3693,59 +3881,143 @@ msgstr "" "GIT_INDEX_VERSION được đặt, nhÆ°ng giá trị của nó lại không hợp lệ.\n" "Dùng phiên bản %i" -#: read-cache.c:1792 +#: read-cache.c:1684 +#, c-format +msgid "bad signature 0x%08x" +msgstr "chữ ký sai 0x%08x" + +#: read-cache.c:1687 +#, c-format +msgid "bad index version %d" +msgstr "phiên bản mục lục sai %d" + +#: read-cache.c:1696 +msgid "bad index file sha1 signature" +msgstr "chữ ký dạng sha1 cho táºp tin mục lục không đúng" + +#: read-cache.c:1726 +#, c-format +msgid "index uses %.4s extension, which we do not understand" +msgstr "mục lục dùng phần mở rá»™ng %.4s, cái mà chúng tôi không hiểu được" + +#: read-cache.c:1728 +#, c-format +msgid "ignoring %.4s extension" +msgstr "Ä‘ang lá» Ä‘i phần mở rá»™ng %.4s" + +#: read-cache.c:1765 +#, c-format +msgid "unknown index entry format 0x%08x" +msgstr "không hiểu định dạng mục lục 0x%08x" + +#: read-cache.c:1781 #, c-format msgid "malformed name field in the index, near path '%s'" msgstr "trÆ°á»ng tên sai sạng trong mục lục, gần Ä‘Æ°á»ng dẫn “%sâ€" -#: read-cache.c:1960 rerere.c:565 rerere.c:599 rerere.c:1111 builtin/add.c:458 -#: builtin/check-ignore.c:177 builtin/checkout.c:289 builtin/checkout.c:585 -#: builtin/checkout.c:953 builtin/clean.c:954 builtin/commit.c:343 -#: builtin/diff-tree.c:115 builtin/grep.c:489 builtin/mv.c:144 -#: builtin/reset.c:244 builtin/rm.c:270 builtin/submodule--helper.c:329 +#: read-cache.c:1836 +msgid "unordered stage entries in index" +msgstr "các mục tin stage không đúng thứ tá»± trong mục lục" + +#: read-cache.c:1839 +#, c-format +msgid "multiple stage entries for merged file '%s'" +msgstr "nhiá»u mục stage cho táºp tin hòa trá»™n “%sâ€" + +#: read-cache.c:1842 +#, c-format +msgid "unordered stage entries for '%s'" +msgstr "các mục tin stage không đúng thứ tá»± cho “%sâ€" + +#: read-cache.c:1949 read-cache.c:2227 rerere.c:565 rerere.c:599 rerere.c:1111 +#: builtin/add.c:459 builtin/check-ignore.c:178 builtin/checkout.c:294 +#: builtin/checkout.c:622 builtin/checkout.c:991 builtin/clean.c:955 +#: builtin/commit.c:344 builtin/diff-tree.c:116 builtin/grep.c:498 +#: builtin/mv.c:145 builtin/reset.c:245 builtin/rm.c:271 +#: builtin/submodule--helper.c:330 msgid "index file corrupt" msgstr "táºp tin ghi bảng mục lục bị há»ng" -#: read-cache.c:2101 +#: read-cache.c:2090 #, c-format msgid "unable to create load_cache_entries thread: %s" msgstr "không thể tạo tuyến load_cache_entries: %s" -#: read-cache.c:2114 +#: read-cache.c:2103 #, c-format msgid "unable to join load_cache_entries thread: %s" msgstr "không thể gia nháºp tuyến load_cache_entries: %s" -#: read-cache.c:2201 +#: read-cache.c:2136 +#, c-format +msgid "%s: index file open failed" +msgstr "%s: mở táºp tin mục lục gặp lá»—i" + +#: read-cache.c:2140 +#, c-format +msgid "%s: cannot stat the open index" +msgstr "%s: không thể lấy thống kê bảng mục lục đã mở" + +#: read-cache.c:2144 +#, c-format +msgid "%s: index file smaller than expected" +msgstr "%s: táºp tin mục lục nhá» hÆ¡n mong đợi" + +#: read-cache.c:2148 +#, c-format +msgid "%s: unable to map index file" +msgstr "%s: không thể ánh xạ táºp tin mục lục" + +#: read-cache.c:2190 #, c-format msgid "unable to create load_index_extensions thread: %s" msgstr "không thể tạo tuyến load_index_extensions: %s" -#: read-cache.c:2228 +#: read-cache.c:2217 #, c-format msgid "unable to join load_index_extensions thread: %s" msgstr "không thể gia nháºp tuyến load_index_extensions: %s" -#: read-cache.c:2982 sequencer.c:4727 wrapper.c:658 builtin/merge.c:1086 +#: read-cache.c:2239 +#, c-format +msgid "could not freshen shared index '%s'" +msgstr "không thể là m tÆ°Æ¡i má»›i mục lục đã chia sẻ “%sâ€" + +#: read-cache.c:2274 +#, c-format +msgid "broken index, expect %s in %s, got %s" +msgstr "mục lục bị há»ng, cần %s trong %s, nhÆ°ng lại nháºn được %s" + +#: read-cache.c:2971 sequencer.c:4791 wrapper.c:658 builtin/merge.c:1087 #, c-format msgid "could not close '%s'" msgstr "không thể đóng “%sâ€" -#: read-cache.c:3055 sequencer.c:2203 sequencer.c:3592 +#: read-cache.c:3044 sequencer.c:2237 sequencer.c:3647 #, c-format msgid "could not stat '%s'" msgstr "không thể lấy thông tin thống kê vỠ“%sâ€" -#: read-cache.c:3068 +#: read-cache.c:3057 #, c-format msgid "unable to open git dir: %s" msgstr "không thể mở thÆ° mục git: %s" -#: read-cache.c:3080 +#: read-cache.c:3069 #, c-format msgid "unable to unlink: %s" msgstr "không thể bá» liên kết (unlink): “%sâ€" +#: read-cache.c:3088 +#, c-format +msgid "cannot fix permission bits on '%s'" +msgstr "không thể sá»a các bÃt phân quyá»n trên “%sâ€" + +#: read-cache.c:3237 +#, c-format +msgid "%s: cannot drop to stage #0" +msgstr "%s: không thể xóa bá» stage #0" + #: rebase-interactive.c:10 msgid "" "\n" @@ -3837,8 +4109,8 @@ msgstr "" msgid "Note that empty commits are commented out" msgstr "Chú ý rằng lần chuyển giao trống rá»—ng là ghi chú" -#: rebase-interactive.c:62 rebase-interactive.c:75 sequencer.c:2186 -#: sequencer.c:4505 sequencer.c:4561 sequencer.c:4836 +#: rebase-interactive.c:62 rebase-interactive.c:75 sequencer.c:2219 +#: sequencer.c:4569 sequencer.c:4625 sequencer.c:4900 #, c-format msgid "could not read '%s'." msgstr "không thể Ä‘á»c “%sâ€." @@ -3853,7 +4125,7 @@ msgstr "“%s†không chỉ đến má»™t lần chuyển giao hợp lệ nà o c msgid "ignoring dangling symref %s" msgstr "Ä‘ang lá» Ä‘i tham chiếu má»m thừa %s" -#: refs.c:585 ref-filter.c:1951 +#: refs.c:585 ref-filter.c:1976 #, c-format msgid "ignoring broken ref %s" msgstr "Ä‘ang lá» Ä‘i tham chiếu há»ng %s" @@ -3878,15 +4150,15 @@ msgstr "tham chiếu “%s†đã có từ trÆ°á»›c rồi" msgid "unexpected object ID when writing '%s'" msgstr "không cần ID đối tượng khi ghi “%sâ€" -#: refs.c:740 sequencer.c:394 sequencer.c:2510 sequencer.c:2636 -#: sequencer.c:2650 sequencer.c:2877 sequencer.c:4725 sequencer.c:4788 +#: refs.c:740 sequencer.c:396 sequencer.c:2549 sequencer.c:2675 +#: sequencer.c:2689 sequencer.c:2923 sequencer.c:4789 sequencer.c:4852 #: wrapper.c:656 #, c-format msgid "could not write to '%s'" msgstr "không thể ghi và o “%sâ€" -#: refs.c:767 sequencer.c:4723 sequencer.c:4782 wrapper.c:225 wrapper.c:395 -#: builtin/am.c:728 +#: refs.c:767 sequencer.c:4787 sequencer.c:4846 wrapper.c:225 wrapper.c:395 +#: builtin/am.c:713 builtin/rebase.c:575 #, c-format msgid "could not open '%s' for writing" msgstr "không thể mở “%s†để ghi" @@ -3899,7 +4171,7 @@ msgstr "gặp ID đối tượng không cần khi xóa “%sâ€" #: refs.c:905 #, c-format msgid "log for ref %s has gap after %s" -msgstr "Nháºt ký cho tham chiếu %s có khoảng trống sau %s" +msgstr "nháºt ký cho tham chiếu %s có khoảng trống sau %s" #: refs.c:911 #, c-format @@ -3938,7 +4210,7 @@ msgstr "“%s†sẵn có; không thể tạo “%sâ€" #: refs.c:2045 refs.c:2080 #, c-format msgid "cannot process '%s' and '%s' at the same time" -msgstr "Không thể xá» lý “%s†và “%s†cùng má»™t lúc" +msgstr "không thể xá» lý “%s†và “%s†cùng má»™t lúc" #: refs/files-backend.c:1228 #, c-format @@ -3961,7 +4233,7 @@ msgstr "không thể xóa bá» tham chiếu: %s" msgid "invalid refspec '%s'" msgstr "refspec không hợp lệ “%sâ€" -#: ref-filter.c:39 wt-status.c:1855 +#: ref-filter.c:39 wt-status.c:1861 msgid "gone" msgstr "đã ra Ä‘i" @@ -4010,87 +4282,92 @@ msgstr "đối số không được thừa nháºn %%(%s): %s" msgid "%%(objecttype) does not take arguments" msgstr "%%(objecttype) không nháºn các đối số" -#: ref-filter.c:235 +#: ref-filter.c:245 +#, c-format +msgid "unrecognized %%(objectsize) argument: %s" +msgstr "tham số không được thừa nháºn %%(objectname): %s" + +#: ref-filter.c:253 #, c-format -msgid "%%(objectsize) does not take arguments" -msgstr "%%(objectsize) không nháºn các đối số" +msgid "%%(deltabase) does not take arguments" +msgstr "%%(deltabase) không nháºn các đối số" -#: ref-filter.c:247 +#: ref-filter.c:265 #, c-format msgid "%%(body) does not take arguments" msgstr "%%(body) không nháºn các đối số" -#: ref-filter.c:256 +#: ref-filter.c:274 #, c-format msgid "%%(subject) does not take arguments" msgstr "%%(subject) không nháºn các đối số" -#: ref-filter.c:278 +#: ref-filter.c:296 #, c-format msgid "unknown %%(trailers) argument: %s" msgstr "không hiểu tham số %%(trailers): %s" -#: ref-filter.c:307 +#: ref-filter.c:325 #, c-format msgid "positive value expected contents:lines=%s" msgstr "cần ná»™i dung mang giá trị dÆ°Æ¡ng:lines=%s" -#: ref-filter.c:309 +#: ref-filter.c:327 #, c-format msgid "unrecognized %%(contents) argument: %s" msgstr "đối số không được thừa nháºn %%(contents): %s" -#: ref-filter.c:324 +#: ref-filter.c:342 #, c-format msgid "positive value expected objectname:short=%s" msgstr "cần ná»™i dung mang giá trị dÆ°Æ¡ng:shot=%s" -#: ref-filter.c:328 +#: ref-filter.c:346 #, c-format msgid "unrecognized %%(objectname) argument: %s" msgstr "đối số không được thừa nháºn %%(objectname): %s" -#: ref-filter.c:358 +#: ref-filter.c:376 #, c-format msgid "expected format: %%(align:<width>,<position>)" msgstr "cần định dạng: %%(align:<width>,<position>)" -#: ref-filter.c:370 +#: ref-filter.c:388 #, c-format msgid "unrecognized position:%s" msgstr "vị trà không được thừa nháºn:%s" -#: ref-filter.c:377 +#: ref-filter.c:395 #, c-format msgid "unrecognized width:%s" msgstr "chiá»u rá»™ng không được thừa nháºn:%s" -#: ref-filter.c:386 +#: ref-filter.c:404 #, c-format msgid "unrecognized %%(align) argument: %s" msgstr "đối số không được thừa nháºn %%(align): %s" -#: ref-filter.c:394 +#: ref-filter.c:412 #, c-format msgid "positive width expected with the %%(align) atom" msgstr "cần giá trị Ä‘á»™ rá»™ng dÆ°Æ¡ng vá»›i nguyên tá» %%(align)" -#: ref-filter.c:412 +#: ref-filter.c:430 #, c-format msgid "unrecognized %%(if) argument: %s" msgstr "đối số không được thừa nháºn %%(if): %s" -#: ref-filter.c:508 +#: ref-filter.c:527 #, c-format msgid "malformed field name: %.*s" msgstr "tên trÆ°á»ng dị hình: %.*s" -#: ref-filter.c:535 +#: ref-filter.c:554 #, c-format msgid "unknown field name: %.*s" msgstr "không hiểu tên trÆ°á»ng: %.*s" -#: ref-filter.c:539 +#: ref-filter.c:558 #, c-format msgid "" "not a git repository, but the field '%.*s' requires access to object data" @@ -4098,62 +4375,62 @@ msgstr "" "không phải là má»™t kho git, nhÆ°ng trÆ°á»ng “%.*s†yêu cầu truy cáºp và o dữ liệu " "đối tượng" -#: ref-filter.c:663 +#: ref-filter.c:682 #, c-format msgid "format: %%(if) atom used without a %%(then) atom" msgstr "định dạng: nguyên tá» %%(if) được dùng mà không có nguyên tá» %%(then)" -#: ref-filter.c:726 +#: ref-filter.c:745 #, c-format msgid "format: %%(then) atom used without an %%(if) atom" msgstr "định dạng: nguyên tá» %%(then) được dùng mà không có nguyên tá» %%(if)" -#: ref-filter.c:728 +#: ref-filter.c:747 #, c-format msgid "format: %%(then) atom used more than once" msgstr "định dạng: nguyên tá» %%(then) được dùng nhiá»u hÆ¡n má»™t lần" -#: ref-filter.c:730 +#: ref-filter.c:749 #, c-format msgid "format: %%(then) atom used after %%(else)" msgstr "định dạng: nguyên tá» %%(then) được dùng sau %%(else)" -#: ref-filter.c:758 +#: ref-filter.c:777 #, c-format msgid "format: %%(else) atom used without an %%(if) atom" msgstr "định dạng: nguyên tá» %%(else) được dùng mà không có nguyên tá» %%(if)" -#: ref-filter.c:760 +#: ref-filter.c:779 #, c-format msgid "format: %%(else) atom used without a %%(then) atom" msgstr "định dạng: nguyên tá» %%(else) được dùng mà không có nguyên tá» %%(then)" -#: ref-filter.c:762 +#: ref-filter.c:781 #, c-format msgid "format: %%(else) atom used more than once" msgstr "định dạng: nguyên tá» %%(else) được dùng nhiá»u hÆ¡n má»™t lần" -#: ref-filter.c:777 +#: ref-filter.c:796 #, c-format msgid "format: %%(end) atom used without corresponding atom" msgstr "định dạng: nguyên tá» %%(end) được dùng mà không có nguyên tá» tÆ°Æ¡ng ứng" -#: ref-filter.c:834 +#: ref-filter.c:853 #, c-format msgid "malformed format string %s" msgstr "chuá»—i định dạng dị hình %s" -#: ref-filter.c:1424 +#: ref-filter.c:1447 #, c-format msgid "(no branch, rebasing %s)" msgstr "(không nhánh, Ä‘ang cải tổ %s)" -#: ref-filter.c:1427 +#: ref-filter.c:1450 #, c-format msgid "(no branch, rebasing detached HEAD %s)" msgstr "(không nhánh, Ä‘ang cải tổ HEAD %s đã tách rá»i)" -#: ref-filter.c:1430 +#: ref-filter.c:1453 #, c-format msgid "(no branch, bisect started on %s)" msgstr "(không nhánh, di chuyển ná»a bÆ°á»›c được bắt đầu tại %s)" @@ -4161,7 +4438,7 @@ msgstr "(không nhánh, di chuyển ná»a bÆ°á»›c được bắt đầu tại %s #. TRANSLATORS: make sure this matches "HEAD #. detached at " in wt-status.c #. -#: ref-filter.c:1438 +#: ref-filter.c:1461 #, c-format msgid "(HEAD detached at %s)" msgstr "(HEAD được tách rá»i tại %s)" @@ -4169,143 +4446,290 @@ msgstr "(HEAD được tách rá»i tại %s)" #. TRANSLATORS: make sure this matches "HEAD #. detached from " in wt-status.c #. -#: ref-filter.c:1445 +#: ref-filter.c:1468 #, c-format msgid "(HEAD detached from %s)" msgstr "(HEAD được tách rá»i từ %s)" -#: ref-filter.c:1449 +#: ref-filter.c:1472 msgid "(no branch)" msgstr "(không nhánh)" -#: ref-filter.c:1483 ref-filter.c:1638 +#: ref-filter.c:1506 ref-filter.c:1663 #, c-format msgid "missing object %s for %s" msgstr "thiếu đối tượng %s cho %s" -#: ref-filter.c:1491 +#: ref-filter.c:1516 #, c-format msgid "parse_object_buffer failed on %s for %s" msgstr "parse_object_buffer gặp lá»—i trên %s cho %s" -#: ref-filter.c:1857 +#: ref-filter.c:1882 #, c-format msgid "malformed object at '%s'" msgstr "đối tượng dị hình tại “%sâ€" -#: ref-filter.c:1946 +#: ref-filter.c:1971 #, c-format msgid "ignoring ref with broken name %s" msgstr "Ä‘ang lá» Ä‘i tham chiếu vá»›i tên há»ng %s" -#: ref-filter.c:2232 +#: ref-filter.c:2257 #, c-format msgid "format: %%(end) atom missing" msgstr "định dạng: thiếu nguyên tá» %%(end)" -#: ref-filter.c:2338 +#: ref-filter.c:2352 +#, c-format +msgid "option `%s' is incompatible with --merged" +msgstr "tùy chá»n “%s†là xung khắc vá»›i tùy chá»n --merged" + +#: ref-filter.c:2355 +#, c-format +msgid "option `%s' is incompatible with --no-merged" +msgstr "tùy chá»n “%s†là xung khắc vá»›i tùy chá»n --no-merged" + +#: ref-filter.c:2365 #, c-format msgid "malformed object name %s" msgstr "tên đối tượng dị hình %s" -#: remote.c:607 +#: ref-filter.c:2370 +#, c-format +msgid "option `%s' must point to a commit" +msgstr "tùy chá»n “%s†phải chỉ đến má»™t lần chuyển giao" + +#: remote.c:363 +#, c-format +msgid "config remote shorthand cannot begin with '/': %s" +msgstr "cấu hình viết tắt máy chủ không thể bắt đầu bằng “/â€: %s" + +#: remote.c:410 +msgid "more than one receivepack given, using the first" +msgstr "đã Ä‘Æ°a ra nhiá»u hÆ¡n má»™t gói nháºn vá», Ä‘ang sá» dụng cái đầu tiên" + +#: remote.c:418 +msgid "more than one uploadpack given, using the first" +msgstr "đã Ä‘Æ°a ra nhiá»u hÆ¡n má»™t gói tải lên, Ä‘ang sá» dụng cái đầu tiên" + +#: remote.c:608 #, c-format msgid "Cannot fetch both %s and %s to %s" msgstr "Không thể lấy vá» cả %s và %s cho %s" -#: remote.c:611 +#: remote.c:612 #, c-format msgid "%s usually tracks %s, not %s" msgstr "%s thÆ°á»ng theo dõi %s, không phải %s" -#: remote.c:615 +#: remote.c:616 #, c-format msgid "%s tracks both %s and %s" msgstr "%s theo dõi cả %s và %s" -#: remote.c:623 -msgid "Internal error" -msgstr "Lá»—i ná»™i bá»™" +#: remote.c:684 +#, c-format +msgid "key '%s' of pattern had no '*'" +msgstr "khóa “%s†của mẫu k có “*â€" + +#: remote.c:694 +#, c-format +msgid "value '%s' of pattern has no '*'" +msgstr "giá trị “%s†của mẫu k có “*â€" + +#: remote.c:1000 +#, c-format +msgid "src refspec %s does not match any" +msgstr "refspec %s nguồn không khá»›p bất kỳ cái gì" + +#: remote.c:1005 +#, c-format +msgid "src refspec %s matches more than one" +msgstr "refspec %s nguồn khá»›p nhiá»u hÆ¡n má»™t" + +#. TRANSLATORS: "matches '%s'%" is the <dst> part of "git push +#. <remote> <src>:<dst>" push, and "being pushed ('%s')" is +#. the <src>. +#. +#: remote.c:1020 +#, c-format +msgid "" +"The destination you provided is not a full refname (i.e.,\n" +"starting with \"refs/\"). We tried to guess what you meant by:\n" +"\n" +"- Looking for a ref that matches '%s' on the remote side.\n" +"- Checking if the <src> being pushed ('%s')\n" +" is a ref in \"refs/{heads,tags}/\". If so we add a corresponding\n" +" refs/{heads,tags}/ prefix on the remote side.\n" +"\n" +"Neither worked, so we gave up. You must fully qualify the ref." +msgstr "" +"ÄÃch bạn đã cung cấp không phải tên tham chiếu đầy đủ (tức là \n" +"bắt đầu bằng \"refs/\"). Chúng tôi đã cố suy luáºn rằng ý của bạn là :\n" +"\n" +"- Tìm kiếm má»™t tham chiếu mà nó khá»›p “%s†bên phÃa máy chủ.\n" +"- Kiểm tra xem <src> được đẩy lên (“%sâ€)\n" +" là má»™t tham chiếu trong \"refs/{heads,tags}/\". Nếu thế chúng tôi thêm má»™t " +"tiá»n tố\n" +" refs/{heads,tags}/ tÆ°Æ¡ng ứng bên phÃa máy chủ.\n" +"\n" +"Nếu cả hai là không thể, thì chúng tôi cÅ©ng chịu thua. Bạn phải dùng tham " +"chiếu dạng đầy đủ." + +#: remote.c:1040 +#, c-format +msgid "" +"The <src> part of the refspec is a commit object.\n" +"Did you mean to create a new branch by pushing to\n" +"'%s:refs/heads/%s'?" +msgstr "" +"Phần <src> của đặc tả Ä‘Æ°á»ng dẫn là má»™t đối tượng lần chuyển giao.\n" +"Có phải ý bạn là má»™t tạo má»™t nhánh má»›i bằng cách đẩy lên\n" +"“%s:refs/heads/%sâ€?" + +#: remote.c:1045 +#, c-format +msgid "" +"The <src> part of the refspec is a tag object.\n" +"Did you mean to create a new tag by pushing to\n" +"'%s:refs/tags/%s'?" +msgstr "" +"Phần <src> của đặc tả Ä‘Æ°á»ng dẫn là má»™t đối tượng thẻ.\n" +"Có phải ý bạn là má»™t tạo má»™t thẻ má»›i bằng cách đẩy lên\n" +"“%s:refs/tags/%sâ€?" + +#: remote.c:1050 +#, c-format +msgid "" +"The <src> part of the refspec is a tree object.\n" +"Did you mean to tag a new tree by pushing to\n" +"'%s:refs/tags/%s'?" +msgstr "" +"Phần <src> của đặc tả Ä‘Æ°á»ng dẫn là má»™t đối tượng cây.\n" +"Có phải ý bạn là má»™t tạo má»™t cây má»›i bằng cách đẩy lên\n" +"“%s:refs/tags/%sâ€?" + +#: remote.c:1055 +#, c-format +msgid "" +"The <src> part of the refspec is a blob object.\n" +"Did you mean to tag a new blob by pushing to\n" +"'%s:refs/tags/%s'?" +msgstr "" +"Phần <src> của đặc tả Ä‘Æ°á»ng dẫn là má»™t đối tượng blob.\n" +"Có phải ý bạn là má»™t tạo má»™t blob má»›i bằng cách đẩy lên\n" +"“%s:refs/tags/%sâ€?" + +#: remote.c:1091 +#, c-format +msgid "%s cannot be resolved to branch" +msgstr "“%s†không thể được phân giải thà nh nhánh" + +#: remote.c:1102 +#, c-format +msgid "unable to delete '%s': remote ref does not exist" +msgstr "không thể xóa “%sâ€: tham chiếu trên máy chủ không tồn tại" + +#: remote.c:1114 +#, c-format +msgid "dst refspec %s matches more than one" +msgstr "dst refspec %s khá»›p nhiá»u hÆ¡n má»™t" + +#: remote.c:1121 +#, c-format +msgid "dst ref %s receives from more than one src" +msgstr "dst ref %s nháºn từ hÆ¡n má»™t nguồn" -#: remote.c:1569 remote.c:1670 +#: remote.c:1624 remote.c:1725 msgid "HEAD does not point to a branch" msgstr "HEAD không chỉ đến má»™t nhánh nà o cả" -#: remote.c:1578 +#: remote.c:1633 #, c-format msgid "no such branch: '%s'" msgstr "không có nhánh nà o nhÆ° thế: “%sâ€" -#: remote.c:1581 +#: remote.c:1636 #, c-format msgid "no upstream configured for branch '%s'" msgstr "không có thượng nguồn được cấu hình cho nhánh “%sâ€" -#: remote.c:1587 +#: remote.c:1642 #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" msgstr "" "nhánh thượng nguồn “%s†không được lÆ°u lại nhÆ° là má»™t nhánh theo dõi máy chủ" -#: remote.c:1602 +#: remote.c:1657 #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "đẩy lên Ä‘Ãch “%s†trên máy chủ “%s†không có nhánh theo dõi ná»™i bá»™" -#: remote.c:1614 +#: remote.c:1669 #, c-format msgid "branch '%s' has no remote for pushing" msgstr "nhánh “%s†không có máy chủ để đẩy lên" -#: remote.c:1624 +#: remote.c:1679 #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "đẩy refspecs cho “%s†không bao gồm “%sâ€" -#: remote.c:1637 +#: remote.c:1692 msgid "push has no destination (push.default is 'nothing')" msgstr "đẩy lên mà không có Ä‘Ãch (push.default là “nothingâ€)" -#: remote.c:1659 +#: remote.c:1714 msgid "cannot resolve 'simple' push to a single destination" msgstr "không thể phân giải đẩy “đơn giản†đến má»™t Ä‘Ãch Ä‘Æ¡n" -#: remote.c:1935 +#: remote.c:1840 +#, c-format +msgid "couldn't find remote ref %s" +msgstr "không thể tìm thấy tham chiếu máy chủ %s" + +#: remote.c:1853 +#, c-format +msgid "* Ignoring funny ref '%s' locally" +msgstr "* Äang bá» qua tham chiếu thú vị ná»™i bá»™ “%sâ€" + +#: remote.c:1990 #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "" "Nhánh của bạn dá»±a trên cÆ¡ sở là “%sâ€, nhÆ°ng trên thượng nguồn không còn.\n" -#: remote.c:1939 +#: remote.c:1994 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (dùng \" git branch --unset-upstream\" để sá»a)\n" -#: remote.c:1942 +#: remote.c:1997 #, c-format msgid "Your branch is up to date with '%s'.\n" msgstr "Nhánh của bạn đã cáºp nháºt vá»›i “%sâ€.\n" -#: remote.c:1946 +#: remote.c:2001 #, c-format msgid "Your branch and '%s' refer to different commits.\n" msgstr "Nhánh của bạn và “%s†tham chiếu đến các lần chuyển giao khác nhau.\n" -#: remote.c:1949 +#: remote.c:2004 #, c-format msgid " (use \"%s\" for details)\n" msgstr " (dùng \"%s\" để biết thêm chi tiết)\n" -#: remote.c:1953 +#: remote.c:2008 #, c-format msgid "Your branch is ahead of '%s' by %d commit.\n" msgid_plural "Your branch is ahead of '%s' by %d commits.\n" msgstr[0] "Nhánh của bạn đứng trÆ°á»›c “%s†%d lần chuyển giao.\n" -#: remote.c:1959 +#: remote.c:2014 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (dùng \"git push\" để xuất bản các lần chuyển giao ná»™i bá»™ của bạn)\n" -#: remote.c:1962 +#: remote.c:2017 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -4314,11 +4738,11 @@ msgstr[0] "" "Nhánh của bạn đứng đằng sau “%s†%d lần chuyển giao, và có thể được chuyển-" "tiếp-nhanh.\n" -#: remote.c:1970 +#: remote.c:2025 msgid " (use \"git pull\" to update your local branch)\n" msgstr " (dùng \"git pull\" để cáºp nháºt nhánh ná»™i bá»™ của bạn)\n" -#: remote.c:1973 +#: remote.c:2028 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -4331,12 +4755,17 @@ msgstr[0] "" "và có %d và %d lần chuyển giao khác nhau cho từng cái,\n" "tÆ°Æ¡ng ứng vá»›i má»—i lần.\n" -#: remote.c:1983 +#: remote.c:2038 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" " (dùng \"git pull\" để hòa trá»™n nhánh trên máy chủ và o trong nhánh của " "bạn)\n" +#: remote.c:2221 +#, c-format +msgid "cannot parse expected object name '%s'" +msgstr "không thể phân tÃch tên đối tượng mong muốn “%sâ€" + #: replace-object.c:21 #, c-format msgid "bad replace ref name: %s" @@ -4360,7 +4789,8 @@ msgstr "MERGE_RR sai há»ng" msgid "unable to write rerere record" msgstr "không thể ghi bản ghi rerere" -#: rerere.c:485 rerere.c:692 sequencer.c:3136 sequencer.c:3162 +#: rerere.c:485 rerere.c:692 sequencer.c:3186 sequencer.c:3212 +#: builtin/fsck.c:314 #, c-format msgid "could not write '%s'" msgstr "không thể ghi “%sâ€" @@ -4393,7 +4823,7 @@ msgstr "gặp lá»—i khi Ä‘ang ghi “%sâ€" #: rerere.c:714 #, c-format msgid "Staged '%s' using previous resolution." -msgstr "Äã tạm cất “%s†sá» dụng cách phân giải kế trÆ°á»›c" +msgstr "Äã tạm cất “%s†sá» dụng cách phân giải kế trÆ°á»›c." #: rerere.c:753 #, c-format @@ -4413,10 +4843,10 @@ msgstr "không thể unlink stray “%sâ€" #: rerere.c:807 #, c-format msgid "Recorded preimage for '%s'" -msgstr "preimage đã được ghi lại cho “%sâ€" +msgstr "Preimage đã được ghi lại cho “%sâ€" -#: rerere.c:881 submodule.c:1763 builtin/submodule--helper.c:1413 -#: builtin/submodule--helper.c:1423 +#: rerere.c:881 submodule.c:2012 builtin/submodule--helper.c:1417 +#: builtin/submodule--helper.c:1427 #, c-format msgid "could not create directory '%s'" msgstr "không thể tạo thÆ° mục “%sâ€" @@ -4450,29 +4880,29 @@ msgstr "Quên phân giải cho “%sâ€\n" msgid "unable to open rr-cache directory" msgstr "không thể mở thÆ° mục rr-cache" -#: revision.c:2324 +#: revision.c:2484 msgid "your current branch appears to be broken" msgstr "nhánh hiện tại của bạn có vẻ nhÆ° bị há»ng" -#: revision.c:2327 +#: revision.c:2487 #, c-format msgid "your current branch '%s' does not have any commits yet" msgstr "nhánh hiện tại của bạn “%s†không có má»™t lần chuyển giao nà o cả" -#: revision.c:2523 +#: revision.c:2684 msgid "--first-parent is incompatible with --bisect" msgstr "--first-parent xung khắc vá»›i --bisect" -#: run-command.c:740 +#: run-command.c:742 msgid "open /dev/null failed" msgstr "gặp lá»—i khi mở “/dev/nullâ€" -#: run-command.c:1229 +#: run-command.c:1231 #, c-format msgid "cannot create async thread: %s" msgstr "không thể tạo tuyến async: %s" -#: run-command.c:1293 +#: run-command.c:1295 #, c-format msgid "" "The '%s' hook was ignored because it's not set as executable.\n" @@ -4481,30 +4911,30 @@ msgstr "" "Móc “%s†bị bá» qua bởi vì nó không thể đặt là thá»±c thi được.\n" "Bạn có thể tắt cảnh báo nà y bằng “git config advice.ignoredHook false“." -#: send-pack.c:142 +#: send-pack.c:141 msgid "unexpected flush packet while reading remote unpack status" msgstr "" "gặp gói flush không cần trong khi Ä‘á»c tình trạng giải nén gói trên máy chủ" -#: send-pack.c:144 +#: send-pack.c:143 #, c-format msgid "unable to parse remote unpack status: %s" msgstr "không thể phân tÃch tình trạng unpack máy chủ: %s" -#: send-pack.c:146 +#: send-pack.c:145 #, c-format msgid "remote unpack failed: %s" msgstr "máy chủ gặp lá»—i unpack: %s" -#: send-pack.c:308 +#: send-pack.c:306 msgid "failed to sign the push certificate" msgstr "gặp lá»—i khi ký chứng thá»±c đẩy" -#: send-pack.c:421 +#: send-pack.c:420 msgid "the receiving end does not support --signed push" msgstr "kết thúc nháºn không há»— trợ đẩy --signed" -#: send-pack.c:423 +#: send-pack.c:422 msgid "" "not sending a push certificate since the receiving end does not support --" "signed push" @@ -4512,42 +4942,42 @@ msgstr "" "đừng gá»i giấy chứng nháºn đẩy trÆ°á»›c khi kết thúc nháºn không há»— trợ đẩy --" "signed" -#: send-pack.c:435 +#: send-pack.c:434 msgid "the receiving end does not support --atomic push" msgstr "kết thúc nháºn không há»— trợ đẩy --atomic" -#: send-pack.c:440 +#: send-pack.c:439 msgid "the receiving end does not support push options" msgstr "kết thúc nháºn không há»— trợ các tùy chá»n của lệnh push" -#: sequencer.c:183 +#: sequencer.c:184 #, c-format msgid "invalid commit message cleanup mode '%s'" msgstr "chế Ä‘á»™ dá»n dẹp ghi chú các lần chuyển giao không hợp lệ “%sâ€" -#: sequencer.c:287 +#: sequencer.c:288 #, c-format msgid "could not delete '%s'" msgstr "không thể xóa bỠ“%sâ€" -#: sequencer.c:313 +#: sequencer.c:314 msgid "revert" msgstr "hoà n nguyên" -#: sequencer.c:315 +#: sequencer.c:316 msgid "cherry-pick" msgstr "cherry-pick" -#: sequencer.c:317 +#: sequencer.c:318 msgid "rebase -i" msgstr "rebase -i" -#: sequencer.c:319 +#: sequencer.c:320 #, c-format msgid "unknown action: %d" msgstr "không nháºn ra thao tác: %d" -#: sequencer.c:376 +#: sequencer.c:378 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -4555,7 +4985,7 @@ msgstr "" "sau khi giải quyết các xung Ä‘á»™t, đánh dấu Ä‘Æ°á»ng dẫn đã sá»a\n" "vá»›i lệnh “git add <Ä‘Æ°á»ng_dẫn>†hoặc “git rm <Ä‘Æ°á»ng_dẫn>â€" -#: sequencer.c:379 +#: sequencer.c:381 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -4565,39 +4995,39 @@ msgstr "" "vá»›i lệnh “git add <Ä‘Æ°á»ng_dẫn>†hoặc “git rm <Ä‘Æ°á»ng_dẫn>â€\n" "và chuyển giao kết quả bằng lệnh “git commitâ€" -#: sequencer.c:392 sequencer.c:2632 +#: sequencer.c:394 sequencer.c:2671 #, c-format msgid "could not lock '%s'" msgstr "không thể khóa “%sâ€" -#: sequencer.c:399 +#: sequencer.c:401 #, c-format msgid "could not write eol to '%s'" msgstr "không thể ghi eol và o “%sâ€" -#: sequencer.c:404 sequencer.c:2515 sequencer.c:2638 sequencer.c:2652 -#: sequencer.c:2885 +#: sequencer.c:406 sequencer.c:2554 sequencer.c:2677 sequencer.c:2691 +#: sequencer.c:2931 #, c-format msgid "failed to finalize '%s'" msgstr "gặp lá»—i khi hoà n thà nh “%sâ€" -#: sequencer.c:427 sequencer.c:921 sequencer.c:1594 sequencer.c:2535 -#: sequencer.c:2867 sequencer.c:2974 builtin/am.c:260 builtin/commit.c:746 -#: builtin/merge.c:1084 builtin/rebase.c:152 +#: sequencer.c:429 sequencer.c:931 sequencer.c:1615 sequencer.c:2574 +#: sequencer.c:2913 sequencer.c:3022 builtin/am.c:245 builtin/commit.c:748 +#: builtin/merge.c:1085 builtin/rebase.c:154 #, c-format msgid "could not read '%s'" -msgstr "Không thể Ä‘á»c “%sâ€." +msgstr "không thể Ä‘á»c “%sâ€" -#: sequencer.c:453 +#: sequencer.c:455 #, c-format msgid "your local changes would be overwritten by %s." msgstr "các thay đổi ná»™i bá»™ của bạn có thể bị ghi đè bởi lệnh %s." -#: sequencer.c:457 +#: sequencer.c:459 msgid "commit your changes or stash them to proceed." msgstr "chuyển giao các thay đổi của bạn hay tạm cất (stash) chúng để xá» lý." -#: sequencer.c:486 +#: sequencer.c:491 #, c-format msgid "%s: fast-forward" msgstr "%s: chuyển-tiếp-nhanh" @@ -4605,70 +5035,70 @@ msgstr "%s: chuyển-tiếp-nhanh" #. TRANSLATORS: %s will be "revert", "cherry-pick" or #. "rebase -i". #. -#: sequencer.c:575 +#: sequencer.c:582 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Không thể ghi táºp tin lÆ°u bảng mục lục má»›i" -#: sequencer.c:591 +#: sequencer.c:598 msgid "unable to update cache tree" msgstr "không thể cáºp nháºt cây bá»™ nhá»› đệm" -#: sequencer.c:604 +#: sequencer.c:612 msgid "could not resolve HEAD commit" msgstr "không thể phân giải lần chuyển giao HEAD" -#: sequencer.c:684 +#: sequencer.c:692 #, c-format msgid "no key present in '%.*s'" msgstr "không có khóa hiện diện trong “%.*sâ€" -#: sequencer.c:695 +#: sequencer.c:703 #, c-format msgid "unable to dequote value of '%s'" msgstr "không thể giải trÃch dẫn giá trị của “%sâ€" -#: sequencer.c:732 wrapper.c:227 wrapper.c:397 builtin/am.c:719 -#: builtin/am.c:811 builtin/merge.c:1081 +#: sequencer.c:740 wrapper.c:227 wrapper.c:397 builtin/am.c:704 +#: builtin/am.c:796 builtin/merge.c:1082 builtin/rebase.c:617 #, c-format msgid "could not open '%s' for reading" msgstr "không thể mở “%s†để Ä‘á»c" -#: sequencer.c:742 +#: sequencer.c:750 msgid "'GIT_AUTHOR_NAME' already given" msgstr "“GIT_AUTHOR_NAME†đã sẵn Ä‘Æ°a ra rồi" -#: sequencer.c:747 +#: sequencer.c:755 msgid "'GIT_AUTHOR_EMAIL' already given" msgstr "“GIT_AUTHOR_EMAIL†đã sẵn Ä‘Æ°a ra rồi" -#: sequencer.c:752 +#: sequencer.c:760 msgid "'GIT_AUTHOR_DATE' already given" msgstr "“GIT_AUTHOR_DATE†đã sẵn Ä‘Æ°a ra rồi" -#: sequencer.c:756 +#: sequencer.c:764 #, c-format msgid "unknown variable '%s'" msgstr "không hiểu biến “%sâ€" -#: sequencer.c:761 +#: sequencer.c:769 msgid "missing 'GIT_AUTHOR_NAME'" msgstr "thiếu “GIT_AUTHOR_NAMEâ€" -#: sequencer.c:763 +#: sequencer.c:771 msgid "missing 'GIT_AUTHOR_EMAIL'" msgstr "thiếu “GIT_AUTHOR_EMAILâ€" -#: sequencer.c:765 +#: sequencer.c:773 msgid "missing 'GIT_AUTHOR_DATE'" msgstr "thiếu “GIT_AUTHOR_DATEâ€" -#: sequencer.c:825 +#: sequencer.c:833 #, c-format msgid "invalid date format '%s' in '%s'" msgstr "định dạng ngà y tháng không hợp lệ “%s†trong “%sâ€" -#: sequencer.c:842 +#: sequencer.c:850 #, c-format msgid "" "you have staged changes in your working tree\n" @@ -4697,15 +5127,15 @@ msgstr "" "\n" " git rebase --continue\n" -#: sequencer.c:935 +#: sequencer.c:945 msgid "writing root commit" msgstr "ghi chuyển giao gốc" -#: sequencer.c:1142 +#: sequencer.c:1155 msgid "'prepare-commit-msg' hook failed" msgstr "móc “prepare-commit-msg†bị lá»—i" -#: sequencer.c:1149 +#: sequencer.c:1162 msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -4736,7 +5166,7 @@ msgstr "" "\n" " git commit --amend --reset-author\n" -#: sequencer.c:1162 +#: sequencer.c:1175 msgid "" "Your name and email address were configured automatically based\n" "on your username and hostname. Please check that they are accurate.\n" @@ -4764,304 +5194,297 @@ msgstr "" "\n" " git commit --amend --reset-author\n" -#: sequencer.c:1202 +#: sequencer.c:1217 msgid "couldn't look up newly created commit" msgstr "không thể tìm thấy lần chuyển giao má»›i hÆ¡n đã được tạo" -#: sequencer.c:1204 +#: sequencer.c:1219 msgid "could not parse newly created commit" msgstr "" "không thể phân tÃch cú pháp của đối tượng chuyển giao má»›i hÆ¡n đã được tạo" -#: sequencer.c:1250 +#: sequencer.c:1265 msgid "unable to resolve HEAD after creating commit" msgstr "không thể phân giải HEAD sau khi tạo lần chuyển giao" -#: sequencer.c:1252 +#: sequencer.c:1267 msgid "detached HEAD" msgstr "đã rá»i khá»i HEAD" -#: sequencer.c:1256 +#: sequencer.c:1271 msgid " (root-commit)" msgstr " (root-commit)" -#: sequencer.c:1277 +#: sequencer.c:1292 msgid "could not parse HEAD" msgstr "không thể phân tÃch HEAD" -#: sequencer.c:1279 +#: sequencer.c:1294 #, c-format msgid "HEAD %s is not a commit!" msgstr "HEAD %s không phải là má»™t lần chuyển giao!" -#: sequencer.c:1283 builtin/commit.c:1543 +#: sequencer.c:1298 builtin/commit.c:1546 msgid "could not parse HEAD commit" msgstr "không thể phân tÃch commit (lần chuyển giao) HEAD" -#: sequencer.c:1334 sequencer.c:1934 +#: sequencer.c:1350 sequencer.c:1964 msgid "unable to parse commit author" msgstr "không thể phân tÃch tác giả của lần chuyển giao" -#: sequencer.c:1344 builtin/am.c:1585 builtin/merge.c:677 +#: sequencer.c:1360 builtin/am.c:1570 builtin/merge.c:678 msgid "git write-tree failed to write a tree" msgstr "lệnh git write-tree gặp lá»—i khi ghi má»™t cây" -#: sequencer.c:1361 sequencer.c:1416 +#: sequencer.c:1377 sequencer.c:1433 #, c-format msgid "unable to read commit message from '%s'" msgstr "không thể Ä‘á»c phần chú thÃch (message) từ “%sâ€" -#: sequencer.c:1383 builtin/am.c:1606 builtin/commit.c:1646 builtin/merge.c:858 -#: builtin/merge.c:883 +#: sequencer.c:1399 builtin/am.c:1591 builtin/commit.c:1649 builtin/merge.c:859 +#: builtin/merge.c:884 msgid "failed to write commit object" msgstr "gặp lá»—i khi ghi đối tượng chuyển giao" -#: sequencer.c:1443 +#: sequencer.c:1460 #, c-format msgid "could not parse commit %s" msgstr "không thể phân tÃch lần chuyển giao %s" -#: sequencer.c:1448 +#: sequencer.c:1465 #, c-format msgid "could not parse parent commit %s" msgstr "không thể phân tÃch lần chuyển giao cha mẹ “%sâ€" -#: sequencer.c:1546 sequencer.c:1654 +#: sequencer.c:1565 sequencer.c:1675 #, c-format msgid "unknown command: %d" msgstr "không hiểu câu lệnh %d" -#: sequencer.c:1601 sequencer.c:1626 +#: sequencer.c:1622 sequencer.c:1647 #, c-format msgid "This is a combination of %d commits." msgstr "Äây là tổ hợp của %d lần chuyển giao." -#: sequencer.c:1611 sequencer.c:4744 +#: sequencer.c:1632 sequencer.c:4808 msgid "need a HEAD to fixup" msgstr "cần má»™t HEAD để sá»a" -#: sequencer.c:1613 sequencer.c:2912 +#: sequencer.c:1634 sequencer.c:2958 msgid "could not read HEAD" msgstr "không thể Ä‘á»c HEAD" -#: sequencer.c:1615 +#: sequencer.c:1636 msgid "could not read HEAD's commit message" msgstr "không thể Ä‘á»c phần chú thÃch (message) của HEAD" -#: sequencer.c:1621 +#: sequencer.c:1642 #, c-format msgid "cannot write '%s'" msgstr "không thể ghi “%sâ€" -#: sequencer.c:1628 git-rebase--preserve-merges.sh:441 +#: sequencer.c:1649 git-rebase--preserve-merges.sh:441 msgid "This is the 1st commit message:" msgstr "Äây là chú thÃch cho lần chuyển giao thứ nhất:" -#: sequencer.c:1636 +#: sequencer.c:1657 #, c-format msgid "could not read commit message of %s" msgstr "không thể Ä‘á»c phần chú thÃch (message) của %s" -#: sequencer.c:1643 +#: sequencer.c:1664 #, c-format msgid "This is the commit message #%d:" msgstr "Äây là chú thÃch cho lần chuyển giao thứ #%d:" -#: sequencer.c:1649 +#: sequencer.c:1670 #, c-format msgid "The commit message #%d will be skipped:" msgstr "Chú thÃch cho lần chuyển giao thứ #%d sẽ bị bá» qua:" -#: sequencer.c:1732 +#: sequencer.c:1758 msgid "your index file is unmerged." msgstr "táºp tin lÆ°u mục lục của bạn không được hòa trá»™n." -#: sequencer.c:1739 +#: sequencer.c:1765 msgid "cannot fixup root commit" msgstr "không thể sá»a chữa lần chuyển giao gốc" -#: sequencer.c:1758 +#: sequencer.c:1784 #, c-format msgid "commit %s is a merge but no -m option was given." msgstr "lần chuyển giao %s là má»™t lần hòa trá»™n nhÆ°ng không Ä‘Æ°a ra tùy chá»n -m." -#: sequencer.c:1766 +#: sequencer.c:1792 sequencer.c:1800 #, c-format msgid "commit %s does not have parent %d" msgstr "lần chuyển giao %s không có cha mẹ %d" -#: sequencer.c:1770 -#, c-format -msgid "mainline was specified but commit %s is not a merge." -msgstr "" -"luồng chÃnh đã được chỉ ra nhÆ°ng lần chuyển giao %s không phải là má»™t lần " -"hòa trá»™n." - -#: sequencer.c:1776 +#: sequencer.c:1806 #, c-format msgid "cannot get commit message for %s" msgstr "không thể lấy ghi chú lần chuyển giao cho %s" #. TRANSLATORS: The first %s will be a "todo" command like #. "revert" or "pick", the second %s a SHA1. -#: sequencer.c:1795 +#: sequencer.c:1825 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: không thể phân tÃch lần chuyển giao mẹ của %s" -#: sequencer.c:1860 +#: sequencer.c:1890 #, c-format msgid "could not rename '%s' to '%s'" msgstr "không thể đổi tên “%s†thà nh “%sâ€" -#: sequencer.c:1915 +#: sequencer.c:1945 #, c-format msgid "could not revert %s... %s" msgstr "không thể hoà n nguyên %s… %s" -#: sequencer.c:1916 +#: sequencer.c:1946 #, c-format msgid "could not apply %s... %s" msgstr "không thể áp dụng miếng vá %s… %s" -#: sequencer.c:1974 +#: sequencer.c:2005 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: gặp lá»—i Ä‘á»c bảng mục lục" -#: sequencer.c:1981 +#: sequencer.c:2012 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: gặp lá»—i khi là m tÆ°Æ¡i má»›i bảng mục lục" -#: sequencer.c:2062 +#: sequencer.c:2094 #, c-format msgid "%s does not accept arguments: '%s'" msgstr "%s không nháºn các đối số: “%sâ€" -#: sequencer.c:2071 +#: sequencer.c:2103 #, c-format msgid "missing arguments for %s" msgstr "thiếu đối số cho %s" -#: sequencer.c:2130 +#: sequencer.c:2163 #, c-format msgid "invalid line %d: %.*s" msgstr "dòng không hợp lệ %d: %.*s" -#: sequencer.c:2138 +#: sequencer.c:2171 #, c-format msgid "cannot '%s' without a previous commit" msgstr "không thể “%s†thể mà không có lần chuyển giao kế trÆ°á»›c" -#: sequencer.c:2209 +#: sequencer.c:2243 msgid "please fix this using 'git rebase --edit-todo'." msgstr "vui lòng sá»a lá»—i nà y bằng cách dùng “git rebase --edit-todoâ€." -#: sequencer.c:2211 +#: sequencer.c:2245 #, c-format msgid "unusable instruction sheet: '%s'" msgstr "bảng chỉ thị không thể dùng được: %s" -#: sequencer.c:2216 +#: sequencer.c:2250 msgid "no commits parsed." msgstr "không có lần chuyển giao nà o được phân tÃch." -#: sequencer.c:2227 +#: sequencer.c:2261 msgid "cannot cherry-pick during a revert." msgstr "không thể cherry-pick trong khi hoà n nguyên." -#: sequencer.c:2229 +#: sequencer.c:2263 msgid "cannot revert during a cherry-pick." msgstr "không thể thá»±c hiện việc hoà n nguyên trong khi Ä‘ang cherry-pick." -#: sequencer.c:2299 +#: sequencer.c:2333 #, c-format msgid "invalid value for %s: %s" msgstr "giá trị cho %s không hợp lệ: %s" -#: sequencer.c:2380 +#: sequencer.c:2420 msgid "unusable squash-onto" msgstr "squash-onto không dùng được" -#: sequencer.c:2396 +#: sequencer.c:2436 #, c-format msgid "malformed options sheet: '%s'" msgstr "bảng tùy chá»n dị hình: “%sâ€" -#: sequencer.c:2479 sequencer.c:4005 +#: sequencer.c:2518 sequencer.c:4067 msgid "empty commit set passed" msgstr "lần chuyển giao trống rá»—ng đặt là hợp quy cách" -#: sequencer.c:2487 +#: sequencer.c:2526 msgid "a cherry-pick or revert is already in progress" msgstr "có má»™t thao tác “cherry-pick†hoặc “revert†đang được thá»±c hiện" -#: sequencer.c:2488 +#: sequencer.c:2527 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "hãy thá» \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:2491 +#: sequencer.c:2530 #, c-format msgid "could not create sequencer directory '%s'" msgstr "không thể tạo thÆ° mục xếp dãy “%sâ€" -#: sequencer.c:2505 +#: sequencer.c:2544 msgid "could not lock HEAD" msgstr "không thể khóa HEAD" -#: sequencer.c:2560 sequencer.c:3761 +#: sequencer.c:2599 sequencer.c:3819 msgid "no cherry-pick or revert in progress" msgstr "không cherry-pick hay hoà n nguyên trong tiến trình" -#: sequencer.c:2562 +#: sequencer.c:2601 msgid "cannot resolve HEAD" msgstr "không thể phân giải HEAD" -#: sequencer.c:2564 sequencer.c:2599 +#: sequencer.c:2603 sequencer.c:2638 msgid "cannot abort from a branch yet to be born" msgstr "không thể hủy bá» từ má»™t nhánh mà nó còn chÆ°a được tạo ra" -#: sequencer.c:2585 builtin/grep.c:721 +#: sequencer.c:2624 builtin/grep.c:732 #, c-format msgid "cannot open '%s'" msgstr "không mở được “%sâ€" -#: sequencer.c:2587 +#: sequencer.c:2626 #, c-format msgid "cannot read '%s': %s" msgstr "không thể Ä‘á»c “%sâ€: %s" -#: sequencer.c:2588 +#: sequencer.c:2627 msgid "unexpected end of file" msgstr "gặp kết thúc táºp tin Ä‘á»™t xuất" -#: sequencer.c:2594 +#: sequencer.c:2633 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "táºp tin HEAD “pre-cherry-pick†đã lÆ°u “%s†bị há»ng" -#: sequencer.c:2605 +#: sequencer.c:2644 msgid "You seem to have moved HEAD. Not rewinding, check your HEAD!" msgstr "" "Bạn có lẽ đã có HEAD đã bị di chuyển Ä‘i, Không thể tua, kiểm tra HEAD của " "bạn!" -#: sequencer.c:2709 sequencer.c:3679 +#: sequencer.c:2750 sequencer.c:3735 #, c-format msgid "could not update %s" msgstr "không thể cáºp nháºt %s" -#: sequencer.c:2747 sequencer.c:3659 +#: sequencer.c:2788 sequencer.c:3715 msgid "cannot read HEAD" msgstr "không thể Ä‘á»c HEAD" -#: sequencer.c:2762 +#: sequencer.c:2805 #, c-format msgid "unable to copy '%s' to '%s'" msgstr "không thể chép “%s†sang “%sâ€" -#: sequencer.c:2770 +#: sequencer.c:2813 #, c-format msgid "" "You can amend the commit now, with\n" @@ -5080,27 +5503,27 @@ msgstr "" "\n" " git rebase --continue\n" -#: sequencer.c:2780 +#: sequencer.c:2823 #, c-format msgid "Could not apply %s... %.*s" msgstr "Không thể áp dụng %s… %.*s" -#: sequencer.c:2787 +#: sequencer.c:2830 #, c-format msgid "Could not merge %.*s" msgstr "Không hòa trá»™n %.*s" -#: sequencer.c:2798 sequencer.c:2802 builtin/difftool.c:640 +#: sequencer.c:2844 sequencer.c:2848 builtin/difftool.c:641 #, c-format msgid "could not copy '%s' to '%s'" msgstr "không thể chép “%s†sang “%sâ€" -#: sequencer.c:2824 sequencer.c:3242 builtin/rebase.c:580 builtin/rebase.c:1019 -#: builtin/rebase.c:1372 builtin/rebase.c:1426 +#: sequencer.c:2870 sequencer.c:3293 builtin/rebase.c:424 builtin/rebase.c:1230 +#: builtin/rebase.c:1591 builtin/rebase.c:1646 msgid "could not read index" msgstr "không thể Ä‘á»c bảng mục lục" -#: sequencer.c:2829 +#: sequencer.c:2875 #, c-format msgid "" "execution failed: %s\n" @@ -5115,11 +5538,11 @@ msgstr "" " git rebase --continue\n" "\n" -#: sequencer.c:2835 +#: sequencer.c:2881 msgid "and made changes to the index and/or the working tree\n" msgstr "và tạo các thay đổi bảng mục lục và /hay cây là m việc\n" -#: sequencer.c:2841 +#: sequencer.c:2887 #, c-format msgid "" "execution succeeded: %s\n" @@ -5136,76 +5559,76 @@ msgstr "" " git rebase --continue\n" "\n" -#: sequencer.c:2902 +#: sequencer.c:2948 #, c-format msgid "illegal label name: '%.*s'" msgstr "tên nhãn dị hình: “%.*sâ€" -#: sequencer.c:2954 +#: sequencer.c:3002 msgid "writing fake root commit" msgstr "ghi lần chuyển giao gốc giả" -#: sequencer.c:2959 +#: sequencer.c:3007 msgid "writing squash-onto" msgstr "Ä‘ang ghi squash-onto" -#: sequencer.c:2997 builtin/rebase.c:585 builtin/rebase.c:591 +#: sequencer.c:3045 builtin/rebase.c:429 builtin/rebase.c:435 #, c-format msgid "failed to find tree of %s" msgstr "gặp lá»—i khi tìm cây của %s" -#: sequencer.c:3015 builtin/rebase.c:604 +#: sequencer.c:3063 builtin/rebase.c:448 msgid "could not write index" msgstr "không thể ghi bảng mục lục" -#: sequencer.c:3042 +#: sequencer.c:3090 #, c-format msgid "could not resolve '%s'" msgstr "không thể phân giải “%sâ€" -#: sequencer.c:3068 +#: sequencer.c:3118 msgid "cannot merge without a current revision" msgstr "không thể hòa trá»™n mà không có má»™t Ä‘iểm xét duyệt hiện tại" -#: sequencer.c:3090 +#: sequencer.c:3140 #, c-format msgid "unable to parse '%.*s'" msgstr "không thể phân tÃch “%.*sâ€" -#: sequencer.c:3099 +#: sequencer.c:3149 #, c-format msgid "nothing to merge: '%.*s'" msgstr "chẳng có gì để hòa trá»™n: “%.*sâ€" -#: sequencer.c:3111 +#: sequencer.c:3161 msgid "octopus merge cannot be executed on top of a [new root]" msgstr "hòa trá»™n octopus không thể được thá»±c thi trên đỉnh của má»™t [new root]" -#: sequencer.c:3126 +#: sequencer.c:3176 #, c-format msgid "could not get commit message of '%s'" msgstr "không thể lấy chú thÃch của lần chuyển giao của “%sâ€" -#: sequencer.c:3274 +#: sequencer.c:3325 #, c-format msgid "could not even attempt to merge '%.*s'" msgstr "không thể ngay cả khi thá» hòa trá»™n “%.*sâ€" -#: sequencer.c:3290 +#: sequencer.c:3341 msgid "merge: Unable to write new index file" msgstr "merge: Không thể ghi táºp tin lÆ°u bảng mục lục má»›i" -#: sequencer.c:3358 builtin/rebase.c:268 +#: sequencer.c:3409 builtin/rebase.c:298 #, c-format msgid "Applied autostash.\n" msgstr "Äã áp dụng autostash.\n" -#: sequencer.c:3370 +#: sequencer.c:3421 #, c-format msgid "cannot store %s" msgstr "không thá» lÆ°u “%sâ€" -#: sequencer.c:3373 builtin/rebase.c:284 +#: sequencer.c:3424 builtin/rebase.c:314 #, c-format msgid "" "Applying autostash resulted in conflicts.\n" @@ -5217,31 +5640,31 @@ msgstr "" "Bạn có thể chạy lệnh \"git stash pop\" hay \"git stash drop\" bất kỳ lúc " "nà o.\n" -#: sequencer.c:3427 +#: sequencer.c:3478 #, c-format msgid "could not checkout %s" msgstr "không thể lấy ra %s" -#: sequencer.c:3441 +#: sequencer.c:3492 #, c-format msgid "%s: not a valid OID" msgstr "%s không phải là má»™t OID hợp lệ" -#: sequencer.c:3446 git-rebase--preserve-merges.sh:724 +#: sequencer.c:3497 git-rebase--preserve-merges.sh:724 msgid "could not detach HEAD" msgstr "không thể tách rá»i HEAD" -#: sequencer.c:3461 +#: sequencer.c:3512 #, c-format msgid "Stopped at HEAD\n" msgstr "Dừng lại ở HEAD\n" -#: sequencer.c:3463 +#: sequencer.c:3514 #, c-format msgid "Stopped at %s\n" msgstr "Dừng lại ở %s\n" -#: sequencer.c:3471 +#: sequencer.c:3522 #, c-format msgid "" "Could not execute the todo command\n" @@ -5262,48 +5685,48 @@ msgstr "" " git rebase --edit-todo\n" " git rebase --continue\n" -#: sequencer.c:3543 +#: sequencer.c:3597 #, c-format msgid "Stopped at %s... %.*s\n" msgstr "Dừng lại ở %s… %.*s\n" -#: sequencer.c:3622 +#: sequencer.c:3677 #, c-format msgid "unknown command %d" msgstr "không hiểu câu lệnh %d" -#: sequencer.c:3667 +#: sequencer.c:3723 msgid "could not read orig-head" msgstr "không thể Ä‘á»c orig-head" -#: sequencer.c:3672 sequencer.c:4741 +#: sequencer.c:3728 sequencer.c:4805 msgid "could not read 'onto'" msgstr "không thể Ä‘á»c “ontoâ€." -#: sequencer.c:3686 +#: sequencer.c:3742 #, c-format msgid "could not update HEAD to %s" msgstr "không thể cáºp nháºt HEAD thà nh %s" -#: sequencer.c:3772 +#: sequencer.c:3831 msgid "cannot rebase: You have unstaged changes." msgstr "không thể cải tổ: Bạn có các thay đổi chÆ°a được Ä‘Æ°a lên bệ phóng." -#: sequencer.c:3781 +#: sequencer.c:3840 msgid "cannot amend non-existing commit" msgstr "không thể tu bá» má»™t lần chuyển giao không tồn tại" -#: sequencer.c:3783 +#: sequencer.c:3842 #, c-format msgid "invalid file: '%s'" msgstr "táºp tin không hợp lệ: “%sâ€" -#: sequencer.c:3785 +#: sequencer.c:3844 #, c-format msgid "invalid contents: '%s'" msgstr "ná»™i dung không hợp lệ: “%sâ€" -#: sequencer.c:3788 +#: sequencer.c:3847 msgid "" "\n" "You have uncommitted changes in your working tree. Please, commit them\n" @@ -5313,54 +5736,54 @@ msgstr "" "Bạn có các thay đổi chÆ°a chuyển giao trong thÆ° mục là m việc. Vui lòng\n" "chuyển giao chúng trÆ°á»›c và sau đó chạy lệnh “git rebase --continue†lần nữa." -#: sequencer.c:3824 sequencer.c:3862 +#: sequencer.c:3883 sequencer.c:3921 #, c-format msgid "could not write file: '%s'" msgstr "không thể ghi táºp tin: “%sâ€" -#: sequencer.c:3877 +#: sequencer.c:3936 msgid "could not remove CHERRY_PICK_HEAD" msgstr "không thể xóa bá» CHERRY_PICK_HEAD" -#: sequencer.c:3884 +#: sequencer.c:3943 msgid "could not commit staged changes." msgstr "không thể chuyển giao các thay đổi đã Ä‘Æ°a lên bệ phóng." -#: sequencer.c:3982 +#: sequencer.c:4044 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: không thể cherry-pick má»™t %s" -#: sequencer.c:3986 +#: sequencer.c:4048 #, c-format msgid "%s: bad revision" msgstr "%s: Ä‘iểm xét duyệt sai" -#: sequencer.c:4021 +#: sequencer.c:4083 msgid "can't revert as initial commit" msgstr "không thể hoà n nguyên má»™t lần chuyển giao khởi tạo" -#: sequencer.c:4466 +#: sequencer.c:4529 msgid "make_script: unhandled options" msgstr "make_script: các tùy chá»n được không xá» lý" -#: sequencer.c:4469 +#: sequencer.c:4532 msgid "make_script: error preparing revisions" msgstr "make_script: lá»—i chuẩn bị Ä‘iểm hiệu chỉnh" -#: sequencer.c:4509 sequencer.c:4565 sequencer.c:4840 +#: sequencer.c:4573 sequencer.c:4629 sequencer.c:4904 #, c-format msgid "unusable todo list: '%s'" msgstr "danh sách cần là m không dùng được: “%sâ€" -#: sequencer.c:4620 +#: sequencer.c:4684 #, c-format msgid "" "unrecognized setting %s for option rebase.missingCommitsCheck. Ignoring." msgstr "" "không nháºn ra cà i đặt %s cho tùy chá»n rebase.missingCommitsCheck. Nên bá» qua." -#: sequencer.c:4690 +#: sequencer.c:4754 #, c-format msgid "" "Warning: some commits may have been dropped accidentally.\n" @@ -5369,7 +5792,7 @@ msgstr "" "Cảnh báo: má»™t số lần chuyển giao có lẽ đã bị xóa má»™t cách tình cá».\n" "Các lần chuyển giao bị xóa (từ má»›i đến cÅ©):\n" -#: sequencer.c:4697 +#: sequencer.c:4761 #, c-format msgid "" "To avoid this message, use \"drop\" to explicitly remove a commit.\n" @@ -5387,7 +5810,7 @@ msgstr "" "Cánh ứng xá» có thể là : ignore, warn, error.\n" "\n" -#: sequencer.c:4710 +#: sequencer.c:4774 #, c-format msgid "" "You can fix this with 'git rebase --edit-todo' and then run 'git rebase --" @@ -5398,30 +5821,30 @@ msgstr "" "continueâ€.\n" "Hoặc là bạn có thể bãi bá» việc cải tổ bằng “git rebase --abortâ€.\n" -#: sequencer.c:4848 sequencer.c:4886 +#: sequencer.c:4912 sequencer.c:4950 msgid "nothing to do" msgstr "không có gì để là m" -#: sequencer.c:4852 +#: sequencer.c:4916 #, c-format msgid "Rebase %s onto %s (%d command)" msgid_plural "Rebase %s onto %s (%d commands)" msgstr[0] "Cải tổ %s và o %s (%d lệnh )" -#: sequencer.c:4864 +#: sequencer.c:4928 #, c-format msgid "could not copy '%s' to '%s'." msgstr "không thể chép “%s†sang “%sâ€." -#: sequencer.c:4868 sequencer.c:4897 +#: sequencer.c:4932 sequencer.c:4961 msgid "could not transform the todo list" msgstr "không thể chuyển dạng danh sách cần là m" -#: sequencer.c:4900 +#: sequencer.c:4964 msgid "could not skip unnecessary pick commands" msgstr "không thể bá» qua các lệnh cáºy (pick) không cần thiết" -#: sequencer.c:4983 +#: sequencer.c:5047 msgid "the script was already rearranged." msgstr "văn lệnh đã sẵn được sắp đặt rồi." @@ -5470,7 +5893,7 @@ msgstr "" #: setup.c:389 msgid "unable to set up work tree using invalid config" -msgstr "Không thể đặt thÆ° mục là m việc hiện hà nh sá» dụng cấu hình không hợp lệ" +msgstr "không thể cà i đặt thÆ° mục là m việc sá» dụng cấu hình không hợp lệ" #: setup.c:393 msgid "this operation must be run in a work tree" @@ -5513,7 +5936,7 @@ msgstr "không có Ä‘Æ°á»ng dẫn trong táºp tin git: %s" #: setup.c:564 #, c-format msgid "not a git repository: %s" -msgstr "Không phải là kho git: %s" +msgstr "không phải là kho git: %s" #: setup.c:663 #, c-format @@ -5530,30 +5953,30 @@ msgstr "không phải là kho git: “%sâ€" msgid "cannot chdir to '%s'" msgstr "không thể chdir (chuyển đổi thÆ° mục) sang “%sâ€" -#: setup.c:711 setup.c:767 setup.c:777 setup.c:816 setup.c:824 setup.c:839 +#: setup.c:711 setup.c:767 setup.c:777 setup.c:816 setup.c:824 msgid "cannot come back to cwd" msgstr "không thể quay lại cwd" -#: setup.c:837 -#, c-format -msgid "not a git repository (or any of the parent directories): %s" -msgstr "không phải là kho git (hoặc bất kỳ thÆ° mục cha mẹ nà o): %s" - -#: setup.c:848 +#: setup.c:838 #, c-format msgid "failed to stat '%*s%s%s'" msgstr "gặp lá»—i khi lấy thống kê vỠ“%*s%s%sâ€" -#: setup.c:1078 +#: setup.c:1068 msgid "Unable to read current working directory" msgstr "Không thể Ä‘á»c thÆ° mục là m việc hiện hà nh" -#: setup.c:1090 setup.c:1096 +#: setup.c:1077 setup.c:1083 #, c-format msgid "cannot change to '%s'" msgstr "không thể chuyển sang “%sâ€" -#: setup.c:1109 +#: setup.c:1088 +#, c-format +msgid "not a git repository (or any of the parent directories): %s" +msgstr "không phải là kho git (hoặc bất kỳ thÆ° mục cha mẹ nà o): %s" + +#: setup.c:1094 #, c-format msgid "" "not a git repository (or any parent up to mount point %s)\n" @@ -5563,7 +5986,7 @@ msgstr "" "Dừng tại biên của hệ thống táºp tin (GIT_DISCOVERY_ACROSS_FILESYSTEM chÆ°a " "đặt)." -#: setup.c:1192 +#: setup.c:1204 #, c-format msgid "" "problem with core.sharedRepository filemode value (0%.3o).\n" @@ -5572,279 +5995,279 @@ msgstr "" "gặp vấn Ä‘á» vá»›i giá trị chế Ä‘á»™ táºp tin core.sharedRepository (0%.3o).\n" "ngÆ°á»i sở hữu táºp tin phải luôn có quyá»n Ä‘á»c và ghi." -#: setup.c:1235 +#: setup.c:1247 msgid "open /dev/null or dup failed" msgstr "gặp lá»—i khi mở “/dev/null†hay dup" -#: setup.c:1250 +#: setup.c:1262 msgid "fork failed" msgstr "gặp lá»—i khi rẽ nhánh tiến trình" -#: setup.c:1255 +#: setup.c:1267 msgid "setsid failed" msgstr "setsid gặp lá»—i" -#: sha1-file.c:381 +#: sha1-file.c:445 #, 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" -#: sha1-file.c:432 +#: sha1-file.c:496 #, 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â€" -#: sha1-file.c:503 +#: sha1-file.c:568 #, 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" -#: sha1-file.c:510 +#: sha1-file.c:575 #, c-format msgid "unable to normalize object directory: %s" msgstr "không thể chuẩn hóa thÆ° mục đối tượng: “%sâ€" -#: sha1-file.c:565 +#: sha1-file.c:618 msgid "unable to fdopen alternates lockfile" msgstr "không thể fdopen táºp tin khóa thay thế" -#: sha1-file.c:583 +#: sha1-file.c:636 msgid "unable to read alternates file" msgstr "không thể Ä‘á»c táºp tin thay thế" -#: sha1-file.c:590 +#: sha1-file.c:643 msgid "unable to move new alternates file into place" msgstr "không thể di chuyển táºp tin thay thế và o chá»—" -#: sha1-file.c:625 +#: sha1-file.c:678 #, c-format msgid "path '%s' does not exist" msgstr "Ä‘Æ°á»ng dẫn “%s†không tồn tại" -#: sha1-file.c:651 +#: sha1-file.c:704 #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "kho tham chiếu “%s†nhÆ° là lấy ra liên kết vẫn chÆ°a được há»— trợ." -#: sha1-file.c:657 +#: sha1-file.c:710 #, 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á»™." -#: sha1-file.c:663 +#: sha1-file.c:716 #, c-format msgid "reference repository '%s' is shallow" msgstr "kho tham chiếu “%s†là nông" -#: sha1-file.c:671 +#: sha1-file.c:724 #, c-format msgid "reference repository '%s' is grafted" msgstr "kho tham chiếu “%s†bị cấy ghép" -#: sha1-file.c:781 +#: sha1-file.c:838 #, c-format msgid "attempting to mmap %<PRIuMAX> over limit %<PRIuMAX>" msgstr "Ä‘ang cố để mmap %<PRIuMAX> vượt quá giá»›i hạn %<PRIuMAX>" -#: sha1-file.c:806 +#: sha1-file.c:863 msgid "mmap failed" msgstr "mmap gặp lá»—i" -#: sha1-file.c:973 +#: sha1-file.c:1027 #, c-format msgid "object file %s is empty" msgstr "táºp tin đối tượng %s trống rá»—ng" -#: sha1-file.c:1093 sha1-file.c:2215 +#: sha1-file.c:1151 sha1-file.c:2288 #, c-format msgid "corrupt loose object '%s'" msgstr "đối tượng mất há»ng “%sâ€" -#: sha1-file.c:1095 sha1-file.c:2219 +#: sha1-file.c:1153 sha1-file.c:2292 #, c-format msgid "garbage at end of loose object '%s'" msgstr "gặp rác tại cuối của đối tượng bị mất “%sâ€" -#: sha1-file.c:1137 +#: sha1-file.c:1195 msgid "invalid object type" msgstr "kiểu đối tượng không hợp lệ" -#: sha1-file.c:1219 +#: sha1-file.c:1279 #, c-format msgid "unable to unpack %s header with --allow-unknown-type" msgstr "không thể giải nén phần đầu gói %s vá»›i --allow-unknown-type" -#: sha1-file.c:1222 +#: sha1-file.c:1282 #, c-format msgid "unable to unpack %s header" msgstr "không thể giải gói phần đầu %s" -#: sha1-file.c:1228 +#: sha1-file.c:1288 #, c-format msgid "unable to parse %s header with --allow-unknown-type" msgstr "không thể phân tÃch phần đầu gói %s vá»›i --allow-unknown-type" -#: sha1-file.c:1231 +#: sha1-file.c:1291 #, c-format msgid "unable to parse %s header" msgstr "không thể phân tÃch phần đầu của “%sâ€" -#: sha1-file.c:1422 +#: sha1-file.c:1481 #, c-format msgid "failed to read object %s" msgstr "gặp lá»—i khi Ä‘á»c đối tượng “%sâ€" -#: sha1-file.c:1426 +#: sha1-file.c:1485 #, c-format msgid "replacement %s not found for %s" msgstr "c%s thay thế không được tìm thấy cho %s" -#: sha1-file.c:1430 +#: sha1-file.c:1489 #, c-format msgid "loose object %s (stored in %s) is corrupt" msgstr "đối tượng mất %s (được lÆ°u trong %s) bị há»ng" -#: sha1-file.c:1434 +#: sha1-file.c:1493 #, 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" -#: sha1-file.c:1536 +#: sha1-file.c:1595 #, c-format -msgid "unable to write sha1 filename %s" -msgstr "không thể ghi và o tên táºp tin sha1 %s" +msgid "unable to write file %s" +msgstr "không thể ghi táºp tin %s" -#: sha1-file.c:1543 +#: sha1-file.c:1602 #, c-format msgid "unable to set permission to '%s'" msgstr "không thể đặt quyá»n thà nh “%sâ€" -#: sha1-file.c:1550 +#: sha1-file.c:1609 msgid "file write error" msgstr "lá»—i ghi táºp tin" -#: sha1-file.c:1569 -msgid "error when closing sha1 file" -msgstr "gặp lá»—i trong khi đóng táºp tin sha1" +#: sha1-file.c:1628 +msgid "error when closing loose object file" +msgstr "gặp lá»—i trong khi đóng táºp tin đối tượng" -#: sha1-file.c:1635 +#: sha1-file.c:1693 #, c-format msgid "insufficient permission for adding an object to repository database %s" msgstr "" "không đủ thẩm quyá»n để thêm má»™t đối tượng và o cÆ¡ sở dữ liệu kho chứa %s" -#: sha1-file.c:1637 +#: sha1-file.c:1695 msgid "unable to create temporary file" msgstr "không thể tạo táºp tin tạm thá»i" -#: sha1-file.c:1661 -msgid "unable to write sha1 file" -msgstr "không thể ghi và o táºp tin sha1" +#: sha1-file.c:1719 +msgid "unable to write loose object file" +msgstr "không thể ghi táºp tin đối tượng đã mất" -#: sha1-file.c:1667 +#: sha1-file.c:1725 #, c-format msgid "unable to deflate new object %s (%d)" msgstr "không thể xả nén đối tượng má»›i %s (%d)" -#: sha1-file.c:1671 +#: sha1-file.c:1729 #, c-format msgid "deflateEnd on object %s failed (%d)" msgstr "deflateEnd trên đối tượng %s gặp lá»—i (%d)" -#: sha1-file.c:1675 +#: sha1-file.c:1733 #, c-format msgid "confused by unstable object source data for %s" msgstr "chÆ°a rõ rà ng baowir dữ liệu nguồn đối tượng không ổn định cho %s" -#: sha1-file.c:1685 builtin/pack-objects.c:918 +#: sha1-file.c:1743 builtin/pack-objects.c:919 #, c-format msgid "failed utime() on %s" msgstr "gặp lá»—i utime() trên “%sâ€" -#: sha1-file.c:1760 +#: sha1-file.c:1818 #, c-format -msgid "cannot read sha1_file for %s" -msgstr "không thể Ä‘á»c sha1_file cho %s" +msgid "cannot read object for %s" +msgstr "không thể Ä‘á»c đối tượng cho %s" -#: sha1-file.c:1805 +#: sha1-file.c:1858 msgid "corrupt commit" msgstr "lần chuyển giao sai há»ng" -#: sha1-file.c:1813 +#: sha1-file.c:1866 msgid "corrupt tag" msgstr "thẻ sai há»ng" -#: sha1-file.c:1912 +#: sha1-file.c:1965 #, c-format msgid "read error while indexing %s" msgstr "gặp lá»—i Ä‘á»c khi đánh mục lục %s" -#: sha1-file.c:1915 +#: sha1-file.c:1968 #, c-format msgid "short read while indexing %s" msgstr "không Ä‘á»c ngắn khi đánh mục lục %s" -#: sha1-file.c:1988 sha1-file.c:1997 +#: sha1-file.c:2041 sha1-file.c:2050 #, c-format msgid "%s: failed to insert into database" msgstr "%s: gặp lá»—i khi thêm và o cÆ¡ sở dữ liệu" -#: sha1-file.c:2003 +#: sha1-file.c:2056 #, c-format msgid "%s: unsupported file type" msgstr "%s: kiểu táºp tin không được há»— trợ" -#: sha1-file.c:2027 +#: sha1-file.c:2080 #, c-format msgid "%s is not a valid object" msgstr "%s không phải là má»™t đối tượng hợp lệ" -#: sha1-file.c:2029 +#: sha1-file.c:2082 #, 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ệ" -#: sha1-file.c:2056 builtin/index-pack.c:154 +#: sha1-file.c:2109 builtin/index-pack.c:154 #, c-format msgid "unable to open %s" msgstr "không thể mở %s" -#: sha1-file.c:2226 sha1-file.c:2278 +#: sha1-file.c:2299 sha1-file.c:2351 #, c-format -msgid "sha1 mismatch for %s (expected %s)" -msgstr "sha1 không khá»›p cho %s (cần %s)" +msgid "hash mismatch for %s (expected %s)" +msgstr "mã băm không khá»›p cho %s (cần %s)" -#: sha1-file.c:2250 +#: sha1-file.c:2323 #, c-format msgid "unable to mmap %s" msgstr "không thể mmap %s" -#: sha1-file.c:2255 +#: sha1-file.c:2328 #, c-format msgid "unable to unpack header of %s" msgstr "không thể giải gói phần đầu của “%sâ€" -#: sha1-file.c:2261 +#: sha1-file.c:2334 #, c-format msgid "unable to parse header of %s" msgstr "không thể phân tÃch phần đầu của “%sâ€" -#: sha1-file.c:2272 +#: sha1-file.c:2345 #, c-format msgid "unable to unpack contents of %s" msgstr "không thể giải gói ná»™i dung của “%sâ€" -#: sha1-name.c:476 +#: sha1-name.c:448 #, c-format msgid "short SHA1 %s is ambiguous" msgstr "tóm lược SHA1 %s chÆ°a rõ rà ng" -#: sha1-name.c:487 +#: sha1-name.c:459 msgid "The candidates are:" msgstr "Các ứng cá» là :" -#: sha1-name.c:770 +#: sha1-name.c:742 msgid "" "Git normally never creates a ref that ends with 40 hex characters\n" "because it will be ignored when you just specify 40-hex. These refs\n" @@ -5868,72 +6291,82 @@ msgstr "" "nà y\n" "bằng cách chạy lệnh \"git config advice.objectNameWarning false\"" -#: submodule.c:116 submodule.c:145 +#: submodule.c:114 submodule.c:143 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" msgstr "" "Không thể thay đổi .gitmodules chÆ°a hòa trá»™n, hãy giải quyết xung Ä‘á»™t trá»™n " "trÆ°á»›c" -#: submodule.c:120 submodule.c:149 +#: submodule.c:118 submodule.c:147 #, c-format msgid "Could not find section in .gitmodules where path=%s" msgstr "Không thể tìm thấy phần trong .gitmodules nÆ¡i mà đưá»ng_dẫn=%s" -#: submodule.c:156 +#: submodule.c:154 #, c-format msgid "Could not remove .gitmodules entry for %s" msgstr "Không thể gỡ bá» mục .gitmodules dà nh cho %s" -#: submodule.c:167 +#: submodule.c:165 msgid "staging updated .gitmodules failed" msgstr "gặp lá»—i khi tổ chức .gitmodules đã cáºp nháºt" -#: submodule.c:329 +#: submodule.c:327 #, c-format msgid "in unpopulated submodule '%s'" -msgstr "Trong mô-Ä‘un-con không có gì “%sâ€" +msgstr "trong mô-Ä‘un-con không có gì “%sâ€" -#: submodule.c:360 +#: submodule.c:358 #, c-format msgid "Pathspec '%s' is in submodule '%.*s'" msgstr "Äặc tả Ä‘Æ°á»ng dẫn “%s†thì ở trong mô-Ä‘un-con “%.*sâ€" -#: submodule.c:857 +#: submodule.c:906 #, c-format msgid "submodule entry '%s' (%s) is a %s, not a commit" msgstr "" "mục tin mô-Ä‘un-con “%s†(%s) là má»™t %s, không phải là má»™t lần chuyển giao" -#: submodule.c:1097 builtin/branch.c:656 builtin/submodule--helper.c:1985 +#: submodule.c:1143 builtin/branch.c:656 builtin/submodule--helper.c:1989 msgid "Failed to resolve HEAD as a valid ref." msgstr "Gặp lá»—i khi phân giải HEAD nhÆ° là má»™t tham chiếu hợp lệ." -#: submodule.c:1404 +#: submodule.c:1477 +#, c-format +msgid "Could not access submodule '%s'" +msgstr "Không thể truy cáºp mô-Ä‘un-con “%sâ€" + +#: submodule.c:1639 #, c-format msgid "'%s' not recognized as a git repository" msgstr "không nháºn ra “%s†là má»™t kho git" -#: submodule.c:1542 +#: submodule.c:1777 #, c-format msgid "could not start 'git status' in submodule '%s'" msgstr "không thể lấy thống kê “git status†trong mô-Ä‘un-con “%sâ€" -#: submodule.c:1555 +#: submodule.c:1790 #, c-format msgid "could not run 'git status' in submodule '%s'" msgstr "không thể chạy “git status†trong mô-Ä‘un-con “%sâ€" -#: submodule.c:1648 +#: submodule.c:1805 +#, c-format +msgid "Could not unset core.worktree setting in submodule '%s'" +msgstr "Không thể đặt core.worktree trong mô-Ä‘un-con “%sâ€" + +#: submodule.c:1895 #, c-format msgid "submodule '%s' has dirty index" msgstr "mô-Ä‘un-con “%s†có mục lục còn bẩn" -#: submodule.c:1700 +#: submodule.c:1947 #, c-format msgid "Submodule '%s' could not be updated." msgstr "Mô-Ä‘un-con “%s†không thể được cáºp nháºt." -#: submodule.c:1747 +#: submodule.c:1996 #, c-format msgid "" "relocate_gitdir for submodule '%s' with more than one worktree not supported" @@ -5941,12 +6374,12 @@ msgstr "" "relocate_gitdir cho mô-Ä‘un-con “%s†vá»›i nhiá»u hÆ¡n má»™t cây là m việc là chÆ°a " "được há»— trợ" -#: submodule.c:1759 submodule.c:1815 +#: submodule.c:2008 submodule.c:2064 #, c-format msgid "could not lookup name for submodule '%s'" msgstr "không thể tìm kiếm tên cho mô-Ä‘un-con “%sâ€" -#: submodule.c:1766 +#: submodule.c:2015 #, c-format msgid "" "Migrating git directory of '%s%s' from\n" @@ -5957,16 +6390,16 @@ msgstr "" "“%s†sang\n" "“%sâ€\n" -#: submodule.c:1850 +#: submodule.c:2099 #, c-format msgid "could not recurse into submodule '%s'" msgstr "không thể đệ quy và o trong mô-Ä‘un-con “%sâ€" -#: submodule.c:1894 +#: submodule.c:2143 msgid "could not start ls-files in .." msgstr "không thể lấy thông tin thống kê vá» ls-files trong .." -#: submodule.c:1933 +#: submodule.c:2182 #, c-format msgid "ls-tree returned unexpected return code %d" msgstr "ls-tree trả vá» mã không nhÆ° mong đợi %d" @@ -6027,7 +6460,7 @@ msgstr "không Ä‘á»c được táºp tin đầu và o “%sâ€" msgid "could not read from stdin" msgstr "không thể Ä‘á»c từ đầu và o tiêu chuẩn" -#: trailer.c:1011 builtin/am.c:47 +#: trailer.c:1011 wrapper.c:701 #, c-format msgid "could not stat %s" msgstr "không thể lấy thông tin thống kê vá» %s" @@ -6066,29 +6499,29 @@ msgstr "không thể Ä‘á»c bó “%sâ€" msgid "transport: invalid depth option '%s'" msgstr "váºn chuyển: tùy chá»n Ä‘á»™ sâu “%s†không hợp lệ" -#: transport.c:616 +#: transport.c:617 msgid "could not parse transport.color.* config" msgstr "không thể phân tÃch cú pháp cấu hình transport.color.*" -#: transport.c:689 +#: transport.c:690 msgid "support for protocol v2 not implemented yet" msgstr "việc há»— trợ giao thức v2 chÆ°a được thá»±c hiện" -#: transport.c:816 +#: transport.c:817 #, c-format msgid "unknown value for config '%s': %s" msgstr "không hiểu giá trị cho cho cấu hình “%sâ€: %s" -#: transport.c:882 +#: transport.c:883 #, c-format msgid "transport '%s' not allowed" msgstr "không cho phép phÆ°Æ¡ng thức váºn chuyển “%sâ€" -#: transport.c:936 +#: transport.c:937 msgid "git-over-rsync is no longer supported" msgstr "git-over-rsync không còn được há»— trợ nữa" -#: transport.c:1031 +#: transport.c:1032 #, c-format msgid "" "The following submodule paths contain changes that can\n" @@ -6097,7 +6530,7 @@ msgstr "" "Các Ä‘Æ°á»ng dẫn mô-Ä‘un-con sau đây có chứa các thay đổi cái mà \n" "có thể được tìm thấy trên má»i máy phục vụ:\n" -#: transport.c:1035 +#: transport.c:1036 #, c-format msgid "" "\n" @@ -6124,19 +6557,19 @@ msgstr "" "để đẩy chúng lên máy phục vụ.\n" "\n" -#: transport.c:1043 +#: transport.c:1044 msgid "Aborting." msgstr "Bãi bá»." -#: transport.c:1182 +#: transport.c:1184 msgid "failed to push all needed submodules" msgstr "gặp lá»—i khi đẩy dữ liệu của tất cả các mô-Ä‘un-con cần thiết" -#: transport.c:1315 transport-helper.c:643 +#: transport.c:1317 transport-helper.c:643 msgid "operation not supported by protocol" msgstr "thao tác không được gia thức há»— trợ" -#: transport.c:1419 +#: transport.c:1421 #, c-format msgid "invalid line while parsing alternate refs: %s" msgstr "dòng không hợp lệ trong khi phân tÃch các tham chiếu thay thế: %s" @@ -6185,7 +6618,7 @@ msgstr "không thể chạy fast-import" msgid "error while running fast-import" msgstr "gặp lá»—i trong khi chạy fast-import" -#: transport-helper.c:531 transport-helper.c:1091 +#: transport-helper.c:531 transport-helper.c:1097 #, c-format msgid "could not read ref %s" msgstr "không thể Ä‘á»c tham chiếu %s" @@ -6208,54 +6641,54 @@ msgstr "Ä‘Æ°á»ng dẫn dịch vụ máy chủ không hợp lệ" msgid "can't connect to subservice %s" msgstr "không thể kết nối đến dịch vụ phụ %s" -#: transport-helper.c:713 +#: transport-helper.c:718 #, c-format msgid "expected ok/error, helper said '%s'" msgstr "cần ok/error, nhÆ°ng bá»™ há»— trợ lại nói “%sâ€" -#: transport-helper.c:766 +#: transport-helper.c:771 #, c-format msgid "helper reported unexpected status of %s" msgstr "bá»™ há»— trợ báo cáo rằng không cần tình trạng của %s" -#: transport-helper.c:827 +#: transport-helper.c:832 #, c-format msgid "helper %s does not support dry-run" msgstr "helper %s không há»— trợ dry-run" -#: transport-helper.c:830 +#: transport-helper.c:835 #, c-format msgid "helper %s does not support --signed" msgstr "helper %s không há»— trợ --signed" -#: transport-helper.c:833 +#: transport-helper.c:838 #, c-format msgid "helper %s does not support --signed=if-asked" msgstr "helper %s không há»— trợ --signed=if-asked" -#: transport-helper.c:840 +#: transport-helper.c:845 #, c-format msgid "helper %s does not support 'push-option'" msgstr "helper %s không há»— trợ “push-optionâ€" -#: transport-helper.c:932 +#: transport-helper.c:937 msgid "remote-helper doesn't support push; refspec needed" msgstr "remote-helper không há»— trợ push; cần đặc tả tham chiếu" -#: transport-helper.c:937 +#: transport-helper.c:942 #, c-format msgid "helper %s does not support 'force'" msgstr "helper %s không há»— trợ “forceâ€" -#: transport-helper.c:984 +#: transport-helper.c:989 msgid "couldn't run fast-export" msgstr "không thể chạy fast-export" -#: transport-helper.c:989 +#: transport-helper.c:994 msgid "error while running fast-export" msgstr "gặp lá»—i trong khi chạy fast-export" -#: transport-helper.c:1014 +#: transport-helper.c:1019 #, c-format msgid "" "No refs in common and none specified; doing nothing.\n" @@ -6265,47 +6698,47 @@ msgstr "" "cả.\n" "Tuy nhiên bạn nên chỉ định má»™t nhánh nhÆ° “master†chẳng hạn.\n" -#: transport-helper.c:1077 +#: transport-helper.c:1083 #, c-format msgid "malformed response in ref list: %s" msgstr "đáp ứng sai dạng trong danh sách tham chiếu: %s" -#: transport-helper.c:1231 +#: transport-helper.c:1236 #, c-format msgid "read(%s) failed" msgstr "read(%s) gặp lá»—i" -#: transport-helper.c:1258 +#: transport-helper.c:1263 #, c-format msgid "write(%s) failed" msgstr "write(%s) gặp lá»—i" -#: transport-helper.c:1307 +#: transport-helper.c:1312 #, c-format msgid "%s thread failed" msgstr "tuyến trình %s gặp lá»—i" -#: transport-helper.c:1311 +#: transport-helper.c:1316 #, c-format msgid "%s thread failed to join: %s" msgstr "tuyến trình %s gặp lá»—i khi gia nháºp: %s" -#: transport-helper.c:1330 transport-helper.c:1334 +#: transport-helper.c:1335 transport-helper.c:1339 #, c-format msgid "can't start thread for copying data: %s" msgstr "không thể khởi chạy tuyến trình để sao chép dữ liệu: %s" -#: transport-helper.c:1371 +#: transport-helper.c:1376 #, c-format msgid "%s process failed to wait" msgstr "xá» lý %s gặp lá»—i khi đợi" -#: transport-helper.c:1375 +#: transport-helper.c:1380 #, c-format msgid "%s process failed" msgstr "xá» lý %s gặp lá»—i" -#: transport-helper.c:1393 transport-helper.c:1402 +#: transport-helper.c:1398 transport-helper.c:1407 msgid "can't start thread for copying data" msgstr "không thể khởi chạy tuyến trình cho việc chép dữ liệu" @@ -6321,11 +6754,11 @@ msgstr "chế Ä‘á»™ dị hình trong Ä‘á» mục cây" msgid "empty filename in tree entry" msgstr "tên táºp tin trống rá»—ng trong mục tin cây" -#: tree-walk.c:115 +#: tree-walk.c:116 msgid "too-short tree file" msgstr "táºp tin cây quá ngắn" -#: unpack-trees.c:112 +#: unpack-trees.c:111 #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -6336,7 +6769,7 @@ msgstr "" "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng Ä‘i trÆ°á»›c khi bạn " "chuyển nhánh." -#: unpack-trees.c:114 +#: unpack-trees.c:113 #, c-format msgid "" "Your local changes to the following files would be overwritten by checkout:\n" @@ -6346,7 +6779,7 @@ msgstr "" "checkout:\n" "%%s" -#: unpack-trees.c:117 +#: unpack-trees.c:116 #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -6357,7 +6790,7 @@ msgstr "" "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng Ä‘i trÆ°á»›c khi bạn hòa " "trá»™n." -#: unpack-trees.c:119 +#: unpack-trees.c:118 #, c-format msgid "" "Your local changes to the following files would be overwritten by merge:\n" @@ -6367,7 +6800,7 @@ msgstr "" "hòa trá»™n:\n" "%%s" -#: unpack-trees.c:122 +#: unpack-trees.c:121 #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -6377,7 +6810,7 @@ msgstr "" "%s:\n" "%%sVui lòng chuyển giao các thay đổi hay tạm cất chúng Ä‘i trÆ°á»›c khi bạn %s." -#: unpack-trees.c:124 +#: unpack-trees.c:123 #, c-format msgid "" "Your local changes to the following files would be overwritten by %s:\n" @@ -6387,7 +6820,7 @@ msgstr "" "%s:\n" "%%s" -#: unpack-trees.c:129 +#: unpack-trees.c:128 #, c-format msgid "" "Updating the following directories would lose untracked files in them:\n" @@ -6397,7 +6830,7 @@ msgstr "" "trong nó:\n" "%s" -#: unpack-trees.c:133 +#: unpack-trees.c:132 #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -6407,7 +6840,7 @@ msgstr "" "checkout:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn chuyển nhánh." -#: unpack-trees.c:135 +#: unpack-trees.c:134 #, c-format msgid "" "The following untracked working tree files would be removed by checkout:\n" @@ -6417,7 +6850,7 @@ msgstr "" "checkout:\n" "%%s" -#: unpack-trees.c:138 +#: unpack-trees.c:137 #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -6427,7 +6860,7 @@ msgstr "" "trá»™n:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn hòa trá»™n." -#: unpack-trees.c:140 +#: unpack-trees.c:139 #, c-format msgid "" "The following untracked working tree files would be removed by merge:\n" @@ -6437,7 +6870,7 @@ msgstr "" "trá»™n:\n" "%%s" -#: unpack-trees.c:143 +#: unpack-trees.c:142 #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -6446,7 +6879,7 @@ msgstr "" "Các táºp tin cây là m việc chÆ°a được theo dõi sau đây sẽ bị gỡ bá» bởi %s:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn %s." -#: unpack-trees.c:145 +#: unpack-trees.c:144 #, c-format msgid "" "The following untracked working tree files would be removed by %s:\n" @@ -6455,7 +6888,7 @@ msgstr "" "Các táºp tin cây là m việc chÆ°a được theo dõi sau đây sẽ bị gỡ bá» bởi %s:\n" "%%s" -#: unpack-trees.c:151 +#: unpack-trees.c:150 #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -6466,7 +6899,7 @@ msgstr "" "checkout:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn chuyển nhánh." -#: unpack-trees.c:153 +#: unpack-trees.c:152 #, c-format msgid "" "The following untracked working tree files would be overwritten by " @@ -6477,7 +6910,7 @@ msgstr "" "checkout:\n" "%%s" -#: unpack-trees.c:156 +#: unpack-trees.c:155 #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -6487,7 +6920,7 @@ msgstr "" "hòa trá»™n:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn hòa trá»™n." -#: unpack-trees.c:158 +#: unpack-trees.c:157 #, c-format msgid "" "The following untracked working tree files would be overwritten by merge:\n" @@ -6497,7 +6930,7 @@ msgstr "" "hòa trá»™n:\n" "%%s" -#: unpack-trees.c:161 +#: unpack-trees.c:160 #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -6507,7 +6940,7 @@ msgstr "" "%s:\n" "%%sVui lòng di chuyển hay gỡ bá» chúng trÆ°á»›c khi bạn %s." -#: unpack-trees.c:163 +#: unpack-trees.c:162 #, c-format msgid "" "The following untracked working tree files would be overwritten by %s:\n" @@ -6517,12 +6950,12 @@ msgstr "" "%s:\n" "%%s" -#: unpack-trees.c:171 +#: unpack-trees.c:170 #, c-format msgid "Entry '%s' overlaps with '%s'. Cannot bind." msgstr "Mục “%s†đè lên “%sâ€. Không thể buá»™c." -#: unpack-trees.c:174 +#: unpack-trees.c:173 #, c-format msgid "" "Cannot update sparse checkout: the following entries are not up to date:\n" @@ -6531,7 +6964,7 @@ msgstr "" "Không thể cáºp nháºt checkout rải rác: các mục tin sau đây chÆ°a cáºp nháºt:\n" "%s" -#: unpack-trees.c:176 +#: unpack-trees.c:175 #, c-format msgid "" "The following working tree files would be overwritten by sparse checkout " @@ -6542,7 +6975,7 @@ msgstr "" "nháºt checkout rải rác:\n" "%s" -#: unpack-trees.c:178 +#: unpack-trees.c:177 #, c-format msgid "" "The following working tree files would be removed by sparse checkout " @@ -6553,7 +6986,7 @@ msgstr "" "nháºt checkout rải rác:\n" "%s" -#: unpack-trees.c:180 +#: unpack-trees.c:179 #, c-format msgid "" "Cannot update submodule:\n" @@ -6562,16 +6995,16 @@ msgstr "" "Không thể cáºp nháºt mô-Ä‘un-con:\n" "%s" -#: unpack-trees.c:254 +#: unpack-trees.c:253 #, c-format msgid "Aborting\n" msgstr "Bãi bá»\n" -#: unpack-trees.c:336 +#: unpack-trees.c:335 msgid "Checking out files" msgstr "Äang lấy ra các táºp tin" -#: unpack-trees.c:368 +#: unpack-trees.c:367 msgid "" "the following paths have collided (e.g. case-sensitive paths\n" "on a case-insensitive filesystem) and only one from the same\n" @@ -6596,7 +7029,7 @@ msgstr "thiếu máy chủ và lược đồ thì không phải là giao thức #: urlmatch.c:232 msgid "a 'file:' URL may not have a port number" -msgstr "URL kiểu “file:†không được chứa cổng" +msgstr "má»™t URL kiểu “file:†không được chứa cổng" #: urlmatch.c:247 msgid "invalid characters in host name" @@ -6610,7 +7043,7 @@ msgstr "tên cổng không hợp lệ" msgid "invalid '..' path segment" msgstr "Ä‘oạn Ä‘Æ°á»ng dẫn “..†không hợp lệ" -#: worktree.c:249 builtin/am.c:2100 +#: worktree.c:249 builtin/am.c:2094 #, c-format msgid "failed to read '%s'" msgstr "gặp lá»—i khi Ä‘á»c “%sâ€" @@ -6653,158 +7086,158 @@ msgstr "không thể truy cáºp “%sâ€" #: wrapper.c:632 msgid "unable to get current working directory" -msgstr "Không thể lấy thÆ° mục là m việc hiện hà nh" +msgstr "không thể lấy thÆ° mục là m việc hiện hà nh" -#: wt-status.c:154 +#: wt-status.c:155 msgid "Unmerged paths:" msgstr "Những Ä‘Æ°á»ng dẫn chÆ°a được hòa trá»™n:" -#: wt-status.c:181 wt-status.c:208 +#: wt-status.c:182 wt-status.c:209 #, c-format msgid " (use \"git reset %s <file>...\" to unstage)" msgstr " (dùng \"git reset %s <táºp-tin>…\" để bá» ra khá»i bệ phóng)" -#: wt-status.c:183 wt-status.c:210 +#: wt-status.c:184 wt-status.c:211 msgid " (use \"git rm --cached <file>...\" to unstage)" msgstr " (dùng \"git rm --cached <táºp-tin>…\" để bá» ra khá»i bệ phóng)" -#: wt-status.c:187 +#: wt-status.c:188 msgid " (use \"git add <file>...\" to mark resolution)" msgstr " (dùng \"git add <táºp-tin>…\" để đánh dấu là cần giải quyết)" -#: wt-status.c:189 wt-status.c:193 +#: wt-status.c:190 wt-status.c:194 msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)" msgstr "" " (dùng \"git add/rm <táºp-tin>…\" nhÆ° là má»™t cách thÃch hợp để đánh dấu là " "cần được giải quyết)" -#: wt-status.c:191 +#: wt-status.c:192 msgid " (use \"git rm <file>...\" to mark resolution)" msgstr " (dùng \"git rm <táºp-tin>…\" để đánh dấu là cần giải quyết)" -#: wt-status.c:202 wt-status.c:1042 +#: wt-status.c:203 wt-status.c:1046 msgid "Changes to be committed:" msgstr "Những thay đổi sẽ được chuyển giao:" -#: wt-status.c:220 wt-status.c:1051 +#: wt-status.c:221 wt-status.c:1055 msgid "Changes not staged for commit:" msgstr "Các thay đổi chÆ°a được đặt lên bệ phóng để chuyển giao:" -#: wt-status.c:224 +#: wt-status.c:225 msgid " (use \"git add <file>...\" to update what will be committed)" msgstr " (dùng \"git add <táºp-tin>…\" để cáºp nháºt những gì sẽ chuyển giao)" -#: wt-status.c:226 +#: wt-status.c:227 msgid " (use \"git add/rm <file>...\" to update what will be committed)" msgstr "" " (dùng \"git add/rm <táºp-tin>…\" để cáºp nháºt những gì sẽ được chuyển giao)" -#: wt-status.c:227 +#: wt-status.c:228 msgid "" " (use \"git checkout -- <file>...\" to discard changes in working directory)" msgstr "" " (dùng \"git checkout -- <táºp-tin>…\" để loại bá» các thay đổi trong thÆ° mục " "là m việc)" -#: wt-status.c:229 +#: wt-status.c:230 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" " (chuyển giao hoặc là loại bá» các ná»™i dung chÆ°a được theo dõi hay đã sá»a " "chữa trong mô-Ä‘un-con)" -#: wt-status.c:241 +#: wt-status.c:242 #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" msgstr "" " (dùng \"git %s <táºp-tin>…\" để thêm và o những gì cần được chuyển giao)" -#: wt-status.c:256 +#: wt-status.c:257 msgid "both deleted:" msgstr "bị xóa bởi cả hai:" -#: wt-status.c:258 +#: wt-status.c:259 msgid "added by us:" msgstr "được thêm và o bởi chúng ta:" -#: wt-status.c:260 +#: wt-status.c:261 msgid "deleted by them:" msgstr "bị xóa Ä‘i bởi há»:" -#: wt-status.c:262 +#: wt-status.c:263 msgid "added by them:" msgstr "được thêm và o bởi há»:" -#: wt-status.c:264 +#: wt-status.c:265 msgid "deleted by us:" msgstr "bị xóa bởi chúng ta:" -#: wt-status.c:266 +#: wt-status.c:267 msgid "both added:" msgstr "được thêm và o bởi cả hai:" -#: wt-status.c:268 +#: wt-status.c:269 msgid "both modified:" msgstr "bị sá»a bởi cả hai:" -#: wt-status.c:278 +#: wt-status.c:279 msgid "new file:" msgstr "táºp tin má»›i:" -#: wt-status.c:280 +#: wt-status.c:281 msgid "copied:" msgstr "đã chép:" -#: wt-status.c:282 +#: wt-status.c:283 msgid "deleted:" msgstr "đã xóa:" -#: wt-status.c:284 +#: wt-status.c:285 msgid "modified:" msgstr "đã sá»a:" -#: wt-status.c:286 +#: wt-status.c:287 msgid "renamed:" msgstr "đã đổi tên:" -#: wt-status.c:288 +#: wt-status.c:289 msgid "typechange:" msgstr "đổi-kiểu:" -#: wt-status.c:290 +#: wt-status.c:291 msgid "unknown:" msgstr "không hiểu:" -#: wt-status.c:292 +#: wt-status.c:293 msgid "unmerged:" msgstr "chÆ°a hòa trá»™n:" -#: wt-status.c:372 +#: wt-status.c:373 msgid "new commits, " msgstr "lần chuyển giao má»›i, " -#: wt-status.c:374 +#: wt-status.c:375 msgid "modified content, " msgstr "ná»™i dung bị sá»a đổi, " -#: wt-status.c:376 +#: wt-status.c:377 msgid "untracked content, " msgstr "ná»™i dung chÆ°a được theo dõi, " -#: wt-status.c:880 +#: wt-status.c:884 #, c-format msgid "Your stash currently has %d entry" msgid_plural "Your stash currently has %d entries" msgstr[0] "Bạn hiện nay ở trong phần cất Ä‘i Ä‘ang có %d mục" -#: wt-status.c:912 +#: wt-status.c:916 msgid "Submodules changed but not updated:" msgstr "Những mô-Ä‘un-con đã bị thay đổi nhÆ°ng chÆ°a được cáºp nháºt:" -#: wt-status.c:914 +#: wt-status.c:918 msgid "Submodule changes to be committed:" msgstr "Những mô-Ä‘un-con thay đổi đã được chuyển giao:" -#: wt-status.c:996 +#: wt-status.c:1000 msgid "" "Do not modify or remove the line above.\n" "Everything below it will be ignored." @@ -6812,109 +7245,109 @@ msgstr "" "Không sá»a hay xóa bá» Ä‘Æ°á»ng ở trên.\n" "Má»i thứ phÃa dÆ°á»›i sẽ được xóa bá»." -#: wt-status.c:1097 +#: wt-status.c:1101 msgid "You have unmerged paths." msgstr "Bạn có những Ä‘Æ°á»ng dẫn chÆ°a được hòa trá»™n." -#: wt-status.c:1100 +#: wt-status.c:1104 msgid " (fix conflicts and run \"git commit\")" msgstr " (sá»a các xung Ä‘á»™t rồi chạy \"git commit\")" -#: wt-status.c:1102 +#: wt-status.c:1106 msgid " (use \"git merge --abort\" to abort the merge)" msgstr " (dùng \"git merge --abort\" để bãi bá» việc hòa trá»™n)" -#: wt-status.c:1106 +#: wt-status.c:1110 msgid "All conflicts fixed but you are still merging." msgstr "Tất cả các xung Ä‘á»™t đã được giải quyết nhÆ°ng bạn vẫn Ä‘ang hòa trá»™n." -#: wt-status.c:1109 +#: wt-status.c:1113 msgid " (use \"git commit\" to conclude merge)" msgstr " (dùng \"git commit\" để hoà n tất việc hòa trá»™n)" -#: wt-status.c:1118 +#: wt-status.c:1122 msgid "You are in the middle of an am session." msgstr "Bạn Ä‘ang ở giữa của má»™t phiên “amâ€." -#: wt-status.c:1121 +#: wt-status.c:1125 msgid "The current patch is empty." msgstr "Miếng vá hiện tại bị trống rá»—ng." -#: wt-status.c:1125 +#: wt-status.c:1129 msgid " (fix conflicts and then run \"git am --continue\")" msgstr " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git am --continue\")" -#: wt-status.c:1127 +#: wt-status.c:1131 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (dùng \"git am --skip\" để bá» qua miếng vá nà y)" -#: wt-status.c:1129 +#: wt-status.c:1133 msgid " (use \"git am --abort\" to restore the original branch)" msgstr " (dùng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)" -#: wt-status.c:1260 +#: wt-status.c:1264 msgid "git-rebase-todo is missing." -msgstr "thiếu git-rebase-todo" +msgstr "thiếu git-rebase-todo." -#: wt-status.c:1262 +#: wt-status.c:1266 msgid "No commands done." msgstr "Không thá»±c hiện lệnh nà o." -#: wt-status.c:1265 +#: wt-status.c:1269 #, c-format msgid "Last command done (%d command done):" msgid_plural "Last commands done (%d commands done):" msgstr[0] "Lệnh thá»±c hiện cuối (%d lệnh được thá»±c thi):" -#: wt-status.c:1276 +#: wt-status.c:1280 #, c-format msgid " (see more in file %s)" msgstr " (xem thêm trong %s)" -#: wt-status.c:1281 +#: wt-status.c:1285 msgid "No commands remaining." msgstr "Không có lệnh nà o còn lại." -#: wt-status.c:1284 +#: wt-status.c:1288 #, c-format msgid "Next command to do (%d remaining command):" msgid_plural "Next commands to do (%d remaining commands):" msgstr[0] "Lệnh cần là m kế tiếp (%d lệnh còn lại):" -#: wt-status.c:1292 +#: wt-status.c:1296 msgid " (use \"git rebase --edit-todo\" to view and edit)" msgstr " (dùng lệnh \"git rebase --edit-todo\" để xem và sá»a)" -#: wt-status.c:1304 +#: wt-status.c:1308 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc “rebase†nhánh “%s†trên “%sâ€." -#: wt-status.c:1309 +#: wt-status.c:1313 msgid "You are currently rebasing." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc “rebase†(“cải tổâ€)." -#: wt-status.c:1322 +#: wt-status.c:1326 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr "" " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh “cải tổ†\"git rebase --continue\")" -#: wt-status.c:1324 +#: wt-status.c:1328 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (dùng lệnh “cải tổ†\"git rebase --skip\" để bá» qua lần vá nà y)" -#: wt-status.c:1326 +#: wt-status.c:1330 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" " (dùng lệnh “cải tổ†\"git rebase --abort\" để check-out nhánh nguyên thủy)" -#: wt-status.c:1333 +#: wt-status.c:1337 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr "" " (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh “cải tổ†\"git rebase --" "continue\")" -#: wt-status.c:1337 +#: wt-status.c:1341 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -6922,134 +7355,134 @@ msgstr "" "Bạn hiện nay Ä‘ang thá»±c hiện việc chia tách má»™t lần chuyển giao trong khi " "Ä‘ang “rebase†nhánh “%s†trên “%sâ€." -#: wt-status.c:1342 +#: wt-status.c:1346 msgid "You are currently splitting a commit during a rebase." msgstr "" "Bạn hiện tại Ä‘ang cắt đôi má»™t lần chuyển giao trong khi Ä‘ang thá»±c hiện việc " "rebase." -#: wt-status.c:1345 +#: wt-status.c:1349 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (Má»™t khi thÆ° mục là m việc của bạn đã gá»n gà ng, chạy lệnh “cải tổ†\"git " "rebase --continue\")" -#: wt-status.c:1349 +#: wt-status.c:1353 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Bạn hiện nay Ä‘ang thá»±c hiện việc sá»a chữa má»™t lần chuyển giao trong khi Ä‘ang " "rebase nhánh “%s†trên “%sâ€." -#: wt-status.c:1354 +#: wt-status.c:1358 msgid "You are currently editing a commit during a rebase." msgstr "Bạn hiện Ä‘ang sá»a má»™t lần chuyển giao trong khi bạn thá»±c hiện rebase." -#: wt-status.c:1357 +#: wt-status.c:1361 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr " (dùng \"git commit --amend\" để “tu bổ†lần chuyển giao hiện tại)" -#: wt-status.c:1359 +#: wt-status.c:1363 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (chạy lệnh “cải tổ†\"git rebase --continue\" má»™t khi bạn cảm thấy hà i " "lòng vá» những thay đổi của mình)" -#: wt-status.c:1368 +#: wt-status.c:1372 #, c-format msgid "You are currently cherry-picking commit %s." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc cherry-pick lần chuyển giao %s." -#: wt-status.c:1373 +#: wt-status.c:1377 msgid " (fix conflicts and run \"git cherry-pick --continue\")" msgstr "" " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git cherry-pick --continue\")" -#: wt-status.c:1376 +#: wt-status.c:1380 msgid " (all conflicts fixed: run \"git cherry-pick --continue\")" msgstr "" " (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh \"git cherry-pick --" "continue\")" -#: wt-status.c:1378 +#: wt-status.c:1382 msgid " (use \"git cherry-pick --abort\" to cancel the cherry-pick operation)" msgstr " (dùng \"git cherry-pick --abort\" để hủy bá» thao tác cherry-pick)" -#: wt-status.c:1386 +#: wt-status.c:1390 #, c-format msgid "You are currently reverting commit %s." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện thao tác hoà n nguyên lần chuyển giao “%sâ€." -#: wt-status.c:1391 +#: wt-status.c:1395 msgid " (fix conflicts and run \"git revert --continue\")" msgstr " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git revert --continue\")" -#: wt-status.c:1394 +#: wt-status.c:1398 msgid " (all conflicts fixed: run \"git revert --continue\")" msgstr "" " (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh \"git revert --continue\")" -#: wt-status.c:1396 +#: wt-status.c:1400 msgid " (use \"git revert --abort\" to cancel the revert operation)" msgstr " (dùng \"git revert --abort\" để hủy bá» thao tác hoà n nguyên)" -#: wt-status.c:1406 +#: wt-status.c:1410 #, c-format msgid "You are currently bisecting, started from branch '%s'." msgstr "" "Bạn hiện nay Ä‘ang thá»±c hiện thao tác di chuyển ná»a bÆ°á»›c (bisect), bắt đầu từ " "nhánh “%sâ€." -#: wt-status.c:1410 +#: wt-status.c:1414 msgid "You are currently bisecting." msgstr "Bạn hiện tại Ä‘ang thá»±c hiện việc bisect (di chuyển ná»a bÆ°á»›c)." -#: wt-status.c:1413 +#: wt-status.c:1417 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr " (dùng \"git bisect reset\" để quay trở lại nhánh nguyên thủy)" -#: wt-status.c:1611 +#: wt-status.c:1617 msgid "On branch " msgstr "Trên nhánh " -#: wt-status.c:1618 +#: wt-status.c:1624 msgid "interactive rebase in progress; onto " msgstr "rebase ở chế Ä‘á»™ tÆ°Æ¡ng tác Ä‘ang được thá»±c hiện; lên trên " -#: wt-status.c:1620 +#: wt-status.c:1626 msgid "rebase in progress; onto " msgstr "rebase Ä‘ang được thá»±c hiện: lên trên " -#: wt-status.c:1625 +#: wt-status.c:1631 msgid "HEAD detached at " msgstr "HEAD được tách rá»i tại " -#: wt-status.c:1627 +#: wt-status.c:1633 msgid "HEAD detached from " msgstr "HEAD được tách rá»i từ " -#: wt-status.c:1630 +#: wt-status.c:1636 msgid "Not currently on any branch." msgstr "Hiện tại chẳng ở nhánh nà o cả." -#: wt-status.c:1647 +#: wt-status.c:1653 msgid "Initial commit" msgstr "Lần chuyển giao khởi tạo" -#: wt-status.c:1648 +#: wt-status.c:1654 msgid "No commits yet" msgstr "Vẫn chÆ°a chuyển giao" -#: wt-status.c:1662 +#: wt-status.c:1668 msgid "Untracked files" msgstr "Những táºp tin chÆ°a được theo dõi" -#: wt-status.c:1664 +#: wt-status.c:1670 msgid "Ignored files" msgstr "Những táºp tin bị lá» Ä‘i" -#: wt-status.c:1668 +#: wt-status.c:1674 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -7061,32 +7494,32 @@ msgstr "" "có lẽ là m nó nhanh hÆ¡n, nhÆ°ng bạn phải cẩn tháºn đừng quên mình phải\n" "tá»± thêm các táºp tin má»›i (xem “git help statusâ€.." -#: wt-status.c:1674 +#: wt-status.c:1680 #, c-format msgid "Untracked files not listed%s" msgstr "Những táºp tin chÆ°a được theo dõi không được liệt kê ra %s" -#: wt-status.c:1676 +#: wt-status.c:1682 msgid " (use -u option to show untracked files)" msgstr " (dùng tùy chá»n -u để hiển thị các táºp tin chÆ°a được theo dõi)" -#: wt-status.c:1682 +#: wt-status.c:1688 msgid "No changes" msgstr "Không có thay đổi nà o" -#: wt-status.c:1687 +#: wt-status.c:1693 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" "không có thay đổi nà o được thêm và o để chuyển giao (dùng \"git add\" và /hoặc " "\"git commit -a\")\n" -#: wt-status.c:1690 +#: wt-status.c:1696 #, c-format msgid "no changes added to commit\n" msgstr "không có thay đổi nà o được thêm và o để chuyển giao\n" -#: wt-status.c:1693 +#: wt-status.c:1699 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -7095,200 +7528,200 @@ msgstr "" "không có gì được thêm và o lần chuyển giao nhÆ°ng có những táºp tin chÆ°a được " "theo dõi hiện diện (dùng \"git add\" để Ä‘Æ°a và o theo dõi)\n" -#: wt-status.c:1696 +#: wt-status.c:1702 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "" "không có gì được thêm và o lần chuyển giao nhÆ°ng có những táºp tin chÆ°a được " "theo dõi hiện diện\n" -#: wt-status.c:1699 +#: wt-status.c:1705 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" "không có gì để chuyển giao (tạo/sao-chép các táºp tin và dùng \"git add\" để " "Ä‘Æ°a và o theo dõi)\n" -#: wt-status.c:1702 wt-status.c:1707 +#: wt-status.c:1708 wt-status.c:1713 #, c-format msgid "nothing to commit\n" msgstr "không có gì để chuyển giao\n" -#: wt-status.c:1705 +#: wt-status.c:1711 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "không có gì để chuyển giao (dùng -u xem các táºp tin chÆ°a được theo dõi)\n" -#: wt-status.c:1709 +#: wt-status.c:1715 #, c-format msgid "nothing to commit, working tree clean\n" msgstr "không có gì để chuyển giao, thÆ° mục là m việc sạch sẽ\n" -#: wt-status.c:1822 +#: wt-status.c:1828 msgid "No commits yet on " -msgstr "Vẫn không thá»±c hiện lệnh chuyển giao nà o" +msgstr "Vẫn không thá»±c hiện lệnh chuyển giao nà o " -#: wt-status.c:1826 +#: wt-status.c:1832 msgid "HEAD (no branch)" msgstr "HEAD (không nhánh)" -#: wt-status.c:1857 +#: wt-status.c:1863 msgid "different" msgstr "khác" -#: wt-status.c:1859 wt-status.c:1867 +#: wt-status.c:1865 wt-status.c:1873 msgid "behind " msgstr "đằng sau " -#: wt-status.c:1862 wt-status.c:1865 +#: wt-status.c:1868 wt-status.c:1871 msgid "ahead " msgstr "phÃa trÆ°á»›c " #. TRANSLATORS: the action is e.g. "pull with rebase" -#: wt-status.c:2374 +#: wt-status.c:2386 #, c-format msgid "cannot %s: You have unstaged changes." msgstr "không thể %s: Bạn có các thay đổi chÆ°a được Ä‘Æ°a lên bệ phóng." -#: wt-status.c:2380 +#: wt-status.c:2392 msgid "additionally, your index contains uncommitted changes." msgstr "" "thêm và o đó, bảng mục lục của bạn có chứa các thay đổi chÆ°a được chuyển giao." -#: wt-status.c:2382 +#: wt-status.c:2394 #, c-format msgid "cannot %s: Your index contains uncommitted changes." msgstr "" "không thể %s: Mục lục của bạn có chứa các thay đổi chÆ°a được chuyển giao." -#: builtin/add.c:24 +#: builtin/add.c:25 msgid "git add [<options>] [--] <pathspec>..." msgstr "git add [<các-tùy-chá»n>] [--] <pathspec>…" -#: builtin/add.c:83 +#: builtin/add.c:84 #, c-format msgid "unexpected diff status %c" msgstr "trạng thái lệnh diff không nhÆ° mong đợi %c" -#: builtin/add.c:88 builtin/commit.c:284 +#: builtin/add.c:89 builtin/commit.c:285 msgid "updating files failed" -msgstr "Cáºp nháºt táºp tin gặp lá»—i" +msgstr "cáºp nháºt táºp tin gặp lá»—i" -#: builtin/add.c:98 +#: builtin/add.c:99 #, c-format msgid "remove '%s'\n" msgstr "gỡ bỠ“%sâ€\n" -#: builtin/add.c:173 +#: builtin/add.c:174 msgid "Unstaged changes after refreshing the index:" msgstr "" "ÄÆ°a ra khá»i bệ phóng các thay đổi sau khi là m tÆ°Æ¡i má»›i lại bảng mục lục:" -#: builtin/add.c:233 builtin/rev-parse.c:895 +#: builtin/add.c:234 builtin/rev-parse.c:896 msgid "Could not read the index" msgstr "Không thể Ä‘á»c bảng mục lục" -#: builtin/add.c:244 +#: builtin/add.c:245 #, c-format msgid "Could not open '%s' for writing." msgstr "Không thể mở “%s†để ghi." -#: builtin/add.c:248 +#: builtin/add.c:249 msgid "Could not write patch" msgstr "Không thể ghi ra miếng vá" -#: builtin/add.c:251 +#: builtin/add.c:252 msgid "editing patch failed" msgstr "gặp lá»—i khi sá»a miếng vá" -#: builtin/add.c:254 +#: builtin/add.c:255 #, c-format msgid "Could not stat '%s'" msgstr "Không thể lấy thông tin thống kê vỠ“%sâ€" -#: builtin/add.c:256 +#: builtin/add.c:257 msgid "Empty patch. Aborted." msgstr "Miếng vá trống rá»—ng. Nên bá» qua." -#: builtin/add.c:261 +#: builtin/add.c:262 #, c-format msgid "Could not apply '%s'" msgstr "Không thể áp dụng miếng vá “%sâ€" -#: builtin/add.c:269 +#: builtin/add.c:270 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Các Ä‘Æ°á»ng dẫn theo sau đây sẽ bị lá» Ä‘i bởi má»™t trong các táºp tin .gitignore " "của bạn:\n" -#: builtin/add.c:289 builtin/clean.c:907 builtin/fetch.c:137 builtin/mv.c:123 -#: builtin/prune-packed.c:56 builtin/pull.c:213 builtin/push.c:557 -#: builtin/remote.c:1345 builtin/rm.c:240 builtin/send-pack.c:165 +#: builtin/add.c:290 builtin/clean.c:908 builtin/fetch.c:137 builtin/mv.c:124 +#: builtin/prune-packed.c:56 builtin/pull.c:214 builtin/push.c:560 +#: builtin/remote.c:1345 builtin/rm.c:241 builtin/send-pack.c:165 msgid "dry run" msgstr "chạy thá»" -#: builtin/add.c:292 +#: builtin/add.c:293 msgid "interactive picking" msgstr "sá»a bằng cách tÆ°Æ¡ng tác" -#: builtin/add.c:293 builtin/checkout.c:1258 builtin/reset.c:305 +#: builtin/add.c:294 builtin/checkout.c:1304 builtin/reset.c:306 msgid "select hunks interactively" msgstr "chá»n “hunks†theo kiểu tÆ°Æ¡ng tác" -#: builtin/add.c:294 +#: builtin/add.c:295 msgid "edit current diff and apply" msgstr "sá»a diff hiện nay và áp dụng nó" -#: builtin/add.c:295 +#: builtin/add.c:296 msgid "allow adding otherwise ignored files" msgstr "cho phép thêm các táºp tin bị bá» qua khác" -#: builtin/add.c:296 +#: builtin/add.c:297 msgid "update tracked files" msgstr "cáºp nháºt các táºp tin được theo dõi" -#: builtin/add.c:297 +#: builtin/add.c:298 msgid "renormalize EOL of tracked files (implies -u)" msgstr "thÆ°á»ng hóa lại EOL của các táºp tin được theo dõi (ý là -u)" -#: builtin/add.c:298 +#: builtin/add.c:299 msgid "record only the fact that the path will be added later" msgstr "chỉ ghi lại sá»± việc mà đưá»ng dẫn sẽ được thêm và o sau" -#: builtin/add.c:299 +#: builtin/add.c:300 msgid "add changes from all tracked and untracked files" msgstr "" "thêm các thay đổi từ tất cả các táºp tin có cÅ©ng nhÆ° không được theo dõi dấu " "vết" -#: builtin/add.c:302 +#: builtin/add.c:303 msgid "ignore paths removed in the working tree (same as --no-all)" msgstr "" "lá» Ä‘i các Ä‘Æ°á»ng dẫn bị gỡ bá» trong cây thÆ° mục là m việc (giống vá»›i --no-all)" -#: builtin/add.c:304 +#: builtin/add.c:305 msgid "don't add, only refresh the index" msgstr "không thêm, chỉ là m tÆ°Æ¡i má»›i bảng mục lục" -#: builtin/add.c:305 +#: builtin/add.c:306 msgid "just skip files which cannot be added because of errors" msgstr "chie bá» qua những táºp tin mà nó không thể được thêm và o bởi vì gặp lá»—i" -#: builtin/add.c:306 +#: builtin/add.c:307 msgid "check if - even missing - files are ignored in dry run" msgstr "" "kiểm tra xem - tháºm chà thiếu - táºp tin bị bá» qua trong quá trình chạy thá»" -#: builtin/add.c:308 builtin/update-index.c:990 +#: builtin/add.c:309 builtin/update-index.c:991 msgid "override the executable bit of the listed files" msgstr "ghi đè lên bÃt thi hà nh của các táºp tin được liệt kê" -#: builtin/add.c:310 +#: builtin/add.c:311 msgid "warn when adding an embedded repository" msgstr "cảnh báo khi thêm má»™t kho nhúng" -#: builtin/add.c:325 +#: builtin/add.c:326 #, c-format msgid "" "You've added another git repository inside your current repository.\n" @@ -7319,150 +7752,150 @@ msgstr "" "\n" "Xem \"git help submodule\" để biết thêm chi tiết." -#: builtin/add.c:353 +#: builtin/add.c:354 #, c-format msgid "adding embedded git repository: %s" msgstr "thêm cần má»™t kho git nhúng: %s" -#: builtin/add.c:371 +#: builtin/add.c:372 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Sá» dụng tùy chá»n -f nếu bạn thá»±c sá»± muốn thêm chúng và o.\n" -#: builtin/add.c:379 +#: builtin/add.c:380 msgid "adding files failed" msgstr "thêm táºp tin gặp lá»—i" -#: builtin/add.c:417 +#: builtin/add.c:418 msgid "-A and -u are mutually incompatible" msgstr "-A và -u xung khắc nhau" -#: builtin/add.c:424 +#: builtin/add.c:425 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "Tùy chá»n --ignore-missing chỉ có thể được dùng cùng vá»›i --dry-run" -#: builtin/add.c:428 +#: builtin/add.c:429 #, 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" -#: builtin/add.c:443 +#: builtin/add.c:444 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Không có gì được chỉ ra, không có gì được thêm và o.\n" -#: builtin/add.c:444 +#: builtin/add.c:445 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Có lẽ ý bạn là “git add .†phải không?\n" -#: builtin/am.c:363 +#: builtin/am.c:348 msgid "could not parse author script" msgstr "không thể phân tÃch cú pháp văn lệnh tác giả" -#: builtin/am.c:447 +#: builtin/am.c:432 #, c-format msgid "'%s' was deleted by the applypatch-msg hook" msgstr "“%s†bị xóa bởi móc applypatch-msg" -#: builtin/am.c:488 +#: builtin/am.c:473 #, c-format msgid "Malformed input line: '%s'." msgstr "Dòng đầu và o dị hình: “%sâ€." -#: builtin/am.c:525 +#: builtin/am.c:510 #, c-format msgid "Failed to copy notes from '%s' to '%s'" msgstr "Gặp lá»—i khi sao chép ghi chú (note) từ “%s†tá»›i “%sâ€" -#: builtin/am.c:551 +#: builtin/am.c:536 msgid "fseek failed" msgstr "fseek gặp lá»—i" -#: builtin/am.c:739 +#: builtin/am.c:724 #, c-format msgid "could not parse patch '%s'" msgstr "không thể phân tÃch cú pháp “%sâ€" -#: builtin/am.c:804 +#: builtin/am.c:789 msgid "Only one StGIT patch series can be applied at once" msgstr "Chỉ có má»™t sê-ri miếng vá StGIT được áp dụng má»™t lúc" -#: builtin/am.c:852 +#: builtin/am.c:837 msgid "invalid timestamp" msgstr "dấu thá»i gian không hợp lệ" -#: builtin/am.c:857 builtin/am.c:869 +#: builtin/am.c:842 builtin/am.c:854 msgid "invalid Date line" msgstr "dòng Ngà y tháng không hợp lệ" -#: builtin/am.c:864 +#: builtin/am.c:849 msgid "invalid timezone offset" msgstr "Ä‘á»™ lệch múi giá» không hợp lệ" -#: builtin/am.c:957 +#: builtin/am.c:942 msgid "Patch format detection failed." msgstr "Dò tìm định dạng miếng vá gặp lá»—i." -#: builtin/am.c:962 builtin/clone.c:408 +#: builtin/am.c:947 builtin/clone.c:409 #, c-format msgid "failed to create directory '%s'" msgstr "tạo thÆ° mục \"%s\" gặp lá»—i" -#: builtin/am.c:967 +#: builtin/am.c:952 msgid "Failed to split patches." msgstr "Gặp lá»—i khi chia nhá» các miếng vá." -#: builtin/am.c:1097 builtin/commit.c:369 +#: builtin/am.c:1082 builtin/commit.c:371 msgid "unable to write index file" msgstr "không thể ghi táºp tin lÆ°u mục lục" -#: builtin/am.c:1111 +#: builtin/am.c:1096 #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." msgstr "Khi bạn đã phân giải xong trục trặc nà y, hãy chạy \"%s --continue\"." -#: builtin/am.c:1112 +#: builtin/am.c:1097 #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead." msgstr "" "Nếu bạn muốn bá» qua miếng vá nà y, hãy chạy lệnh \"%s --skip\" để thay thế." -#: builtin/am.c:1113 +#: builtin/am.c:1098 #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "Äể phục hồi lại nhánh gốc và dừng vá, hãy chạy \"%s --abort\"." -#: builtin/am.c:1196 +#: builtin/am.c:1181 msgid "Patch sent with format=flowed; space at the end of lines might be lost." msgstr "" "Miếng vá được gá»i vá»›i format=flowed; khoảng trống ở cuối của các dòng có thể " "bị mất." -#: builtin/am.c:1224 +#: builtin/am.c:1209 msgid "Patch is empty." msgstr "Miếng vá trống rá»—ng." -#: builtin/am.c:1290 +#: builtin/am.c:1275 #, c-format msgid "invalid ident line: %.*s" msgstr "dòng thụt lá» không hợp lệ: %.*s" -#: builtin/am.c:1312 +#: builtin/am.c:1297 #, c-format msgid "unable to parse commit %s" msgstr "không thể phân tÃch lần chuyển giao “%sâ€" -#: builtin/am.c:1508 +#: builtin/am.c:1493 msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "Kho thiếu đối tượng blob cần thiết để trở vá» trên “3-way mergeâ€." -#: builtin/am.c:1510 +#: builtin/am.c:1495 msgid "Using index info to reconstruct a base tree..." msgstr "" "Sá» dụng thông tin trong bảng mục lục để cấu trúc lại má»™t cây (tree) cÆ¡ sở…" -#: builtin/am.c:1529 +#: builtin/am.c:1514 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." @@ -7470,29 +7903,29 @@ msgstr "" "Bạn đã sá»a miếng vá của mình bằng cách thủ công à ?\n" "Nó không thể áp dụng các blob đã được ghi lại trong bảng mục lục của nó." -#: builtin/am.c:1535 +#: builtin/am.c:1520 msgid "Falling back to patching base and 3-way merge..." msgstr "Äang trở lại để vá cÆ¡ sở và “hòa trá»™n 3-Ä‘Æ°á»ngâ€â€¦" -#: builtin/am.c:1561 +#: builtin/am.c:1546 msgid "Failed to merge in the changes." msgstr "Gặp lá»—i khi trá»™n và o các thay đổi." -#: builtin/am.c:1593 +#: builtin/am.c:1578 msgid "applying to an empty history" msgstr "áp dụng và o má»™t lịch sá» trống rá»—ng" -#: builtin/am.c:1639 builtin/am.c:1643 +#: builtin/am.c:1624 builtin/am.c:1628 #, c-format msgid "cannot resume: %s does not exist." msgstr "không thể phục hồi: %s không tồn tại." -#: builtin/am.c:1659 +#: builtin/am.c:1644 msgid "cannot be interactive without stdin connected to a terminal." msgstr "" -"không thể được tÆ°Æ¡ng tác mà không có stdin kết nối vá»›i má»™t thiết bị cuối" +"không thể được tÆ°Æ¡ng tác mà không có stdin kết nối vá»›i má»™t thiết bị cuối." -#: builtin/am.c:1664 +#: builtin/am.c:1649 msgid "Commit Body is:" msgstr "Thân của lần chuyển giao là :" @@ -7500,36 +7933,36 @@ msgstr "Thân của lần chuyển giao là :" #. in your translation. The program will only accept English #. input at this point. #. -#: builtin/am.c:1674 +#: builtin/am.c:1659 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" "Ãp dụng? đồng ý [y]/khô[n]g/chỉnh sá»a [e]/hiển thị miếng [v]á/chấp nháºn tất " "cả [a]: " -#: builtin/am.c:1724 +#: builtin/am.c:1709 #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "Bảng mục lục bẩn: không thể áp dụng các miếng vá (bẩn: %s)" -#: builtin/am.c:1764 builtin/am.c:1832 +#: builtin/am.c:1749 builtin/am.c:1817 #, c-format msgid "Applying: %.*s" msgstr "Ãp dụng: %.*s" -#: builtin/am.c:1781 +#: builtin/am.c:1766 msgid "No changes -- Patch already applied." msgstr "Không thay đổi gì cả -- Miếng vá đã được áp dụng rồi." -#: builtin/am.c:1787 +#: builtin/am.c:1772 #, c-format msgid "Patch failed at %s %.*s" msgstr "Gặp lá»—i khi vá tại %s %.*s" -#: builtin/am.c:1791 +#: builtin/am.c:1776 msgid "Use 'git am --show-current-patch' to see the failed patch" msgstr "Dùng “git am --show-current-patch†để xem miếng vá bị lá»—i" -#: builtin/am.c:1835 +#: builtin/am.c:1820 msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" @@ -7540,7 +7973,7 @@ msgstr "" "đã sẵn được Ä‘Æ°a và o vá»›i cùng ná»™i dung thay đổi; bạn có lẽ muốn bá» qua miếng " "vá nà y." -#: builtin/am.c:1842 +#: builtin/am.c:1827 msgid "" "You still have unmerged paths in your index.\n" "You should 'git add' each file with resolved conflicts to mark them as " @@ -7553,17 +7986,17 @@ msgstr "" "Bạn có lẽ muốn chạy “git rm“ trên má»™t táºp tin để chấp nháºn \"được xóa bởi há»" "\" cho nó." -#: builtin/am.c:1949 builtin/am.c:1953 builtin/am.c:1965 builtin/reset.c:328 -#: builtin/reset.c:336 +#: builtin/am.c:1934 builtin/am.c:1938 builtin/am.c:1950 builtin/reset.c:329 +#: builtin/reset.c:337 #, c-format msgid "Could not parse object '%s'." -msgstr "không thể phân tÃch đối tượng “%sâ€." +msgstr "Không thể phân tÃch đối tượng “%sâ€." -#: builtin/am.c:2001 +#: builtin/am.c:1986 msgid "failed to clean index" msgstr "gặp lá»—i khi dá»n bảng mục lục" -#: builtin/am.c:2036 +#: builtin/am.c:2030 msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" @@ -7571,144 +8004,144 @@ msgstr "" "Bạn có lẽ đã có HEAD đã bị di chuyển Ä‘i kể từ lần “am†thất bại cuối cùng.\n" "Không thể chuyển tá»›i ORIG_HEAD" -#: builtin/am.c:2129 +#: builtin/am.c:2123 #, c-format msgid "Invalid value for --patch-format: %s" msgstr "Giá trị không hợp lệ cho --patch-format: %s" -#: builtin/am.c:2165 +#: builtin/am.c:2159 msgid "git am [<options>] [(<mbox> | <Maildir>)...]" msgstr "git am [<các-tùy-chá»n>] [(<mbox>|<Maildir>)…]" -#: builtin/am.c:2166 +#: builtin/am.c:2160 msgid "git am [<options>] (--continue | --skip | --abort)" msgstr "git am [<các-tùy-chá»n>] (--continue | --skip | --abort)" -#: builtin/am.c:2172 +#: builtin/am.c:2166 msgid "run interactively" msgstr "chạy kiểu tÆ°Æ¡ng tác" -#: builtin/am.c:2174 +#: builtin/am.c:2168 msgid "historical option -- no-op" msgstr "tùy chá»n lịch sá» -- không-toán-tá»" -#: builtin/am.c:2176 +#: builtin/am.c:2170 msgid "allow fall back on 3way merging if needed" msgstr "cho phép quay trở lại để hòa trá»™n kiểu “3way†nếu cần" -#: builtin/am.c:2177 builtin/init-db.c:486 builtin/prune-packed.c:58 +#: builtin/am.c:2171 builtin/init-db.c:486 builtin/prune-packed.c:58 #: builtin/repack.c:306 msgid "be quiet" msgstr "im lặng" -#: builtin/am.c:2179 +#: builtin/am.c:2173 msgid "add a Signed-off-by line to the commit message" -msgstr "Thêm dòng Signed-off-by cho ghi chú của lần chuyển giao" +msgstr "thêm dòng Signed-off-by cho ghi chú của lần chuyển giao" -#: builtin/am.c:2182 +#: builtin/am.c:2176 msgid "recode into utf8 (default)" msgstr "chuyển mã thà nh utf8 (mặc định)" -#: builtin/am.c:2184 +#: builtin/am.c:2178 msgid "pass -k flag to git-mailinfo" msgstr "chuyển cá» -k cho git-mailinfo" -#: builtin/am.c:2186 +#: builtin/am.c:2180 msgid "pass -b flag to git-mailinfo" msgstr "chuyển cá» -b cho git-mailinfo" -#: builtin/am.c:2188 +#: builtin/am.c:2182 msgid "pass -m flag to git-mailinfo" msgstr "chuyển cá» -m cho git-mailinfo" -#: builtin/am.c:2190 +#: builtin/am.c:2184 msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "chuyển cá» --keep-cr cho git-mailsplit vá»›i định dạng mbox" -#: builtin/am.c:2193 +#: builtin/am.c:2187 msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" msgstr "" "đừng chuyển cá» --keep-cr cho git-mailsplit không phụ thuá»™c và o am.keepcr" -#: builtin/am.c:2196 +#: builtin/am.c:2190 msgid "strip everything before a scissors line" msgstr "cắt má»i thứ trÆ°á»›c dòng scissors" -#: builtin/am.c:2198 builtin/am.c:2201 builtin/am.c:2204 builtin/am.c:2207 -#: builtin/am.c:2210 builtin/am.c:2213 builtin/am.c:2216 builtin/am.c:2219 -#: builtin/am.c:2225 +#: builtin/am.c:2192 builtin/am.c:2195 builtin/am.c:2198 builtin/am.c:2201 +#: builtin/am.c:2204 builtin/am.c:2207 builtin/am.c:2210 builtin/am.c:2213 +#: builtin/am.c:2219 msgid "pass it through git-apply" msgstr "chuyển nó qua git-apply" -#: builtin/am.c:2215 builtin/commit.c:1340 builtin/fmt-merge-msg.c:671 -#: builtin/fmt-merge-msg.c:674 builtin/grep.c:868 builtin/merge.c:239 -#: builtin/pull.c:151 builtin/pull.c:209 builtin/rebase.c:854 +#: builtin/am.c:2209 builtin/commit.c:1343 builtin/fmt-merge-msg.c:671 +#: builtin/fmt-merge-msg.c:674 builtin/grep.c:879 builtin/merge.c:240 +#: builtin/pull.c:152 builtin/pull.c:210 builtin/rebase.c:1062 #: builtin/repack.c:317 builtin/repack.c:321 builtin/repack.c:323 #: builtin/show-branch.c:651 builtin/show-ref.c:171 builtin/tag.c:386 -#: parse-options.h:144 parse-options.h:146 parse-options.h:268 +#: parse-options.h:144 parse-options.h:146 parse-options.h:266 msgid "n" msgstr "n" -#: builtin/am.c:2221 builtin/branch.c:637 builtin/for-each-ref.c:38 +#: builtin/am.c:2215 builtin/branch.c:637 builtin/for-each-ref.c:38 #: builtin/replace.c:544 builtin/tag.c:422 builtin/verify-tag.c:39 msgid "format" msgstr "định dạng" -#: builtin/am.c:2222 +#: builtin/am.c:2216 msgid "format the patch(es) are in" msgstr "định dạng (các) miếng vá theo" -#: builtin/am.c:2228 +#: builtin/am.c:2222 msgid "override error message when patch failure occurs" msgstr "đè lên các lá»i nhắn lá»—i khi xảy ra lá»—i vá nghiêm trá»ng" -#: builtin/am.c:2230 +#: builtin/am.c:2224 msgid "continue applying patches after resolving a conflict" msgstr "tiếp tục áp dụng các miếng vá sau khi giải quyết xung Ä‘á»™t" -#: builtin/am.c:2233 +#: builtin/am.c:2227 msgid "synonyms for --continue" msgstr "đồng nghÄ©a vá»›i --continue" -#: builtin/am.c:2236 +#: builtin/am.c:2230 msgid "skip the current patch" msgstr "bá» qua miếng vá hiện hà nh" -#: builtin/am.c:2239 +#: builtin/am.c:2233 msgid "restore the original branch and abort the patching operation." msgstr "phục hồi lại nhánh gốc và loại bá» thao tác vá." -#: builtin/am.c:2242 +#: builtin/am.c:2236 msgid "abort the patching operation but keep HEAD where it is." msgstr "bá» qua thao tác vá nhÆ°ng vẫn giữ HEAD chỉ đến nó." -#: builtin/am.c:2245 +#: builtin/am.c:2239 msgid "show the patch being applied." msgstr "hiển thị miếng vá đã được áp dụng rồi." -#: builtin/am.c:2249 +#: builtin/am.c:2243 msgid "lie about committer date" msgstr "nói dối vá» ngà y chuyển giao" -#: builtin/am.c:2251 +#: builtin/am.c:2245 msgid "use current timestamp for author date" msgstr "dùng dấu thá»i gian hiện tại cho ngà y tác giả" -#: builtin/am.c:2253 builtin/commit.c:1483 builtin/merge.c:273 -#: builtin/pull.c:184 builtin/rebase.c:898 builtin/rebase--interactive.c:183 -#: builtin/revert.c:113 builtin/tag.c:402 +#: builtin/am.c:2247 builtin/commit.c:1486 builtin/merge.c:274 +#: builtin/pull.c:185 builtin/rebase.c:1106 builtin/rebase--interactive.c:185 +#: builtin/revert.c:114 builtin/tag.c:402 msgid "key-id" msgstr "mã-số-khóa" -#: builtin/am.c:2254 builtin/rebase.c:899 builtin/rebase--interactive.c:184 +#: builtin/am.c:2248 builtin/rebase.c:1107 builtin/rebase--interactive.c:186 msgid "GPG-sign commits" -msgstr "lần chuyển giao ký-GPG" +msgstr "Các lần chuyển giao ký-GPG" -#: builtin/am.c:2257 +#: builtin/am.c:2251 msgid "(internal use for git-rebase)" msgstr "(dùng ná»™i bá»™ cho git-rebase)" -#: builtin/am.c:2275 +#: builtin/am.c:2269 msgid "" "The -b/--binary option has been a no-op for long time, and\n" "it will be removed. Please do not use it anymore." @@ -7716,16 +8149,16 @@ msgstr "" "Tùy chá»n -b/--binary đã không dùng từ lâu rồi, và \n" "nó sẽ được bá» Ä‘i. Xin đừng sá» dụng nó thêm nữa." -#: builtin/am.c:2282 +#: builtin/am.c:2276 msgid "failed to read the index" msgstr "gặp lá»—i Ä‘á»c bảng mục lục" -#: builtin/am.c:2297 +#: builtin/am.c:2291 #, c-format msgid "previous rebase directory %s still exists but mbox given." msgstr "thÆ° mục rebase trÆ°á»›c %s không sẵn có nhÆ°ng mbox lại Ä‘Æ°a ra." -#: builtin/am.c:2321 +#: builtin/am.c:2315 #, c-format msgid "" "Stray %s directory found.\n" @@ -7734,7 +8167,7 @@ msgstr "" "Tìm thấy thÆ° mục lạc %s.\n" "Dùng \"git am --abort\" để loại bá» nó Ä‘i." -#: builtin/am.c:2327 +#: builtin/am.c:2321 msgid "Resolve operation not in progress, we are not resuming." msgstr "Thao tác phân giải không được tiến hà nh, chúng ta không phục hồi lại." @@ -7755,87 +8188,296 @@ msgstr "không thể chuyển hÆ°á»›ng kết xuất" msgid "git archive: Remote with no URL" msgstr "git archive: Máy chủ không có địa chỉ URL" -#: builtin/archive.c:58 +#: builtin/archive.c:61 msgid "git archive: expected ACK/NAK, got a flush packet" msgstr "git archive: cần ACK/NAK, nhÆ°ng lại nháºn được gói flush" -#: builtin/archive.c:61 +#: builtin/archive.c:64 #, c-format msgid "git archive: NACK %s" msgstr "git archive: NACK %s" -#: builtin/archive.c:64 +#: builtin/archive.c:65 msgid "git archive: protocol error" msgstr "git archive: lá»—i giao thức" -#: builtin/archive.c:68 +#: builtin/archive.c:69 msgid "git archive: expected a flush" msgstr "git archive: cần má»™t flush (đẩy dữ liệu lên Ä‘Ä©a)" -#: builtin/bisect--helper.c:12 +#: builtin/bisect--helper.c:22 msgid "git bisect--helper --next-all [--no-checkout]" msgstr "git bisect--helper --next-all [--no-checkout]" -#: builtin/bisect--helper.c:13 +#: builtin/bisect--helper.c:23 msgid "git bisect--helper --write-terms <bad_term> <good_term>" msgstr "git bisect--helper --write-terms <bad_term> <good_term>" -#: builtin/bisect--helper.c:14 +#: builtin/bisect--helper.c:24 msgid "git bisect--helper --bisect-clean-state" msgstr "git bisect--helper --bisect-clean-state" -#: builtin/bisect--helper.c:46 +#: builtin/bisect--helper.c:25 +msgid "git bisect--helper --bisect-reset [<commit>]" +msgstr "git bisect--helper --bisect-reset [<lần_chuyển_giao>]" + +#: builtin/bisect--helper.c:26 +msgid "" +"git bisect--helper --bisect-write [--no-log] <state> <revision> <good_term> " +"<bad_term>" +msgstr "" +"git bisect--helper --bisect-write [--no-log] <state> <revision> <lúc_sai> " +"<lúc_đúng>" + +#: builtin/bisect--helper.c:27 +msgid "" +"git bisect--helper --bisect-check-and-set-terms <command> <good_term> " +"<bad_term>" +msgstr "" +"git bisect--helper --bisect-check-and-set-terms <command> <lúc_sai> " +"<lúc_đúng>" + +#: builtin/bisect--helper.c:28 +msgid "git bisect--helper --bisect-next-check <good_term> <bad_term> [<term>]" +msgstr "git bisect--helper --bisect-next-check <lúc_sai> <lúc_đúng> [<term>]" + +#: builtin/bisect--helper.c:29 +msgid "" +"git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --" +"term-new]" +msgstr "" +"git bisect--helper --bisect-terms [--term-good | --term-old | --term-bad | --" +"term-new]" + +#: builtin/bisect--helper.c:30 +msgid "" +"git bisect--helper --bisect-start [--term-{old,good}=<term> --term-{new,bad}" +"=<term>][--no-checkout] [<bad> [<good>...]] [--] [<paths>...]" +msgstr "" +"git bisect--helper --bisect-start [--term-{old,good}=<term> --term-{new,bad}" +"=<term>][--no-checkout] [<sai> [<đúng>…]] [--] [<Ä‘Æ°á»ng/dẫn>…]" + +#: builtin/bisect--helper.c:86 #, c-format msgid "'%s' is not a valid term" -msgstr "“%s†không phải má»™t thá»i hạn hợp lệ." +msgstr "“%s†không phải má»™t thá»i hạn hợp lệ" -#: builtin/bisect--helper.c:50 +#: builtin/bisect--helper.c:90 #, c-format msgid "can't use the builtin command '%s' as a term" msgstr "không thể dùng lệnh tÃch hợp “%s†nhÆ° là má»™t thá»i kỳ" -#: builtin/bisect--helper.c:60 +#: builtin/bisect--helper.c:100 #, c-format msgid "can't change the meaning of the term '%s'" msgstr "không thể thay đổi nghÄ©a của thá»i kỳ “%sâ€" -#: builtin/bisect--helper.c:71 +#: builtin/bisect--helper.c:111 msgid "please use two different terms" msgstr "vui lòng dùng hai thá»i kỳ khác nhau" -#: builtin/bisect--helper.c:78 +#: builtin/bisect--helper.c:118 msgid "could not open the file BISECT_TERMS" msgstr "không thể mở táºp tin BISECT_TERMS" -#: builtin/bisect--helper.c:120 +#: builtin/bisect--helper.c:155 +#, c-format +msgid "We are not bisecting.\n" +msgstr "Chúng tôi Ä‘ang không bisect.\n" + +#: builtin/bisect--helper.c:163 +#, c-format +msgid "'%s' is not a valid commit" +msgstr "“%s†không phải má»™t lần chuyển giao hợp lệ" + +#: builtin/bisect--helper.c:174 +#, c-format +msgid "" +"could not check out original HEAD '%s'. Try 'git bisect reset <commit>'." +msgstr "" +"không thể lấy ra HEAD nguyên thủy của “%sâ€. Hãy thỠ“git bisect reset <lần-" +"chuyển-giao>â€." + +#: builtin/bisect--helper.c:215 +#, c-format +msgid "Bad bisect_write argument: %s" +msgstr "Äối số bisect_write sai: %s" + +#: builtin/bisect--helper.c:220 +#, c-format +msgid "couldn't get the oid of the rev '%s'" +msgstr "không thể lấy oid của Ä‘iểm xét duyệt “%sâ€" + +#: builtin/bisect--helper.c:232 +#, c-format +msgid "couldn't open the file '%s'" +msgstr "không thể mở táºp tin “%sâ€" + +#: builtin/bisect--helper.c:258 +#, c-format +msgid "Invalid command: you're currently in a %s/%s bisect" +msgstr "Lệnh không hợp lệ: bạn hiện Ä‘ang ở má»™t bisect %s/%s" + +#: builtin/bisect--helper.c:285 +#, c-format +msgid "" +"You need to give me at least one %s and %s revision.\n" +"You can use \"git bisect %s\" and \"git bisect %s\" for that." +msgstr "" +"Bạn phải chỉ cho tôi Ãt nhất má»™t Ä‘iểm %s và má»™t %s.\n" +"Bạn có thể sá» dụng \"git bisect %s\" và \"git bisect %s\" cho cái đó." + +#: builtin/bisect--helper.c:289 +#, c-format +msgid "" +"You need to start by \"git bisect start\".\n" +"You then need to give me at least one %s and %s revision.\n" +"You can use \"git bisect %s\" and \"git bisect %s\" for that." +msgstr "" +"Bạn cần bắt đầu bằng lệnh \"git bisect start\".\n" +"Bạn sau đó cần phải chỉ cho tôi Ãt nhất má»™t Ä‘iểm xét duyệt %s và má»™t %s.\n" +"Bạn có thể sá» dụng \"git bisect %s\" và \"git bisect %s\" cho chúng." + +#: builtin/bisect--helper.c:321 +#, c-format +msgid "bisecting only with a %s commit" +msgstr "chỉ thá»±c hiện việc bisect vá»›i má»™t lần chuyển giao %s" + +#. TRANSLATORS: Make sure to include [Y] and [n] in your +#. translation. The program will only accept English input +#. at this point. +#. +#: builtin/bisect--helper.c:329 +msgid "Are you sure [Y/n]? " +msgstr "Bạn có chắc chắn chÆ°a [Y/n]? " + +#: builtin/bisect--helper.c:376 +msgid "no terms defined" +msgstr "chÆ°a định nghÄ©a thá»i kỳ nà o" + +#: builtin/bisect--helper.c:379 +#, c-format +msgid "" +"Your current terms are %s for the old state\n" +"and %s for the new state.\n" +msgstr "" +"Bạn hiện tại Ä‘ang ở thá»i kỳ %s cho tình trạng cÅ©\n" +"và %s cho tình trạng má»›i.\n" + +#: builtin/bisect--helper.c:389 +#, c-format +msgid "" +"invalid argument %s for 'git bisect terms'.\n" +"Supported options are: --term-good|--term-old and --term-bad|--term-new." +msgstr "" +"tham số không hợp lệ %s cho “git bisect termsâ€.\n" +"Các tùy chá»n há»— trợ là : --term-good|--term-old và --term-bad|--term-new." + +#: builtin/bisect--helper.c:475 +#, c-format +msgid "unrecognized option: '%s'" +msgstr "tùy chá»n không được thừa nháºn: “%sâ€" + +#: builtin/bisect--helper.c:479 +#, c-format +msgid "'%s' does not appear to be a valid revision" +msgstr "“%s†không có vẻ nhÆ° là má»™t Ä‘iểm xét duyệt hợp lệ" + +#: builtin/bisect--helper.c:511 +msgid "bad HEAD - I need a HEAD" +msgstr "sai HEAD - Tôi cần má»™t HEAD" + +#: builtin/bisect--helper.c:526 +#, c-format +msgid "checking out '%s' failed. Try 'git bisect start <valid-branch>'." +msgstr "lấy ra “%s†ra gặp lá»—i. Hãy thá» \"git bisect reset <nhánh_hợp_lệ>\"." + +#: builtin/bisect--helper.c:547 +msgid "won't bisect on cg-seek'ed tree" +msgstr "sẽ không di chuyển ná»a bÆ°á»›c trên cây được cg-seek" + +#: builtin/bisect--helper.c:550 +msgid "bad HEAD - strange symbolic ref" +msgstr "sai HEAD - tham chiếu má»m kỳ lạ" + +#: builtin/bisect--helper.c:627 msgid "perform 'git bisect next'" msgstr "thá»±c hiện “git bisect nextâ€" -#: builtin/bisect--helper.c:122 +#: builtin/bisect--helper.c:629 msgid "write the terms to .git/BISECT_TERMS" msgstr "ghi thá»i kỳ và o .git/BISECT_TERMS" -#: builtin/bisect--helper.c:124 +#: builtin/bisect--helper.c:631 msgid "cleanup the bisection state" msgstr "dá»n dẹp tình trạng di chuyển ná»a bÆ°á»›c" -#: builtin/bisect--helper.c:126 +#: builtin/bisect--helper.c:633 msgid "check for expected revs" msgstr "kiểm tra cho Ä‘iểm xem xét cần dùng" -#: builtin/bisect--helper.c:128 +#: builtin/bisect--helper.c:635 +msgid "reset the bisection state" +msgstr "đặt lại trạng di chuyển ná»a bÆ°á»›c" + +#: builtin/bisect--helper.c:637 +msgid "write out the bisection state in BISECT_LOG" +msgstr "ghi ra tình trạng di chuyển ná»a bÆ°á»›c trong BISECT_LOG" + +#: builtin/bisect--helper.c:639 +msgid "check and set terms in a bisection state" +msgstr "kiểm tra và đặt thá»i Ä‘iểm trong di chuyển ná»a bÆ°á»›c" + +#: builtin/bisect--helper.c:641 +msgid "check whether bad or good terms exist" +msgstr "kiểm tra xem các thá»i Ä‘iểm xấu/tốt có tồn tại không" + +#: builtin/bisect--helper.c:643 +msgid "print out the bisect terms" +msgstr "in ra các thá»i Ä‘iểm di chuyển ná»a bÆ°á»›c" + +#: builtin/bisect--helper.c:645 +msgid "start the bisect session" +msgstr "bắt đầu phiên di chuyển ná»a bÆ°á»›c" + +#: builtin/bisect--helper.c:647 msgid "update BISECT_HEAD instead of checking out the current commit" msgstr "" "cáºp nháºt BISECT_HEAD thay vì lấy ra (checking out) lần chuyển giao hiện hà nh" -#: builtin/bisect--helper.c:143 +#: builtin/bisect--helper.c:649 +msgid "no log for BISECT_WRITE" +msgstr "không có nháºt ký cho BISECT_WRITE" + +#: builtin/bisect--helper.c:666 msgid "--write-terms requires two arguments" msgstr "--write-terms cần hai tham số" -#: builtin/bisect--helper.c:147 +#: builtin/bisect--helper.c:670 msgid "--bisect-clean-state requires no arguments" msgstr "--bisect-clean-state không nháºn đối số" +#: builtin/bisect--helper.c:677 +msgid "--bisect-reset requires either no argument or a commit" +msgstr "" +"--bisect-reset requires không nháºn đối số cÅ©ng không nháºn lần chuyển giao" + +#: builtin/bisect--helper.c:681 +msgid "--bisect-write requires either 4 or 5 arguments" +msgstr "--bisect-write cần 4 hoặc 5 tham số" + +#: builtin/bisect--helper.c:687 +msgid "--check-and-set-terms requires 3 arguments" +msgstr "--check-and-set-terms cần 3 tham số" + +#: builtin/bisect--helper.c:693 +msgid "--bisect-next-check requires 2 or 3 arguments" +msgstr "--bisect-next-check cần 2 hoặc 3 tham số" + +#: builtin/bisect--helper.c:699 +msgid "--bisect-terms requires 0 or 1 argument" +msgstr "--bisect-terms cần 0 hoặc 1 tham số" + #: builtin/blame.c:31 msgid "git blame [<options>] [<rev-opts>] [<rev>] [--] <file>" msgstr "git blame [<các-tùy-chá»n>] [<rev-opts>] [<rev>] [--] <táºp-tin>" @@ -7972,7 +8614,7 @@ msgstr "n,m" msgid "Process only line range n,m, counting from 1" msgstr "Xá» lý chỉ dòng vùng n,m, tÃnh từ 1" -#: builtin/blame.c:873 +#: builtin/blame.c:875 msgid "--progress can't be used with --incremental or porcelain formats" msgstr "" "--progress không được dùng cùng vá»›i --incremental hay các định dạng porcelain" @@ -7985,17 +8627,17 @@ msgstr "" #. your language may need more or fewer display #. columns. #. -#: builtin/blame.c:924 +#: builtin/blame.c:926 msgid "4 years, 11 months ago" msgstr "4 năm, 11 tháng trÆ°á»›c" -#: builtin/blame.c:1011 +#: builtin/blame.c:1018 #, c-format msgid "file %s has only %lu line" msgid_plural "file %s has only %lu lines" msgstr[0] "táºp tin %s chỉ có %lu dòng" -#: builtin/blame.c:1057 +#: builtin/blame.c:1064 msgid "Blaming lines" msgstr "Các dòng blame" @@ -8195,7 +8837,7 @@ msgstr "cà i đặt chế Ä‘á»™ theo dõi (xem git-pull(1))" msgid "do not use" msgstr "không dùng" -#: builtin/branch.c:602 builtin/rebase--interactive.c:180 +#: builtin/branch.c:602 builtin/rebase--interactive.c:182 msgid "upstream" msgstr "thượng nguồn" @@ -8294,7 +8936,7 @@ msgid "field name to sort on" msgstr "tên trÆ°á»ng cần sắp xếp" #: builtin/branch.c:633 builtin/for-each-ref.c:43 builtin/notes.c:415 -#: builtin/notes.c:418 builtin/notes.c:578 builtin/notes.c:581 +#: builtin/notes.c:418 builtin/notes.c:581 builtin/notes.c:584 #: builtin/tag.c:418 msgid "object" msgstr "đối tượng" @@ -8312,9 +8954,9 @@ msgstr "sắp xếp và lá»c là phân biệt HOA thÆ°á»ng" msgid "format to use for the output" msgstr "định dạng sẽ dùng cho đầu ra" -#: builtin/branch.c:660 builtin/clone.c:739 +#: builtin/branch.c:660 builtin/clone.c:746 msgid "HEAD not found below refs/heads!" -msgstr "không tìm thấy HEAD ở dÆ°á»›i refs/heads!" +msgstr "Không tìm thấy HEAD ở dÆ°á»›i refs/heads!" #: builtin/branch.c:683 msgid "--column and --verbose are incompatible" @@ -8362,7 +9004,7 @@ msgstr "" "không thể đặt thượng nguồn của HEAD thà nh %s khi mà nó chẳng chỉ đến nhánh " "nà o cả." -#: builtin/branch.c:776 builtin/branch.c:798 +#: builtin/branch.c:776 builtin/branch.c:799 #, c-format msgid "no such branch '%s'" msgstr "không có nhánh nà o nhÆ° thế “%sâ€" @@ -8372,26 +9014,26 @@ msgstr "không có nhánh nà o nhÆ° thế “%sâ€" msgid "branch '%s' does not exist" msgstr "chÆ°a có nhánh “%sâ€" -#: builtin/branch.c:792 +#: builtin/branch.c:793 msgid "too many arguments to unset upstream" msgstr "quá nhiá»u tham số để bỠđặt thượng nguồn" -#: builtin/branch.c:796 +#: builtin/branch.c:797 msgid "could not unset upstream of HEAD when it does not point to any branch." msgstr "không thể bỠđặt thượng nguồn của HEAD không chỉ đến má»™t nhánh nà o cả." -#: builtin/branch.c:802 +#: builtin/branch.c:803 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Nhánh “%s†không có thông tin thượng nguồn" -#: builtin/branch.c:812 +#: builtin/branch.c:813 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "hai tùy chá»n -a và -r áp dụng cho lệnh “git branch†không hợp lý đối vá»›i tên " "nhánh" -#: builtin/branch.c:815 +#: builtin/branch.c:816 msgid "" "the '--set-upstream' option is no longer supported. Please use '--track' or " "'--set-upstream-to' instead." @@ -8412,7 +9054,7 @@ msgstr "Cần má»™t kho chứa để có thể tạo má»™t bundle." msgid "Need a repository to unbundle." msgstr "Cần má»™t kho chứa để có thể giải nén má»™t bundle." -#: builtin/cat-file.c:587 +#: builtin/cat-file.c:593 msgid "" "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -" "p | <type> | --textconv | --filters) [--path=<path>] <object>" @@ -8420,7 +9062,7 @@ msgstr "" "git cat-file (-t [--allow-unknown-type] | -s [--allow-unknown-type] | -e | -" "p | <kiểu> | --textconv) | --filters) [--path=<Ä‘Æ°á»ng/dẫn>] <đối_tượng>" -#: builtin/cat-file.c:588 +#: builtin/cat-file.c:594 msgid "" "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --" "filters]" @@ -8428,133 +9070,133 @@ msgstr "" "git cat-file (--batch | --batch-check) [--follow-symlinks] [--textconv | --" "filters]" -#: builtin/cat-file.c:609 +#: builtin/cat-file.c:615 msgid "only one batch option may be specified" msgstr "chỉ má»™t tùy chá»n batch được chỉ ra" -#: builtin/cat-file.c:627 +#: builtin/cat-file.c:633 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "<kiểu> là má»™t trong số: blob, tree, commit hoặc tag" -#: builtin/cat-file.c:628 +#: builtin/cat-file.c:634 msgid "show object type" msgstr "hiển thị kiểu đối tượng" -#: builtin/cat-file.c:629 +#: builtin/cat-file.c:635 msgid "show object size" msgstr "hiển thị kÃch thÆ°á»›c đối tượng" -#: builtin/cat-file.c:631 +#: builtin/cat-file.c:637 msgid "exit with zero when there's no error" msgstr "thoát vá»›i 0 khi không có lá»—i" -#: builtin/cat-file.c:632 +#: builtin/cat-file.c:638 msgid "pretty-print object's content" msgstr "in ná»™i dung đối tượng dạng dá»… Ä‘á»c" -#: builtin/cat-file.c:634 +#: builtin/cat-file.c:640 msgid "for blob objects, run textconv on object's content" msgstr "vá»›i đối tượng blob, chạy lệnh textconv trên ná»™i dung của đối tượng" -#: builtin/cat-file.c:636 +#: builtin/cat-file.c:642 msgid "for blob objects, run filters on object's content" msgstr "vá»›i đối tượng blob, chạy lệnh filters trên ná»™i dung của đối tượng" -#: builtin/cat-file.c:637 git-submodule.sh:857 +#: builtin/cat-file.c:643 git-submodule.sh:860 msgid "blob" msgstr "blob" -#: builtin/cat-file.c:638 +#: builtin/cat-file.c:644 msgid "use a specific path for --textconv/--filters" msgstr "dùng má»™t Ä‘Æ°á»ng dẫn rõ rà ng cho --textconv/--filters" -#: builtin/cat-file.c:640 +#: builtin/cat-file.c:646 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" -#: builtin/cat-file.c:641 +#: builtin/cat-file.c:647 msgid "buffer --batch output" msgstr "đệm kết xuất --batch" -#: builtin/cat-file.c:643 +#: builtin/cat-file.c:649 msgid "show info and content of objects fed from the standard input" msgstr "" "hiển thị thông tin và ná»™i dung của các đối tượng lấy từ đầu và o tiêu chuẩn" -#: builtin/cat-file.c:647 +#: builtin/cat-file.c:653 msgid "show info about objects fed from the standard input" msgstr "hiển thị các thông tin vỠđối tượng fed từ đầu và o tiêu chuẩn" -#: builtin/cat-file.c:651 +#: builtin/cat-file.c:657 msgid "follow in-tree symlinks (used with --batch or --batch-check)" msgstr "theo liên kết má»m trong-cây (được dùng vá»›i --batch hay --batch-check)" -#: builtin/cat-file.c:653 +#: builtin/cat-file.c:659 msgid "show all objects with --batch or --batch-check" msgstr "hiển thị má»i đối tượng vá»›i --batch hay --batch-check" -#: builtin/cat-file.c:655 +#: builtin/cat-file.c:661 msgid "do not order --batch-all-objects output" msgstr "đừng sắp xếp đầu ra --batch-all-objects" -#: builtin/check-attr.c:12 +#: builtin/check-attr.c:13 msgid "git check-attr [-a | --all | <attr>...] [--] <pathname>..." msgstr "git check-attr [-a | --all | <attr>…] [--] tên-Ä‘Æ°á»ng-dẫn…" -#: builtin/check-attr.c:13 +#: builtin/check-attr.c:14 msgid "git check-attr --stdin [-z] [-a | --all | <attr>...]" msgstr "git check-attr --stdin [-z] [-a | --all | <attr>…]" -#: builtin/check-attr.c:20 +#: builtin/check-attr.c:21 msgid "report all attributes set on file" msgstr "báo cáo tất cả các thuá»™c tÃnh đặt trên táºp tin" -#: builtin/check-attr.c:21 +#: builtin/check-attr.c:22 msgid "use .gitattributes only from the index" msgstr "chỉ dùng .gitattributes từ bảng mục lục" -#: builtin/check-attr.c:22 builtin/check-ignore.c:24 builtin/hash-object.c:101 +#: builtin/check-attr.c:23 builtin/check-ignore.c:25 builtin/hash-object.c:102 msgid "read file names from stdin" msgstr "Ä‘á»c tên táºp tin từ đầu và o tiêu chuẩn" -#: builtin/check-attr.c:24 builtin/check-ignore.c:26 +#: builtin/check-attr.c:25 builtin/check-ignore.c:27 msgid "terminate input and output records by a NUL character" msgstr "chấm dứt các bản ghi và o và ra bằng ký tá»± NULL" -#: builtin/check-ignore.c:20 builtin/checkout.c:1234 builtin/gc.c:517 -#: builtin/worktree.c:495 +#: builtin/check-ignore.c:21 builtin/checkout.c:1280 builtin/gc.c:517 +#: builtin/worktree.c:496 msgid "suppress progress reporting" msgstr "chặn các báo cáo tiến trình hoạt Ä‘á»™ng" -#: builtin/check-ignore.c:28 +#: builtin/check-ignore.c:29 msgid "show non-matching input paths" msgstr "hiển thị những Ä‘Æ°á»ng dẫn đầu và o không khá»›p vá»›i mẫu" -#: builtin/check-ignore.c:30 +#: builtin/check-ignore.c:31 msgid "ignore index when checking" msgstr "bá» qua mục lục khi kiểm tra" -#: builtin/check-ignore.c:159 +#: builtin/check-ignore.c:160 msgid "cannot specify pathnames with --stdin" msgstr "không thể chỉ định các tên Ä‘Æ°á»ng dẫn vá»›i --stdin" -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:163 msgid "-z only makes sense with --stdin" msgstr "-z chỉ hợp lý vá»›i --stdin" -#: builtin/check-ignore.c:164 +#: builtin/check-ignore.c:165 msgid "no path specified" msgstr "chÆ°a chỉ ra Ä‘Æ°á»ng dẫn" -#: builtin/check-ignore.c:168 +#: builtin/check-ignore.c:169 msgid "--quiet is only valid with a single pathname" msgstr "--quiet chỉ hợp lệ vá»›i tên Ä‘Æ°á»ng dẫn Ä‘Æ¡n" -#: builtin/check-ignore.c:170 +#: builtin/check-ignore.c:171 msgid "cannot have both --quiet and --verbose" msgstr "không thể dùng cả hai tùy chá»n --quiet và --verbose" -#: builtin/check-ignore.c:173 +#: builtin/check-ignore.c:174 msgid "--non-matching is only valid with --verbose" msgstr "tùy-chá»n --non-matching chỉ hợp lệ khi dùng vá»›i --verbose" @@ -8575,166 +9217,184 @@ msgstr "không thể phân tÃch danh bạ: “%sâ€" msgid "no contacts specified" msgstr "chÆ°a chỉ ra danh bạ" -#: builtin/checkout-index.c:128 +#: builtin/checkout-index.c:131 msgid "git checkout-index [<options>] [--] [<file>...]" msgstr "git checkout-index [<các-tùy-chá»n>] [--] [<táºp-tin>…]" -#: builtin/checkout-index.c:145 +#: builtin/checkout-index.c:148 msgid "stage should be between 1 and 3 or all" msgstr "stage nên giữa 1 và 3 hay all" -#: builtin/checkout-index.c:161 +#: builtin/checkout-index.c:164 msgid "check out all files in the index" msgstr "lấy ra toà n bá»™ các táºp tin trong bảng mục lục" -#: builtin/checkout-index.c:162 +#: builtin/checkout-index.c:165 msgid "force overwrite of existing files" msgstr "ép buá»™c ghi đè lên táºp tin đã sẵn có từ trÆ°á»›c" -#: builtin/checkout-index.c:164 +#: builtin/checkout-index.c:167 msgid "no warning for existing files and files not in index" msgstr "" "không cảnh báo cho những táºp tin tồn tại và không có trong bảng mục lục" -#: builtin/checkout-index.c:166 +#: builtin/checkout-index.c:169 msgid "don't checkout new files" msgstr "không checkout các táºp tin má»›i" -#: builtin/checkout-index.c:168 +#: builtin/checkout-index.c:171 msgid "update stat information in the index file" msgstr "cáºp nháºt thông tin thống kê trong táºp tin lÆ°u bảng mục lục má»›i" -#: builtin/checkout-index.c:172 +#: builtin/checkout-index.c:175 msgid "read list of paths from the standard input" msgstr "Ä‘á»c danh sách Ä‘Æ°á»ng dẫn từ đầu và o tiêu chuẩn" -#: builtin/checkout-index.c:174 +#: builtin/checkout-index.c:177 msgid "write the content to temporary files" msgstr "ghi ná»™i dung và o táºp tin tạm" -#: builtin/checkout-index.c:175 builtin/column.c:31 -#: builtin/submodule--helper.c:1368 builtin/submodule--helper.c:1371 -#: builtin/submodule--helper.c:1379 builtin/submodule--helper.c:1853 -#: builtin/worktree.c:668 +#: builtin/checkout-index.c:178 builtin/column.c:31 +#: builtin/submodule--helper.c:1372 builtin/submodule--helper.c:1375 +#: builtin/submodule--helper.c:1383 builtin/submodule--helper.c:1857 +#: builtin/worktree.c:669 msgid "string" msgstr "chuá»—i" -#: builtin/checkout-index.c:176 +#: builtin/checkout-index.c:179 msgid "when creating files, prepend <string>" msgstr "khi tạo các táºp tin, nối thêm <chuá»—i>" -#: builtin/checkout-index.c:178 +#: builtin/checkout-index.c:181 msgid "copy out the files from named stage" msgstr "sao chép ra các táºp tin từ bệ phóng có tên" -#: builtin/checkout.c:31 +#: builtin/checkout.c:32 msgid "git checkout [<options>] <branch>" msgstr "git checkout [<các-tùy-chá»n>] <nhánh>" -#: builtin/checkout.c:32 +#: builtin/checkout.c:33 msgid "git checkout [<options>] [<branch>] -- <file>..." msgstr "git checkout [<các-tùy-chá»n>] [<nhánh>] -- <táºp-tin>…" -#: builtin/checkout.c:144 builtin/checkout.c:177 +#: builtin/checkout.c:147 builtin/checkout.c:181 #, c-format msgid "path '%s' does not have our version" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản của chúng ta" -#: builtin/checkout.c:146 builtin/checkout.c:179 +#: builtin/checkout.c:149 builtin/checkout.c:183 #, c-format msgid "path '%s' does not have their version" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản của chúng" -#: builtin/checkout.c:162 +#: builtin/checkout.c:165 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "Ä‘Æ°á»ng dẫn “%s†không có tất cả các phiên bản cần thiết" -#: builtin/checkout.c:206 +#: builtin/checkout.c:210 #, c-format msgid "path '%s' does not have necessary versions" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản cần thiết" -#: builtin/checkout.c:224 +#: builtin/checkout.c:228 #, c-format msgid "path '%s': cannot merge" msgstr "Ä‘Æ°á»ng dẫn “%sâ€: không thể hòa trá»™n" -#: builtin/checkout.c:240 +#: builtin/checkout.c:244 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Không thể thêm kết quả hòa trá»™n cho “%sâ€" -#: builtin/checkout.c:262 builtin/checkout.c:265 builtin/checkout.c:268 -#: builtin/checkout.c:271 +#: builtin/checkout.c:267 builtin/checkout.c:270 builtin/checkout.c:273 +#: builtin/checkout.c:276 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "không được dùng “%s†vá»›i các Ä‘Æ°á»ng dẫn cáºp nháºt" -#: builtin/checkout.c:274 builtin/checkout.c:277 +#: builtin/checkout.c:279 builtin/checkout.c:282 #, c-format msgid "'%s' cannot be used with %s" msgstr "không được dùng “%s†vá»›i %s" -#: builtin/checkout.c:280 +#: builtin/checkout.c:285 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "" "Không thể cáºp nháºt các Ä‘Æ°á»ng dẫn và chuyển đến nhánh “%s†cùng má»™t lúc." -#: builtin/checkout.c:349 builtin/checkout.c:356 +#: builtin/checkout.c:354 builtin/checkout.c:361 #, c-format msgid "path '%s' is unmerged" msgstr "Ä‘Æ°á»ng dẫn “%s†không được hòa trá»™n" -#: builtin/checkout.c:608 +#: builtin/checkout.c:397 +#, c-format +msgid "Recreated %d merge conflict" +msgid_plural "Recreated %d merge conflicts" +msgstr[0] "Äã tạo lại %d xung Ä‘á»™t hòa trá»™n" + +#: builtin/checkout.c:402 +#, c-format +msgid "Updated %d path from %s" +msgid_plural "Updated %d paths from %s" +msgstr[0] "Äã cáºp nháºt Ä‘Æ°á»ng dẫn %d từ %s" + +#: builtin/checkout.c:409 +#, c-format +msgid "Updated %d path from the index" +msgid_plural "Updated %d paths from the index" +msgstr[0] "Äã cáºp nháºt Ä‘Æ°á»ng dẫn %d từ mục lục" + +#: builtin/checkout.c:645 msgid "you need to resolve your current index first" msgstr "bạn cần phải giải quyết bảng mục lục hiện tại của bạn trÆ°á»›c đã" -#: builtin/checkout.c:745 +#: builtin/checkout.c:782 #, c-format msgid "Can not do reflog for '%s': %s\n" msgstr "Không thể thá»±c hiện reflog cho “%sâ€: %s\n" -#: builtin/checkout.c:786 +#: builtin/checkout.c:824 msgid "HEAD is now at" msgstr "HEAD hiện giá» tại" -#: builtin/checkout.c:790 builtin/clone.c:692 +#: builtin/checkout.c:828 builtin/clone.c:699 msgid "unable to update HEAD" msgstr "không thể cáºp nháºt HEAD" -#: builtin/checkout.c:794 +#: builtin/checkout.c:832 #, c-format msgid "Reset branch '%s'\n" msgstr "Äặt lại nhánh “%sâ€\n" -#: builtin/checkout.c:797 +#: builtin/checkout.c:835 #, c-format msgid "Already on '%s'\n" msgstr "Äã sẵn sà ng trên “%sâ€\n" -#: builtin/checkout.c:801 +#: builtin/checkout.c:839 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Äã chuyển tá»›i và đặt lại nhánh “%sâ€\n" -#: builtin/checkout.c:803 builtin/checkout.c:1166 +#: builtin/checkout.c:841 builtin/checkout.c:1212 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Äã chuyển đến nhánh má»›i “%sâ€\n" -#: builtin/checkout.c:805 +#: builtin/checkout.c:843 #, c-format msgid "Switched to branch '%s'\n" msgstr "Äã chuyển đến nhánh “%sâ€\n" -#: builtin/checkout.c:856 +#: builtin/checkout.c:894 #, c-format msgid " ... and %d more.\n" msgstr " … và nhiá»u hÆ¡n %d.\n" -#: builtin/checkout.c:862 +#: builtin/checkout.c:900 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -8753,7 +9413,7 @@ msgstr[0] "" "\n" "%s\n" -#: builtin/checkout.c:881 +#: builtin/checkout.c:919 #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -8774,164 +9434,173 @@ msgstr[0] "" " git branch <tên_nhánh_má»›i> %s\n" "\n" -#: builtin/checkout.c:913 +#: builtin/checkout.c:951 msgid "internal error in revision walk" msgstr "lá»—i ná»™i bá»™ trong khi di chuyển qua các Ä‘iểm xét duyệt" -#: builtin/checkout.c:917 +#: builtin/checkout.c:955 msgid "Previous HEAD position was" msgstr "Vị trà trÆ°á»›c kia của HEAD là " -#: builtin/checkout.c:945 builtin/checkout.c:1161 +#: builtin/checkout.c:983 builtin/checkout.c:1207 msgid "You are on a branch yet to be born" msgstr "Bạn tại nhánh mà nó chÆ°a hỠđược sinh ra" -#: builtin/checkout.c:1066 +#: builtin/checkout.c:1104 #, c-format msgid "only one reference expected, %d given." msgstr "chỉ cần má»™t tham chiếu, nhÆ°ng lại Ä‘Æ°a ra %d." -#: builtin/checkout.c:1107 builtin/worktree.c:289 builtin/worktree.c:444 +#: builtin/checkout.c:1140 +#, c-format +msgid "" +"'%s' could be both a local file and a tracking branch.\n" +"Please use -- (and optionally --no-guess) to disambiguate" +msgstr "" +"“%s†không thể là cả táºp tin ná»™i bá»™ và má»™t nhánh theo dõi.\n" +"Vui long dùng -- (và tùy chá»n thêm --no-guess) để tránh lẫn lá»™n" + +#: builtin/checkout.c:1153 builtin/worktree.c:290 builtin/worktree.c:445 #, c-format msgid "invalid reference: %s" msgstr "tham chiếu không hợp lệ: %s" -#: builtin/checkout.c:1136 +#: builtin/checkout.c:1182 #, c-format msgid "reference is not a tree: %s" msgstr "tham chiếu không phải là má»™t cây:%s" -#: builtin/checkout.c:1175 +#: builtin/checkout.c:1221 msgid "paths cannot be used with switching branches" msgstr "các Ä‘Æ°á»ng dẫn không thể dùng cùng vá»›i các nhánh chuyển" -#: builtin/checkout.c:1178 builtin/checkout.c:1182 +#: builtin/checkout.c:1224 builtin/checkout.c:1228 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "“%s†không thể được sá» dụng vá»›i các nhánh chuyển" -#: builtin/checkout.c:1186 builtin/checkout.c:1189 builtin/checkout.c:1194 -#: builtin/checkout.c:1197 +#: builtin/checkout.c:1232 builtin/checkout.c:1235 builtin/checkout.c:1240 +#: builtin/checkout.c:1243 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "“%s†không thể được dùng vá»›i “%sâ€" -#: builtin/checkout.c:1202 +#: builtin/checkout.c:1248 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "Không thể chuyển nhánh đến má»™t thứ không phải là lần chuyển giao “%sâ€" -#: builtin/checkout.c:1235 builtin/checkout.c:1237 builtin/clone.c:119 -#: builtin/remote.c:169 builtin/remote.c:171 builtin/worktree.c:488 -#: builtin/worktree.c:490 +#: builtin/checkout.c:1281 builtin/checkout.c:1283 builtin/clone.c:120 +#: builtin/remote.c:169 builtin/remote.c:171 builtin/worktree.c:489 +#: builtin/worktree.c:491 msgid "branch" msgstr "nhánh" -#: builtin/checkout.c:1236 +#: builtin/checkout.c:1282 msgid "create and checkout a new branch" msgstr "tạo và checkout má»™t nhánh má»›i" -#: builtin/checkout.c:1238 +#: builtin/checkout.c:1284 msgid "create/reset and checkout a branch" msgstr "tạo/đặt_lại và checkout má»™t nhánh" -#: builtin/checkout.c:1239 +#: builtin/checkout.c:1285 msgid "create reflog for new branch" msgstr "tạo reflog cho nhánh má»›i" -#: builtin/checkout.c:1240 builtin/worktree.c:492 +#: builtin/checkout.c:1286 builtin/worktree.c:493 msgid "detach HEAD at named commit" msgstr "rá»i bá» HEAD tại lần chuyển giao theo tên" -#: builtin/checkout.c:1241 +#: builtin/checkout.c:1287 msgid "set upstream info for new branch" msgstr "đặt thông tin thượng nguồn cho nhánh má»›i" -#: builtin/checkout.c:1243 +#: builtin/checkout.c:1289 msgid "new-branch" msgstr "nhánh-má»›i" -#: builtin/checkout.c:1243 +#: builtin/checkout.c:1289 msgid "new unparented branch" msgstr "nhánh không cha má»›i" -#: builtin/checkout.c:1245 +#: builtin/checkout.c:1291 msgid "checkout our version for unmerged files" msgstr "" "lấy ra (checkout) phiên bản của chúng ta cho các táºp tin chÆ°a được hòa trá»™n" -#: builtin/checkout.c:1248 +#: builtin/checkout.c:1294 msgid "checkout their version for unmerged files" msgstr "" "lấy ra (checkout) phiên bản của chúng há» cho các táºp tin chÆ°a được hòa trá»™n" -#: builtin/checkout.c:1250 +#: builtin/checkout.c:1296 msgid "force checkout (throw away local modifications)" msgstr "ép buá»™c lấy ra (bá» Ä‘i những thay đổi ná»™i bá»™)" -#: builtin/checkout.c:1252 +#: builtin/checkout.c:1298 msgid "perform a 3-way merge with the new branch" msgstr "thá»±c hiện hòa trá»™n kiểu 3-way vá»›i nhánh má»›i" -#: builtin/checkout.c:1254 builtin/merge.c:275 +#: builtin/checkout.c:1300 builtin/merge.c:276 msgid "update ignored files (default)" msgstr "cáºp nháºt các táºp tin bị bá» qua (mặc định)" -#: builtin/checkout.c:1256 builtin/log.c:1573 parse-options.h:274 +#: builtin/checkout.c:1302 builtin/log.c:1586 parse-options.h:272 msgid "style" msgstr "kiểu" -#: builtin/checkout.c:1257 +#: builtin/checkout.c:1303 msgid "conflict style (merge or diff3)" msgstr "xung Ä‘á»™t kiểu (hòa trá»™n hoặc diff3)" -#: builtin/checkout.c:1260 +#: builtin/checkout.c:1306 msgid "do not limit pathspecs to sparse entries only" msgstr "không giá»›i hạn đặc tả Ä‘Æ°á»ng dẫn thà nh chỉ các mục thÆ°a thá»›t" -#: builtin/checkout.c:1262 -msgid "second guess 'git checkout <no-such-branch>'" -msgstr "gợi ý thứ hai \"git checkout <không-nhánh-nà o-nhÆ°-váºy>\"" +#: builtin/checkout.c:1308 +msgid "do not second guess 'git checkout <no-such-branch>'" +msgstr "đừng gợi ý thứ hai \"git checkout <không-nhánh-nà o-nhÆ°-váºy>\"" -#: builtin/checkout.c:1264 +#: builtin/checkout.c:1310 msgid "do not check if another worktree is holding the given ref" msgstr "không kiểm tra nếu cây là m việc khác Ä‘ang giữ tham chiếu đã cho" -#: builtin/checkout.c:1268 builtin/clone.c:86 builtin/fetch.c:141 -#: builtin/merge.c:272 builtin/pull.c:129 builtin/push.c:572 +#: builtin/checkout.c:1314 builtin/clone.c:87 builtin/fetch.c:141 +#: builtin/merge.c:273 builtin/pull.c:130 builtin/push.c:575 #: builtin/send-pack.c:174 msgid "force progress reporting" msgstr "ép buá»™c báo cáo tiến triển công việc" -#: builtin/checkout.c:1298 +#: builtin/checkout.c:1345 msgid "-b, -B and --orphan are mutually exclusive" msgstr "Các tùy chá»n -b, -B và --orphan loại từ lẫn nhau" -#: builtin/checkout.c:1315 +#: builtin/checkout.c:1362 msgid "--track needs a branch name" msgstr "--track cần tên má»™t nhánh" -#: builtin/checkout.c:1320 +#: builtin/checkout.c:1367 msgid "missing branch name; try -b" msgstr "thiếu tên nhánh; hãy thá» -b" -#: builtin/checkout.c:1357 +#: builtin/checkout.c:1404 msgid "invalid path specification" msgstr "Ä‘Æ°á»ng dẫn đã cho không hợp lệ" -#: builtin/checkout.c:1364 +#: builtin/checkout.c:1411 #, c-format msgid "'%s' is not a commit and a branch '%s' cannot be created from it" msgstr "" "“%s†không phải là má»™t lần chuyển giao và má»™t nhánh'%s†không thể được tạo " "từ đó" -#: builtin/checkout.c:1368 +#: builtin/checkout.c:1415 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: --detach không nháºn má»™t đối số Ä‘Æ°á»ng dẫn “%sâ€" -#: builtin/checkout.c:1372 +#: builtin/checkout.c:1419 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -8939,7 +9608,7 @@ msgstr "" "git checkout: --ours/--theirs, --force và --merge là xung khắc vá»›i nhau khi\n" "checkout bảng mục lục (index)." -#: builtin/checkout.c:1392 +#: builtin/checkout.c:1439 #, c-format msgid "" "'%s' matched more than one remote tracking branch.\n" @@ -8969,38 +9638,38 @@ msgstr "" "chÆ°a rõ rà ng, và dụ máy chủ “originâ€, cân nhắc cà i đặt\n" "checkout.defaultRemote=origin trong cấu hình của bạn." -#: builtin/clean.c:27 +#: builtin/clean.c:28 msgid "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <pattern>] [-x | -X] [--] <paths>..." msgstr "" "git clean [-d] [-f] [-i] [-n] [-q] [-e <mẫu>] [-x | -X] [--] <Ä‘Æ°á»ng-dẫn>…" -#: builtin/clean.c:31 +#: builtin/clean.c:32 #, c-format msgid "Removing %s\n" msgstr "Äang gỡ bá» %s\n" -#: builtin/clean.c:32 +#: builtin/clean.c:33 #, c-format msgid "Would remove %s\n" msgstr "Có thể gỡ bá» %s\n" -#: builtin/clean.c:33 +#: builtin/clean.c:34 #, c-format msgid "Skipping repository %s\n" msgstr "Äang bá» qua kho chứa %s\n" -#: builtin/clean.c:34 +#: builtin/clean.c:35 #, c-format msgid "Would skip repository %s\n" msgstr "Nên bá» qua kho chứa %s\n" -#: builtin/clean.c:35 +#: builtin/clean.c:36 #, c-format msgid "failed to remove %s" msgstr "gặp lá»—i khi gỡ bá» %s" -#: builtin/clean.c:298 git-add--interactive.perl:579 +#: builtin/clean.c:299 git-add--interactive.perl:579 #, c-format msgid "" "Prompt help:\n" @@ -9013,7 +9682,7 @@ msgstr "" "foo - chá»n mục trên cÆ¡ sở tiá»n tố duy nhất\n" " - (để trống) không chá»n gì cả\n" -#: builtin/clean.c:302 git-add--interactive.perl:588 +#: builtin/clean.c:303 git-add--interactive.perl:588 #, c-format msgid "" "Prompt help:\n" @@ -9034,38 +9703,38 @@ msgstr "" "* - chá»n tất\n" " - (để trống) kết thúc việc chá»n\n" -#: builtin/clean.c:518 git-add--interactive.perl:554 +#: builtin/clean.c:519 git-add--interactive.perl:554 #: git-add--interactive.perl:559 #, c-format, perl-format msgid "Huh (%s)?\n" msgstr "Hả (%s)?\n" -#: builtin/clean.c:660 +#: builtin/clean.c:661 #, c-format msgid "Input ignore patterns>> " msgstr "Mẫu để lá»c các táºp tin đầu và o cần lá» Ä‘i>> " -#: builtin/clean.c:697 +#: builtin/clean.c:698 #, c-format msgid "WARNING: Cannot find items matched by: %s" msgstr "CẢNH BÃO: Không tìm thấy các mục được khá»›p bởi: %s" -#: builtin/clean.c:718 +#: builtin/clean.c:719 msgid "Select items to delete" msgstr "Chá»n mục muốn xóa" #. TRANSLATORS: Make sure to keep [y/N] as is -#: builtin/clean.c:759 +#: builtin/clean.c:760 #, c-format msgid "Remove %s [y/N]? " msgstr "Xóa bỠ“%s†[y/N]? " -#: builtin/clean.c:784 git-add--interactive.perl:1717 +#: builtin/clean.c:785 git-add--interactive.perl:1717 #, c-format msgid "Bye.\n" msgstr "Tạm biệt.\n" -#: builtin/clean.c:792 +#: builtin/clean.c:793 msgid "" "clean - start cleaning\n" "filter by pattern - exclude items from deletion\n" @@ -9083,63 +9752,63 @@ msgstr "" "help - hiển thị chÃnh trợ giúp nà y\n" "? - trợ giúp dà nh cho chá»n bằng cách nhắc" -#: builtin/clean.c:819 git-add--interactive.perl:1793 +#: builtin/clean.c:820 git-add--interactive.perl:1793 msgid "*** Commands ***" msgstr "*** Lệnh ***" -#: builtin/clean.c:820 git-add--interactive.perl:1790 +#: builtin/clean.c:821 git-add--interactive.perl:1790 msgid "What now" msgstr "Giá» thì sao" -#: builtin/clean.c:828 +#: builtin/clean.c:829 msgid "Would remove the following item:" msgid_plural "Would remove the following items:" msgstr[0] "Có muốn gỡ bá» (các) mục sau đây không:" -#: builtin/clean.c:844 +#: builtin/clean.c:845 msgid "No more files to clean, exiting." msgstr "Không còn táºp-tin nà o để dá»n dẹp, Ä‘ang thoát ra." -#: builtin/clean.c:906 +#: builtin/clean.c:907 msgid "do not print names of files removed" msgstr "không hiển thị tên của các táºp tin đã gỡ bá»" -#: builtin/clean.c:908 +#: builtin/clean.c:909 msgid "force" msgstr "ép buá»™c" -#: builtin/clean.c:909 +#: builtin/clean.c:910 msgid "interactive cleaning" msgstr "dá»n bằng kiểu tÆ°Æ¡ng tác" -#: builtin/clean.c:911 +#: builtin/clean.c:912 msgid "remove whole directories" msgstr "gỡ bá» toà n bá»™ thÆ° mục" -#: builtin/clean.c:912 builtin/describe.c:545 builtin/describe.c:547 -#: builtin/grep.c:886 builtin/log.c:166 builtin/log.c:168 -#: builtin/ls-files.c:556 builtin/name-rev.c:415 builtin/name-rev.c:417 +#: builtin/clean.c:913 builtin/describe.c:546 builtin/describe.c:548 +#: builtin/grep.c:897 builtin/log.c:167 builtin/log.c:169 +#: builtin/ls-files.c:557 builtin/name-rev.c:415 builtin/name-rev.c:417 #: builtin/show-ref.c:178 msgid "pattern" msgstr "mẫu" -#: builtin/clean.c:913 +#: builtin/clean.c:914 msgid "add <pattern> to ignore rules" msgstr "thêm <mẫu> và o trong qui tắc bá» qua" -#: builtin/clean.c:914 +#: builtin/clean.c:915 msgid "remove ignored files, too" msgstr "đồng thá»i gỡ bá» cả các táºp tin bị bá» qua" -#: builtin/clean.c:916 +#: builtin/clean.c:917 msgid "remove only ignored files" msgstr "chỉ gỡ bá» những táºp tin bị bá» qua" -#: builtin/clean.c:934 +#: builtin/clean.c:935 msgid "-x and -X cannot be used together" msgstr "-x và -X không thể dùng cùng nhau" -#: builtin/clean.c:938 +#: builtin/clean.c:939 msgid "" "clean.requireForce set to true and neither -i, -n, nor -f given; refusing to " "clean" @@ -9147,7 +9816,7 @@ msgstr "" "clean.requireForce được đặt thà nh true và không Ä‘Æ°a ra tùy chá»n -i, -n mà " "cÅ©ng không -f; từ chối lệnh dá»n dẹp (clean)" -#: builtin/clean.c:941 +#: builtin/clean.c:942 msgid "" "clean.requireForce defaults to true and neither -i, -n, nor -f given; " "refusing to clean" @@ -9155,148 +9824,148 @@ msgstr "" "clean.requireForce mặc định được đặt là true và không Ä‘Æ°a ra tùy chá»n -i, -n " "mà cÅ©ng không -f; từ chối lệnh dá»n dẹp (clean)" -#: builtin/clone.c:43 +#: builtin/clone.c:44 msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<các-tùy-chá»n>] [--] <kho> [<t.mục>]" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "don't create a checkout" msgstr "không tạo má»™t checkout" -#: builtin/clone.c:89 builtin/clone.c:91 builtin/init-db.c:481 +#: builtin/clone.c:90 builtin/clone.c:92 builtin/init-db.c:481 msgid "create a bare repository" msgstr "tạo kho thuần" -#: builtin/clone.c:93 +#: builtin/clone.c:94 msgid "create a mirror repository (implies bare)" msgstr "tạo kho bản sao (ý là kho thuần)" -#: builtin/clone.c:95 +#: builtin/clone.c:96 msgid "to clone from a local repository" msgstr "để nhân bản từ kho ná»™i bá»™" -#: builtin/clone.c:97 +#: builtin/clone.c:98 msgid "don't use local hardlinks, always copy" msgstr "không sá» dụng liên kết cứng ná»™i bá»™, luôn sao chép" -#: builtin/clone.c:99 +#: builtin/clone.c:100 msgid "setup as shared repository" msgstr "cà i đặt đây là kho chia sẻ" -#: builtin/clone.c:101 builtin/clone.c:105 +#: builtin/clone.c:102 builtin/clone.c:106 msgid "pathspec" msgstr "đặc-tả-Ä‘Æ°á»ng-dẫn" -#: builtin/clone.c:101 builtin/clone.c:105 +#: builtin/clone.c:102 builtin/clone.c:106 msgid "initialize submodules in the clone" msgstr "khởi tạo mô-Ä‘un-con trong bản sao" -#: builtin/clone.c:108 +#: builtin/clone.c:109 msgid "number of submodules cloned in parallel" msgstr "số lượng mô-Ä‘un-con được nhân bản đồng thá»i" -#: builtin/clone.c:109 builtin/init-db.c:478 +#: builtin/clone.c:110 builtin/init-db.c:478 msgid "template-directory" msgstr "thÆ°-mục-mẫu" -#: builtin/clone.c:110 builtin/init-db.c:479 +#: builtin/clone.c:111 builtin/init-db.c:479 msgid "directory from which templates will be used" msgstr "thÆ° mục mà tại đó các mẫu sẽ được dùng" -#: builtin/clone.c:112 builtin/clone.c:114 builtin/submodule--helper.c:1375 -#: builtin/submodule--helper.c:1856 +#: builtin/clone.c:113 builtin/clone.c:115 builtin/submodule--helper.c:1379 +#: builtin/submodule--helper.c:1860 msgid "reference repository" msgstr "kho tham chiếu" -#: builtin/clone.c:116 builtin/submodule--helper.c:1377 -#: builtin/submodule--helper.c:1858 +#: builtin/clone.c:117 builtin/submodule--helper.c:1381 +#: builtin/submodule--helper.c:1862 msgid "use --reference only while cloning" msgstr "chỉ dùng --reference khi nhân bản" -#: builtin/clone.c:117 builtin/column.c:27 builtin/merge-file.c:46 -#: builtin/pack-objects.c:3301 builtin/repack.c:329 +#: builtin/clone.c:118 builtin/column.c:27 builtin/merge-file.c:46 +#: builtin/pack-objects.c:3303 builtin/repack.c:329 msgid "name" msgstr "tên" -#: builtin/clone.c:118 +#: builtin/clone.c:119 msgid "use <name> instead of 'origin' to track upstream" msgstr "dùng <tên> thay cho “origin†để theo dõi thượng nguồn" -#: builtin/clone.c:120 +#: builtin/clone.c:121 msgid "checkout <branch> instead of the remote's HEAD" msgstr "lấy ra <nhánh> thay cho HEAD của máy chủ" -#: builtin/clone.c:122 +#: builtin/clone.c:123 msgid "path to git-upload-pack on the remote" msgstr "Ä‘Æ°á»ng dẫn đến git-upload-pack trên máy chủ" -#: builtin/clone.c:123 builtin/fetch.c:142 builtin/grep.c:825 -#: builtin/pull.c:217 +#: builtin/clone.c:124 builtin/fetch.c:142 builtin/grep.c:836 +#: builtin/pull.c:218 msgid "depth" msgstr "Ä‘á»™-sâu" -#: builtin/clone.c:124 +#: builtin/clone.c:125 msgid "create a shallow clone of that depth" msgstr "tạo bản sao không đầy đủ cho mức sâu đã cho" -#: builtin/clone.c:125 builtin/fetch.c:144 builtin/pack-objects.c:3292 +#: builtin/clone.c:126 builtin/fetch.c:144 builtin/pack-objects.c:3292 msgid "time" msgstr "thá»i-gian" -#: builtin/clone.c:126 +#: builtin/clone.c:127 msgid "create a shallow clone since a specific time" msgstr "tạo bản sao không đầy đủ từ thá»i Ä‘iểm đã cho" -#: builtin/clone.c:127 builtin/fetch.c:146 builtin/fetch.c:169 -#: builtin/rebase.c:831 +#: builtin/clone.c:128 builtin/fetch.c:146 builtin/fetch.c:169 +#: builtin/rebase.c:1039 msgid "revision" msgstr "Ä‘iểm xét duyệt" -#: builtin/clone.c:128 builtin/fetch.c:147 +#: builtin/clone.c:129 builtin/fetch.c:147 msgid "deepen history of shallow clone, excluding rev" msgstr "là m sâu hÆ¡n lịch sá» của bản sao shallow, bằng Ä‘iểm xét duyệt loại trừ" -#: builtin/clone.c:130 +#: builtin/clone.c:131 msgid "clone only one branch, HEAD or --branch" msgstr "chỉ nhân bản má»™t nhánh, HEAD hoặc --branch" -#: builtin/clone.c:132 +#: builtin/clone.c:133 msgid "don't clone any tags, and make later fetches not to follow them" msgstr "" "đứng có nhân bản bất kỳ nhánh nà o, và là m cho những lần lấy vá» sau không " "theo chúng nữa" -#: builtin/clone.c:134 +#: builtin/clone.c:135 msgid "any cloned submodules will be shallow" msgstr "má»i mô-Ä‘un-con nhân bản sẽ là shallow (nông)" -#: builtin/clone.c:135 builtin/init-db.c:487 +#: builtin/clone.c:136 builtin/init-db.c:487 msgid "gitdir" msgstr "gitdir" -#: builtin/clone.c:136 builtin/init-db.c:488 +#: builtin/clone.c:137 builtin/init-db.c:488 msgid "separate git dir from working tree" msgstr "không dùng chung thÆ° mục dà nh riêng cho git và thÆ° mục là m việc" -#: builtin/clone.c:137 +#: builtin/clone.c:138 msgid "key=value" msgstr "khóa=giá_trị" -#: builtin/clone.c:138 +#: builtin/clone.c:139 msgid "set config inside the new repository" msgstr "đặt cấu hình bên trong má»™t kho chứa má»›i" -#: builtin/clone.c:139 builtin/fetch.c:165 builtin/pull.c:230 -#: builtin/push.c:583 +#: builtin/clone.c:140 builtin/fetch.c:165 builtin/pull.c:231 +#: builtin/push.c:586 msgid "use IPv4 addresses only" msgstr "chỉ dùng địa chỉ IPv4" -#: builtin/clone.c:141 builtin/fetch.c:167 builtin/pull.c:233 -#: builtin/push.c:585 +#: builtin/clone.c:142 builtin/fetch.c:167 builtin/pull.c:234 +#: builtin/push.c:588 msgid "use IPv6 addresses only" msgstr "chỉ dùng địa chỉ IPv6" -#: builtin/clone.c:279 +#: builtin/clone.c:280 msgid "" "No directory name could be guessed.\n" "Please specify a directory on the command line" @@ -9304,47 +9973,47 @@ msgstr "" "Không Ä‘oán được thÆ° mục tên là gì.\n" "Vui lòng chỉ định tên má»™t thÆ° mục trên dòng lệnh" -#: builtin/clone.c:332 +#: builtin/clone.c:333 #, c-format msgid "info: Could not add alternate for '%s': %s\n" msgstr "thông tin: không thể thêm thay thế cho “%sâ€: %s\n" -#: builtin/clone.c:404 +#: builtin/clone.c:405 #, c-format msgid "failed to open '%s'" msgstr "gặp lá»—i khi mở “%sâ€" -#: builtin/clone.c:412 +#: builtin/clone.c:413 #, c-format msgid "%s exists and is not a directory" msgstr "%s có tồn tại nhÆ°ng lại không phải là má»™t thÆ° mục" -#: builtin/clone.c:426 +#: builtin/clone.c:427 #, c-format msgid "failed to stat %s\n" msgstr "gặp lá»—i khi lấy thông tin thống kê vá» %s\n" -#: builtin/clone.c:443 +#: builtin/clone.c:444 #, c-format msgid "failed to unlink '%s'" msgstr "gặp lá»—i khi bá» liên kết (unlink) “%sâ€" -#: builtin/clone.c:448 +#: builtin/clone.c:449 #, c-format msgid "failed to create link '%s'" msgstr "gặp lá»—i khi tạo được liên kết má»m %s" -#: builtin/clone.c:452 +#: builtin/clone.c:453 #, c-format msgid "failed to copy file to '%s'" msgstr "gặp lá»—i khi sao chép táºp tin và “%sâ€" -#: builtin/clone.c:478 +#: builtin/clone.c:479 #, c-format msgid "done.\n" msgstr "hoà n tất.\n" -#: builtin/clone.c:492 +#: builtin/clone.c:493 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -9354,95 +10023,95 @@ msgstr "" "Bạn kiểm tra kỹ xem cái gì được lấy ra bằng lệnh “git statusâ€\n" "và thá» lấy ra vá»›i lệnh “git checkout -f HEADâ€\n" -#: builtin/clone.c:569 +#: builtin/clone.c:570 #, 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)." -#: builtin/clone.c:680 +#: builtin/clone.c:687 #, c-format msgid "unable to update %s" msgstr "không thể cáºp nháºt %s" -#: builtin/clone.c:730 +#: builtin/clone.c:737 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "refers HEAD máy chủ chỉ đến ref không tồn tại, không thể lấy ra.\n" -#: builtin/clone.c:761 +#: builtin/clone.c:768 msgid "unable to checkout working tree" msgstr "không thể lấy ra (checkout) cây là m việc" -#: builtin/clone.c:806 +#: builtin/clone.c:813 msgid "unable to write parameters to config file" msgstr "không thể ghi các tham số và o táºp tin cấu hình" -#: builtin/clone.c:869 +#: builtin/clone.c:876 msgid "cannot repack to clean up" msgstr "không thể đóng gói để dá»n dẹp" -#: builtin/clone.c:871 +#: builtin/clone.c:878 msgid "cannot unlink temporary alternates file" msgstr "không thể bá» liên kết táºp tin thay thế tạm thá»i" -#: builtin/clone.c:911 builtin/receive-pack.c:1941 +#: builtin/clone.c:918 builtin/receive-pack.c:1941 msgid "Too many arguments." msgstr "Có quá nhiá»u đối số." -#: builtin/clone.c:915 +#: builtin/clone.c:922 msgid "You must specify a repository to clone." msgstr "Bạn phải chỉ định má»™t kho để mà nhân bản (clone)." -#: builtin/clone.c:928 +#: builtin/clone.c:935 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "tùy chá»n --bare và --origin %s xung khắc nhau." -#: builtin/clone.c:931 +#: builtin/clone.c:938 msgid "--bare and --separate-git-dir are incompatible." msgstr "tùy chá»n --bare và --separate-git-dir xung khắc nhau." -#: builtin/clone.c:944 +#: builtin/clone.c:951 #, c-format msgid "repository '%s' does not exist" msgstr "kho chứa “%s†chÆ°a tồn tại" -#: builtin/clone.c:950 builtin/fetch.c:1606 +#: builtin/clone.c:957 builtin/fetch.c:1608 #, c-format msgid "depth %s is not a positive number" msgstr "Ä‘á»™ sâu %s không phải là má»™t số nguyên dÆ°Æ¡ng" -#: builtin/clone.c:960 +#: builtin/clone.c:967 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "Ä‘Æ°á»ng dẫn Ä‘Ãch “%s†đã có từ trÆ°á»›c và không phải là má»™t thÆ° mục rá»—ng." -#: builtin/clone.c:970 +#: builtin/clone.c:977 #, c-format msgid "working tree '%s' already exists." msgstr "cây là m việc “%s†đã sẵn tồn tại rồi." -#: builtin/clone.c:985 builtin/clone.c:1006 builtin/difftool.c:271 -#: builtin/worktree.c:295 builtin/worktree.c:325 +#: builtin/clone.c:992 builtin/clone.c:1013 builtin/difftool.c:272 +#: builtin/worktree.c:296 builtin/worktree.c:326 #, c-format msgid "could not create leading directories of '%s'" msgstr "không thể tạo các thÆ° mục dẫn đầu của “%sâ€" -#: builtin/clone.c:990 +#: builtin/clone.c:997 #, c-format msgid "could not create work tree dir '%s'" msgstr "không thể tạo cây thÆ° mục là m việc dir “%sâ€" -#: builtin/clone.c:1010 +#: builtin/clone.c:1017 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Äang nhân bản thà nh kho chứa bare “%sâ€â€¦\n" -#: builtin/clone.c:1012 +#: builtin/clone.c:1019 #, c-format msgid "Cloning into '%s'...\n" msgstr "Äang nhân bản thà nh “%sâ€â€¦\n" -#: builtin/clone.c:1036 +#: builtin/clone.c:1043 msgid "" "clone --recursive is not compatible with both --reference and --reference-if-" "able" @@ -9450,41 +10119,41 @@ msgstr "" "nhân bản --recursive không tÆ°Æ¡ng thÃch vá»›i cả hai --reference và --reference-" "if-able" -#: builtin/clone.c:1097 +#: builtin/clone.c:1104 msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth bị lá» Ä‘i khi nhân bản ná»™i bá»™; hãy sá» dụng file:// để thay thế." -#: builtin/clone.c:1099 +#: builtin/clone.c:1106 msgid "--shallow-since is ignored in local clones; use file:// instead." msgstr "" "--shallow-since bị lá» Ä‘i khi nhân bản ná»™i bá»™; hãy sá» dụng file:// để thay " "thế." -#: builtin/clone.c:1101 +#: builtin/clone.c:1108 msgid "--shallow-exclude is ignored in local clones; use file:// instead." msgstr "" "--shallow-exclude bị lá» Ä‘i khi nhân bản ná»™i bá»™; hãy sá» dụng file:// để thay " "thế." -#: builtin/clone.c:1103 +#: builtin/clone.c:1110 msgid "--filter is ignored in local clones; use file:// instead." msgstr "" "--filter bị lá» Ä‘i khi nhân bản ná»™i bá»™; hãy sá» dụng file:// để thay thế." -#: builtin/clone.c:1106 +#: builtin/clone.c:1113 msgid "source repository is shallow, ignoring --local" msgstr "kho nguồn là nông, nên bá» qua --local" -#: builtin/clone.c:1111 +#: builtin/clone.c:1118 msgid "--local is ignored" msgstr "--local bị lá» Ä‘i" -#: builtin/clone.c:1181 builtin/clone.c:1189 +#: builtin/clone.c:1192 builtin/clone.c:1200 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "Nhánh máy chủ %s không tìm thấy trong thượng nguồn %s" -#: builtin/clone.c:1192 +#: builtin/clone.c:1203 msgid "You appear to have cloned an empty repository." msgstr "Bạn hình nhÆ° là đã nhân bản má»™t kho trống rá»—ng." @@ -9520,15 +10189,15 @@ msgstr "Chèn thêm khoảng trắng giữa các cá»™t" msgid "--command must be the first argument" msgstr "--command phải là đối số đầu tiên" -#: builtin/commit.c:40 +#: builtin/commit.c:41 msgid "git commit [<options>] [--] <pathspec>..." msgstr "git commit [<các-tùy-chá»n>] [--] <pathspec>…" -#: builtin/commit.c:45 +#: builtin/commit.c:46 msgid "git status [<options>] [--] <pathspec>..." msgstr "git status [<các-tùy-chá»n>] [--] <pathspec>…" -#: builtin/commit.c:50 +#: builtin/commit.c:51 msgid "" "You asked to amend the most recent commit, but doing so would make\n" "it empty. You can repeat your command with --allow-empty, or you can\n" @@ -9541,7 +10210,7 @@ msgstr "" "hoặc là bạn gỡ bá» các lần chuyển giao má»™t cách hoà n toà n bằng lệnh:\n" "\"git reset HEAD^\".\n" -#: builtin/commit.c:55 +#: builtin/commit.c:56 msgid "" "The previous cherry-pick is now empty, possibly due to conflict resolution.\n" "If you wish to commit it anyway, use:\n" @@ -9556,11 +10225,11 @@ msgstr "" " git commit --allow-empty\n" "\n" -#: builtin/commit.c:62 +#: builtin/commit.c:63 msgid "Otherwise, please use 'git reset'\n" msgstr "Nếu không được thì dùng lệnh \"git reset\"\n" -#: builtin/commit.c:65 +#: builtin/commit.c:66 msgid "" "If you wish to skip this commit, use:\n" "\n" @@ -9576,63 +10245,63 @@ msgstr "" "Thế thì \"git cherry-pick --continue\" sẽ phục hồi lại việc cherry-pick\n" "những lần chuyển giao còn lại.\n" -#: builtin/commit.c:311 +#: builtin/commit.c:312 msgid "failed to unpack HEAD tree object" msgstr "gặp lá»—i khi tháo dỡ HEAD đối tượng cây" -#: builtin/commit.c:352 +#: builtin/commit.c:353 msgid "unable to create temporary index" msgstr "không thể tạo bảng mục lục tạm thá»i" -#: builtin/commit.c:358 +#: builtin/commit.c:359 msgid "interactive add failed" msgstr "gặp lá»—i khi thêm bằng cách tÆ°Æ¡ng" -#: builtin/commit.c:371 +#: builtin/commit.c:373 msgid "unable to update temporary index" msgstr "không thể cáºp nháºt bảng mục lục tạm thá»i" -#: builtin/commit.c:373 +#: builtin/commit.c:375 msgid "Failed to update main cache tree" msgstr "Gặp lá»—i khi cáºp nháºt cây bá»™ nhá»› đệm" -#: builtin/commit.c:398 builtin/commit.c:421 builtin/commit.c:467 +#: builtin/commit.c:400 builtin/commit.c:423 builtin/commit.c:469 msgid "unable to write new_index file" msgstr "không thể ghi táºp tin lÆ°u bảng mục lục má»›i (new_index)" -#: builtin/commit.c:450 +#: builtin/commit.c:452 msgid "cannot do a partial commit during a merge." msgstr "" "không thể thá»±c hiện việc chuyển giao cục bá»™ trong khi Ä‘ang được hòa trá»™n." -#: builtin/commit.c:452 +#: builtin/commit.c:454 msgid "cannot do a partial commit during a cherry-pick." msgstr "" "không thể thá»±c hiện việc chuyển giao bá»™ pháºn trong khi Ä‘ang cherry-pick." -#: builtin/commit.c:460 +#: builtin/commit.c:462 msgid "cannot read the index" msgstr "không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:479 +#: builtin/commit.c:481 msgid "unable to write temporary index file" msgstr "không thể ghi táºp tin lÆ°u bảng mục lục tạm thá»i" -#: builtin/commit.c:577 +#: builtin/commit.c:579 #, c-format msgid "commit '%s' lacks author header" msgstr "lần chuyển giao “%s†thiếu phần tác giả ở đầu" -#: builtin/commit.c:579 +#: builtin/commit.c:581 #, c-format msgid "commit '%s' has malformed author line" msgstr "lần chuyển giao “%s†có phần tác giả ở đầu dị dạng" -#: builtin/commit.c:598 +#: builtin/commit.c:600 msgid "malformed --author parameter" msgstr "đối số cho --author bị dị hình" -#: builtin/commit.c:650 +#: builtin/commit.c:652 msgid "" "unable to select a comment character that is not used\n" "in the current commit message" @@ -9640,38 +10309,38 @@ msgstr "" "không thể chá»n má»™t ký tá»± ghi chú cái mà không được dùng\n" "trong phần ghi chú hiện tại" -#: builtin/commit.c:687 builtin/commit.c:720 builtin/commit.c:1049 +#: builtin/commit.c:689 builtin/commit.c:722 builtin/commit.c:1052 #, c-format msgid "could not lookup commit %s" msgstr "không thể tìm kiếm commit (lần chuyển giao) %s" -#: builtin/commit.c:699 builtin/shortlog.c:317 +#: builtin/commit.c:701 builtin/shortlog.c:319 #, c-format msgid "(reading log message from standard input)\n" msgstr "(Ä‘ang Ä‘á»c thông Ä‘iệp nháºt ký từ đầu và o tiêu chuẩn)\n" -#: builtin/commit.c:701 +#: builtin/commit.c:703 msgid "could not read log from standard input" msgstr "không thể Ä‘á»c nháºt ký từ đầu và o tiêu chuẩn" -#: builtin/commit.c:705 +#: builtin/commit.c:707 #, c-format msgid "could not read log file '%s'" msgstr "không Ä‘á»c được tệp nháºt ký “%sâ€" -#: builtin/commit.c:734 builtin/commit.c:742 +#: builtin/commit.c:736 builtin/commit.c:744 msgid "could not read SQUASH_MSG" msgstr "không thể Ä‘á»c SQUASH_MSG" -#: builtin/commit.c:739 +#: builtin/commit.c:741 msgid "could not read MERGE_MSG" msgstr "không thể Ä‘á»c MERGE_MSG" -#: builtin/commit.c:793 +#: builtin/commit.c:795 msgid "could not write commit template" msgstr "không thể ghi mẫu chuyển giao" -#: builtin/commit.c:811 +#: builtin/commit.c:813 #, c-format msgid "" "\n" @@ -9686,7 +10355,7 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:816 +#: builtin/commit.c:818 #, c-format msgid "" "\n" @@ -9701,7 +10370,7 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:829 +#: builtin/commit.c:831 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -9712,7 +10381,7 @@ msgstr "" "bắt đầu bằng “%c†sẽ được bá» qua, nếu phần chú thÃch rá»—ng sẽ hủy bá» lần " "chuyển giao.\n" -#: builtin/commit.c:837 +#: builtin/commit.c:839 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -9724,157 +10393,156 @@ msgstr "" "bắt đầu bằng “%c†sẽ được bá» qua; bạn có thể xóa chúng Ä‘i nếu muốn thế.\n" "Phần chú thÃch nà y nếu trống rá»—ng sẽ hủy bá» lần chuyển giao.\n" -#: builtin/commit.c:854 +#: builtin/commit.c:856 #, c-format msgid "%sAuthor: %.*s <%.*s>" msgstr "%sTác giả: %.*s <%.*s>" -#: builtin/commit.c:862 +#: builtin/commit.c:864 #, c-format msgid "%sDate: %s" msgstr "%sNgà y tháng: %s" -#: builtin/commit.c:869 +#: builtin/commit.c:871 #, c-format msgid "%sCommitter: %.*s <%.*s>" msgstr "%sNgÆ°á»i chuyển giao: %.*s <%.*s>" -#: builtin/commit.c:887 +#: builtin/commit.c:889 msgid "Cannot read index" msgstr "Không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:953 +#: builtin/commit.c:956 msgid "Error building trees" msgstr "Gặp lá»—i khi xây dá»±ng cây" -#: builtin/commit.c:967 builtin/tag.c:258 +#: builtin/commit.c:970 builtin/tag.c:258 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Xin hãy cung cấp lá»i chú giải hoặc là dùng tùy chá»n -m hoặc là -F.\n" -#: builtin/commit.c:1011 +#: builtin/commit.c:1014 #, c-format msgid "--author '%s' is not 'Name <email>' and matches no existing author" msgstr "" "--author “%s†không phải là “Há» và tên <thÆ° Ä‘iện tá»l>†và không khá»›p bất kỳ " "tác giả nà o sẵn có" -#: builtin/commit.c:1025 +#: builtin/commit.c:1028 #, c-format msgid "Invalid ignored mode '%s'" msgstr "Chế Ä‘á»™ bá» qua không hợp lệ “%sâ€" -#: builtin/commit.c:1039 builtin/commit.c:1276 +#: builtin/commit.c:1042 builtin/commit.c:1279 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Chế Ä‘á»™ cho các táºp tin chÆ°a được theo dõi không hợp lệ “%sâ€" -#: builtin/commit.c:1077 +#: builtin/commit.c:1080 msgid "--long and -z are incompatible" msgstr "hai tùy chá»n -long và -z không tÆ°Æ¡ng thÃch vá»›i nhau" -#: builtin/commit.c:1110 +#: builtin/commit.c:1113 msgid "Using both --reset-author and --author does not make sense" msgstr "Sá» dụng cả hai tùy chá»n --reset-author và --author không hợp lý" -#: builtin/commit.c:1119 +#: builtin/commit.c:1122 msgid "You have nothing to amend." msgstr "Không có gì để mà “tu bổ†cả." -#: builtin/commit.c:1122 +#: builtin/commit.c:1125 msgid "You are in the middle of a merge -- cannot amend." msgstr "" "Bạn Ä‘ang ở giữa của quá trình hòa trá»™n -- không thể thá»±c hiện việc “tu bổâ€." -#: builtin/commit.c:1124 +#: builtin/commit.c:1127 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "" "Bạn Ä‘ang ở giữa của quá trình cherry-pick -- không thể thá»±c hiện việc “tu " "bổâ€." -#: builtin/commit.c:1127 +#: builtin/commit.c:1130 msgid "Options --squash and --fixup cannot be used together" msgstr "Các tùy chá»n --squash và --fixup không thể sá» dụng cùng vá»›i nhau" -#: builtin/commit.c:1137 +#: builtin/commit.c:1140 msgid "Only one of -c/-C/-F/--fixup can be used." -msgstr "" -"Chỉ được dùng má»™t trong số tùy chá»n trong số các tùy chá»n -c/-C/-F/--fixup" +msgstr "Chỉ được dùng má»™t trong số tùy chá»n trong số -c/-C/-F/--fixup." -#: builtin/commit.c:1139 +#: builtin/commit.c:1142 msgid "Option -m cannot be combined with -c/-C/-F." msgstr "Tùy chá»n -m không thể được tổ hợp cùng vá»›i -c/-C/-F." -#: builtin/commit.c:1147 +#: builtin/commit.c:1150 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" "--reset-author chỉ có thể được sá» dụng vá»›i tùy chá»n -C, -c hay --amend." -#: builtin/commit.c:1164 +#: builtin/commit.c:1167 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Chỉ má»™t trong các tùy chá»n --include/--only/--all/--interactive/--patch được " "sá» dụng." -#: builtin/commit.c:1166 +#: builtin/commit.c:1169 msgid "No paths with --include/--only does not make sense." msgstr "Không Ä‘Æ°á»ng dẫn vá»›i các tùy chá»n --include/--only không hợp lý." -#: builtin/commit.c:1180 builtin/tag.c:546 +#: builtin/commit.c:1183 builtin/tag.c:546 #, c-format msgid "Invalid cleanup mode %s" msgstr "Chế Ä‘á»™ dá»n dẹp không hợp lệ %s" -#: builtin/commit.c:1185 +#: builtin/commit.c:1188 msgid "Paths with -a does not make sense." msgstr "Các Ä‘Æ°á»ng dẫn vá»›i tùy chá»n -a không hợp lý." -#: builtin/commit.c:1311 builtin/commit.c:1495 +#: builtin/commit.c:1314 builtin/commit.c:1498 msgid "show status concisely" msgstr "hiển thị trạng thái ở dạng súc tÃch" -#: builtin/commit.c:1313 builtin/commit.c:1497 +#: builtin/commit.c:1316 builtin/commit.c:1500 msgid "show branch information" msgstr "hiển thị thông tin nhánh" -#: builtin/commit.c:1315 +#: builtin/commit.c:1318 msgid "show stash information" msgstr "hiển thị thông tin vá» tạm cất" -#: builtin/commit.c:1317 builtin/commit.c:1499 +#: builtin/commit.c:1320 builtin/commit.c:1502 msgid "compute full ahead/behind values" msgstr "tÃnh đầy đủ giá trị trÆ°á»›c/sau" -#: builtin/commit.c:1319 +#: builtin/commit.c:1322 msgid "version" msgstr "phiên bản" -#: builtin/commit.c:1319 builtin/commit.c:1501 builtin/push.c:558 -#: builtin/worktree.c:639 +#: builtin/commit.c:1322 builtin/commit.c:1504 builtin/push.c:561 +#: builtin/worktree.c:640 msgid "machine-readable output" msgstr "kết xuất dạng máy-có-thể-Ä‘á»c" -#: builtin/commit.c:1322 builtin/commit.c:1503 +#: builtin/commit.c:1325 builtin/commit.c:1506 msgid "show status in long format (default)" msgstr "hiển thị trạng thái ở định dạng dà i (mặc định)" -#: builtin/commit.c:1325 builtin/commit.c:1506 +#: builtin/commit.c:1328 builtin/commit.c:1509 msgid "terminate entries with NUL" msgstr "chấm dứt các mục bằng NUL" -#: builtin/commit.c:1327 builtin/commit.c:1331 builtin/commit.c:1509 -#: builtin/fast-export.c:1007 builtin/fast-export.c:1010 builtin/rebase.c:910 +#: builtin/commit.c:1330 builtin/commit.c:1334 builtin/commit.c:1512 +#: builtin/fast-export.c:1085 builtin/fast-export.c:1088 builtin/rebase.c:1118 #: builtin/tag.c:400 msgid "mode" msgstr "chế Ä‘á»™" -#: builtin/commit.c:1328 builtin/commit.c:1509 +#: builtin/commit.c:1331 builtin/commit.c:1512 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" "hiển thị các táºp tin chÆ°a được theo dõi dấu vết, các chế Ä‘á»™ tùy chá»n: all, " "normal, no. (Mặc định: all)" -#: builtin/commit.c:1332 +#: builtin/commit.c:1335 msgid "" "show ignored files, optional modes: traditional, matching, no. (Default: " "traditional)" @@ -9882,11 +10550,11 @@ msgstr "" "hiển thị các táºp tin bị bá» qua, các chế Ä‘á»™ tùy chá»n: traditional, matching, " "no. (Mặc định: traditional)" -#: builtin/commit.c:1334 parse-options.h:164 +#: builtin/commit.c:1337 parse-options.h:164 msgid "when" msgstr "khi" -#: builtin/commit.c:1335 +#: builtin/commit.c:1338 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -9894,198 +10562,198 @@ msgstr "" "bá» qua các thay đổi trong mô-Ä‘un-con, tùy chá»n khi: all, dirty, untracked. " "(Mặc định: all)" -#: builtin/commit.c:1337 +#: builtin/commit.c:1340 msgid "list untracked files in columns" msgstr "hiển thị danh sách các táºp-tin chÆ°a được theo dõi trong các cá»™t" -#: builtin/commit.c:1338 +#: builtin/commit.c:1341 msgid "do not detect renames" msgstr "không dò tìm các tên thay đổi" -#: builtin/commit.c:1340 +#: builtin/commit.c:1343 msgid "detect renames, optionally set similarity index" msgstr "dò các tên thay đổi, tùy ý đặt mục lục tÆ°Æ¡ng tá»±" -#: builtin/commit.c:1360 +#: builtin/commit.c:1363 msgid "Unsupported combination of ignored and untracked-files arguments" msgstr "" "Không há»— trỡ tổ hợp các tham số các táºp tin bị bá» qua và không được theo dõi" -#: builtin/commit.c:1465 +#: builtin/commit.c:1468 msgid "suppress summary after successful commit" msgstr "không hiển thị tổng kết sau khi chuyển giao thà nh công" -#: builtin/commit.c:1466 +#: builtin/commit.c:1469 msgid "show diff in commit message template" msgstr "hiển thị sá»± khác biệt trong mẫu tin nhắn chuyển giao" -#: builtin/commit.c:1468 +#: builtin/commit.c:1471 msgid "Commit message options" msgstr "Các tùy chá»n ghi chú commit" -#: builtin/commit.c:1469 builtin/merge.c:263 builtin/tag.c:397 +#: builtin/commit.c:1472 builtin/merge.c:264 builtin/tag.c:397 msgid "read message from file" msgstr "Ä‘á»c chú thÃch từ táºp tin" -#: builtin/commit.c:1470 +#: builtin/commit.c:1473 msgid "author" msgstr "tác giả" -#: builtin/commit.c:1470 +#: builtin/commit.c:1473 msgid "override author for commit" msgstr "ghi đè tác giả cho commit" -#: builtin/commit.c:1471 builtin/gc.c:518 +#: builtin/commit.c:1474 builtin/gc.c:518 msgid "date" msgstr "ngà y tháng" -#: builtin/commit.c:1471 +#: builtin/commit.c:1474 msgid "override date for commit" msgstr "ghi đè ngà y tháng cho lần chuyển giao" -#: builtin/commit.c:1472 builtin/merge.c:259 builtin/notes.c:409 -#: builtin/notes.c:572 builtin/tag.c:395 +#: builtin/commit.c:1475 builtin/merge.c:260 builtin/notes.c:409 +#: builtin/notes.c:575 builtin/tag.c:395 msgid "message" msgstr "chú thÃch" -#: builtin/commit.c:1472 +#: builtin/commit.c:1475 msgid "commit message" msgstr "chú thÃch của lần chuyển giao" -#: builtin/commit.c:1473 builtin/commit.c:1474 builtin/commit.c:1475 -#: builtin/commit.c:1476 ref-filter.h:92 parse-options.h:280 +#: builtin/commit.c:1476 builtin/commit.c:1477 builtin/commit.c:1478 +#: builtin/commit.c:1479 parse-options.h:278 ref-filter.h:92 msgid "commit" msgstr "lần_chuyển_giao" -#: builtin/commit.c:1473 +#: builtin/commit.c:1476 msgid "reuse and edit message from specified commit" msgstr "dùng lại các ghi chú từ lần chuyển giao đã cho nhÆ°ng có cho sá»a chữa" -#: builtin/commit.c:1474 +#: builtin/commit.c:1477 msgid "reuse message from specified commit" msgstr "dùng lại các ghi chú từ lần chuyển giao đã cho" -#: builtin/commit.c:1475 +#: builtin/commit.c:1478 msgid "use autosquash formatted message to fixup specified commit" msgstr "" "dùng ghi chú có định dạng autosquash để sá»a chữa lần chuyển giao đã chỉ ra" -#: builtin/commit.c:1476 +#: builtin/commit.c:1479 msgid "use autosquash formatted message to squash specified commit" msgstr "" "dùng lá»i nhắn có định dạng tá»± Ä‘á»™ng nén để nén lại các lần chuyển giao đã chỉ " "ra" -#: builtin/commit.c:1477 +#: builtin/commit.c:1480 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "" "lần chuyển giao nháºn tôi là tác giả (được dùng vá»›i tùy chá»n -C/-c/--amend)" -#: builtin/commit.c:1478 builtin/log.c:1520 builtin/merge.c:276 -#: builtin/pull.c:155 builtin/revert.c:106 +#: builtin/commit.c:1481 builtin/log.c:1533 builtin/merge.c:277 +#: builtin/pull.c:156 builtin/revert.c:107 msgid "add Signed-off-by:" msgstr "(nên dùng) thêm dòng Signed-off-by:" -#: builtin/commit.c:1479 +#: builtin/commit.c:1482 msgid "use specified template file" msgstr "sá» dụng táºp tin mẫu đã cho" -#: builtin/commit.c:1480 +#: builtin/commit.c:1483 msgid "force edit of commit" msgstr "ép buá»™c sá»a lần commit" -#: builtin/commit.c:1481 +#: builtin/commit.c:1484 msgid "default" msgstr "mặc định" -#: builtin/commit.c:1481 builtin/tag.c:401 +#: builtin/commit.c:1484 builtin/tag.c:401 msgid "how to strip spaces and #comments from message" msgstr "là m thế nà o để cắt bá» khoảng trắng và #ghichú từ mẩu tin nhắn" -#: builtin/commit.c:1482 +#: builtin/commit.c:1485 msgid "include status in commit message template" msgstr "bao gồm các trạng thái trong mẫu ghi chú chuyển giao" -#: builtin/commit.c:1484 builtin/merge.c:274 builtin/pull.c:185 -#: builtin/revert.c:114 +#: builtin/commit.c:1487 builtin/merge.c:275 builtin/pull.c:186 +#: builtin/revert.c:115 msgid "GPG sign commit" -msgstr "ký lần chuyển giao dùng GPG" +msgstr "Ký lần chuyển giao dùng GPG" -#: builtin/commit.c:1487 +#: builtin/commit.c:1490 msgid "Commit contents options" msgstr "Các tùy ná»™i dung ghi chú commit" -#: builtin/commit.c:1488 +#: builtin/commit.c:1491 msgid "commit all changed files" msgstr "chuyển giao tất cả các táºp tin có thay đổi" -#: builtin/commit.c:1489 +#: builtin/commit.c:1492 msgid "add specified files to index for commit" msgstr "thêm các táºp tin đã chỉ ra và o bảng mục lục để chuyển giao" -#: builtin/commit.c:1490 +#: builtin/commit.c:1493 msgid "interactively add files" msgstr "thêm các táºp-tin bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1491 +#: builtin/commit.c:1494 msgid "interactively add changes" msgstr "thêm các thay đổi bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1492 +#: builtin/commit.c:1495 msgid "commit only specified files" msgstr "chỉ chuyển giao các táºp tin đã chỉ ra" -#: builtin/commit.c:1493 +#: builtin/commit.c:1496 msgid "bypass pre-commit and commit-msg hooks" msgstr "vòng qua móc (hook) pre-commit và commit-msg" -#: builtin/commit.c:1494 +#: builtin/commit.c:1497 msgid "show what would be committed" msgstr "hiển thị xem cái gì có thể được chuyển giao" -#: builtin/commit.c:1507 +#: builtin/commit.c:1510 msgid "amend previous commit" msgstr "“tu bổ†(amend) lần commit trÆ°á»›c" -#: builtin/commit.c:1508 +#: builtin/commit.c:1511 msgid "bypass post-rewrite hook" msgstr "vòng qua móc (hook) post-rewrite" -#: builtin/commit.c:1513 +#: builtin/commit.c:1516 msgid "ok to record an empty change" msgstr "ok để ghi lại má»™t thay đổi trống rá»—ng" -#: builtin/commit.c:1515 +#: builtin/commit.c:1518 msgid "ok to record a change with an empty message" msgstr "ok để ghi các thay đổi vá»›i lá»i nhắn trống rá»—ng" -#: builtin/commit.c:1588 +#: builtin/commit.c:1591 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Táºp tin MERGE_HEAD sai há»ng (%s)" -#: builtin/commit.c:1595 +#: builtin/commit.c:1598 msgid "could not read MERGE_MODE" msgstr "không thể Ä‘á»c MERGE_MODE" -#: builtin/commit.c:1614 +#: builtin/commit.c:1617 #, c-format msgid "could not read commit message: %s" msgstr "không thể Ä‘á»c phần chú thÃch (message) của lần chuyển giao: %s" -#: builtin/commit.c:1625 +#: builtin/commit.c:1628 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Bãi bá» việc chuyển giao bởi vì phần chú thÃch của nó trống rá»—ng.\n" -#: builtin/commit.c:1630 +#: builtin/commit.c:1633 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "" "Äang bá» qua việc chuyển giao; bạn đã không biên soạn phần chú thÃch " "(message).\n" -#: builtin/commit.c:1665 +#: builtin/commit.c:1668 msgid "" "repository has been updated, but unable to write\n" "new_index file. Check that disk is not full and quota is\n" @@ -10118,7 +10786,7 @@ msgstr "" #: builtin/commit-graph.c:48 builtin/commit-graph.c:78 #: builtin/commit-graph.c:132 builtin/commit-graph.c:190 builtin/fetch.c:153 -#: builtin/log.c:1540 +#: builtin/log.c:1553 msgid "dir" msgstr "tmục" @@ -10315,48 +10983,48 @@ msgstr "giá trị" msgid "with --get, use default value when missing entry" msgstr "vá»›i --get, dùng giá trị mặc định khi thiếu mục tin" -#: builtin/config.c:171 +#: builtin/config.c:172 #, c-format msgid "wrong number of arguments, should be %d" msgstr "sai số lượng tham số, phải là %d" -#: builtin/config.c:173 +#: builtin/config.c:174 #, c-format msgid "wrong number of arguments, should be from %d to %d" msgstr "sai số lượng tham số, phải từ %d đến %d" -#: builtin/config.c:307 +#: builtin/config.c:308 #, c-format msgid "invalid key pattern: %s" msgstr "mẫu khóa không hợp lệ: %s" -#: builtin/config.c:343 +#: builtin/config.c:344 #, c-format msgid "failed to format default config value: %s" msgstr "gặp lá»—i khi định dạng giá trị cấu hình mặc định: %s" -#: builtin/config.c:400 +#: builtin/config.c:401 #, c-format msgid "cannot parse color '%s'" msgstr "không thể phân tÃch mà u “%sâ€" -#: builtin/config.c:442 +#: builtin/config.c:443 msgid "unable to parse default color value" msgstr "không thể phân tÃch giá trị mà u mặc định" -#: builtin/config.c:495 builtin/config.c:741 +#: builtin/config.c:496 builtin/config.c:742 msgid "not in a git directory" msgstr "không trong thÆ° mục git" -#: builtin/config.c:498 +#: builtin/config.c:499 msgid "writing to stdin is not supported" msgstr "việc ghi ra đầu ra tiêu chuẩn là không được há»— trợ" -#: builtin/config.c:501 +#: builtin/config.c:502 msgid "writing config blobs is not supported" msgstr "không há»— trợ ghi cấu hình các blob" -#: builtin/config.c:586 +#: builtin/config.c:587 #, c-format msgid "" "# This is Git's per-user configuration file.\n" @@ -10371,23 +11039,23 @@ msgstr "" "#\tname = %s\n" "#\temail = %s\n" -#: builtin/config.c:610 +#: builtin/config.c:611 msgid "only one config file at a time" msgstr "chỉ má»™t táºp tin cấu hình má»™t lần" -#: builtin/config.c:615 +#: builtin/config.c:616 msgid "--local can only be used inside a git repository" msgstr "--local chỉ có thể được dùng bên trong má»™t kho git" -#: builtin/config.c:618 +#: builtin/config.c:619 msgid "--blob can only be used inside a git repository" msgstr "--blob chỉ có thể được dùng bên trong má»™t kho git" -#: builtin/config.c:637 +#: builtin/config.c:638 msgid "$HOME not set" msgstr "ChÆ°a đặt biến môi trÆ°á»ng HOME" -#: builtin/config.c:657 +#: builtin/config.c:658 msgid "" "--worktree cannot be used with multiple working trees unless the config\n" "extension worktreeConfig is enabled. Please read \"CONFIGURATION FILE\"\n" @@ -10397,19 +11065,19 @@ msgstr "" "worktreeConfig được báºt. Vui lòng Ä‘á»c phần \"CONFIGURATION FILE\"\n" "trong \"git help worktree\" để biết thêm chi tiết" -#: builtin/config.c:687 +#: builtin/config.c:688 msgid "--get-color and variable type are incoherent" msgstr "--get-color và kiểu biến là không mạch lạc" -#: builtin/config.c:692 +#: builtin/config.c:693 msgid "only one action at a time" msgstr "chỉ má»™t thao tác má»—i lần" -#: builtin/config.c:705 +#: builtin/config.c:706 msgid "--name-only is only applicable to --list or --get-regexp" msgstr "--name-only chỉ được áp dụng cho --list hoặc --get-regexp" -#: builtin/config.c:711 +#: builtin/config.c:712 msgid "" "--show-origin is only applicable to --get, --get-all, --get-regexp, and --" "list" @@ -10417,33 +11085,33 @@ msgstr "" "--show-origin chỉ được áp dụng cho --get, --get-all, --get-regexp, hoặc --" "list" -#: builtin/config.c:717 +#: builtin/config.c:718 msgid "--default is only applicable to --get" msgstr "--default chỉ được áp dụng cho --get" -#: builtin/config.c:730 +#: builtin/config.c:731 #, c-format msgid "unable to read config file '%s'" msgstr "không thể Ä‘á»c táºp tin cấu hình “%sâ€" -#: builtin/config.c:733 +#: builtin/config.c:734 msgid "error processing config file(s)" msgstr "gặp lá»—i khi xá» lý các táºp tin cấu hình" -#: builtin/config.c:743 +#: builtin/config.c:744 msgid "editing stdin is not supported" msgstr "sá»a chữa đầu ra tiêu chuẩn là không được há»— trợ" -#: builtin/config.c:745 +#: builtin/config.c:746 msgid "editing blobs is not supported" msgstr "việc sá»a chữa các blob là không được há»— trợ" -#: builtin/config.c:759 +#: builtin/config.c:760 #, c-format msgid "cannot create configuration file %s" msgstr "không thể tạo táºp tin cấu hình “%sâ€" -#: builtin/config.c:772 +#: builtin/config.c:773 #, c-format msgid "" "cannot overwrite multiple values with a single value\n" @@ -10452,7 +11120,7 @@ msgstr "" "không thể ghi đè nhiá»u giá trị vá»›i má»™t giá trị Ä‘Æ¡n\n" " Dùng má»™t biểu thức chÃnh quy, --add hay --replace-all để thay đổi %s." -#: builtin/config.c:846 builtin/config.c:857 +#: builtin/config.c:847 builtin/config.c:858 #, c-format msgid "no such section: %s" msgstr "không có Ä‘oạn: %s" @@ -10465,57 +11133,57 @@ msgstr "git count-objects [-v] [-H | --human-readable]" msgid "print sizes in human readable format" msgstr "hiển thị kÃch cỡ theo định dạng dà nh cho ngÆ°á»i Ä‘á»c" -#: builtin/describe.c:26 +#: builtin/describe.c:27 msgid "git describe [<options>] [<commit-ish>...]" msgstr "git describe [<các-tùy-chá»n>] <commit-ish>*" -#: builtin/describe.c:27 +#: builtin/describe.c:28 msgid "git describe [<options>] --dirty" msgstr "git describe [<các-tùy-chá»n>] --dirty" -#: builtin/describe.c:62 +#: builtin/describe.c:63 msgid "head" -msgstr "phÃa trÆ°á»›c " +msgstr "phÃa trÆ°á»›c" -#: builtin/describe.c:62 +#: builtin/describe.c:63 msgid "lightweight" msgstr "hạng nhẹ" -#: builtin/describe.c:62 +#: builtin/describe.c:63 msgid "annotated" msgstr "có diá»…n giải" -#: builtin/describe.c:272 +#: builtin/describe.c:273 #, c-format msgid "annotated tag %s not available" msgstr "thẻ đã được ghi chú %s không sẵn để dùng" -#: builtin/describe.c:276 +#: builtin/describe.c:277 #, c-format msgid "annotated tag %s has no embedded name" msgstr "thẻ được chú giải %s không có tên nhúng" -#: builtin/describe.c:278 +#: builtin/describe.c:279 #, c-format msgid "tag '%s' is really '%s' here" msgstr "thẻ “%s†đã thá»±c sá»± ở đây “%s†rồi" -#: builtin/describe.c:322 +#: builtin/describe.c:323 #, c-format msgid "no tag exactly matches '%s'" msgstr "không có thẻ nà o khá»›p chÃnh xác vá»›i “%sâ€" -#: builtin/describe.c:324 +#: builtin/describe.c:325 #, c-format msgid "No exact match on refs or tags, searching to describe\n" msgstr "Không có tham chiếu hay thẻ khá»›p đúng, Ä‘ang tìm kiếm mô tả\n" -#: builtin/describe.c:378 +#: builtin/describe.c:379 #, c-format msgid "finished search at %s\n" msgstr "việc tìm kiếm đã kết thúc tại %s\n" -#: builtin/describe.c:404 +#: builtin/describe.c:405 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -10524,7 +11192,7 @@ msgstr "" "Không có thẻ được chú giải nà o được mô tả là “%sâ€.\n" "Tuy nhiên, ở đây có những thẻ không được chú giải: hãy thá» --tags." -#: builtin/describe.c:408 +#: builtin/describe.c:409 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -10533,12 +11201,12 @@ msgstr "" "Không có thẻ có thể mô tả “%sâ€.\n" "Hãy thá» --always, hoặc tạo má»™t số thẻ." -#: builtin/describe.c:438 +#: builtin/describe.c:439 #, c-format msgid "traversed %lu commits\n" msgstr "đã xuyên %lu qua lần chuyển giao\n" -#: builtin/describe.c:441 +#: builtin/describe.c:442 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -10547,149 +11215,149 @@ msgstr "" "tìm thấy nhiá»u hÆ¡n %i thẻ; đã liệt kê %i cái gần\n" "đây nhất bá» Ä‘i tìm kiếm tại %s\n" -#: builtin/describe.c:509 +#: builtin/describe.c:510 #, c-format msgid "describe %s\n" msgstr "mô tả %s\n" -#: builtin/describe.c:512 builtin/log.c:513 +#: builtin/describe.c:513 builtin/log.c:516 #, c-format msgid "Not a valid object name %s" msgstr "Không phải tên đối tượng %s hợp lệ" -#: builtin/describe.c:520 +#: builtin/describe.c:521 #, c-format msgid "%s is neither a commit nor blob" msgstr "%s không phải là má»™t lần commit cÅ©ng không phải blob" -#: builtin/describe.c:534 +#: builtin/describe.c:535 msgid "find the tag that comes after the commit" msgstr "tìm các thẻ mà nó đến trÆ°á»›c lần chuyển giao" -#: builtin/describe.c:535 +#: builtin/describe.c:536 msgid "debug search strategy on stderr" msgstr "chiến lược tìm kiếm gỡ lá»—i trên đầu ra lá»—i chuẩn stderr" -#: builtin/describe.c:536 +#: builtin/describe.c:537 msgid "use any ref" msgstr "dùng ref bất kỳ" -#: builtin/describe.c:537 +#: builtin/describe.c:538 msgid "use any tag, even unannotated" msgstr "dùng thẻ bất kỳ, cả khi “unannotatedâ€" -#: builtin/describe.c:538 +#: builtin/describe.c:539 msgid "always use long format" msgstr "luôn dùng định dạng dà i" -#: builtin/describe.c:539 +#: builtin/describe.c:540 msgid "only follow first parent" msgstr "chỉ theo cha mẹ đầu tiên" -#: builtin/describe.c:542 +#: builtin/describe.c:543 msgid "only output exact matches" msgstr "chỉ xuất những gì khá»›p chÃnh xác" -#: builtin/describe.c:544 +#: builtin/describe.c:545 msgid "consider <n> most recent tags (default: 10)" msgstr "coi nhÆ° <n> thẻ gần đây nhất (mặc định: 10)" -#: builtin/describe.c:546 +#: builtin/describe.c:547 msgid "only consider tags matching <pattern>" msgstr "chỉ cân nhắc đến những thẻ khá»›p vá»›i <mẫu>" -#: builtin/describe.c:548 +#: builtin/describe.c:549 msgid "do not consider tags matching <pattern>" msgstr "không coi rằng các thẻ khá»›p vá»›i <mẫu>" -#: builtin/describe.c:550 builtin/name-rev.c:424 +#: builtin/describe.c:551 builtin/name-rev.c:424 msgid "show abbreviated commit object as fallback" msgstr "hiển thị đối tượng chuyển giao vắn tắt nhÆ° là fallback" -#: builtin/describe.c:551 builtin/describe.c:554 +#: builtin/describe.c:552 builtin/describe.c:555 msgid "mark" msgstr "dấu" -#: builtin/describe.c:552 +#: builtin/describe.c:553 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "thêm <dấu> trên cây thÆ° mục là m việc bẩn (mặc định \"-dirty\")" -#: builtin/describe.c:555 +#: builtin/describe.c:556 msgid "append <mark> on broken working tree (default: \"-broken\")" msgstr "thêm <dấu> trên cây thÆ° mục là m việc bị há»ng (mặc định \"-broken\")" -#: builtin/describe.c:573 +#: builtin/describe.c:574 msgid "--long is incompatible with --abbrev=0" msgstr "--long là xung khắc vá»›i tùy chá»n --abbrev=0" -#: builtin/describe.c:602 +#: builtin/describe.c:603 msgid "No names found, cannot describe anything." msgstr "Không tìm thấy các tên, không thể mô tả gì cả." -#: builtin/describe.c:652 +#: builtin/describe.c:654 msgid "--dirty is incompatible with commit-ishes" msgstr "--dirty là xung khắc vá»›i các tùy chá»n commit-ish" -#: builtin/describe.c:654 +#: builtin/describe.c:656 msgid "--broken is incompatible with commit-ishes" msgstr "--broken là xung khắc vá»›i commit-ishes" -#: builtin/diff.c:83 +#: builtin/diff.c:84 #, c-format msgid "'%s': not a regular file or symlink" msgstr "“%sâ€: không phải táºp tin bình thÆ°á»ng hay liên kết má»m" -#: builtin/diff.c:234 +#: builtin/diff.c:235 #, c-format msgid "invalid option: %s" msgstr "tùy chá»n không hợp lệ: %s" -#: builtin/diff.c:363 +#: builtin/diff.c:364 msgid "Not a git repository" msgstr "Không phải là kho git" -#: builtin/diff.c:407 +#: builtin/diff.c:408 #, c-format msgid "invalid object '%s' given." msgstr "đối tượng đã cho “%s†không hợp lệ." -#: builtin/diff.c:416 +#: builtin/diff.c:417 #, c-format msgid "more than two blobs given: '%s'" msgstr "đã cho nhiá»u hÆ¡n hai đối tượng blob: “%sâ€" -#: builtin/diff.c:421 +#: builtin/diff.c:422 #, c-format msgid "unhandled object '%s' given." msgstr "đã cho đối tượng không thể nắm giữ “%sâ€." -#: builtin/difftool.c:30 +#: builtin/difftool.c:31 msgid "git difftool [<options>] [<commit> [<commit>]] [--] [<path>...]" msgstr "" "git difftool [<các-tùy-chá»n>] [<lần_chuyển_giao> [<lần_chuyển_giao>]] [--] " "<Ä‘Æ°á»ng-dẫn>…]" -#: builtin/difftool.c:260 +#: builtin/difftool.c:261 #, c-format msgid "failed: %d" msgstr "gặp lá»—i: %d" -#: builtin/difftool.c:302 +#: builtin/difftool.c:303 #, c-format msgid "could not read symlink %s" msgstr "không thể Ä‘á»c liên kết má»m %s" -#: builtin/difftool.c:304 +#: builtin/difftool.c:305 #, c-format msgid "could not read symlink file %s" msgstr "không Ä‘á»c được táºp tin liên kết má»m %s" -#: builtin/difftool.c:312 +#: builtin/difftool.c:313 #, c-format msgid "could not read object %s for symlink %s" -msgstr "Không thể Ä‘á»c đối tượng %s cho liên kết má»m %s" +msgstr "không thể Ä‘á»c đối tượng %s cho liên kết má»m %s" -#: builtin/difftool.c:413 +#: builtin/difftool.c:414 msgid "" "combined diff formats('-c' and '--cc') are not supported in\n" "directory diff mode('-d' and '--dir-diff')." @@ -10697,53 +11365,53 @@ msgstr "" "các định dạng diff tổ hợp(“-c†và “--ccâ€) chÆ°a được há»— trợ trong\n" "chế Ä‘á»™ diff thÆ° mục(“-d†và “--dir-diffâ€)." -#: builtin/difftool.c:633 +#: builtin/difftool.c:634 #, c-format msgid "both files modified: '%s' and '%s'." msgstr "cả hai táºp tin đã bị sá»a: “%s†và “%sâ€." -#: builtin/difftool.c:635 +#: builtin/difftool.c:636 msgid "working tree file has been left." msgstr "cây là m việc ở bên trái." -#: builtin/difftool.c:646 +#: builtin/difftool.c:647 #, c-format msgid "temporary files exist in '%s'." msgstr "các táºp tin tạm đã sẵn có trong “%sâ€." -#: builtin/difftool.c:647 +#: builtin/difftool.c:648 msgid "you may want to cleanup or recover these." -msgstr "bạn có lẽ muốn dá»n dẹp hay " +msgstr "bạn có lẽ muốn dá»n dẹp hay phục hồi ở đây." -#: builtin/difftool.c:696 +#: builtin/difftool.c:697 msgid "use `diff.guitool` instead of `diff.tool`" msgstr "dùng “diff.guitool“ thay vì dùng “diff.tool“" -#: builtin/difftool.c:698 +#: builtin/difftool.c:699 msgid "perform a full-directory diff" msgstr "thá»±c hiện má»™t diff toà n thÆ° mục" -#: builtin/difftool.c:700 +#: builtin/difftool.c:701 msgid "do not prompt before launching a diff tool" msgstr "đừng nhắc khi khởi chạy công cụ diff" -#: builtin/difftool.c:705 +#: builtin/difftool.c:706 msgid "use symlinks in dir-diff mode" msgstr "dùng liên kết má»m trong diff-thÆ°-mục" -#: builtin/difftool.c:706 +#: builtin/difftool.c:707 msgid "tool" msgstr "công cụ" -#: builtin/difftool.c:707 +#: builtin/difftool.c:708 msgid "use the specified diff tool" msgstr "dùng công cụ diff đã cho" -#: builtin/difftool.c:709 +#: builtin/difftool.c:710 msgid "print a list of diff tools that may be used with `--tool`" msgstr "in ra danh sách các công cụ dif cái mà có thẻ dùng vá»›i “--tool“" -#: builtin/difftool.c:712 +#: builtin/difftool.c:713 msgid "" "make 'git-difftool' exit when an invoked diff tool returns a non - zero exit " "code" @@ -10751,15 +11419,15 @@ msgstr "" "là m cho “git-difftool†thoát khi gá»i công cụ diff trả vá» mã không phải số " "không" -#: builtin/difftool.c:715 +#: builtin/difftool.c:716 msgid "specify a custom command for viewing diffs" msgstr "chỉ định má»™t lệnh tùy ý để xem diff" -#: builtin/difftool.c:739 +#: builtin/difftool.c:740 msgid "no <tool> given for --tool=<tool>" msgstr "chÆ°a Ä‘Æ°a ra <công_cụ> cho --tool=<công_cụ>" -#: builtin/difftool.c:746 +#: builtin/difftool.c:747 msgid "no <cmd> given for --extcmd=<cmd>" msgstr "chÆ°a Ä‘Æ°a ra <lệnh> cho --extcmd=<lệnh>" @@ -10767,54 +11435,64 @@ msgstr "chÆ°a Ä‘Æ°a ra <lệnh> cho --extcmd=<lệnh>" msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-opts]" -#: builtin/fast-export.c:1006 +#: builtin/fast-export.c:1084 msgid "show progress after <n> objects" msgstr "hiển thị tiến triển sau <n> đối tượng" -#: builtin/fast-export.c:1008 +#: builtin/fast-export.c:1086 msgid "select handling of signed tags" msgstr "chá»n Ä‘iá»u khiển của thẻ đã ký" -#: builtin/fast-export.c:1011 +#: builtin/fast-export.c:1089 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" -#: builtin/fast-export.c:1014 +#: builtin/fast-export.c:1092 msgid "Dump marks to this file" msgstr "Äổ các đánh dấu nà y và o táºp-tin" -#: builtin/fast-export.c:1016 +#: builtin/fast-export.c:1094 msgid "Import marks from this file" -msgstr "nháºp và o đánh dấu từ táºp tin nà y" +msgstr "Nháºp và o đánh dấu từ táºp tin nà y" -#: builtin/fast-export.c:1018 +#: builtin/fast-export.c:1096 msgid "Fake a tagger when tags lack one" msgstr "Là m giả má»™t cái thẻ khi thẻ bị thiếu má»™t cái" -#: builtin/fast-export.c:1020 +#: builtin/fast-export.c:1098 msgid "Output full tree for each commit" msgstr "Xuất ra toà n bá»™ cây cho má»—i lần chuyển giao" -#: builtin/fast-export.c:1022 +#: builtin/fast-export.c:1100 msgid "Use the done feature to terminate the stream" msgstr "Sá» dụng tÃnh năng done để chấm dứt luồng dữ liệu" -#: builtin/fast-export.c:1023 +#: builtin/fast-export.c:1101 msgid "Skip output of blob data" msgstr "Bá» qua kết xuất của dữ liệu blob" -#: builtin/fast-export.c:1024 builtin/log.c:1588 +#: builtin/fast-export.c:1102 builtin/log.c:1601 msgid "refspec" msgstr "refspec" -#: builtin/fast-export.c:1025 +#: builtin/fast-export.c:1103 msgid "Apply refspec to exported refs" msgstr "Ãp dụng refspec cho refs đã xuất" -#: builtin/fast-export.c:1026 +#: builtin/fast-export.c:1104 msgid "anonymize output" msgstr "kết xuất anonymize" +#: builtin/fast-export.c:1106 +msgid "Reference parents which are not in fast-export stream by object id" +msgstr "" +"Các cha mẹ tham chiếu cái mà k trong luồng dữ liệu fast-export bởi mã id đối " +"tượng" + +#: builtin/fast-export.c:1108 +msgid "Show original object ids of blobs/commits" +msgstr "Hiển thị các mã id nguyên gốc của blobs/commits" + #: builtin/fetch.c:28 msgid "git fetch [<options>] [<repository> [<refspec>...]]" msgstr "git fetch [<các-tùy-chá»n>] [<kho-chứa> [<refspec>…]]" @@ -10831,15 +11509,15 @@ msgstr "git fetch --multiple [<các-tùy-chá»n>] [(<kho> | <nhóm>)…]" msgid "git fetch --all [<options>]" msgstr "git fetch --all [<các-tùy-chá»n>]" -#: builtin/fetch.c:115 builtin/pull.c:194 +#: builtin/fetch.c:115 builtin/pull.c:195 msgid "fetch from all remotes" msgstr "lấy vá» từ tất cả các máy chủ" -#: builtin/fetch.c:117 builtin/pull.c:197 +#: builtin/fetch.c:117 builtin/pull.c:198 msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "nối thêm và o .git/FETCH_HEAD thay vì ghi đè lên nó" -#: builtin/fetch.c:119 builtin/pull.c:200 +#: builtin/fetch.c:119 builtin/pull.c:201 msgid "path to upload pack on remote end" msgstr "Ä‘Æ°á»ng dẫn đến gói tải lên trên máy chủ cuối" @@ -10851,7 +11529,7 @@ msgstr "ép buá»™c ghi đè lên tham chiếu ná»™i bá»™" msgid "fetch from multiple remotes" msgstr "lấy từ nhiá»u máy chủ cùng lúc" -#: builtin/fetch.c:124 builtin/pull.c:204 +#: builtin/fetch.c:124 builtin/pull.c:205 msgid "fetch all tags and associated objects" msgstr "lấy tất cả các thẻ cùng vá»›i các đối tượng liên quan đến nó" @@ -10863,7 +11541,7 @@ msgstr "không lấy tất cả các thẻ (--no-tags)" msgid "number of submodules fetched in parallel" msgstr "số lượng mô-Ä‘un-con được lấy đồng thá»i" -#: builtin/fetch.c:130 builtin/pull.c:207 +#: builtin/fetch.c:130 builtin/pull.c:208 msgid "prune remote-tracking branches no longer on remote" msgstr "" "cắt cụt (prune) các nhánh “remote-tracking†không còn tồn tại trên máy chủ " @@ -10873,7 +11551,7 @@ msgstr "" msgid "prune local tags no longer on remote and clobber changed tags" msgstr "cắt xém các thẻ ná»™i bá»™ không còn ở máy chủ và xóa các thẻ đã thay đổi" -#: builtin/fetch.c:133 builtin/fetch.c:156 builtin/pull.c:132 +#: builtin/fetch.c:133 builtin/fetch.c:156 builtin/pull.c:133 msgid "on-demand" msgstr "khi-cần" @@ -10881,7 +11559,7 @@ msgstr "khi-cần" msgid "control recursive fetching of submodules" msgstr "Ä‘iá»u khiển việc lấy vỠđệ quy trong các mô-Ä‘un-con" -#: builtin/fetch.c:138 builtin/pull.c:215 +#: builtin/fetch.c:138 builtin/pull.c:216 msgid "keep downloaded pack" msgstr "giữ lại gói đã tải vá»" @@ -10889,7 +11567,7 @@ msgstr "giữ lại gói đã tải vá»" msgid "allow updating of HEAD ref" msgstr "cho phép cáºp nháºt th.chiếu HEAD" -#: builtin/fetch.c:143 builtin/fetch.c:149 builtin/pull.c:218 +#: builtin/fetch.c:143 builtin/fetch.c:149 builtin/pull.c:219 msgid "deepen history of shallow clone" msgstr "là m sâu hÆ¡n lịch sá» của bản sao" @@ -10897,7 +11575,7 @@ msgstr "là m sâu hÆ¡n lịch sá» của bản sao" msgid "deepen history of shallow repository based on time" msgstr "là m sâu hÆ¡n lịch sá» của kho bản sao shallow dá»±a trên thá»i gian" -#: builtin/fetch.c:151 builtin/pull.c:221 +#: builtin/fetch.c:151 builtin/pull.c:222 msgid "convert to a complete repository" msgstr "chuyển đổi hoà n toà n sang kho git" @@ -10913,24 +11591,24 @@ msgstr "" "mặc định cho việc lấy đệ quy các mô-Ä‘un-con (có mức Æ°u tiên thấp hÆ¡n các táºp " "tin cấu hình config)" -#: builtin/fetch.c:161 builtin/pull.c:224 +#: builtin/fetch.c:161 builtin/pull.c:225 msgid "accept refs that update .git/shallow" msgstr "chấp nháºn tham chiếu cáºp nháºt .git/shallow" -#: builtin/fetch.c:162 builtin/pull.c:226 +#: builtin/fetch.c:162 builtin/pull.c:227 msgid "refmap" msgstr "refmap" -#: builtin/fetch.c:163 builtin/pull.c:227 +#: builtin/fetch.c:163 builtin/pull.c:228 msgid "specify fetch refmap" msgstr "chỉ ra refmap cần lấy vá»" -#: builtin/fetch.c:164 builtin/ls-remote.c:77 builtin/push.c:582 +#: builtin/fetch.c:164 builtin/ls-remote.c:77 builtin/push.c:585 #: builtin/send-pack.c:172 msgid "server-specific" msgstr "đặc-tả-máy-phục-vụ" -#: builtin/fetch.c:164 builtin/ls-remote.c:77 builtin/push.c:582 +#: builtin/fetch.c:164 builtin/ls-remote.c:77 builtin/push.c:585 #: builtin/send-pack.c:173 msgid "option to transmit" msgstr "tùy chá»n để chuyển giao" @@ -10940,81 +11618,81 @@ msgid "report that we have only objects reachable from this object" msgstr "" "báo cáo rằng chúng ta chỉ có các đối tượng tiếp cáºn được từ đối tượng nà y" -#: builtin/fetch.c:470 +#: builtin/fetch.c:469 msgid "Couldn't find remote ref HEAD" msgstr "Không thể tìm thấy máy chủ cho tham chiếu HEAD" -#: builtin/fetch.c:609 +#: builtin/fetch.c:608 #, c-format msgid "configuration fetch.output contains invalid value %s" msgstr "phần cấu hình fetch.output có chứa giá-trị không hợp lệ %s" -#: builtin/fetch.c:702 +#: builtin/fetch.c:705 #, c-format msgid "object %s not found" -msgstr "Không tìm thấy đối tượng %s" +msgstr "không tìm thấy đối tượng %s" -#: builtin/fetch.c:706 +#: builtin/fetch.c:709 msgid "[up to date]" msgstr "[đã cáºp nháºt]" -#: builtin/fetch.c:719 builtin/fetch.c:735 builtin/fetch.c:807 +#: builtin/fetch.c:722 builtin/fetch.c:738 builtin/fetch.c:801 msgid "[rejected]" msgstr "[Bị từ chối]" -#: builtin/fetch.c:720 +#: builtin/fetch.c:723 msgid "can't fetch in current branch" msgstr "không thể fetch (lấy) vá» nhánh hiện hà nh" -#: builtin/fetch.c:730 +#: builtin/fetch.c:733 msgid "[tag update]" msgstr "[cáºp nháºt thẻ]" -#: builtin/fetch.c:731 builtin/fetch.c:771 builtin/fetch.c:787 -#: builtin/fetch.c:802 +#: builtin/fetch.c:734 builtin/fetch.c:771 builtin/fetch.c:784 +#: builtin/fetch.c:796 msgid "unable to update local ref" msgstr "không thể cáºp nháºt tham chiếu ná»™i bá»™" -#: builtin/fetch.c:735 +#: builtin/fetch.c:738 msgid "would clobber existing tag" msgstr "nên xóa chồng các thẻ có sẵn" -#: builtin/fetch.c:757 +#: builtin/fetch.c:760 msgid "[new tag]" msgstr "[thẻ má»›i]" -#: builtin/fetch.c:760 +#: builtin/fetch.c:763 msgid "[new branch]" msgstr "[nhánh má»›i]" -#: builtin/fetch.c:763 +#: builtin/fetch.c:766 msgid "[new ref]" msgstr "[ref (tham chiếu) má»›i]" -#: builtin/fetch.c:802 +#: builtin/fetch.c:796 msgid "forced update" msgstr "cưỡng bức cáºp nháºt" -#: builtin/fetch.c:807 +#: builtin/fetch.c:801 msgid "non-fast-forward" msgstr "không-phải-chuyển-tiếp-nhanh" -#: builtin/fetch.c:853 +#: builtin/fetch.c:847 #, c-format msgid "%s did not send all necessary objects\n" msgstr "%s đã không gá»i tất cả các đối tượng cần thiết\n" -#: builtin/fetch.c:874 +#: builtin/fetch.c:868 #, c-format msgid "reject %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" -#: builtin/fetch.c:963 builtin/fetch.c:1085 +#: builtin/fetch.c:959 builtin/fetch.c:1081 #, c-format msgid "From %.*s\n" msgstr "Từ %.*s\n" -#: builtin/fetch.c:974 +#: builtin/fetch.c:970 #, c-format msgid "" "some local refs could not be updated; try running\n" @@ -11023,59 +11701,60 @@ 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" -#: builtin/fetch.c:1055 +#: builtin/fetch.c:1051 #, c-format msgid " (%s will become dangling)" msgstr " (%s sẽ trở thà nh không đầu (không được quản lý))" -#: builtin/fetch.c:1056 +#: builtin/fetch.c:1052 #, c-format msgid " (%s has become dangling)" msgstr " (%s đã trở thà nh không đầu (không được quản lý))" -#: builtin/fetch.c:1088 +#: builtin/fetch.c:1084 msgid "[deleted]" msgstr "[đã xóa]" -#: builtin/fetch.c:1089 builtin/remote.c:1036 +#: builtin/fetch.c:1085 builtin/remote.c:1036 msgid "(none)" msgstr "(không)" -#: builtin/fetch.c:1112 +#: builtin/fetch.c:1108 #, c-format msgid "Refusing to fetch into current branch %s of non-bare repository" msgstr "" "Từ chối việc lấy và o trong nhánh hiện tại %s của má»™t kho chứa không phải kho " "trần (bare)" -#: builtin/fetch.c:1131 +#: builtin/fetch.c:1127 #, c-format msgid "Option \"%s\" value \"%s\" is not valid for %s" msgstr "Tùy chá»n \"%s\" có giá trị \"%s\" là không hợp lệ cho %s" -#: builtin/fetch.c:1134 +#: builtin/fetch.c:1130 #, c-format msgid "Option \"%s\" is ignored for %s\n" msgstr "Tùy chá»n \"%s\" bị bá» qua vá»›i %s\n" -#: builtin/fetch.c:1433 +#: builtin/fetch.c:1434 #, c-format msgid "Fetching %s\n" msgstr "Äang lấy “%s†vá»\n" -#: builtin/fetch.c:1435 builtin/remote.c:100 +#: builtin/fetch.c:1436 builtin/remote.c:100 #, c-format msgid "Could not fetch %s" -msgstr "không thể “%s†vá»" +msgstr "Không thể lấy“%s†vá»" -#: builtin/fetch.c:1481 builtin/fetch.c:1649 +#: builtin/fetch.c:1482 msgid "" -"--filter can only be used with the remote configured in core.partialClone" +"--filter can only be used with the remote configured in extensions." +"partialClone" msgstr "" -"--filter chỉ có thể được dùng vá»›i máy chủ được cấu hình bằng core." +"--filter chỉ có thể được dùng vá»›i máy chủ được cấu hình bằng extensions." "partialClone" -#: builtin/fetch.c:1504 +#: builtin/fetch.c:1506 msgid "" "No remote repository specified. Please, specify either a URL or a\n" "remote name from which new revisions should be fetched." @@ -11083,43 +11762,51 @@ msgstr "" "ChÆ°a chỉ ra kho chứa máy chủ. Xin hãy chỉ định hoặc là URL hoặc\n" "tên máy chủ từ cái mà những Ä‘iểm xét duyệt má»›i có thể được fetch (lấy vá»)." -#: builtin/fetch.c:1541 +#: builtin/fetch.c:1543 msgid "You need to specify a tag name." msgstr "Bạn phải định rõ tên thẻ." -#: builtin/fetch.c:1590 +#: builtin/fetch.c:1592 msgid "Negative depth in --deepen is not supported" msgstr "Mức sâu là số âm trong --deepen là không được há»— trợ" -#: builtin/fetch.c:1592 +#: builtin/fetch.c:1594 msgid "--deepen and --depth are mutually exclusive" msgstr "Các tùy chá»n--deepen và --depth loại từ lẫn nhau" -#: builtin/fetch.c:1597 +#: builtin/fetch.c:1599 msgid "--depth and --unshallow cannot be used together" msgstr "tùy chá»n --depth và --unshallow không thể sá» dụng cùng vá»›i nhau" -#: builtin/fetch.c:1599 +#: builtin/fetch.c:1601 msgid "--unshallow on a complete repository does not make sense" msgstr "--unshallow trên kho hoà n chỉnh là không hợp lý" -#: builtin/fetch.c:1615 +#: builtin/fetch.c:1617 msgid "fetch --all does not take a repository argument" msgstr "lệnh lấy vá» \"fetch --all\" không lấy đối số kho chứa" -#: builtin/fetch.c:1617 +#: builtin/fetch.c:1619 msgid "fetch --all does not make sense with refspecs" msgstr "lệnh lấy vá» \"fetch --all\" không hợp lý vá»›i refspecs" -#: builtin/fetch.c:1626 +#: builtin/fetch.c:1628 #, c-format msgid "No such remote or remote group: %s" -msgstr "không có nhóm máy chủ hay máy chủ nhÆ° thế: %s" +msgstr "Không có nhóm máy chủ hay máy chủ nhÆ° thế: %s" -#: builtin/fetch.c:1633 +#: builtin/fetch.c:1635 msgid "Fetching a group and specifying refspecs does not make sense" msgstr "Việc lấy vá» cả má»™t nhóm và chỉ định refspecs không hợp lý" +#: builtin/fetch.c:1651 +msgid "" +"--filter can only be used with the remote configured in extensions." +"partialclone" +msgstr "" +"--filter chỉ có thể được dùng vá»›i máy chủ được cấu hình bằng extensions." +"partialclone" + #: builtin/fmt-merge-msg.c:18 msgid "" "git fmt-merge-msg [-m <message>] [--log[=<n>] | --no-log] [--file <file>]" @@ -11209,66 +11896,249 @@ msgstr "chỉ hiển thị những tham chiếu mà nó chứa lần chuyển gi msgid "print only refs which don't contain the commit" msgstr "chỉ hiển thị những tham chiếu mà nó không chứa lần chuyển giao" -#: builtin/fsck.c:598 +#: builtin/fsck.c:88 builtin/fsck.c:160 builtin/fsck.c:161 +msgid "unknown" +msgstr "không hiểu" + +#. TRANSLATORS: e.g. error in tree 01bfda: <more explanation> +#: builtin/fsck.c:120 builtin/fsck.c:136 +#, c-format +msgid "error in %s %s: %s" +msgstr "lá»—i trong %s %s: %s" + +#. TRANSLATORS: e.g. warning in tree 01bfda: <more explanation> +#: builtin/fsck.c:131 +#, c-format +msgid "warning in %s %s: %s" +msgstr "có cảnh báo trong %s %s: %s" + +#: builtin/fsck.c:157 builtin/fsck.c:159 +#, c-format +msgid "broken link from %7s %s" +msgstr "liên kết gãy từ %7s %s" + +#: builtin/fsck.c:168 +msgid "wrong object type in link" +msgstr "kiểu đối tượng sai trong liên kết" + +#: builtin/fsck.c:184 +#, c-format +msgid "" +"broken link from %7s %s\n" +" to %7s %s" +msgstr "" +"liên kết gãy từ %7s %s \n" +" tá»›i %7s %s" + +#: builtin/fsck.c:253 +#, c-format +msgid "missing %s %s" +msgstr "thiếu %s %s" + +#: builtin/fsck.c:279 +#, c-format +msgid "unreachable %s %s" +msgstr "không tiếp cáºn được %s %s" + +#: builtin/fsck.c:298 +#, c-format +msgid "dangling %s %s" +msgstr "dangling %s %s" + +#: builtin/fsck.c:307 +msgid "could not create lost-found" +msgstr "không thể tạo lost-found" + +#: builtin/fsck.c:318 +#, c-format +msgid "could not finish '%s'" +msgstr "không thể hoà n thà nh “%sâ€" + +#: builtin/fsck.c:335 +#, c-format +msgid "Checking %s" +msgstr "Äang kiểm tra %s" + +#: builtin/fsck.c:353 +#, c-format +msgid "Checking connectivity (%d objects)" +msgstr "Äang kiểm tra kết nối (%d đối tượng)" + +#: builtin/fsck.c:372 +#, c-format +msgid "Checking %s %s" +msgstr "Äang kiểm tra %s %s" + +#: builtin/fsck.c:376 +msgid "broken links" +msgstr "các liên kết bị gẫy" + +#: builtin/fsck.c:385 +#, c-format +msgid "root %s" +msgstr "gốc %s" + +#: builtin/fsck.c:393 +#, c-format +msgid "tagged %s %s (%s) in %s" +msgstr "đã đánh thẻ %s %s (%s) trong %s" + +#: builtin/fsck.c:422 +#, c-format +msgid "%s: object corrupt or missing" +msgstr "%s: đối tượng thiếu hay há»ng" + +#: builtin/fsck.c:447 +#, c-format +msgid "%s: invalid reflog entry %s" +msgstr "%s: mục reflog không hợp lệ %s" + +#: builtin/fsck.c:461 +#, c-format +msgid "Checking reflog %s->%s" +msgstr "Äang kiểm tra việc đổi tên của “%s†thà nh “%sâ€" + +#: builtin/fsck.c:495 +#, c-format +msgid "%s: invalid sha1 pointer %s" +msgstr "%s: con trá» sha1 không hợp lệ %s" + +#: builtin/fsck.c:502 +#, c-format +msgid "%s: not a commit" +msgstr "%s: không phải là má»™t lần chuyển giao" + +#: builtin/fsck.c:557 +msgid "notice: No default references" +msgstr "cảnh báo: Không có các tham chiếu mặc định" + +#: builtin/fsck.c:572 +#, c-format +msgid "%s: object corrupt or missing: %s" +msgstr "%s: thiếu đối tượng hoặc há»ng: %s" + +#: builtin/fsck.c:585 +#, c-format +msgid "%s: object could not be parsed: %s" +msgstr "%s: không thể phân tÃch cú đối tượng: %s" + +#: builtin/fsck.c:605 +#, c-format +msgid "bad sha1 file: %s" +msgstr "táºp tin sha1 sai: %s" + +#: builtin/fsck.c:620 +msgid "Checking object directory" +msgstr "Äang kiểm tra thÆ° mục đối tượng" + +#: builtin/fsck.c:623 msgid "Checking object directories" msgstr "Äang kiểm tra các thÆ° mục đối tượng" -#: builtin/fsck.c:693 +#: builtin/fsck.c:638 +#, c-format +msgid "Checking %s link" +msgstr "Äang lấy liên kết %s" + +#: builtin/fsck.c:643 builtin/index-pack.c:833 +#, c-format +msgid "invalid %s" +msgstr "%s không hợp lệ" + +#: builtin/fsck.c:650 +#, c-format +msgid "%s points to something strange (%s)" +msgstr "%s chỉ đến thứ gì đó xa lạ (%s)" + +#: builtin/fsck.c:656 +#, c-format +msgid "%s: detached HEAD points at nothing" +msgstr "%s: HEAD đã tách rá»i không chỉ và o đâu cả" + +#: builtin/fsck.c:660 +#, c-format +msgid "notice: %s points to an unborn branch (%s)" +msgstr "chú ý: %s chỉ đến má»™t nhánh chÆ°a sinh (%s)" + +#: builtin/fsck.c:672 +msgid "Checking cache tree" +msgstr "Äang kiểm tra cây nhá»› tạm" + +#: builtin/fsck.c:677 +#, c-format +msgid "%s: invalid sha1 pointer in cache-tree" +msgstr "%s: con trá» sha1 không hợp lệ trong cache-tree" + +#: builtin/fsck.c:688 +msgid "non-tree in cache-tree" +msgstr "non-tree trong cache-tree" + +#: builtin/fsck.c:719 msgid "git fsck [<options>] [<object>...]" msgstr "git fsck [<các-tùy-chá»n>] [<đối-tượng>…]" -#: builtin/fsck.c:699 +#: builtin/fsck.c:725 msgid "show unreachable objects" msgstr "hiển thị các đối tượng không thể Ä‘á»c được" -#: builtin/fsck.c:700 +#: builtin/fsck.c:726 msgid "show dangling objects" msgstr "hiển thị các đối tượng không được quản lý" -#: builtin/fsck.c:701 +#: builtin/fsck.c:727 msgid "report tags" msgstr "báo cáo các thẻ" -#: builtin/fsck.c:702 +#: builtin/fsck.c:728 msgid "report root nodes" msgstr "báo cáo node gốc" -#: builtin/fsck.c:703 +#: builtin/fsck.c:729 msgid "make index objects head nodes" msgstr "tạo “index objects head nodesâ€" -#: builtin/fsck.c:704 +#: builtin/fsck.c:730 msgid "make reflogs head nodes (default)" msgstr "tạo “reflogs head nodes†(mặc định)" -#: builtin/fsck.c:705 +#: builtin/fsck.c:731 msgid "also consider packs and alternate objects" msgstr "cÅ©ng cân nhắc đến các đối tượng gói và thay thế" -#: builtin/fsck.c:706 +#: builtin/fsck.c:732 msgid "check only connectivity" msgstr "chỉ kiểm tra kết nối" -#: builtin/fsck.c:707 +#: builtin/fsck.c:733 msgid "enable more strict checking" msgstr "cho phép kiểm tra hạn chế hÆ¡n" -#: builtin/fsck.c:709 +#: builtin/fsck.c:735 msgid "write dangling objects in .git/lost-found" msgstr "ghi các đối tượng không được quản lý trong .git/lost-found" -#: builtin/fsck.c:710 builtin/prune.c:110 +#: builtin/fsck.c:736 builtin/prune.c:110 msgid "show progress" msgstr "hiển thị quá trình" -#: builtin/fsck.c:711 +#: builtin/fsck.c:737 msgid "show verbose names for reachable objects" msgstr "hiển thị tên chi tiết cho các đối tượng Ä‘á»c được" -#: builtin/fsck.c:776 +#: builtin/fsck.c:797 msgid "Checking objects" msgstr "Äang kiểm tra các đối tượng" +#: builtin/fsck.c:825 +#, c-format +msgid "%s: object missing" +msgstr "%s: thiếu đối tượng" + +#: builtin/fsck.c:837 +#, c-format +msgid "invalid parameter: expected sha1, got '%s'" +msgstr "tham số không hợp lệ: cần sha1, nhÆ°ng lại nháºn được “%sâ€" + #: builtin/gc.c:34 msgid "git gc [<options>]" msgstr "git gc [<các-tùy-chá»n>]" @@ -11358,23 +12228,23 @@ msgstr "" "gc Ä‘ang được thá»±c hiện trên máy “%s†pid %<PRIuMAX> (dùng --force nếu không " "phải thế)" -#: builtin/gc.c:670 +#: builtin/gc.c:672 msgid "" "There are too many unreachable loose objects; run 'git prune' to remove them." msgstr "" "Có quá nhiá»u đối tượng tá»± do không được dùng đến; hãy chạy lệnh “git prune†" "để xóa bá» chúng Ä‘i." -#: builtin/grep.c:28 +#: builtin/grep.c:29 msgid "git grep [<options>] [-e] <pattern> [<rev>...] [[--] <path>...]" msgstr "git grep [<các-tùy-chá»n>] [-e] <mẫu> [<rev>…] [[--] <Ä‘Æ°á»ng-dẫn>…]" -#: builtin/grep.c:224 +#: builtin/grep.c:225 #, c-format msgid "grep: failed to create thread: %s" msgstr "grep: gặp lá»—i tạo tuyến (thread): %s" -#: builtin/grep.c:278 +#: builtin/grep.c:279 #, c-format msgid "invalid number of threads specified (%d) for %s" msgstr "số tuyến đã cho không hợp lệ (%d) cho %s" @@ -11383,263 +12253,263 @@ msgstr "số tuyến đã cho không hợp lệ (%d) cho %s" #. variable for tweaking threads, currently #. grep.threads #. -#: builtin/grep.c:286 builtin/index-pack.c:1506 builtin/index-pack.c:1697 -#: builtin/pack-objects.c:2719 +#: builtin/grep.c:287 builtin/index-pack.c:1506 builtin/index-pack.c:1697 +#: builtin/pack-objects.c:2717 #, c-format msgid "no threads support, ignoring %s" msgstr "không há»— trợ Ä‘a tuyến, bá» qua %s" -#: builtin/grep.c:458 builtin/grep.c:579 builtin/grep.c:620 +#: builtin/grep.c:466 builtin/grep.c:590 builtin/grep.c:631 #, c-format msgid "unable to read tree (%s)" msgstr "không thể Ä‘á»c cây (%s)" -#: builtin/grep.c:635 +#: builtin/grep.c:646 #, c-format msgid "unable to grep from object of type %s" msgstr "không thể thá»±c hiện lệnh grep (lá»c tìm) từ đối tượng thuá»™c kiểu %s" -#: builtin/grep.c:701 +#: builtin/grep.c:712 #, c-format msgid "switch `%c' expects a numerical value" msgstr "chuyển đến “%c†cần má»™t giá trị bằng số" -#: builtin/grep.c:800 +#: builtin/grep.c:811 msgid "search in index instead of in the work tree" msgstr "tìm trong bảng mục lục thay vì trong cây là m việc" -#: builtin/grep.c:802 +#: builtin/grep.c:813 msgid "find in contents not managed by git" msgstr "tìm trong ná»™i dung không được quản lý bởi git" -#: builtin/grep.c:804 +#: builtin/grep.c:815 msgid "search in both tracked and untracked files" msgstr "tìm kiếm các táºp tin được và chÆ°a được theo dõi dấu vết" -#: builtin/grep.c:806 +#: builtin/grep.c:817 msgid "ignore files specified via '.gitignore'" msgstr "các táºp tin bị bá» qua được chỉ định thông qua “.gitignoreâ€" -#: builtin/grep.c:808 +#: builtin/grep.c:819 msgid "recursively search in each submodule" msgstr "tìm kiếm đệ quy trong từng mô-Ä‘un-con" -#: builtin/grep.c:811 +#: builtin/grep.c:822 msgid "show non-matching lines" msgstr "hiển thị những dòng không khá»›p vá»›i mẫu" -#: builtin/grep.c:813 +#: builtin/grep.c:824 msgid "case insensitive matching" msgstr "phân biệt HOA/thÆ°á»ng" -#: builtin/grep.c:815 +#: builtin/grep.c:826 msgid "match patterns only at word boundaries" msgstr "chỉ khá»›p mẫu tại Ä‘Æ°á»ng ranh giá»›i từ" -#: builtin/grep.c:817 +#: builtin/grep.c:828 msgid "process binary files as text" msgstr "xá» lý táºp tin nhị phân nhÆ° là dạng văn bản thÆ°á»ng" -#: builtin/grep.c:819 +#: builtin/grep.c:830 msgid "don't match patterns in binary files" msgstr "không khá»›p mẫu trong các táºp tin nhị phân" -#: builtin/grep.c:822 +#: builtin/grep.c:833 msgid "process binary files with textconv filters" msgstr "xá» lý táºp tin nhị phân vá»›i các bá»™ lá»c “textconvâ€" -#: builtin/grep.c:824 +#: builtin/grep.c:835 msgid "search in subdirectories (default)" msgstr "tìm kiếm trong thÆ° mục con (mặc định)" -#: builtin/grep.c:826 +#: builtin/grep.c:837 msgid "descend at most <depth> levels" msgstr "hạ xuống Ãt nhất là mức <sâu>" -#: builtin/grep.c:830 +#: builtin/grep.c:841 msgid "use extended POSIX regular expressions" msgstr "dùng biểu thức chÃnh qui POSIX có mở rá»™ng" -#: builtin/grep.c:833 +#: builtin/grep.c:844 msgid "use basic POSIX regular expressions (default)" msgstr "sá» dụng biểu thức chÃnh quy kiểu POSIX (mặc định)" -#: builtin/grep.c:836 +#: builtin/grep.c:847 msgid "interpret patterns as fixed strings" msgstr "diá»…n dịch các mẫu nhÆ° là chuá»—i cố định" -#: builtin/grep.c:839 +#: builtin/grep.c:850 msgid "use Perl-compatible regular expressions" msgstr "sá» dụng biểu thức chÃnh quy tÆ°Æ¡ng thÃch Perl" -#: builtin/grep.c:842 +#: builtin/grep.c:853 msgid "show line numbers" msgstr "hiển thị số của dòng" -#: builtin/grep.c:843 +#: builtin/grep.c:854 msgid "show column number of first match" msgstr "hiển thị số cá»™t của khá»›p vá»›i mẫu đầu tiên" -#: builtin/grep.c:844 +#: builtin/grep.c:855 msgid "don't show filenames" msgstr "không hiển thị tên táºp tin" -#: builtin/grep.c:845 +#: builtin/grep.c:856 msgid "show filenames" msgstr "hiển thị các tên táºp tin" -#: builtin/grep.c:847 +#: builtin/grep.c:858 msgid "show filenames relative to top directory" msgstr "hiển thị tên táºp tin tÆ°Æ¡ng đối vá»›i thÆ° mục đỉnh (top)" -#: builtin/grep.c:849 +#: builtin/grep.c:860 msgid "show only filenames instead of matching lines" msgstr "chỉ hiển thị tên táºp tin thay vì những dòng khá»›p vá»›i mẫu" -#: builtin/grep.c:851 +#: builtin/grep.c:862 msgid "synonym for --files-with-matches" msgstr "đồng nghÄ©a vá»›i --files-with-matches" -#: builtin/grep.c:854 +#: builtin/grep.c:865 msgid "show only the names of files without match" msgstr "chỉ hiển thị tên cho những táºp tin không khá»›p vá»›i mẫu" -#: builtin/grep.c:856 +#: builtin/grep.c:867 msgid "print NUL after filenames" msgstr "thêm NUL và o sau tên táºp tin" -#: builtin/grep.c:859 +#: builtin/grep.c:870 msgid "show only matching parts of a line" msgstr "chỉ hiển thị những phần khá»›p vá»›i mẫu của má»™t dòng" -#: builtin/grep.c:861 +#: builtin/grep.c:872 msgid "show the number of matches instead of matching lines" msgstr "hiển thị số lượng khá»›p thay vì những dòng khá»›p vá»›i mẫu" -#: builtin/grep.c:862 +#: builtin/grep.c:873 msgid "highlight matches" msgstr "tô sáng phần khá»›p mẫu" -#: builtin/grep.c:864 +#: builtin/grep.c:875 msgid "print empty line between matches from different files" msgstr "hiển thị dòng trống giữa các lần khá»›p từ các táºp tin khác biệt" -#: builtin/grep.c:866 +#: builtin/grep.c:877 msgid "show filename only once above matches from same file" msgstr "" "hiển thị tên táºp tin má»™t lần phÃa trên các lần khá»›p từ cùng má»™t táºp tin" -#: builtin/grep.c:869 +#: builtin/grep.c:880 msgid "show <n> context lines before and after matches" msgstr "hiển thị <n> dòng ná»™i dung phÃa trÆ°á»›c và sau các lần khá»›p" -#: builtin/grep.c:872 +#: builtin/grep.c:883 msgid "show <n> context lines before matches" msgstr "hiển thị <n> dòng ná»™i dung trÆ°á»›c khá»›p" -#: builtin/grep.c:874 +#: builtin/grep.c:885 msgid "show <n> context lines after matches" msgstr "hiển thị <n> dòng ná»™i dung sau khá»›p" -#: builtin/grep.c:876 +#: builtin/grep.c:887 msgid "use <n> worker threads" msgstr "dùng <n> tuyến trình là m việc" -#: builtin/grep.c:877 +#: builtin/grep.c:888 msgid "shortcut for -C NUM" msgstr "dạng viết tắt của -C Sá»" -#: builtin/grep.c:880 +#: builtin/grep.c:891 msgid "show a line with the function name before matches" msgstr "hiển thị dòng vói tên hà m trÆ°á»›c các lần khá»›p" -#: builtin/grep.c:882 +#: builtin/grep.c:893 msgid "show the surrounding function" msgstr "hiển thị hà m bao quanh" -#: builtin/grep.c:885 +#: builtin/grep.c:896 msgid "read patterns from file" msgstr "Ä‘á»c mẫu từ táºp-tin" -#: builtin/grep.c:887 +#: builtin/grep.c:898 msgid "match <pattern>" msgstr "match <mẫu>" -#: builtin/grep.c:889 +#: builtin/grep.c:900 msgid "combine patterns specified with -e" msgstr "tổ hợp mẫu được chỉ ra vá»›i tùy chá»n -e" -#: builtin/grep.c:901 +#: builtin/grep.c:912 msgid "indicate hit with exit status without output" msgstr "Ä‘Æ°a ra gợi ý vá»›i trạng thái thoát mà không có kết xuất" -#: builtin/grep.c:903 +#: builtin/grep.c:914 msgid "show only matches from files that match all patterns" msgstr "chỉ hiển thị những cái khá»›p từ táºp tin mà nó khá»›p toà n bá»™ các mẫu" -#: builtin/grep.c:905 +#: builtin/grep.c:916 msgid "show parse tree for grep expression" msgstr "hiển thị cây phân tÃch cú pháp cho biểu thức “grep†(tìm kiếm)" -#: builtin/grep.c:909 +#: builtin/grep.c:920 msgid "pager" msgstr "dà n trang" -#: builtin/grep.c:909 +#: builtin/grep.c:920 msgid "show matching files in the pager" msgstr "hiển thị các táºp tin khá»›p trong trang giấy" -#: builtin/grep.c:913 +#: builtin/grep.c:924 msgid "allow calling of grep(1) (ignored by this build)" msgstr "cho phép gá»i grep(1) (bị bá» qua bởi lần dịch nà y)" -#: builtin/grep.c:977 +#: builtin/grep.c:988 msgid "no pattern given" msgstr "chÆ°a chỉ ra mẫu" -#: builtin/grep.c:1013 +#: builtin/grep.c:1024 msgid "--no-index or --untracked cannot be used with revs" msgstr "--no-index hay --untracked không được sá» dụng cùng vá»›i revs" -#: builtin/grep.c:1020 +#: builtin/grep.c:1032 #, c-format msgid "unable to resolve revision: %s" msgstr "không thể phân giải Ä‘iểm xét duyệt: %s" -#: builtin/grep.c:1051 +#: builtin/grep.c:1063 msgid "invalid option combination, ignoring --threads" msgstr "tổ hợp tùy chá»n không hợp lệ, bá» qua --threads" -#: builtin/grep.c:1054 builtin/pack-objects.c:3397 +#: builtin/grep.c:1066 builtin/pack-objects.c:3400 msgid "no threads support, ignoring --threads" msgstr "không há»— trợ Ä‘a tuyến, bá» qua --threads" -#: builtin/grep.c:1057 builtin/index-pack.c:1503 builtin/pack-objects.c:2716 +#: builtin/grep.c:1069 builtin/index-pack.c:1503 builtin/pack-objects.c:2714 #, c-format msgid "invalid number of threads specified (%d)" msgstr "số tuyến chỉ ra không hợp lệ (%d)" -#: builtin/grep.c:1080 +#: builtin/grep.c:1092 msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager chỉ là m việc trên cây-là m-việc" -#: builtin/grep.c:1103 +#: builtin/grep.c:1115 msgid "option not supported with --recurse-submodules" msgstr "tùy chá»n không được há»— trợ vá»›i --recurse-submodules" -#: builtin/grep.c:1109 +#: builtin/grep.c:1121 msgid "--cached or --untracked cannot be used with --no-index" msgstr "--cached hay --untracked không được sá» dụng vá»›i --no-index" -#: builtin/grep.c:1115 +#: builtin/grep.c:1127 msgid "--[no-]exclude-standard cannot be used for tracked contents" msgstr "--[no-]exclude-standard không thể sá» dụng cho ná»™i dung lÆ°u dấu vết" -#: builtin/grep.c:1123 +#: builtin/grep.c:1135 msgid "both --cached and trees are given" msgstr "cả hai --cached và các cây phải được chỉ ra" -#: builtin/hash-object.c:84 +#: builtin/hash-object.c:85 msgid "" "git hash-object [-t <type>] [-w] [--path=<file> | --no-filters] [--stdin] " "[--] <file>..." @@ -11647,36 +12517,36 @@ msgstr "" "git hash-object [-t <kiểu>] [-w] [--path=<táºp-tin> | --no-filters] [--stdin] " "[--] <táºp-tin>…" -#: builtin/hash-object.c:85 +#: builtin/hash-object.c:86 msgid "git hash-object --stdin-paths" msgstr "git hash-object --stdin-paths" -#: builtin/hash-object.c:97 +#: builtin/hash-object.c:98 msgid "type" msgstr "kiểu" -#: builtin/hash-object.c:97 +#: builtin/hash-object.c:98 msgid "object type" msgstr "kiểu đối tượng" -#: builtin/hash-object.c:98 +#: builtin/hash-object.c:99 msgid "write the object into the object database" msgstr "ghi đối tượng và o dữ liệu đối tượng" -#: builtin/hash-object.c:100 +#: builtin/hash-object.c:101 msgid "read the object from stdin" msgstr "Ä‘á»c đối tượng từ đầu và o tiêu chuẩn stdin" -#: builtin/hash-object.c:102 +#: builtin/hash-object.c:103 msgid "store file as is without filters" msgstr "lÆ°u các táºp tin mà nó không có các bá»™ lá»c" -#: builtin/hash-object.c:103 +#: builtin/hash-object.c:104 msgid "" "just hash any random garbage to create corrupt objects for debugging Git" msgstr "chỉ cần băm rác ngẫu nhiên để tạo má»™t đối tượng há»ng để mà gỡ lá»—i Git" -#: builtin/hash-object.c:104 +#: builtin/hash-object.c:105 msgid "process file as it were from this path" msgstr "xá» lý táºp tin nhÆ° là nó Ä‘ang ở thÆ° mục nà y" @@ -11770,12 +12640,12 @@ msgstr "không có trình xem trợ giúp dạng manpage tiếp hợp vá»›i yêu msgid "no info viewer handled the request" msgstr "không có trình xem trợ giúp dạng info tiếp hợp vá»›i yêu cầu" -#: builtin/help.c:430 builtin/help.c:441 git.c:322 +#: builtin/help.c:430 builtin/help.c:441 git.c:323 #, c-format msgid "'%s' is aliased to '%s'" msgstr "“%s†được đặt bà danh thà nh “%sâ€" -#: builtin/help.c:444 +#: builtin/help.c:444 git.c:347 #, c-format msgid "bad alias.%s string: %s" msgstr "chuá»—i alias.%s sai: %s" @@ -11797,7 +12667,7 @@ msgstr "kiểu đối tượng không khá»›p tại %s" #: builtin/index-pack.c:204 #, c-format msgid "did not receive expected object %s" -msgstr "Không thể lấy vỠđối tượng cần %s" +msgstr "không thể lấy vỠđối tượng cần %s" #: builtin/index-pack.c:207 #, c-format @@ -11822,7 +12692,7 @@ msgstr "lá»—i Ä‘á»c ở đầu và o" msgid "used more bytes than were available" msgstr "sá» dụng nhiá»u hÆ¡n số lượng byte mà nó sẵn có" -#: builtin/index-pack.c:279 builtin/pack-objects.c:598 +#: builtin/index-pack.c:279 builtin/pack-objects.c:599 msgid "pack too large for current definition of off_t" msgstr "gói quá lá»›n so vá»›i định nghÄ©a hiện tại của kiểu off_t" @@ -11830,7 +12700,7 @@ msgstr "gói quá lá»›n so vá»›i định nghÄ©a hiện tại của kiểu off_t" msgid "pack exceeds maximum allowed size" msgstr "gói đã vượt quá cỡ tối Ä‘a được phép" -#: builtin/index-pack.c:297 +#: builtin/index-pack.c:297 builtin/repack.c:250 #, c-format msgid "unable to create '%s'" msgstr "không thể tạo “%sâ€" @@ -11892,8 +12762,8 @@ msgstr "sá»± mâu thuẫn xả nén nghiêm trá»ng" msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "Sá»° VA CHẠM SHA1 Äà XẢY RA VỚI %s!" -#: builtin/index-pack.c:729 builtin/pack-objects.c:151 -#: builtin/pack-objects.c:211 builtin/pack-objects.c:305 +#: builtin/index-pack.c:729 builtin/pack-objects.c:152 +#: builtin/pack-objects.c:212 builtin/pack-objects.c:306 #, c-format msgid "unable to read %s" msgstr "không thể Ä‘á»c %s" @@ -11917,11 +12787,6 @@ msgstr "đối tượng blob không hợp lệ %s" msgid "fsck error in packed object" msgstr "lá»—i fsck trong đối tượng đóng gói" -#: builtin/index-pack.c:833 -#, c-format -msgid "invalid %s" -msgstr "%s không hợp lệ" - #: builtin/index-pack.c:838 #, c-format msgid "Not all child objects of %s are reachable" @@ -11959,7 +12824,7 @@ msgstr "lá»™n xá»™n hÆ¡n cả Ä‘iên rồ khi chạy hà m parse_pack_objects()" msgid "Resolving deltas" msgstr "Äang phân giải các delta" -#: builtin/index-pack.c:1196 builtin/pack-objects.c:2492 +#: builtin/index-pack.c:1196 builtin/pack-objects.c:2486 #, c-format msgid "unable to create thread: %s" msgstr "không thể tạo tuyến: %s" @@ -12022,7 +12887,7 @@ msgstr "không thể lÆ°u táºp tin gói" msgid "cannot store index file" msgstr "không thể lÆ°u trữ táºp tin ghi mục lục" -#: builtin/index-pack.c:1497 builtin/pack-objects.c:2727 +#: builtin/index-pack.c:1497 builtin/pack-objects.c:2725 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "sai pack.indexversion=%<PRIu32>" @@ -12188,7 +13053,7 @@ msgstr "" #: builtin/init-db.c:576 #, c-format msgid "Cannot access work tree '%s'" -msgstr "không thể truy cáºp cây (tree) là m việc “%sâ€" +msgstr "Không thể truy cáºp cây (tree) là m việc “%sâ€" #: builtin/interpret-trailers.c:15 msgid "" @@ -12254,120 +13119,120 @@ msgstr "--trailer cùng vá»›i --only-input không hợp lý" msgid "no input file given for in-place editing" msgstr "không Ä‘Æ°a ra táºp tin đầu và o để sá»a tại-chá»—" -#: builtin/log.c:54 +#: builtin/log.c:55 msgid "git log [<options>] [<revision-range>] [[--] <path>...]" msgstr "git log [<các-tùy-chá»n>] [<vùng-xem-xét>] [[--] <Ä‘Æ°á»ng-dẫn>…]" -#: builtin/log.c:55 +#: builtin/log.c:56 msgid "git show [<options>] <object>..." msgstr "git show [<các-tùy-chá»n>] <đối-tượng>…" -#: builtin/log.c:99 +#: builtin/log.c:100 #, c-format msgid "invalid --decorate option: %s" msgstr "tùy chá»n--decorate không hợp lệ: %s" -#: builtin/log.c:162 +#: builtin/log.c:163 msgid "suppress diff output" msgstr "chặn má»i kết xuất từ diff" -#: builtin/log.c:163 +#: builtin/log.c:164 msgid "show source" msgstr "hiển thị mã nguồn" -#: builtin/log.c:164 +#: builtin/log.c:165 msgid "Use mail map file" msgstr "Sá» dụng táºp tin ánh xạ thÆ°" -#: builtin/log.c:166 +#: builtin/log.c:167 msgid "only decorate refs that match <pattern>" msgstr "chỉ tô sáng các tham chiếu khá»›p vá»›i <mẫu>" -#: builtin/log.c:168 +#: builtin/log.c:169 msgid "do not decorate refs that match <pattern>" msgstr "không tô sáng các tham chiếu khá»›p vá»›i <mẫu>" -#: builtin/log.c:169 +#: builtin/log.c:170 msgid "decorate options" msgstr "các tùy chá»n trang trÃ" -#: builtin/log.c:172 +#: builtin/log.c:173 msgid "Process line range n,m in file, counting from 1" msgstr "Xá» lý chỉ dòng vùng n,m trong táºp tin, tÃnh từ 1" -#: builtin/log.c:270 +#: builtin/log.c:271 #, c-format msgid "Final output: %d %s\n" msgstr "Kết xuất cuối cùng: %d %s\n" -#: builtin/log.c:522 +#: builtin/log.c:525 #, c-format msgid "git show %s: bad file" msgstr "git show %s: sai táºp tin" -#: builtin/log.c:537 builtin/log.c:631 +#: builtin/log.c:540 builtin/log.c:634 #, c-format msgid "Could not read object %s" msgstr "Không thể Ä‘á»c đối tượng %s" -#: builtin/log.c:655 +#: builtin/log.c:659 #, c-format msgid "Unknown type: %d" msgstr "Không nháºn ra kiểu: %d" -#: builtin/log.c:776 +#: builtin/log.c:780 msgid "format.headers without value" msgstr "format.headers không có giá trị cụ thể" -#: builtin/log.c:877 +#: builtin/log.c:881 msgid "name of output directory is too long" msgstr "tên của thÆ° mục kết xuất quá dà i" -#: builtin/log.c:893 +#: builtin/log.c:897 #, c-format msgid "Cannot open patch file %s" msgstr "Không thể mở táºp tin miếng vá: %s" -#: builtin/log.c:910 +#: builtin/log.c:914 msgid "Need exactly one range." msgstr "Cần chÃnh xác má»™t vùng." -#: builtin/log.c:920 +#: builtin/log.c:924 msgid "Not a range." msgstr "Không phải là má»™t vùng." -#: builtin/log.c:1043 +#: builtin/log.c:1047 msgid "Cover letter needs email format" msgstr "“Cover letter†cần cho định dạng thÆ°" -#: builtin/log.c:1119 +#: builtin/log.c:1132 #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to Ä‘iên rồ: %s" -#: builtin/log.c:1146 +#: builtin/log.c:1159 msgid "git format-patch [<options>] [<since> | <revision-range>]" msgstr "git format-patch [<các-tùy-chá»n>] [<kể-từ> | <vùng-xem-xét>]" -#: builtin/log.c:1204 +#: builtin/log.c:1217 msgid "Two output directories?" msgstr "Hai thÆ° mục kết xuất?" -#: builtin/log.c:1311 builtin/log.c:2054 builtin/log.c:2056 builtin/log.c:2068 +#: builtin/log.c:1324 builtin/log.c:2068 builtin/log.c:2070 builtin/log.c:2082 #, c-format msgid "Unknown commit %s" msgstr "Không hiểu lần chuyển giao %s" -#: builtin/log.c:1321 builtin/notes.c:894 builtin/tag.c:526 +#: builtin/log.c:1334 builtin/notes.c:897 builtin/tag.c:526 #, c-format msgid "Failed to resolve '%s' as a valid ref." msgstr "Gặp lá»—i khi phân giải “%s†nhÆ° là má»™t tham chiếu hợp lệ." -#: builtin/log.c:1326 +#: builtin/log.c:1339 msgid "Could not find exact merge base." msgstr "Không tìm thấy ná»n hòa trá»™n chÃnh xác." -#: builtin/log.c:1330 +#: builtin/log.c:1343 msgid "" "Failed to get upstream, if you want to record base commit automatically,\n" "please use git branch --set-upstream-to to track a remote branch.\n" @@ -12378,280 +13243,280 @@ msgstr "" "nhánh máy chủ. Hoặc là bạn có thể chỉ định lần chuyển giao ná»n bằng\n" "\"--base=<base-commit-id>\" má»™t cách thủ công." -#: builtin/log.c:1350 +#: builtin/log.c:1363 msgid "Failed to find exact merge base" -msgstr "Gặp lá»—i khi tìm ná»n hòa trá»™n chÃnh xác." +msgstr "Gặp lá»—i khi tìm ná»n hòa trá»™n chÃnh xác" -#: builtin/log.c:1361 +#: builtin/log.c:1374 msgid "base commit should be the ancestor of revision list" msgstr "lần chuyển giao ná»n không là tổ tiên của danh sách Ä‘iểm xét duyệt" -#: builtin/log.c:1365 +#: builtin/log.c:1378 msgid "base commit shouldn't be in revision list" msgstr "lần chuyển giao ná»n không được trong danh sách Ä‘iểm xét duyệt" -#: builtin/log.c:1418 +#: builtin/log.c:1431 msgid "cannot get patch id" msgstr "không thể lấy mã miếng vá" -#: builtin/log.c:1470 +#: builtin/log.c:1483 msgid "failed to infer range-diff ranges" msgstr "gặp lá»—i khi suy luáºn range-diff (vùng khác biệt)" -#: builtin/log.c:1515 +#: builtin/log.c:1528 msgid "use [PATCH n/m] even with a single patch" msgstr "dùng [PATCH n/m] ngay cả vá»›i miếng vá Ä‘Æ¡n" -#: builtin/log.c:1518 +#: builtin/log.c:1531 msgid "use [PATCH] even with multiple patches" msgstr "dùng [VÃ] ngay cả vá»›i các miếng vá phức tạp" -#: builtin/log.c:1522 +#: builtin/log.c:1535 msgid "print patches to standard out" msgstr "hiển thị miếng vá ra đầu ra chuẩn" -#: builtin/log.c:1524 +#: builtin/log.c:1537 msgid "generate a cover letter" msgstr "tạo bì thÆ°" -#: builtin/log.c:1526 +#: builtin/log.c:1539 msgid "use simple number sequence for output file names" msgstr "sá» dụng chá»—i dãy số dạng Ä‘Æ¡n giản cho tên táºp-tin xuất ra" -#: builtin/log.c:1527 +#: builtin/log.c:1540 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1528 +#: builtin/log.c:1541 msgid "use <sfx> instead of '.patch'" msgstr "sá» dụng <sfx> thay cho “.patchâ€" -#: builtin/log.c:1530 +#: builtin/log.c:1543 msgid "start numbering patches at <n> instead of 1" msgstr "bắt đầu đánh số miếng vá từ <n> thay vì 1" -#: builtin/log.c:1532 +#: builtin/log.c:1545 msgid "mark the series as Nth re-roll" msgstr "đánh dấu chuá»—i nối tiếp dạng thứ-N re-roll" -#: builtin/log.c:1534 +#: builtin/log.c:1547 msgid "Use [RFC PATCH] instead of [PATCH]" msgstr "Dùng [RFC VÃ] thay cho [VÃ]" -#: builtin/log.c:1537 +#: builtin/log.c:1550 msgid "Use [<prefix>] instead of [PATCH]" msgstr "Dùng [<tiá»n-tố>] thay cho [VÃ]" -#: builtin/log.c:1540 +#: builtin/log.c:1553 msgid "store resulting files in <dir>" msgstr "lÆ°u các táºp tin kết quả trong <t.mục>" -#: builtin/log.c:1543 +#: builtin/log.c:1556 msgid "don't strip/add [PATCH]" msgstr "không strip/add [VÃ]" -#: builtin/log.c:1546 +#: builtin/log.c:1559 msgid "don't output binary diffs" msgstr "không kết xuất diff (những khác biệt) nhị phân" -#: builtin/log.c:1548 +#: builtin/log.c:1561 msgid "output all-zero hash in From header" msgstr "xuất má»i mã băm all-zero trong phần đầu From" -#: builtin/log.c:1550 +#: builtin/log.c:1563 msgid "don't include a patch matching a commit upstream" msgstr "không bao gồm miếng vá khá»›p vá»›i má»™t lần chuyển giao thượng nguồn" -#: builtin/log.c:1552 +#: builtin/log.c:1565 msgid "show patch format instead of default (patch + stat)" msgstr "hiển thị định dạng miếng vá thay vì mặc định (miếng vá + thống kê)" -#: builtin/log.c:1554 +#: builtin/log.c:1567 msgid "Messaging" msgstr "Lá»i nhắn" -#: builtin/log.c:1555 +#: builtin/log.c:1568 msgid "header" msgstr "đầu Ä‘á» thÆ°" -#: builtin/log.c:1556 +#: builtin/log.c:1569 msgid "add email header" msgstr "thêm đầu Ä‘á» thÆ°" -#: builtin/log.c:1557 builtin/log.c:1559 +#: builtin/log.c:1570 builtin/log.c:1572 msgid "email" msgstr "thÆ° Ä‘iện tá»" -#: builtin/log.c:1557 +#: builtin/log.c:1570 msgid "add To: header" msgstr "thêm To: đầu Ä‘á» thÆ°" -#: builtin/log.c:1559 +#: builtin/log.c:1572 msgid "add Cc: header" msgstr "thêm Cc: đầu Ä‘á» thÆ°" -#: builtin/log.c:1561 +#: builtin/log.c:1574 msgid "ident" msgstr "thụt lá»" -#: builtin/log.c:1562 +#: builtin/log.c:1575 msgid "set From address to <ident> (or committer ident if absent)" msgstr "" "đặt “Äịa chỉ gá»i†thà nh <thụ lá»> (hoặc thụt lá» ngÆ°á»i commit nếu bá» quên)" -#: builtin/log.c:1564 +#: builtin/log.c:1577 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1565 +#: builtin/log.c:1578 msgid "make first mail a reply to <message-id>" msgstr "dùng thÆ° đầu tiên để trả lá»i <message-id>" -#: builtin/log.c:1566 builtin/log.c:1569 +#: builtin/log.c:1579 builtin/log.c:1582 msgid "boundary" msgstr "ranh giá»›i" -#: builtin/log.c:1567 +#: builtin/log.c:1580 msgid "attach the patch" msgstr "Ä‘Ãnh kèm miếng vá" -#: builtin/log.c:1570 +#: builtin/log.c:1583 msgid "inline the patch" msgstr "dùng miếng vá là m ná»™i dung" -#: builtin/log.c:1574 +#: builtin/log.c:1587 msgid "enable message threading, styles: shallow, deep" msgstr "cho phép luồng lá»i nhắn, kiểu: “shallowâ€, “deepâ€" -#: builtin/log.c:1576 +#: builtin/log.c:1589 msgid "signature" msgstr "chữ ký" -#: builtin/log.c:1577 +#: builtin/log.c:1590 msgid "add a signature" msgstr "thêm chữ ký" -#: builtin/log.c:1578 +#: builtin/log.c:1591 msgid "base-commit" msgstr "lần_chuyển_giao_ná»n" -#: builtin/log.c:1579 +#: builtin/log.c:1592 msgid "add prerequisite tree info to the patch series" msgstr "add trÆ°á»›c hết đòi há»i thông tin cây tá»›i sê-ri miếng vá" -#: builtin/log.c:1581 +#: builtin/log.c:1594 msgid "add a signature from a file" msgstr "thêm chữ ký từ má»™t táºp tin" -#: builtin/log.c:1582 +#: builtin/log.c:1595 msgid "don't print the patch filenames" msgstr "không hiển thị các tên táºp tin của miếng vá" -#: builtin/log.c:1584 +#: builtin/log.c:1597 msgid "show progress while generating patches" msgstr "hiển thị bá»™ Ä‘o tiến triển trong khi tạo các miếng vá" -#: builtin/log.c:1585 +#: builtin/log.c:1598 msgid "rev" msgstr "rev" -#: builtin/log.c:1586 +#: builtin/log.c:1599 msgid "show changes against <rev> in cover letter or single patch" msgstr "" "hiển thị các thay đổi dá»±a trên <rev> trong các chữ bao bá»c hoặc miếng vá Ä‘Æ¡n" -#: builtin/log.c:1589 +#: builtin/log.c:1602 msgid "show changes against <refspec> in cover letter or single patch" msgstr "" "hiển thị các thay đổi dá»±a trên <refspec> trong các chữ bao bá»c hoặc miếng vá " "Ä‘Æ¡n" -#: builtin/log.c:1591 +#: builtin/log.c:1604 msgid "percentage by which creation is weighted" msgstr "tá»· lệ phần trăm theo cái tạo là weighted" -#: builtin/log.c:1666 +#: builtin/log.c:1679 #, c-format msgid "invalid ident line: %s" msgstr "dòng thụt lá» không hợp lệ: %s" -#: builtin/log.c:1681 +#: builtin/log.c:1694 msgid "-n and -k are mutually exclusive" msgstr "-n và -k loại từ lẫn nhau" -#: builtin/log.c:1683 +#: builtin/log.c:1696 msgid "--subject-prefix/--rfc and -k are mutually exclusive" msgstr "--subject-prefix/--rfc và -k xung khắc nhau" -#: builtin/log.c:1691 +#: builtin/log.c:1704 msgid "--name-only does not make sense" msgstr "--name-only không hợp lý" -#: builtin/log.c:1693 +#: builtin/log.c:1706 msgid "--name-status does not make sense" msgstr "--name-status không hợp lý" -#: builtin/log.c:1695 +#: builtin/log.c:1708 msgid "--check does not make sense" msgstr "--check không hợp lý" -#: builtin/log.c:1727 +#: builtin/log.c:1740 msgid "standard output, or directory, which one?" msgstr "đầu ra chuẩn, hay thÆ° mục, chá»n cái nà o?" -#: builtin/log.c:1729 +#: builtin/log.c:1742 #, c-format msgid "Could not create directory '%s'" msgstr "Không thể tạo thÆ° mục “%sâ€" -#: builtin/log.c:1816 +#: builtin/log.c:1829 msgid "--interdiff requires --cover-letter or single patch" msgstr "--interdiff cần --cover-letter hoặc vá Ä‘Æ¡n" -#: builtin/log.c:1820 +#: builtin/log.c:1833 msgid "Interdiff:" msgstr "Interdiff:" -#: builtin/log.c:1821 +#: builtin/log.c:1834 #, c-format msgid "Interdiff against v%d:" msgstr "Interdiff dá»±a trên v%d:" -#: builtin/log.c:1827 +#: builtin/log.c:1840 msgid "--creation-factor requires --range-diff" msgstr "--creation-factor yêu cầu --range-diff" -#: builtin/log.c:1831 +#: builtin/log.c:1844 msgid "--range-diff requires --cover-letter or single patch" msgstr "--range-diff yêu cầu --cover-letter hoặc miếng vá Ä‘Æ¡n" -#: builtin/log.c:1839 +#: builtin/log.c:1852 msgid "Range-diff:" msgstr "Range-diff:" -#: builtin/log.c:1840 +#: builtin/log.c:1853 #, c-format msgid "Range-diff against v%d:" msgstr "Range-diff dá»±a trên v%d:" -#: builtin/log.c:1851 +#: builtin/log.c:1864 #, c-format msgid "unable to read signature file '%s'" msgstr "không thể Ä‘á»c táºp tin chữ ký “%sâ€" -#: builtin/log.c:1887 +#: builtin/log.c:1900 msgid "Generating patches" msgstr "Äang tạo các miếng vá" -#: builtin/log.c:1931 +#: builtin/log.c:1944 msgid "Failed to create output files" msgstr "Gặp lá»—i khi tạo các táºp tin kết xuất" -#: builtin/log.c:1989 +#: builtin/log.c:2003 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<thượng-nguồn> [<đầu> [<giá»›i-hạn>]]]" -#: builtin/log.c:2043 +#: builtin/log.c:2057 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -12659,110 +13524,110 @@ msgstr "" "Không tìm thấy nhánh mạng được theo dõi, hãy chỉ định <thượng-nguồn> má»™t " "cách thủ công.\n" -#: builtin/ls-files.c:469 +#: builtin/ls-files.c:470 msgid "git ls-files [<options>] [<file>...]" msgstr "git ls-files [<các-tùy-chá»n>] [<táºp-tin>…]" -#: builtin/ls-files.c:525 +#: builtin/ls-files.c:526 msgid "identify the file status with tags" msgstr "nháºn dạng các trạng thái táºp tin vá»›i thẻ" -#: builtin/ls-files.c:527 +#: builtin/ls-files.c:528 msgid "use lowercase letters for 'assume unchanged' files" msgstr "" "dùng chữ cái viết thÆ°á»ng cho các táºp tin “assume unchanged†(giả định không " "thay đổi)" -#: builtin/ls-files.c:529 +#: builtin/ls-files.c:530 msgid "use lowercase letters for 'fsmonitor clean' files" msgstr "dùng chữ cái viết thÆ°á»ng cho các táºp tin “fsmonitor cleanâ€" -#: builtin/ls-files.c:531 +#: builtin/ls-files.c:532 msgid "show cached files in the output (default)" msgstr "hiển thị các táºp tin được nhá»› tạm và o đầu ra (mặc định)" -#: builtin/ls-files.c:533 +#: builtin/ls-files.c:534 msgid "show deleted files in the output" msgstr "hiển thị các táºp tin đã xóa trong kết xuất" -#: builtin/ls-files.c:535 +#: builtin/ls-files.c:536 msgid "show modified files in the output" msgstr "hiển thị các táºp tin đã bị sá»a đổi ra kết xuất" -#: builtin/ls-files.c:537 +#: builtin/ls-files.c:538 msgid "show other files in the output" msgstr "hiển thị các táºp tin khác trong kết xuất" -#: builtin/ls-files.c:539 +#: builtin/ls-files.c:540 msgid "show ignored files in the output" msgstr "hiển thị các táºp tin bị bá» qua trong kết xuất" -#: builtin/ls-files.c:542 +#: builtin/ls-files.c:543 msgid "show staged contents' object name in the output" msgstr "hiển thị tên đối tượng của ná»™i dung được đặt lên bệ phóng ra kết xuất" -#: builtin/ls-files.c:544 +#: builtin/ls-files.c:545 msgid "show files on the filesystem that need to be removed" msgstr "hiển thị các táºp tin trên hệ thống táºp tin mà nó cần được gỡ bá»" -#: builtin/ls-files.c:546 +#: builtin/ls-files.c:547 msgid "show 'other' directories' names only" msgstr "chỉ hiển thị tên của các thÆ° mục “khácâ€" -#: builtin/ls-files.c:548 +#: builtin/ls-files.c:549 msgid "show line endings of files" msgstr "hiển thị kết thúc dòng của các táºp tin" -#: builtin/ls-files.c:550 +#: builtin/ls-files.c:551 msgid "don't show empty directories" msgstr "không hiển thị thÆ° mục rá»—ng" -#: builtin/ls-files.c:553 +#: builtin/ls-files.c:554 msgid "show unmerged files in the output" msgstr "hiển thị các táºp tin chÆ°a hòa trá»™n trong kết xuất" -#: builtin/ls-files.c:555 +#: builtin/ls-files.c:556 msgid "show resolve-undo information" msgstr "hiển thị thông tin resolve-undo" -#: builtin/ls-files.c:557 +#: builtin/ls-files.c:558 msgid "skip files matching pattern" msgstr "bá» qua những táºp tin khá»›p vá»›i má»™t mẫu" -#: builtin/ls-files.c:560 +#: builtin/ls-files.c:561 msgid "exclude patterns are read from <file>" msgstr "mẫu loại trừ được Ä‘á»c từ <táºp tin>" -#: builtin/ls-files.c:563 +#: builtin/ls-files.c:564 msgid "read additional per-directory exclude patterns in <file>" msgstr "Ä‘á»c thêm các mẫu ngoại trừ má»—i thÆ° mục trong <táºp tin>" -#: builtin/ls-files.c:565 +#: builtin/ls-files.c:566 msgid "add the standard git exclusions" msgstr "thêm loại trừ tiêu chuẩn kiểu git" -#: builtin/ls-files.c:569 +#: builtin/ls-files.c:570 msgid "make the output relative to the project top directory" msgstr "là m cho kết xuất liên quan đến thÆ° mục ở mức cao nhất (gốc) của dá»± án" -#: builtin/ls-files.c:572 +#: builtin/ls-files.c:573 msgid "recurse through submodules" msgstr "đệ quy xuyên qua mô-Ä‘un con" -#: builtin/ls-files.c:574 +#: builtin/ls-files.c:575 msgid "if any <file> is not in the index, treat this as an error" msgstr "nếu <táºp tin> bất kỳ không ở trong bảng mục lục, xá» lý nó nhÆ° má»™t lá»—i" -#: builtin/ls-files.c:575 +#: builtin/ls-files.c:576 msgid "tree-ish" msgstr "tree-ish" -#: builtin/ls-files.c:576 +#: builtin/ls-files.c:577 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "" "giả định rằng các Ä‘Æ°á»ng dẫn đã bị gỡ bá» kể từ <tree-ish> nay vẫn hiện diện" -#: builtin/ls-files.c:578 +#: builtin/ls-files.c:579 msgid "show debugging data" msgstr "hiển thị dữ liệu gỡ lá»—i" @@ -12780,7 +13645,7 @@ msgstr "" msgid "do not print remote URL" msgstr "không hiển thị URL máy chủ" -#: builtin/ls-remote.c:60 builtin/ls-remote.c:62 builtin/rebase.c:903 +#: builtin/ls-remote.c:60 builtin/ls-remote.c:62 builtin/rebase.c:1111 msgid "exec" msgstr "thá»±c thi" @@ -12853,184 +13718,189 @@ msgstr "liệt kê cây mục tin; không chỉ thÆ° mục hiện hà nh (ngụ à msgid "empty mbox: '%s'" msgstr "mbox trống rá»—ng: “%sâ€" -#: builtin/merge.c:52 +#: builtin/merge.c:53 msgid "git merge [<options>] [<commit>...]" msgstr "git merge [<các-tùy-chá»n>] [<commit>…]" -#: builtin/merge.c:53 +#: builtin/merge.c:54 msgid "git merge --abort" msgstr "git merge --abort" -#: builtin/merge.c:54 +#: builtin/merge.c:55 msgid "git merge --continue" msgstr "git merge --continue" -#: builtin/merge.c:111 +#: builtin/merge.c:112 msgid "switch `m' requires a value" msgstr "switch “m†yêu cầu má»™t giá trị" -#: builtin/merge.c:177 +#: builtin/merge.c:132 +#, c-format +msgid "option `%s' requires a value" +msgstr "tùy chá»n “%s†yêu cầu má»™t giá trị" + +#: builtin/merge.c:178 #, c-format msgid "Could not find merge strategy '%s'.\n" msgstr "Không tìm thấy chiến lược hòa trá»™n “%sâ€.\n" -#: builtin/merge.c:178 +#: builtin/merge.c:179 #, c-format msgid "Available strategies are:" msgstr "Các chiến lược sẵn sà ng là :" -#: builtin/merge.c:183 +#: builtin/merge.c:184 #, c-format msgid "Available custom strategies are:" msgstr "Các chiến lược tùy chỉnh sẵn sà ng là :" -#: builtin/merge.c:234 builtin/pull.c:143 +#: builtin/merge.c:235 builtin/pull.c:144 msgid "do not show a diffstat at the end of the merge" msgstr "không hiển thị thống kê khác biệt tại cuối của lần hòa trá»™n" -#: builtin/merge.c:237 builtin/pull.c:146 +#: builtin/merge.c:238 builtin/pull.c:147 msgid "show a diffstat at the end of the merge" msgstr "hiển thị thống kê khác biệt tại cuối của hòa trá»™n" -#: builtin/merge.c:238 builtin/pull.c:149 +#: builtin/merge.c:239 builtin/pull.c:150 msgid "(synonym to --stat)" msgstr "(đồng nghÄ©a vá»›i --stat)" -#: builtin/merge.c:240 builtin/pull.c:152 +#: builtin/merge.c:241 builtin/pull.c:153 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" -#: builtin/merge.c:243 builtin/pull.c:158 +#: builtin/merge.c:244 builtin/pull.c:159 msgid "create a single commit instead of doing a merge" msgstr "tạo má»™t lần chuyển giao Ä‘Æ°on thay vì thá»±c hiện việc hòa trá»™n" -#: builtin/merge.c:245 builtin/pull.c:161 +#: builtin/merge.c:246 builtin/pull.c:162 msgid "perform a commit if the merge succeeds (default)" msgstr "thá»±c hiện chuyển giao nếu hòa trá»™n thà nh công (mặc định)" -#: builtin/merge.c:247 builtin/pull.c:164 +#: builtin/merge.c:248 builtin/pull.c:165 msgid "edit message before committing" msgstr "sá»a chú thÃch trÆ°á»›c khi chuyển giao" -#: builtin/merge.c:248 +#: builtin/merge.c:249 msgid "allow fast-forward (default)" msgstr "cho phép chuyển-tiếp-nhanh (mặc định)" -#: builtin/merge.c:250 builtin/pull.c:170 +#: builtin/merge.c:251 builtin/pull.c:171 msgid "abort if fast-forward is not possible" msgstr "bá» qua nếu chuyển-tiếp-nhanh không thể được" -#: builtin/merge.c:254 builtin/pull.c:173 +#: builtin/merge.c:255 builtin/pull.c:174 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" -#: builtin/merge.c:255 builtin/notes.c:784 builtin/pull.c:177 -#: builtin/rebase.c:916 builtin/rebase--interactive.c:186 builtin/revert.c:110 +#: builtin/merge.c:256 builtin/notes.c:787 builtin/pull.c:178 +#: builtin/rebase.c:1124 builtin/rebase--interactive.c:188 builtin/revert.c:111 msgid "strategy" msgstr "chiến lược" -#: builtin/merge.c:256 builtin/pull.c:178 +#: builtin/merge.c:257 builtin/pull.c:179 msgid "merge strategy to use" msgstr "chiến lược hòa trá»™n sẽ dùng" -#: builtin/merge.c:257 builtin/pull.c:181 +#: builtin/merge.c:258 builtin/pull.c:182 msgid "option=value" msgstr "tùy_chá»n=giá_trị" -#: builtin/merge.c:258 builtin/pull.c:182 +#: builtin/merge.c:259 builtin/pull.c:183 msgid "option for selected merge strategy" msgstr "tùy chá»n cho chiến lược hòa trá»™n đã chá»n" -#: builtin/merge.c:260 +#: builtin/merge.c:261 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "hòa trá»™n ghi chú của lần chuyển giao (dà nh cho hòa trá»™n không-chuyển-tiếp-" "nhanh)" -#: builtin/merge.c:267 +#: builtin/merge.c:268 msgid "abort the current in-progress merge" msgstr "bãi bá» quá trình hòa trá»™n hiện tại Ä‘ang thá»±c hiện" -#: builtin/merge.c:269 +#: builtin/merge.c:270 msgid "continue the current in-progress merge" msgstr "tiếp tục quá trình hòa trá»™n hiện tại Ä‘ang thá»±c hiện" -#: builtin/merge.c:271 builtin/pull.c:189 +#: builtin/merge.c:272 builtin/pull.c:190 msgid "allow merging unrelated histories" msgstr "cho phép hòa trá»™n lịch sá» không liên quan" -#: builtin/merge.c:277 +#: builtin/merge.c:278 msgid "verify commit-msg hook" msgstr "thẩm tra móc (hook) commit-msg" -#: builtin/merge.c:302 +#: builtin/merge.c:303 msgid "could not run stash." msgstr "không thể chạy stash." -#: builtin/merge.c:307 +#: builtin/merge.c:308 msgid "stash failed" msgstr "lệnh tạm cất gặp lá»—i" -#: builtin/merge.c:312 +#: builtin/merge.c:313 #, c-format msgid "not a valid object: %s" msgstr "không phải là má»™t đối tượng hợp lệ: %s" -#: builtin/merge.c:334 builtin/merge.c:351 +#: builtin/merge.c:335 builtin/merge.c:352 msgid "read-tree failed" msgstr "read-tree gặp lá»—i" -#: builtin/merge.c:381 +#: builtin/merge.c:382 msgid " (nothing to squash)" msgstr " (không có gì để squash)" -#: builtin/merge.c:392 +#: builtin/merge.c:393 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Squash commit -- không cáºp nháºt HEAD\n" -#: builtin/merge.c:442 +#: builtin/merge.c:443 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "Không có lá»i chú thÃch hòa trá»™n -- nên không cáºp nháºt HEAD\n" -#: builtin/merge.c:493 +#: builtin/merge.c:494 #, c-format msgid "'%s' does not point to a commit" msgstr "“%s†không chỉ đến má»™t lần chuyển giao nà o cả" -#: builtin/merge.c:580 +#: builtin/merge.c:581 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Chuá»—i branch.%s.mergeoptions sai: %s" -#: builtin/merge.c:701 +#: builtin/merge.c:702 msgid "Not handling anything other than two heads merge." -msgstr "Không cầm nắm gì ngoà i hai head hòa trá»™n" +msgstr "Không cầm nắm gì ngoà i hai head hòa trá»™n." -#: builtin/merge.c:715 +#: builtin/merge.c:716 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Không hiểu tùy chá»n cho merge-recursive: -X%s" -#: builtin/merge.c:730 +#: builtin/merge.c:731 #, c-format msgid "unable to write %s" msgstr "không thể ghi %s" -#: builtin/merge.c:782 +#: builtin/merge.c:783 #, c-format msgid "Could not read from '%s'" msgstr "Không thể Ä‘á»c từ “%sâ€" -#: builtin/merge.c:791 +#: builtin/merge.c:792 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Vẫn chÆ°a hòa trá»™n các lần chuyển giao; sá» dụng lệnh “git commit†để hoà n tất " "việc hòa trá»™n.\n" -#: builtin/merge.c:797 +#: builtin/merge.c:798 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -13048,71 +13918,71 @@ msgstr "" "rá»—ng\n" "sẽ hủy bá» lần chuyển giao.\n" -#: builtin/merge.c:833 +#: builtin/merge.c:834 msgid "Empty commit message." msgstr "Chú thÃch của lần commit (chuyển giao) bị trống rá»—ng." -#: builtin/merge.c:852 +#: builtin/merge.c:853 #, c-format msgid "Wonderful.\n" msgstr "Tuyệt vá»i.\n" -#: builtin/merge.c:905 +#: builtin/merge.c:906 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Việc tá»± Ä‘á»™ng hòa trá»™n gặp lá»—i; hãy sá»a các xung Ä‘á»™t sau đó chuyển giao kết " "quả.\n" -#: builtin/merge.c:944 +#: builtin/merge.c:945 msgid "No current branch." -msgstr "không phải nhánh hiện hà nh" +msgstr "Không phải nhánh hiện hà nh." -#: builtin/merge.c:946 +#: builtin/merge.c:947 msgid "No remote for the current branch." msgstr "Không có máy chủ cho nhánh hiện hà nh." -#: builtin/merge.c:948 +#: builtin/merge.c:949 msgid "No default upstream defined for the current branch." msgstr "Không có thượng nguồn mặc định được định nghÄ©a cho nhánh hiện hà nh." -#: builtin/merge.c:953 +#: builtin/merge.c:954 #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "Không nhánh mạng theo dõi cho %s từ %s" -#: builtin/merge.c:1010 +#: builtin/merge.c:1011 #, c-format msgid "Bad value '%s' in environment '%s'" msgstr "Giá trị sai “%s†trong biến môi trÆ°á»ng “%sâ€" -#: builtin/merge.c:1113 +#: builtin/merge.c:1114 #, c-format msgid "not something we can merge in %s: %s" msgstr "không phải là má»™t thứ gì đó mà chúng tôi có thể hòa trá»™n trong %s: %s" -#: builtin/merge.c:1147 +#: builtin/merge.c:1148 msgid "not something we can merge" msgstr "không phải là thứ gì đó mà chúng tôi có thể hòa trá»™n" -#: builtin/merge.c:1250 +#: builtin/merge.c:1251 msgid "--abort expects no arguments" msgstr "--abort không nháºn các đối số" -#: builtin/merge.c:1254 +#: builtin/merge.c:1255 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "" "Ở đây không có lần hòa trá»™n nà o được hủy bá» giữa chừng cả (thiếu MERGE_HEAD)." -#: builtin/merge.c:1266 +#: builtin/merge.c:1267 msgid "--continue expects no arguments" msgstr "--continue không nháºn đối số" -#: builtin/merge.c:1270 +#: builtin/merge.c:1271 msgid "There is no merge in progress (MERGE_HEAD missing)." msgstr "Ở đây không có lần hòa trá»™n nà o Ä‘ang được xá» lý cả (thiếu MERGE_HEAD)." -#: builtin/merge.c:1286 +#: builtin/merge.c:1287 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." @@ -13120,7 +13990,7 @@ msgstr "" "Bạn chÆ°a kết thúc việc hòa trá»™n (MERGE_HEAD vẫn tồn tại).\n" "Hãy chuyển giao các thay đổi trÆ°á»›c khi bạn có thể hòa trá»™n." -#: builtin/merge.c:1293 +#: builtin/merge.c:1294 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." @@ -13128,94 +13998,94 @@ msgstr "" "Bạn chÆ°a kết thúc việc cherry-pick (CHERRY_PICK_HEAD vẫn tồn tại).\n" "Hãy chuyển giao các thay đổi trÆ°á»›c khi bạn có thể hòa trá»™n." -#: builtin/merge.c:1296 +#: builtin/merge.c:1297 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "Bạn chÆ°a kết thúc việc cherry-pick (CHERRY_PICK_HEAD vẫn tồn tại)." -#: builtin/merge.c:1305 +#: builtin/merge.c:1306 msgid "You cannot combine --squash with --no-ff." msgstr "Bạn không thể kết hợp --squash vá»›i --no-ff." -#: builtin/merge.c:1313 +#: builtin/merge.c:1314 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Không chỉ ra lần chuyển giao và merge.defaultToUpstream chÆ°a được đặt." -#: builtin/merge.c:1330 +#: builtin/merge.c:1331 msgid "Squash commit into empty head not supported yet" msgstr "Squash commit và o má»™t head trống rá»—ng vẫn chÆ°a được há»— trợ" -#: builtin/merge.c:1332 +#: builtin/merge.c:1333 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" "Chuyển giao không-chuyển-tiếp-nhanh không hợp lý ở trong má»™t head trống rá»—ng" -#: builtin/merge.c:1337 +#: builtin/merge.c:1338 #, c-format msgid "%s - not something we can merge" msgstr "%s - không phải là thứ gì đó mà chúng tôi có thể hòa trá»™n" -#: builtin/merge.c:1339 +#: builtin/merge.c:1340 msgid "Can merge only exactly one commit into empty head" msgstr "" "Không thể hòa trá»™n má»™t cách đúng đắn má»™t lần chuyển giao và o má»™t head rá»—ng" -#: builtin/merge.c:1421 +#: builtin/merge.c:1422 msgid "refusing to merge unrelated histories" msgstr "từ chối hòa trá»™n lịch sá» không liên quan" -#: builtin/merge.c:1430 +#: builtin/merge.c:1431 msgid "Already up to date." msgstr "Äã cáºp nháºt rồi." -#: builtin/merge.c:1440 +#: builtin/merge.c:1441 #, c-format msgid "Updating %s..%s\n" msgstr "Äang cáºp nháºt %s..%s\n" -#: builtin/merge.c:1482 +#: builtin/merge.c:1483 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Äang thá» hòa trá»™n kiểu “trivial in-indexâ€â€¦\n" -#: builtin/merge.c:1489 +#: builtin/merge.c:1490 #, c-format msgid "Nope.\n" msgstr "Không.\n" -#: builtin/merge.c:1514 +#: builtin/merge.c:1515 msgid "Already up to date. Yeeah!" msgstr "Äã cáºp nháºt rồi. Yeeah!" -#: builtin/merge.c:1520 +#: builtin/merge.c:1521 msgid "Not possible to fast-forward, aborting." msgstr "Thá»±c hiện lệnh chuyển-tiếp-nhanh là không thể được, Ä‘ang bá» qua." -#: builtin/merge.c:1543 builtin/merge.c:1622 +#: builtin/merge.c:1544 builtin/merge.c:1623 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Äang tua lại cây thà nh thá»i xa xÆ°a…\n" -#: builtin/merge.c:1547 +#: builtin/merge.c:1548 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Äang thá» chiến lược hòa trá»™n %s…\n" -#: builtin/merge.c:1613 +#: builtin/merge.c:1614 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Không có chiến lược hòa trá»™n nà o được nắm giữ (handle) sá»± hòa trá»™n.\n" -#: builtin/merge.c:1615 +#: builtin/merge.c:1616 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Hòa trá»™n vá»›i chiến lược %s gặp lá»—i.\n" -#: builtin/merge.c:1624 +#: builtin/merge.c:1625 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Sá» dụng %s để chuẩn bị giải quyết bằng tay.\n" -#: builtin/merge.c:1636 +#: builtin/merge.c:1637 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -13302,32 +14172,32 @@ msgstr "không cảnh báo vá» các xung Ä‘á»™t xảy ra" msgid "set labels for file1/orig-file/file2" msgstr "đặt nhãn cho táºp-tin-1/táºp-tin-gốc/táºp-tin-2" -#: builtin/merge-recursive.c:45 +#: builtin/merge-recursive.c:46 #, c-format msgid "unknown option %s" msgstr "không hiểu tùy chá»n %s" -#: builtin/merge-recursive.c:51 +#: builtin/merge-recursive.c:52 #, c-format msgid "could not parse object '%s'" msgstr "không thể phân tÃch đối tượng “%sâ€" -#: builtin/merge-recursive.c:55 +#: builtin/merge-recursive.c:56 #, c-format msgid "cannot handle more than %d base. Ignoring %s." msgid_plural "cannot handle more than %d bases. Ignoring %s." -msgstr[0] "không thể xá» lý nhiá»u hÆ¡n %d ná»n. Bá» qua %s" +msgstr[0] "không thể xá» lý nhiá»u hÆ¡n %d ná»n. Bá» qua %s." -#: builtin/merge-recursive.c:63 +#: builtin/merge-recursive.c:64 msgid "not handling anything other than two heads merge." -msgstr "không cầm nắm gì ngoà i hai head hòa trá»™n" +msgstr "không xá» lý gì ngoà i hai head hòa trá»™n." -#: builtin/merge-recursive.c:69 builtin/merge-recursive.c:71 +#: builtin/merge-recursive.c:70 builtin/merge-recursive.c:72 #, c-format msgid "could not resolve ref '%s'" msgstr "không thể phân giải tham chiếu %s" -#: builtin/merge-recursive.c:77 +#: builtin/merge-recursive.c:78 #, c-format msgid "Merging %s with %s\n" msgstr "Äang hòa trá»™n %s vá»›i %s\n" @@ -13340,7 +14210,7 @@ msgstr "git mktree [-z] [--missing] [--batch]" msgid "input is NUL terminated" msgstr "đầu và o được chấm dứt bởi NUL" -#: builtin/mktree.c:155 builtin/write-tree.c:25 +#: builtin/mktree.c:155 builtin/write-tree.c:26 msgid "allow missing objects" msgstr "cho phép thiếu đối tượng" @@ -13365,95 +14235,95 @@ msgstr "có quá nhiá»u đối số" msgid "unrecognized verb: %s" msgstr "verb không được thừa nháºn: %s" -#: builtin/mv.c:17 +#: builtin/mv.c:18 msgid "git mv [<options>] <source>... <destination>" msgstr "git mv [<các-tùy-chá»n>] <nguồn>… <Ä‘Ãch>" -#: builtin/mv.c:82 +#: builtin/mv.c:83 #, 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?" -#: builtin/mv.c:84 +#: builtin/mv.c:85 msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" "Hãy Ä‘Æ°a các thay đổi của bạn và o .gitmodules hay tạm cất chúng Ä‘i để xá» lý" -#: builtin/mv.c:102 +#: builtin/mv.c:103 #, c-format msgid "%.*s is in index" msgstr "%.*s trong bảng mục lục" -#: builtin/mv.c:124 +#: builtin/mv.c:125 msgid "force move/rename even if target exists" msgstr "ép buá»™c di chuyển hay đổi tên tháºm chà cả khi Ä‘Ãch đã tồn tại" -#: builtin/mv.c:126 +#: builtin/mv.c:127 msgid "skip move/rename errors" msgstr "bá» qua các lá»—i liên quan đến di chuyển, đổi tên" -#: builtin/mv.c:168 +#: builtin/mv.c:169 #, c-format msgid "destination '%s' is not a directory" msgstr "có Ä‘Ãch “%s†nhÆ°ng đây không phải là má»™t thÆ° mục" -#: builtin/mv.c:179 +#: builtin/mv.c:180 #, c-format msgid "Checking rename of '%s' to '%s'\n" msgstr "Äang kiểm tra việc đổi tên của “%s†thà nh “%sâ€\n" -#: builtin/mv.c:183 +#: builtin/mv.c:184 msgid "bad source" msgstr "nguồn sai" -#: builtin/mv.c:186 +#: builtin/mv.c:187 msgid "can not move directory into itself" msgstr "không thể di chuyển má»™t thÆ° mục và o trong chÃnh nó được" -#: builtin/mv.c:189 +#: builtin/mv.c:190 msgid "cannot move directory over file" msgstr "không di chuyển được thÆ° mục thông qua táºp tin" -#: builtin/mv.c:198 +#: builtin/mv.c:199 msgid "source directory is empty" msgstr "thÆ° mục nguồn là trống rá»—ng" -#: builtin/mv.c:223 +#: builtin/mv.c:224 msgid "not under version control" msgstr "không nằm dÆ°á»›i sá»± quản lý mã nguồn" -#: builtin/mv.c:226 +#: builtin/mv.c:227 msgid "destination exists" msgstr "Ä‘Ãch đã tồn tại sẵn rồi" -#: builtin/mv.c:234 +#: builtin/mv.c:235 #, c-format msgid "overwriting '%s'" msgstr "Ä‘ang ghi đè lên “%sâ€" -#: builtin/mv.c:237 +#: builtin/mv.c:238 msgid "Cannot overwrite" msgstr "Không thể ghi đè" -#: builtin/mv.c:240 +#: builtin/mv.c:241 msgid "multiple sources for the same target" -msgstr "Nhiá»u nguồn cho cùng má»™t Ä‘Ãch" +msgstr "nhiá»u nguồn cho cùng má»™t Ä‘Ãch" -#: builtin/mv.c:242 +#: builtin/mv.c:243 msgid "destination directory does not exist" msgstr "thÆ° mục Ä‘Ãch không tồn tại" -#: builtin/mv.c:249 +#: builtin/mv.c:250 #, c-format msgid "%s, source=%s, destination=%s" msgstr "%s, nguồn=%s, Ä‘Ãch=%s" -#: builtin/mv.c:270 +#: builtin/mv.c:271 #, c-format msgid "Renaming %s to %s\n" msgstr "Äổi tên %s thà nh %s\n" -#: builtin/mv.c:276 builtin/remote.c:717 builtin/repack.c:511 +#: builtin/mv.c:277 builtin/remote.c:717 builtin/repack.c:513 #, c-format msgid "renaming '%s' failed" msgstr "gặp lá»—i khi đổi tên “%sâ€" @@ -13651,8 +14521,8 @@ msgid "could not open or read '%s'" msgstr "không thể mở hay Ä‘á»c “%sâ€" #: builtin/notes.c:263 builtin/notes.c:313 builtin/notes.c:315 -#: builtin/notes.c:383 builtin/notes.c:438 builtin/notes.c:524 -#: builtin/notes.c:529 builtin/notes.c:607 builtin/notes.c:669 +#: builtin/notes.c:383 builtin/notes.c:438 builtin/notes.c:526 +#: builtin/notes.c:531 builtin/notes.c:610 builtin/notes.c:672 #, c-format msgid "failed to resolve '%s' as a valid ref." msgstr "gặp lá»—i khi phân giải “%s†nhÆ° là má»™t tham chiếu hợp lệ." @@ -13685,38 +14555,38 @@ msgstr "gặp lá»—i khi sao chép ghi chú (note) từ “%s†sang “%sâ€" msgid "refusing to %s notes in %s (outside of refs/notes/)" msgstr "từ chối %s ghi chú trong %s (nằm ngoà i refs/notes/)" -#: builtin/notes.c:376 builtin/notes.c:431 builtin/notes.c:507 -#: builtin/notes.c:519 builtin/notes.c:595 builtin/notes.c:662 -#: builtin/notes.c:812 builtin/notes.c:959 builtin/notes.c:980 +#: builtin/notes.c:376 builtin/notes.c:431 builtin/notes.c:509 +#: builtin/notes.c:521 builtin/notes.c:598 builtin/notes.c:665 +#: builtin/notes.c:815 builtin/notes.c:963 builtin/notes.c:985 msgid "too many parameters" msgstr "quá nhiá»u đối số" -#: builtin/notes.c:389 builtin/notes.c:675 +#: builtin/notes.c:389 builtin/notes.c:678 #, c-format msgid "no note found for object %s." msgstr "không tìm thấy ghi chú cho đối tượng %s." -#: builtin/notes.c:410 builtin/notes.c:573 +#: builtin/notes.c:410 builtin/notes.c:576 msgid "note contents as a string" msgstr "ná»™i dung ghi chú (note) nằm trong má»™t chuá»—i" -#: builtin/notes.c:413 builtin/notes.c:576 +#: builtin/notes.c:413 builtin/notes.c:579 msgid "note contents in a file" msgstr "ná»™i dung ghi chú (note) nằm trong má»™t táºp tin" -#: builtin/notes.c:416 builtin/notes.c:579 +#: builtin/notes.c:416 builtin/notes.c:582 msgid "reuse and edit specified note object" msgstr "dùng lại nhÆ°ng có sá»a chữa đối tượng note đã chỉ ra" -#: builtin/notes.c:419 builtin/notes.c:582 +#: builtin/notes.c:419 builtin/notes.c:585 msgid "reuse specified note object" msgstr "dùng lại đối tượng ghi chú (note) đã chỉ ra" -#: builtin/notes.c:422 builtin/notes.c:585 +#: builtin/notes.c:422 builtin/notes.c:588 msgid "allow storing empty note" msgstr "cho lÆ°u trữ ghi chú trống rá»—ng" -#: builtin/notes.c:423 builtin/notes.c:494 +#: builtin/notes.c:423 builtin/notes.c:496 msgid "replace existing notes" msgstr "thay thế ghi chú trÆ°á»›c" @@ -13729,29 +14599,29 @@ msgstr "" "Không thể thêm các ghi chú. Äã tìm thấy các ghi chú đã có sẵn cho đối tượng " "%s. Sá» dụng tùy chá»n “-f†để ghi đè lên các ghi chú cÅ©" -#: builtin/notes.c:463 builtin/notes.c:542 +#: builtin/notes.c:463 builtin/notes.c:544 #, c-format msgid "Overwriting existing notes for object %s\n" msgstr "Äang ghi đè lên ghi chú cÅ© cho đối tượng %s\n" -#: builtin/notes.c:474 builtin/notes.c:634 builtin/notes.c:899 +#: builtin/notes.c:475 builtin/notes.c:637 builtin/notes.c:902 #, c-format msgid "Removing note for object %s\n" msgstr "Äang gỡ bá» ghi chú (note) cho đối tượng %s\n" -#: builtin/notes.c:495 +#: builtin/notes.c:497 msgid "read objects from stdin" msgstr "Ä‘á»c các đối tượng từ đầu và o tiêu chuẩn" -#: builtin/notes.c:497 +#: builtin/notes.c:499 msgid "load rewriting config for <command> (implies --stdin)" msgstr "tải cấu hình chép lại cho <lệnh> (ngầm định là --stdin)" -#: builtin/notes.c:515 +#: builtin/notes.c:517 msgid "too few parameters" msgstr "quá Ãt đối số" -#: builtin/notes.c:536 +#: builtin/notes.c:538 #, c-format msgid "" "Cannot copy notes. Found existing notes for object %s. Use '-f' to overwrite " @@ -13760,12 +14630,12 @@ msgstr "" "Không thể sao chép các ghi chú. Äã tìm thấy các ghi chú đã có sẵn cho đối " "tượng %s. Sá» dụng tùy chá»n “-f†để ghi đè lên các ghi chú cÅ©" -#: builtin/notes.c:548 +#: builtin/notes.c:550 #, c-format msgid "missing notes on source object %s. Cannot copy." msgstr "thiếu ghi chú trên đối tượng nguồn %s. Không thể sao chép." -#: builtin/notes.c:600 +#: builtin/notes.c:603 #, c-format msgid "" "The -m/-F/-c/-C options have been deprecated for the 'edit' subcommand.\n" @@ -13774,52 +14644,52 @@ msgstr "" "Các tùy chá»n -m/-F/-c/-C đã cổ không còn dùng nữa cho lệnh con “editâ€.\n" "Xin hãy sá» dụng lệnh sau để thay thế: “git notes add -f -m/-F/-c/-Câ€.\n" -#: builtin/notes.c:695 +#: builtin/notes.c:698 msgid "failed to delete ref NOTES_MERGE_PARTIAL" msgstr "gặp lá»—i khi xóa tham chiếu NOTES_MERGE_PARTIAL" -#: builtin/notes.c:697 +#: builtin/notes.c:700 msgid "failed to delete ref NOTES_MERGE_REF" msgstr "gặp lá»—i khi xóa tham chiếu NOTES_MERGE_REF" -#: builtin/notes.c:699 +#: builtin/notes.c:702 msgid "failed to remove 'git notes merge' worktree" msgstr "gặp lá»—i khi gỡ bá» cây là m việc “git notes mergeâ€" -#: builtin/notes.c:719 +#: builtin/notes.c:722 msgid "failed to read ref NOTES_MERGE_PARTIAL" msgstr "gặp lá»—i khi Ä‘á»c tham chiếu NOTES_MERGE_PARTIAL" -#: builtin/notes.c:721 +#: builtin/notes.c:724 msgid "could not find commit from NOTES_MERGE_PARTIAL." msgstr "không thể tìm thấy lần chuyển giao từ NOTES_MERGE_PARTIAL." -#: builtin/notes.c:723 +#: builtin/notes.c:726 msgid "could not parse commit from NOTES_MERGE_PARTIAL." msgstr "không thể phân tÃch cú pháp lần chuyển giao từ NOTES_MERGE_PARTIAL." -#: builtin/notes.c:736 +#: builtin/notes.c:739 msgid "failed to resolve NOTES_MERGE_REF" msgstr "gặp lá»—i khi phân giải NOTES_MERGE_REF" -#: builtin/notes.c:739 +#: builtin/notes.c:742 msgid "failed to finalize notes merge" msgstr "gặp lá»—i khi hoà n thà nh hòa trá»™n ghi chú" -#: builtin/notes.c:765 +#: builtin/notes.c:768 #, c-format msgid "unknown notes merge strategy %s" msgstr "không hiểu chiến lược hòa trá»™n ghi chú %s" -#: builtin/notes.c:781 +#: builtin/notes.c:784 msgid "General options" msgstr "Tùy chá»n chung" -#: builtin/notes.c:783 +#: builtin/notes.c:786 msgid "Merge options" msgstr "Tùy chá»n vá» hòa trá»™n" -#: builtin/notes.c:785 +#: builtin/notes.c:788 msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" @@ -13827,48 +14697,48 @@ msgstr "" "phân giải các xung Ä‘á»™t “notes†sá» dụng chiến lược đã Ä‘Æ°a ra (manual/ours/" "theirs/union/cat_sort_uniq)" -#: builtin/notes.c:787 +#: builtin/notes.c:790 msgid "Committing unmerged notes" msgstr "Chuyển giao các note chÆ°a được hòa trá»™n" -#: builtin/notes.c:789 +#: builtin/notes.c:792 msgid "finalize notes merge by committing unmerged notes" msgstr "" "các note cuối cùng được hòa trá»™n bởi các note chÆ°a hòa trá»™n của lần chuyển " "giao" -#: builtin/notes.c:791 +#: builtin/notes.c:794 msgid "Aborting notes merge resolution" msgstr "Hủy bá» phân giải ghi chú (note) hòa trá»™n" -#: builtin/notes.c:793 +#: builtin/notes.c:796 msgid "abort notes merge" msgstr "bá» qua hòa trá»™n các ghi chú (note)" -#: builtin/notes.c:804 +#: builtin/notes.c:807 msgid "cannot mix --commit, --abort or -s/--strategy" msgstr "không thể trá»™n lẫn --commit, --abort hay -s/--strategy" -#: builtin/notes.c:809 +#: builtin/notes.c:812 msgid "must specify a notes ref to merge" msgstr "bạn phải chỉ định tham chiếu ghi chú để hòa trá»™n" -#: builtin/notes.c:833 +#: builtin/notes.c:836 #, c-format msgid "unknown -s/--strategy: %s" msgstr "không hiểu -s/--strategy: %s" -#: builtin/notes.c:870 +#: builtin/notes.c:873 #, c-format msgid "a notes merge into %s is already in-progress at %s" msgstr "má»™t ghi chú hòa trá»™n và o %s đã sẵn trong quá trình xá» lý tại %s" -#: builtin/notes.c:873 +#: builtin/notes.c:876 #, c-format msgid "failed to store link to current notes ref (%s)" msgstr "gặp lá»—i khi lÆ°u liên kết đến tham chiếu ghi chú hiện tại (%s)" -#: builtin/notes.c:875 +#: builtin/notes.c:878 #, c-format msgid "" "Automatic notes merge failed. Fix conflicts in %s and commit the result with " @@ -13879,36 +14749,36 @@ msgstr "" "chuyển giao kết quả bằng “git notes merge --commitâ€, hoặc bãi bá» việc hòa " "trá»™n bằng “git notes merge --abortâ€.\n" -#: builtin/notes.c:897 +#: builtin/notes.c:900 #, c-format msgid "Object %s has no note\n" msgstr "Äối tượng %s không có ghi chú (note)\n" -#: builtin/notes.c:909 +#: builtin/notes.c:912 msgid "attempt to remove non-existent note is not an error" msgstr "cố gắng gỡ bá» má»™t note chÆ°a từng tồn tại không phải là má»™t lá»—i" -#: builtin/notes.c:912 +#: builtin/notes.c:915 msgid "read object names from the standard input" msgstr "Ä‘á»c tên đối tượng từ thiết bị nháºp chuẩn" -#: builtin/notes.c:950 builtin/prune.c:108 builtin/worktree.c:164 +#: builtin/notes.c:954 builtin/prune.c:108 builtin/worktree.c:165 msgid "do not remove, show only" msgstr "không gỡ bá», chỉ hiển thị" -#: builtin/notes.c:951 +#: builtin/notes.c:955 msgid "report pruned notes" msgstr "báo cáo các đối tượng đã prune" -#: builtin/notes.c:993 +#: builtin/notes.c:998 msgid "notes-ref" msgstr "notes-ref" -#: builtin/notes.c:994 +#: builtin/notes.c:999 msgid "use notes from <notes-ref>" msgstr "dùng “notes†từ <notes-ref>" -#: builtin/notes.c:1029 +#: builtin/notes.c:1034 #, c-format msgid "unknown subcommand: %s" msgstr "không hiểu câu lệnh con: %s" @@ -13927,126 +14797,126 @@ msgstr "" "git pack-objects [các-tùy-chá»n…] <base-name> [< <danh-sách-ref> | < <danh-" "sách-đối-tượng>]" -#: builtin/pack-objects.c:422 +#: builtin/pack-objects.c:423 #, c-format msgid "bad packed object CRC for %s" msgstr "CRC của đối tượng gói sai vá»›i %s" -#: builtin/pack-objects.c:433 +#: builtin/pack-objects.c:434 #, c-format msgid "corrupt packed object for %s" msgstr "đối tượng đã đóng gói sai há»ng cho %s" -#: builtin/pack-objects.c:564 +#: builtin/pack-objects.c:565 #, c-format msgid "recursive delta detected for object %s" msgstr "dò thấy delta đệ quy cho đối tượng %s" -#: builtin/pack-objects.c:775 +#: builtin/pack-objects.c:776 #, c-format msgid "ordered %u objects, expected %<PRIu32>" msgstr "đã sắp xếp %u đối tượng, cần %<PRIu32>" -#: builtin/pack-objects.c:788 +#: builtin/pack-objects.c:789 #, c-format msgid "packfile is invalid: %s" msgstr "táºp tin gói không hợp lệ: %s" -#: builtin/pack-objects.c:792 +#: builtin/pack-objects.c:793 #, c-format msgid "unable to open packfile for reuse: %s" msgstr "không thể mở táºp tin gói để dùng lại: %s" -#: builtin/pack-objects.c:796 +#: builtin/pack-objects.c:797 msgid "unable to seek in reused packfile" msgstr "không thể di chuyển vị trà đá»c trong táºp tin gói dùng lại" -#: builtin/pack-objects.c:807 +#: builtin/pack-objects.c:808 msgid "unable to read from reused packfile" msgstr "không thể Ä‘á»c từ táºp tin gói dùng lại" -#: builtin/pack-objects.c:835 +#: builtin/pack-objects.c:836 msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" msgstr "tắt ghi bitmap, các gói bị chia nhá» bởi vì pack.packSizeLimit" -#: builtin/pack-objects.c:848 +#: builtin/pack-objects.c:849 msgid "Writing objects" msgstr "Äang ghi lại các đối tượng" -#: builtin/pack-objects.c:910 builtin/update-index.c:88 +#: builtin/pack-objects.c:911 builtin/update-index.c:89 #, c-format msgid "failed to stat %s" msgstr "gặp lá»—i khi lấy thông tin thống kê vá» %s" -#: builtin/pack-objects.c:963 +#: builtin/pack-objects.c:964 #, c-format msgid "wrote %<PRIu32> objects while expecting %<PRIu32>" msgstr "đã ghi %<PRIu32> đối tượng trong khi cần %<PRIu32>" -#: builtin/pack-objects.c:1157 +#: builtin/pack-objects.c:1158 msgid "disabling bitmap writing, as some objects are not being packed" msgstr "tắt ghi bitmap, nhÆ° váºy má»™t số đối tượng sẽ không được đóng gói" -#: builtin/pack-objects.c:1585 +#: builtin/pack-objects.c:1586 #, c-format msgid "delta base offset overflow in pack for %s" msgstr "khoảng bù cÆ¡ sở cho delta bị trà n trong gói cho %s" -#: builtin/pack-objects.c:1594 +#: builtin/pack-objects.c:1595 #, c-format msgid "delta base offset out of bound for %s" msgstr "khoảng bù cÆ¡ sở cho delta nằm ngoà i phạm cho %s" -#: builtin/pack-objects.c:1863 +#: builtin/pack-objects.c:1864 msgid "Counting objects" msgstr "Äang đếm các đối tượng" -#: builtin/pack-objects.c:1998 +#: builtin/pack-objects.c:1994 #, c-format msgid "unable to get size of %s" msgstr "không thể lấy kÃch cỡ của %s" -#: builtin/pack-objects.c:2013 +#: builtin/pack-objects.c:2009 #, c-format msgid "unable to parse object header of %s" msgstr "không thể phân tÃch phần đầu đối tượng của “%sâ€" -#: builtin/pack-objects.c:2083 builtin/pack-objects.c:2099 -#: builtin/pack-objects.c:2109 +#: builtin/pack-objects.c:2079 builtin/pack-objects.c:2095 +#: builtin/pack-objects.c:2105 #, c-format msgid "object %s cannot be read" msgstr "không thể Ä‘á»c đối tượng %s" -#: builtin/pack-objects.c:2086 builtin/pack-objects.c:2113 +#: builtin/pack-objects.c:2082 builtin/pack-objects.c:2109 #, c-format msgid "object %s inconsistent object length (%<PRIuMAX> vs %<PRIuMAX>)" msgstr "" "đối tượng %s không nhất quán vá» chiá»u dà i đối tượng (%<PRIuMAX> so vá»›i " "%<PRIuMAX>)" -#: builtin/pack-objects.c:2123 +#: builtin/pack-objects.c:2119 msgid "suboptimal pack - out of memory" msgstr "suboptimal pack - hết bá»™ nhá»›" -#: builtin/pack-objects.c:2451 +#: builtin/pack-objects.c:2445 #, c-format msgid "Delta compression using up to %d threads" msgstr "Nén delta dùng tá»›i %d tuyến trình" -#: builtin/pack-objects.c:2583 +#: builtin/pack-objects.c:2577 #, c-format msgid "unable to pack objects reachable from tag %s" msgstr "không thể đóng gói các đối tượng tiếp cáºn được từ thẻ “%sâ€" -#: builtin/pack-objects.c:2670 +#: builtin/pack-objects.c:2664 msgid "Compressing objects" msgstr "Äang nén các đối tượng" -#: builtin/pack-objects.c:2676 +#: builtin/pack-objects.c:2670 msgid "inconsistency with delta count" msgstr "mâu thuẫn vá»›i số lượng delta" -#: builtin/pack-objects.c:2753 +#: builtin/pack-objects.c:2751 #, c-format msgid "" "expected edge object ID, got garbage:\n" @@ -14055,7 +14925,7 @@ msgstr "" "cần ID đối tượng cạnh, nháºn được rác:\n" " %s" -#: builtin/pack-objects.c:2759 +#: builtin/pack-objects.c:2757 #, c-format msgid "" "expected object ID, got garbage:\n" @@ -14064,20 +14934,20 @@ msgstr "" "cần ID đối tượng, nháºn được rác:\n" " %s" -#: builtin/pack-objects.c:2857 +#: builtin/pack-objects.c:2855 msgid "invalid value for --missing" msgstr "giá trị cho --missing không hợp lệ" -#: builtin/pack-objects.c:2916 builtin/pack-objects.c:3024 +#: builtin/pack-objects.c:2914 builtin/pack-objects.c:3022 msgid "cannot open pack index" msgstr "không thể mở mục lục của gói" -#: builtin/pack-objects.c:2947 +#: builtin/pack-objects.c:2945 #, c-format msgid "loose object at %s could not be examined" msgstr "đối tượng mất tại %s không thể đã kiểm tra" -#: builtin/pack-objects.c:3032 +#: builtin/pack-objects.c:3030 msgid "unable to force loose object" msgstr "không thể buá»™c mất đối tượng" @@ -14175,7 +15045,7 @@ msgstr "không thể tạo kết xuất gói trống rá»—ng" #: builtin/pack-objects.c:3271 msgid "read revision arguments from standard input" -msgstr " Ä‘á»c tham số “revision†từ thiết bị nháºp chuẩn" +msgstr "Ä‘á»c tham số “revision†từ thiết bị nháºp chuẩn" #: builtin/pack-objects.c:3273 msgid "limit the objects to those that are not yet packed" @@ -14215,85 +15085,89 @@ msgstr "" "xả nén (gỡ khá»i gói) các đối tượng không thể Ä‘á»c được má»›i hÆ¡n <thá»i-gian>" #: builtin/pack-objects.c:3296 +msgid "use the sparse reachability algorithm" +msgstr "dung thuáºt toán “sparse reachabilityâ€" + +#: builtin/pack-objects.c:3298 msgid "create thin packs" msgstr "tạo gói nhẹ" -#: builtin/pack-objects.c:3298 +#: builtin/pack-objects.c:3300 msgid "create packs suitable for shallow fetches" msgstr "tạo gói để phù hợp cho lấy vá» nông (shallow)" -#: builtin/pack-objects.c:3300 +#: builtin/pack-objects.c:3302 msgid "ignore packs that have companion .keep file" msgstr "bá» qua các gói mà nó có táºp tin .keep Ä‘i kèm" -#: builtin/pack-objects.c:3302 +#: builtin/pack-objects.c:3304 msgid "ignore this pack" msgstr "bá» qua gói nà y" -#: builtin/pack-objects.c:3304 +#: builtin/pack-objects.c:3306 msgid "pack compression level" msgstr "mức nén gói" -#: builtin/pack-objects.c:3306 +#: builtin/pack-objects.c:3308 msgid "do not hide commits by grafts" msgstr "không ẩn các lần chuyển giao bởi “graftsâ€" -#: builtin/pack-objects.c:3308 +#: builtin/pack-objects.c:3310 msgid "use a bitmap index if available to speed up counting objects" msgstr "dùng mục lục ánh xạ nếu có thể được để nâng cao tốc Ä‘á»™ đếm đối tượng" -#: builtin/pack-objects.c:3310 +#: builtin/pack-objects.c:3312 msgid "write a bitmap index together with the pack index" msgstr "ghi má»™t mục lục ánh xạ cùng vá»›i mục lục gói" -#: builtin/pack-objects.c:3313 +#: builtin/pack-objects.c:3315 msgid "handling for missing objects" msgstr "xá» lý cho thiếu đối tượng" -#: builtin/pack-objects.c:3316 +#: builtin/pack-objects.c:3318 msgid "do not pack objects in promisor packfiles" msgstr "không thể đóng gói các đối tượng trong các táºp tin gói hứa hẹn" -#: builtin/pack-objects.c:3318 +#: builtin/pack-objects.c:3320 msgid "respect islands during delta compression" msgstr "tôn trá»ng island trong suốt quá trình nén “deltaâ€" -#: builtin/pack-objects.c:3342 +#: builtin/pack-objects.c:3345 #, c-format msgid "delta chain depth %d is too deep, forcing %d" msgstr "mức sau xÃch delta %d là quá sâu, buá»™c dùng %d" -#: builtin/pack-objects.c:3347 +#: builtin/pack-objects.c:3350 #, c-format msgid "pack.deltaCacheLimit is too high, forcing %d" msgstr "pack.deltaCacheLimit là quá cao, ép dùng %d" -#: builtin/pack-objects.c:3401 +#: builtin/pack-objects.c:3404 msgid "--max-pack-size cannot be used to build a pack for transfer" msgstr "" "--max-pack-size không thể được sá» dụng để xây dá»±ng má»™t gói để váºn chuyển" -#: builtin/pack-objects.c:3403 +#: builtin/pack-objects.c:3406 msgid "minimum pack size limit is 1 MiB" msgstr "giá»›i hạn kÃch thÆ°á»›c tối thiểu của gói là 1 MiB" -#: builtin/pack-objects.c:3408 +#: builtin/pack-objects.c:3411 msgid "--thin cannot be used to build an indexable pack" msgstr "--thin không thể được dùng để xây dá»±ng gói đánh mục lục được" -#: builtin/pack-objects.c:3411 +#: builtin/pack-objects.c:3414 msgid "--keep-unreachable and --unpack-unreachable are incompatible" msgstr "--keep-unreachable và --unpack-unreachable xung khắc nhau" -#: builtin/pack-objects.c:3417 +#: builtin/pack-objects.c:3420 msgid "cannot use --filter without --stdout" msgstr "không thể dùng tùy chá»n --filter mà không có --stdout" -#: builtin/pack-objects.c:3476 +#: builtin/pack-objects.c:3479 msgid "Enumerating objects" msgstr "Äánh số các đối tượng" -#: builtin/pack-objects.c:3495 +#: builtin/pack-objects.c:3498 #, c-format msgid "Total %<PRIu32> (delta %<PRIu32>), reused %<PRIu32> (delta %<PRIu32>)" msgstr "Tổng %<PRIu32> (delta %<PRIu32>), dùng lại %<PRIu32> (delta %<PRIu32>)" @@ -14334,57 +15208,57 @@ msgstr "các đối tượng hết hạn cÅ© hÆ¡n khoảng <thá»i gian>" msgid "limit traversal to objects outside promisor packfiles" msgstr "giá»›i hạn giao đến các đối tượng nằm ngoà i các táºp tin gói hứa hẹn" -#: builtin/prune.c:129 +#: builtin/prune.c:128 msgid "cannot prune in a precious-objects repo" msgstr "không thể tỉa bá»›t trong má»™t kho đối_tượng_vÄ©_đại" -#: builtin/pull.c:60 builtin/pull.c:62 +#: builtin/pull.c:61 builtin/pull.c:63 #, c-format msgid "Invalid value for %s: %s" msgstr "Giá trị không hợp lệ %s: %s" -#: builtin/pull.c:82 +#: builtin/pull.c:83 msgid "git pull [<options>] [<repository> [<refspec>...]]" msgstr "git pull [<các-tùy-chá»n>] [<kho-chứa> [<refspec>…]]" -#: builtin/pull.c:133 +#: builtin/pull.c:134 msgid "control for recursive fetching of submodules" msgstr "Ä‘iá»u khiển việc lấy vỠđệ quy của các mô-Ä‘un-con" -#: builtin/pull.c:137 +#: builtin/pull.c:138 msgid "Options related to merging" msgstr "Các tùy chá»n liên quan đến hòa trá»™n" -#: builtin/pull.c:140 +#: builtin/pull.c:141 msgid "incorporate changes by rebasing rather than merging" msgstr "các thay đổi hợp nhất bằng cải tổ thay vì hòa trá»™n" -#: builtin/pull.c:167 builtin/rebase--interactive.c:147 builtin/revert.c:122 +#: builtin/pull.c:168 builtin/rebase--interactive.c:149 builtin/revert.c:123 msgid "allow fast-forward" msgstr "cho phép chuyển-tiếp-nhanh" -#: builtin/pull.c:176 +#: builtin/pull.c:177 msgid "automatically stash/stash pop before and after rebase" msgstr "tá»± Ä‘á»™ng stash/stash pop tÆ°á»›c và sau tu bổ (rebase)" -#: builtin/pull.c:192 +#: builtin/pull.c:193 msgid "Options related to fetching" msgstr "Các tùy chá»n liên quan đến lệnh lấy vá»" -#: builtin/pull.c:202 +#: builtin/pull.c:203 msgid "force overwrite of local branch" msgstr "ép buá»™c ghi đè lên nhánh ná»™i bá»™" -#: builtin/pull.c:210 +#: builtin/pull.c:211 msgid "number of submodules pulled in parallel" msgstr "số lượng mô-Ä‘un-con được đẩy lên đồng thá»i" -#: builtin/pull.c:305 +#: builtin/pull.c:306 #, c-format msgid "Invalid value for pull.ff: %s" msgstr "Giá trị không hợp lệ cho pull.ff: %s" -#: builtin/pull.c:421 +#: builtin/pull.c:422 msgid "" "There is no candidate for rebasing against among the refs that you just " "fetched." @@ -14392,14 +15266,14 @@ msgstr "" "Ở đây không có ứng cá» nà o để cải tổ lại trong số các tham chiếu mà bạn vừa " "lấy vá»." -#: builtin/pull.c:423 +#: builtin/pull.c:424 msgid "" "There are no candidates for merging among the refs that you just fetched." msgstr "" "Ở đây không có ứng cá» nà o để hòa trá»™n trong số các tham chiếu mà bạn vừa lấy " "vá»." -#: builtin/pull.c:424 +#: builtin/pull.c:425 msgid "" "Generally this means that you provided a wildcard refspec which had no\n" "matches on the remote end." @@ -14408,7 +15282,7 @@ msgstr "" "tá»±\n" "đại diện mà nó lại không khá»›p trên Ä‘iểm cuối máy phục vụ." -#: builtin/pull.c:427 +#: builtin/pull.c:428 #, c-format msgid "" "You asked to pull from the remote '%s', but did not specify\n" @@ -14420,43 +15294,43 @@ msgstr "" "theo mặc định cho nhánh hiện tại của bạn, bạn phải chỉ định\n" "má»™t nhánh trên dòng lệnh." -#: builtin/pull.c:432 builtin/rebase.c:761 git-parse-remote.sh:73 +#: builtin/pull.c:433 builtin/rebase.c:956 git-parse-remote.sh:73 msgid "You are not currently on a branch." msgstr "Hiện tại bạn chẳng ở nhánh nà o cả." -#: builtin/pull.c:434 builtin/pull.c:449 git-parse-remote.sh:79 +#: builtin/pull.c:435 builtin/pull.c:450 git-parse-remote.sh:79 msgid "Please specify which branch you want to rebase against." msgstr "Vui lòng chỉ định nhánh nà o bạn muốn cải tổ lại." -#: builtin/pull.c:436 builtin/pull.c:451 git-parse-remote.sh:82 +#: builtin/pull.c:437 builtin/pull.c:452 git-parse-remote.sh:82 msgid "Please specify which branch you want to merge with." msgstr "Vui lòng chỉ định nhánh nà o bạn muốn hòa trá»™n và o." -#: builtin/pull.c:437 builtin/pull.c:452 +#: builtin/pull.c:438 builtin/pull.c:453 msgid "See git-pull(1) for details." msgstr "Xem git-pull(1) để biết thêm chi tiết." -#: builtin/pull.c:439 builtin/pull.c:445 builtin/pull.c:454 -#: builtin/rebase.c:767 git-parse-remote.sh:64 +#: builtin/pull.c:440 builtin/pull.c:446 builtin/pull.c:455 +#: builtin/rebase.c:962 git-parse-remote.sh:64 msgid "<remote>" msgstr "<máy chủ>" -#: builtin/pull.c:439 builtin/pull.c:454 builtin/pull.c:459 -#: git-legacy-rebase.sh:556 git-parse-remote.sh:65 +#: builtin/pull.c:440 builtin/pull.c:455 builtin/pull.c:460 +#: git-legacy-rebase.sh:564 git-parse-remote.sh:65 msgid "<branch>" msgstr "<nhánh>" -#: builtin/pull.c:447 builtin/rebase.c:759 git-parse-remote.sh:75 +#: builtin/pull.c:448 builtin/rebase.c:954 git-parse-remote.sh:75 msgid "There is no tracking information for the current branch." msgstr "Ở đây không có thông tin theo dõi cho nhánh hiện hà nh." -#: builtin/pull.c:456 git-parse-remote.sh:95 +#: builtin/pull.c:457 git-parse-remote.sh:95 msgid "" "If you wish to set tracking information for this branch you can do so with:" msgstr "" "Nếu bạn muốn theo dõi thông tin cho nhánh nà y bạn có thể thá»±c hiện bằng lệnh:" -#: builtin/pull.c:461 +#: builtin/pull.c:462 #, c-format msgid "" "Your configuration specifies to merge with the ref '%s'\n" @@ -14465,34 +15339,34 @@ msgstr "" "Các đặc tả cấu hình của bạn để hòa trá»™n vá»›i tham chiếu “%sâ€\n" "từ máy dịch vụ, nhÆ°ng không có nhánh nà o nhÆ° thế được lấy vá»." -#: builtin/pull.c:565 +#: builtin/pull.c:566 #, c-format msgid "unable to access commit %s" msgstr "không thể truy cáºp lần chuyển giao “%sâ€" -#: builtin/pull.c:843 +#: builtin/pull.c:844 msgid "ignoring --verify-signatures for rebase" msgstr "bá» qua --verify-signatures khi rebase" -#: builtin/pull.c:891 +#: builtin/pull.c:892 msgid "--[no-]autostash option is only valid with --rebase." msgstr "tùy chá»n --[no-]autostash chỉ hợp lệ khi dùng vá»›i --rebase." -#: builtin/pull.c:899 +#: builtin/pull.c:900 msgid "Updating an unborn branch with changes added to the index." msgstr "" "Äang cáºp nháºt má»™t nhánh chÆ°a được sinh ra vá»›i các thay đổi được thêm và o " "bảng mục lục." -#: builtin/pull.c:902 +#: builtin/pull.c:904 msgid "pull with rebase" msgstr "pull vá»›i rebase" -#: builtin/pull.c:903 +#: builtin/pull.c:905 msgid "please commit or stash them." msgstr "xin hãy chuyển giao hoặc tạm cất (stash) chúng." -#: builtin/pull.c:928 +#: builtin/pull.c:930 #, c-format msgid "" "fetch updated the current branch head.\n" @@ -14503,7 +15377,7 @@ msgstr "" "Ä‘ang chuyển-tiếp-nhanh cây là m việc của bạn từ\n" "lần chuyển giaot %s." -#: builtin/pull.c:934 +#: builtin/pull.c:936 #, c-format msgid "" "Cannot fast-forward your working tree.\n" @@ -14521,15 +15395,15 @@ msgstr "" "$ git reset --hard\n" "để khôi phục lại." -#: builtin/pull.c:949 +#: builtin/pull.c:951 msgid "Cannot merge multiple branches into empty head." msgstr "Không thể hòa trá»™n nhiá»u nhánh và o trong má»™t head trống rá»—ng." -#: builtin/pull.c:953 +#: builtin/pull.c:955 msgid "Cannot rebase onto multiple branches." msgstr "Không thể thá»±c hiện lệnh rebase (cải tổ) trên nhiá»u nhánh." -#: builtin/pull.c:960 +#: builtin/pull.c:962 msgid "cannot rebase with locally recorded submodule modifications" msgstr "" "không thể cải tổ vá»›i các thay đổi mô-Ä‘un-con được ghi lại má»™t cách cục bá»™" @@ -14546,7 +15420,7 @@ msgstr "dùng tốc ký thẻ không có <thẻ>" msgid "--delete only accepts plain target ref names" msgstr "--delete chỉ chấp nháºn các tên tham chiếu dạng thÆ°á»ng" -#: builtin/push.c:165 +#: builtin/push.c:167 msgid "" "\n" "To choose either option permanently, see push.default in 'git help config'." @@ -14555,7 +15429,7 @@ msgstr "" "Äể chá»n má»—i tùy chá»n má»™t cách cố định, xem push.default trong “git help " "configâ€." -#: builtin/push.c:168 +#: builtin/push.c:170 #, c-format msgid "" "The upstream branch of your current branch does not match\n" @@ -14580,7 +15454,7 @@ msgstr "" " git push %s HEAD\n" "%s" -#: builtin/push.c:183 +#: builtin/push.c:185 #, c-format msgid "" "You are not currently on a branch.\n" @@ -14595,7 +15469,7 @@ msgstr "" "\n" " git push %s HEAD:<tên-của-nhánh-máy-chủ>\n" -#: builtin/push.c:197 +#: builtin/push.c:199 #, c-format msgid "" "The current branch %s has no upstream branch.\n" @@ -14609,12 +15483,12 @@ msgstr "" "\n" " git push --set-upstream %s %s\n" -#: builtin/push.c:205 +#: builtin/push.c:207 #, c-format msgid "The current branch %s has multiple upstream branches, refusing to push." msgstr "Nhánh hiện tại %s có nhiá»u nhánh thượng nguồn, từ chối push." -#: builtin/push.c:208 +#: builtin/push.c:210 #, c-format msgid "" "You are pushing to remote '%s', which is not the upstream of\n" @@ -14626,14 +15500,14 @@ msgstr "" "nhánh hiện tại “%s†của bạn, mà không báo cho tôi biết là cái gì được push\n" "để cáºp nháºt nhánh máy chủ nà o." -#: builtin/push.c:267 +#: builtin/push.c:269 msgid "" "You didn't specify any refspecs to push, and push.default is \"nothing\"." msgstr "" "Bạn đã không chỉ ra má»™t refspecs nà o để đẩy lên, và push.default là \"không " "là gì cả\"." -#: builtin/push.c:274 +#: builtin/push.c:276 msgid "" "Updates were rejected because the tip of your current branch is behind\n" "its remote counterpart. Integrate the remote changes (e.g.\n" @@ -14646,7 +15520,7 @@ msgstr "" "Xem “Note about fast-forwards†trong “git push --help†để có thông tin chi " "tiết." -#: builtin/push.c:280 +#: builtin/push.c:282 msgid "" "Updates were rejected because a pushed branch tip is behind its remote\n" "counterpart. Check out this branch and integrate the remote changes\n" @@ -14660,7 +15534,7 @@ msgstr "" "Xem “Note about fast-forwards†trong “git push --help†để có thông tin chi " "tiết." -#: builtin/push.c:286 +#: builtin/push.c:288 msgid "" "Updates were rejected because the remote contains work that you do\n" "not have locally. This is usually caused by another repository pushing\n" @@ -14675,11 +15549,11 @@ msgstr "" "Xem “Note about fast-forwards†trong “git push --help†để có thông tin chi " "tiết." -#: builtin/push.c:293 +#: builtin/push.c:295 msgid "Updates were rejected because the tag already exists in the remote." msgstr "Việc cáºp nháºt bị từ chối bởi vì thẻ đã sẵn có từ trÆ°á»›c trên máy chủ." -#: builtin/push.c:296 +#: builtin/push.c:298 msgid "" "You cannot update a remote ref that points at a non-commit object,\n" "or update a remote ref to make it point at a non-commit object,\n" @@ -14691,22 +15565,22 @@ msgstr "" "đối tượng\n" "không phải chuyển giao, mà không sá» dụng tùy chá»n “--forceâ€.\n" -#: builtin/push.c:357 +#: builtin/push.c:359 #, c-format msgid "Pushing to %s\n" msgstr "Äang đẩy lên %s\n" -#: builtin/push.c:361 +#: builtin/push.c:364 #, c-format msgid "failed to push some refs to '%s'" msgstr "gặp lá»—i khi đẩy tá»›i má»™t số tham chiếu đến “%sâ€" -#: builtin/push.c:395 +#: builtin/push.c:398 #, c-format msgid "bad repository '%s'" msgstr "repository (kho) sai “%sâ€" -#: builtin/push.c:396 +#: builtin/push.c:399 msgid "" "No configured push destination.\n" "Either specify the URL from the command-line or configure a remote " @@ -14727,104 +15601,104 @@ msgstr "" "\n" " git push <tên>\n" -#: builtin/push.c:551 +#: builtin/push.c:554 msgid "repository" msgstr "kho" -#: builtin/push.c:552 builtin/send-pack.c:164 +#: builtin/push.c:555 builtin/send-pack.c:164 msgid "push all refs" msgstr "đẩy tất cả các tham chiếu" -#: builtin/push.c:553 builtin/send-pack.c:166 +#: builtin/push.c:556 builtin/send-pack.c:166 msgid "mirror all refs" msgstr "mirror tất cả các tham chiếu" -#: builtin/push.c:555 +#: builtin/push.c:558 msgid "delete refs" msgstr "xóa các tham chiếu" -#: builtin/push.c:556 +#: builtin/push.c:559 msgid "push tags (can't be used with --all or --mirror)" msgstr "đẩy các thẻ (không dùng cùng vá»›i --all hay --mirror)" -#: builtin/push.c:559 builtin/send-pack.c:167 +#: builtin/push.c:562 builtin/send-pack.c:167 msgid "force updates" msgstr "ép buá»™c cáºp nháºt" -#: builtin/push.c:561 builtin/send-pack.c:181 +#: builtin/push.c:564 builtin/send-pack.c:181 msgid "<refname>:<expect>" msgstr "<tên-tham-chiếu>:<cần>" -#: builtin/push.c:562 builtin/send-pack.c:182 +#: builtin/push.c:565 builtin/send-pack.c:182 msgid "require old value of ref to be at this value" msgstr "yêu cầu giá-trị cÅ© của tham chiếu thì là giá-trị nà y" -#: builtin/push.c:565 +#: builtin/push.c:568 msgid "control recursive pushing of submodules" msgstr "Ä‘iá»u khiển việc đẩy lên (push) đệ qui của mô-Ä‘un-con" -#: builtin/push.c:567 builtin/send-pack.c:175 +#: builtin/push.c:570 builtin/send-pack.c:175 msgid "use thin pack" msgstr "tạo gói nhẹ" -#: builtin/push.c:568 builtin/push.c:569 builtin/send-pack.c:161 +#: builtin/push.c:571 builtin/push.c:572 builtin/send-pack.c:161 #: builtin/send-pack.c:162 msgid "receive pack program" msgstr "chÆ°Æ¡ng trình nháºn gói" -#: builtin/push.c:570 +#: builtin/push.c:573 msgid "set upstream for git pull/status" msgstr "đặt thượng nguồn cho git pull/status" -#: builtin/push.c:573 +#: builtin/push.c:576 msgid "prune locally removed refs" msgstr "xén tỉa những tham chiếu bị gỡ bá»" -#: builtin/push.c:575 +#: builtin/push.c:578 msgid "bypass pre-push hook" msgstr "vòng qua móc tiá»n-đẩy (pre-push)" -#: builtin/push.c:576 +#: builtin/push.c:579 msgid "push missing but relevant tags" msgstr "push phần bị thiếu nhÆ°ng các thẻ lại thÃch hợp" -#: builtin/push.c:579 builtin/send-pack.c:169 +#: builtin/push.c:582 builtin/send-pack.c:169 msgid "GPG sign the push" msgstr "ký lần đẩy dùng GPG" -#: builtin/push.c:581 builtin/send-pack.c:176 +#: builtin/push.c:584 builtin/send-pack.c:176 msgid "request atomic transaction on remote side" msgstr "yêu cầu giao dịch hạt nhân bên phÃa máy chủ" -#: builtin/push.c:599 +#: builtin/push.c:602 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "--delete là xung khắc vá»›i các tùy chá»n --all, --mirror và --tags" -#: builtin/push.c:601 +#: builtin/push.c:604 msgid "--delete doesn't make sense without any refs" msgstr "--delete không hợp lý nếu không có bất kỳ tham chiếu nà o" -#: builtin/push.c:604 +#: builtin/push.c:607 msgid "--all and --tags are incompatible" msgstr "--all và --tags xung khắc nhau" -#: builtin/push.c:606 +#: builtin/push.c:609 msgid "--all can't be combined with refspecs" msgstr "--all không thể được tổ hợp cùng vá»›i đặc tả Ä‘Æ°á»ng dẫn" -#: builtin/push.c:610 +#: builtin/push.c:613 msgid "--mirror and --tags are incompatible" msgstr "--mirror và --tags xung khắc nhau" -#: builtin/push.c:612 +#: builtin/push.c:615 msgid "--mirror can't be combined with refspecs" msgstr "--mirror không thể được tổ hợp cùng vá»›i đặc tả Ä‘Æ°á»ng dẫn" -#: builtin/push.c:615 +#: builtin/push.c:618 msgid "--all and --mirror are incompatible" msgstr "--all và --mirror xung khắc nhau" -#: builtin/push.c:634 +#: builtin/push.c:637 msgid "push options must not have new line characters" msgstr "các tùy chá»n push phải không có ký tá»± dòng má»›i" @@ -14862,7 +15736,7 @@ msgstr "định dạng đối số Ä‘Æ¡n phải là má»™t vùng đối xứng" msgid "need two commit ranges" msgstr "cần hai vùng lần chuyển giao" -#: builtin/read-tree.c:40 +#: builtin/read-tree.c:41 msgid "" "git read-tree [(-m [--trivial] [--aggressive] | --reset | --prefix=<prefix>) " "[-u [--exclude-per-directory=<gitignore>] | -i]] [--no-sparse-checkout] [--" @@ -14873,72 +15747,72 @@ msgstr "" "[--index-output=<táºp-tin>] (--empty | <tree-ish1> [<tree-ish2> [<tree-" "ish3>]])" -#: builtin/read-tree.c:123 +#: builtin/read-tree.c:124 msgid "write resulting index to <file>" msgstr "ghi mục lục kết quả và o <táºp-tin>" -#: builtin/read-tree.c:126 +#: builtin/read-tree.c:127 msgid "only empty the index" msgstr "chỉ vá»›i bảng mục lục trống rá»—ng" -#: builtin/read-tree.c:128 +#: builtin/read-tree.c:129 msgid "Merging" msgstr "Hòa trá»™n" -#: builtin/read-tree.c:130 +#: builtin/read-tree.c:131 msgid "perform a merge in addition to a read" msgstr "thá»±c hiện má»™t hòa trá»™n thêm và o việc Ä‘á»c" -#: builtin/read-tree.c:132 +#: builtin/read-tree.c:133 msgid "3-way merge if no file level merging required" msgstr "" -"hòa trá»™n kiểu “3-way†nếu không có táºp tin mức hòa trá»™n nà o được yêu cầu " +"hòa trá»™n kiểu “3-way†nếu không có táºp tin mức hòa trá»™n nà o được yêu cầu" -#: builtin/read-tree.c:134 +#: builtin/read-tree.c:135 msgid "3-way merge in presence of adds and removes" msgstr "hòa trá»™n 3-way trong sá»± hiện diện của “adds†và “removesâ€" -#: builtin/read-tree.c:136 +#: builtin/read-tree.c:137 msgid "same as -m, but discard unmerged entries" msgstr "giống vá»›i -m, nhÆ°ng bá» qua các mục chÆ°a được hòa trá»™n" -#: builtin/read-tree.c:137 +#: builtin/read-tree.c:138 msgid "<subdirectory>/" msgstr "<thÆ°-mục-con>/" -#: builtin/read-tree.c:138 +#: builtin/read-tree.c:139 msgid "read the tree into the index under <subdirectory>/" msgstr "Ä‘á»c cây và o trong bảng mục lục dÆ°á»›i <thÆ°_mục_con>/" -#: builtin/read-tree.c:141 +#: builtin/read-tree.c:142 msgid "update working tree with merge result" msgstr "cáºp nháºt cây là m việc vá»›i kết quả hòa trá»™n" -#: builtin/read-tree.c:143 +#: builtin/read-tree.c:144 msgid "gitignore" msgstr "gitignore" -#: builtin/read-tree.c:144 +#: builtin/read-tree.c:145 msgid "allow explicitly ignored files to be overwritten" msgstr "cho phép các táºp tin rõ rà ng bị lá» Ä‘i được ghi đè" -#: builtin/read-tree.c:147 +#: builtin/read-tree.c:148 msgid "don't check the working tree after merging" msgstr "không kiểm tra cây là m việc sau hòa trá»™n" -#: builtin/read-tree.c:148 +#: builtin/read-tree.c:149 msgid "don't update the index or the work tree" msgstr "không cáºp nháºt bảng mục lục hay cây là m việc" -#: builtin/read-tree.c:150 +#: builtin/read-tree.c:151 msgid "skip applying sparse checkout filter" msgstr "bá» qua áp dụng bá»™ lá»c lấy ra (checkout) thÆ°a thá»›t" -#: builtin/read-tree.c:152 +#: builtin/read-tree.c:153 msgid "debug unpack-trees" msgstr "gỡ lá»—i “unpack-treesâ€" -#: builtin/rebase.c:29 +#: builtin/rebase.c:30 msgid "" "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] [<upstream>] " "[<branch>]" @@ -14946,48 +15820,52 @@ msgstr "" "git rebase [-i] [các-tùy-chá»n] [--exec <lệnh>] [--onto <newbase>] " "[<upstream>] [<nhánh>]" -#: builtin/rebase.c:31 +#: builtin/rebase.c:32 msgid "" "git rebase [-i] [options] [--exec <cmd>] [--onto <newbase>] --root [<branch>]" msgstr "" "git rebase [-i] [các-tùy-chá»n] [--exec <lệnh>] [--onto <newbase>] --root " "[<nhánh>]" -#: builtin/rebase.c:33 +#: builtin/rebase.c:34 msgid "git rebase --continue | --abort | --skip | --edit-todo" msgstr "git rebase --continue | --abort | --skip | --edit-todo" -#: builtin/rebase.c:119 +#: builtin/rebase.c:121 builtin/rebase.c:1437 #, c-format msgid "%s requires an interactive rebase" msgstr "%s cần má»™t cải tổ kiểu tÆ°Æ¡ng tác" -#: builtin/rebase.c:171 +#: builtin/rebase.c:173 #, c-format msgid "could not get 'onto': '%s'" msgstr "không thể đặt lấy “ontoâ€: “%sâ€" -#: builtin/rebase.c:186 +#: builtin/rebase.c:188 #, c-format msgid "invalid orig-head: '%s'" msgstr "orig-head không hợp lệ: “%sâ€" -#: builtin/rebase.c:214 +#: builtin/rebase.c:213 #, c-format msgid "ignoring invalid allow_rerere_autoupdate: '%s'" msgstr "Ä‘ang bá» qua allow_rerere_autoupdate không hợp lệ: “%sâ€" -#: builtin/rebase.c:259 +#: builtin/rebase.c:289 #, c-format msgid "Could not read '%s'" msgstr "Không thể Ä‘á»c “%sâ€" -#: builtin/rebase.c:277 +#: builtin/rebase.c:307 #, c-format msgid "Cannot store %s" msgstr "Không thể lÆ°u “%sâ€" -#: builtin/rebase.c:337 +#: builtin/rebase.c:402 +msgid "could not determine HEAD revision" +msgstr "không thể dò tìm Ä‘iểm xét duyệt HEAD" + +#: builtin/rebase.c:522 msgid "" "Resolve all conflicts manually, mark them as resolved with\n" "\"git add/rm <conflicted_files>\", then run \"git rebase --continue\".\n" @@ -15002,11 +15880,26 @@ msgstr "" "Äể bãi bá» và quay trở lại trạng thái trÆ°á»›c \"git rebase\", chạy \"git rebase " "--abort\"." -#: builtin/rebase.c:561 -msgid "could not determine HEAD revision" -msgstr "không thể dò tìm Ä‘iểm xét duyệt HEAD" +#: builtin/rebase.c:603 +#, c-format +msgid "" +"\n" +"git encountered an error while preparing the patches to replay\n" +"these revisions:\n" +"\n" +" %s\n" +"\n" +"As a result, git cannot rebase them." +msgstr "" +"\n" +"git chạm trán má»™t lá»—i trong khi Ä‘ang chuẩn bị các miếng vá để diá»…n lại\n" +"những Ä‘iểm xét duyệt nà y:\n" +"\n" +" %s\n" +"\n" +"Kết quả là git không thể cải tổ lại chúng." -#: builtin/rebase.c:753 +#: builtin/rebase.c:948 #, c-format msgid "" "%s\n" @@ -15023,7 +15916,7 @@ msgstr "" " git rebase “<nhánh>â€\n" "\n" -#: builtin/rebase.c:769 +#: builtin/rebase.c:964 #, c-format msgid "" "If you wish to set tracking information for this branch you can do so with:\n" @@ -15037,153 +15930,165 @@ msgstr "" " git branch --set-upstream-to=%s/<nhánh> %s\n" "\n" -#: builtin/rebase.c:832 +#: builtin/rebase.c:994 +msgid "exec commands cannot contain newlines" +msgstr "các lệnh thá»±c thi không thể chứa các ký tá»± dòng má»›i" + +#: builtin/rebase.c:998 +msgid "empty exec command" +msgstr "lệnh thá»±c thi trống rá»—ng" + +#: builtin/rebase.c:1040 msgid "rebase onto given branch instead of upstream" -msgstr "cải tổ và o nhánh đã cho thay cho thượng nguồn." +msgstr "cải tổ và o nhánh đã cho thay cho thượng nguồn" -#: builtin/rebase.c:834 +#: builtin/rebase.c:1042 msgid "allow pre-rebase hook to run" msgstr "cho phép móc (hook) pre-rebase được chạy" -#: builtin/rebase.c:836 +#: builtin/rebase.c:1044 msgid "be quiet. implies --no-stat" msgstr "hãy im lặng. ý là --no-stat" -#: builtin/rebase.c:839 +#: builtin/rebase.c:1047 msgid "display a diffstat of what changed upstream" msgstr "hiển thị má»™t diffstat của những thay đổi thượng nguồn" -#: builtin/rebase.c:842 +#: builtin/rebase.c:1050 msgid "do not show diffstat of what changed upstream" msgstr "đừng hiển thị diffstat của những thay đổi thượng nguồn" -#: builtin/rebase.c:845 +#: builtin/rebase.c:1053 msgid "add a Signed-off-by: line to each commit" msgstr "thêm dòng Signed-off-by: cho từng lần chuyển giao" -#: builtin/rebase.c:847 builtin/rebase.c:851 builtin/rebase.c:853 +#: builtin/rebase.c:1055 builtin/rebase.c:1059 builtin/rebase.c:1061 msgid "passed to 'git am'" msgstr "chuyển cho “git amâ€" -#: builtin/rebase.c:855 builtin/rebase.c:857 +#: builtin/rebase.c:1063 builtin/rebase.c:1065 msgid "passed to 'git apply'" msgstr "chuyển cho “git applyâ€" -#: builtin/rebase.c:859 builtin/rebase.c:862 +#: builtin/rebase.c:1067 builtin/rebase.c:1070 msgid "cherry-pick all commits, even if unchanged" msgstr "" "cherry-pick tất cả các lần chuyển giao, ngay cả khi không có thay đổi gì" -#: builtin/rebase.c:864 +#: builtin/rebase.c:1072 msgid "continue" msgstr "tiếp tục" -#: builtin/rebase.c:867 +#: builtin/rebase.c:1075 msgid "skip current patch and continue" msgstr "bá» qua miếng vá hiện hà nh và tiếp tục" -#: builtin/rebase.c:869 +#: builtin/rebase.c:1077 msgid "abort and check out the original branch" msgstr "bãi bá» và lấy ra nhánh nguyên thủy" -#: builtin/rebase.c:872 +#: builtin/rebase.c:1080 msgid "abort but keep HEAD where it is" msgstr "bãi bá» nhÆ°ng vẫn vẫn giữ HEAD chỉ đến nó" -#: builtin/rebase.c:873 +#: builtin/rebase.c:1081 msgid "edit the todo list during an interactive rebase" msgstr "sá»a danh sách cần là m trong quá trình “rebase†(cải tổ) tÆ°Æ¡ng tác" -#: builtin/rebase.c:876 +#: builtin/rebase.c:1084 msgid "show the patch file being applied or merged" msgstr "hiển thị miếng vá đã được áp dụng hay hòa trá»™n" -#: builtin/rebase.c:879 +#: builtin/rebase.c:1087 msgid "use merging strategies to rebase" msgstr "dùng chiến lược hòa trá»™n để cải tổ" -#: builtin/rebase.c:883 +#: builtin/rebase.c:1091 msgid "let the user edit the list of commits to rebase" msgstr "để ngÆ°á»i dùng sá»a danh sách các lần chuyển giao muốn cải tổ" -#: builtin/rebase.c:887 +#: builtin/rebase.c:1095 msgid "try to recreate merges instead of ignoring them" msgstr "thá» khôi phục lại các hòa trá»™n thay vì bá» qua chúng" -#: builtin/rebase.c:891 +#: builtin/rebase.c:1099 msgid "allow rerere to update index with resolved conflict" msgstr "" "cho phép rerere cáºp nháºt bảng mục lục vá»›i các xung Ä‘á»™t đã được giải quyết" -#: builtin/rebase.c:894 +#: builtin/rebase.c:1102 msgid "preserve empty commits during rebase" msgstr "ngăn cấm các lần chuyển giao trống rá»—ng trong suốt quá trình cải tổ" -#: builtin/rebase.c:896 +#: builtin/rebase.c:1104 msgid "move commits that begin with squash!/fixup! under -i" msgstr "di chuyển các lần chuyển giao mà bắt đầu bằng squash!/fixup! dÆ°á»›i -i" -#: builtin/rebase.c:902 +#: builtin/rebase.c:1110 msgid "automatically stash/stash pop before and after" msgstr "tá»± Ä‘á»™ng stash/stash pop trÆ°á»›c và sau" -#: builtin/rebase.c:904 +#: builtin/rebase.c:1112 msgid "add exec lines after each commit of the editable list" msgstr "thêm các dòng thá»±c thi sau từng lần chuyển giao của danh sách sá»a được" -#: builtin/rebase.c:908 +#: builtin/rebase.c:1116 msgid "allow rebasing commits with empty messages" msgstr "chấp nháºn cải tổ các chuyển giao mà không ghi chú gì" -#: builtin/rebase.c:911 +#: builtin/rebase.c:1119 msgid "try to rebase merges instead of skipping them" msgstr "cố thá» cải tổ các hòa trá»™n thay vì bá» qua chúng" -#: builtin/rebase.c:914 +#: builtin/rebase.c:1122 msgid "use 'merge-base --fork-point' to refine upstream" msgstr "dùng “merge-base --fork-point†để định nghÄ©a lại thượng nguồn" -#: builtin/rebase.c:916 +#: builtin/rebase.c:1124 msgid "use the given merge strategy" msgstr "dùng chiến lược hòa trá»™n đã cho" -#: builtin/rebase.c:918 builtin/revert.c:111 +#: builtin/rebase.c:1126 builtin/revert.c:112 msgid "option" msgstr "tùy chá»n" -#: builtin/rebase.c:919 +#: builtin/rebase.c:1127 msgid "pass the argument through to the merge strategy" msgstr "chuyển thao số đến chiến lược hòa trá»™n" -#: builtin/rebase.c:922 +#: builtin/rebase.c:1130 msgid "rebase all reachable commits up to the root(s)" msgstr "cải tổ tất các các lần chuyển giao cho đến root" -#: builtin/rebase.c:938 +#: builtin/rebase.c:1133 builtin/rebase--interactive.c:198 +msgid "automatically re-schedule any `exec` that fails" +msgstr "láºp lịch lại má»™t cách tá»± Ä‘á»™ng bất kỳ “exec“ bị lá»—i" + +#: builtin/rebase.c:1149 #, c-format msgid "could not exec %s" msgstr "không thể thá»±c thi %s" -#: builtin/rebase.c:956 git-legacy-rebase.sh:213 +#: builtin/rebase.c:1167 git-legacy-rebase.sh:220 msgid "It looks like 'git am' is in progress. Cannot rebase." msgstr "" "Hình nhÆ° Ä‘ang trong quá trình thá»±c hiện lệnh “git-amâ€. Không thể rebase." -#: builtin/rebase.c:997 git-legacy-rebase.sh:395 +#: builtin/rebase.c:1208 git-legacy-rebase.sh:406 msgid "No rebase in progress?" msgstr "Không có tiến trình rebase nà o phải không?" -#: builtin/rebase.c:1001 git-legacy-rebase.sh:406 +#: builtin/rebase.c:1212 git-legacy-rebase.sh:417 msgid "The --edit-todo action can only be used during interactive rebase." msgstr "" "Hà nh Ä‘á»™ng “--edit-todo†chỉ có thể dùng trong quá trình “rebase†(sá»a lịch " "sá») tÆ°Æ¡ng tác." -#: builtin/rebase.c:1015 git-legacy-rebase.sh:413 +#: builtin/rebase.c:1226 git-legacy-rebase.sh:424 msgid "Cannot read HEAD" msgstr "Không thể Ä‘á»c HEAD" -#: builtin/rebase.c:1028 git-legacy-rebase.sh:416 +#: builtin/rebase.c:1238 git-legacy-rebase.sh:427 msgid "" "You must edit all merge conflicts and then\n" "mark them as resolved using git add" @@ -15191,21 +16096,21 @@ msgstr "" "Bạn phải sá»a tất cả các lần hòa trá»™n xung Ä‘á»™t và sau\n" "đó đánh dấu chúng là cần xá» lý sá» dụng lệnh git add" -#: builtin/rebase.c:1047 +#: builtin/rebase.c:1257 msgid "could not discard worktree changes" msgstr "không thể loại bá» các thay đổi cây-là m-việc" -#: builtin/rebase.c:1066 +#: builtin/rebase.c:1276 #, c-format msgid "could not move back to %s" msgstr "không thể quay trở lại %s" -#: builtin/rebase.c:1077 builtin/rm.c:368 +#: builtin/rebase.c:1287 builtin/rm.c:369 #, c-format msgid "could not remove '%s'" msgstr "không thể gỡ bỠ“%sâ€" -#: builtin/rebase.c:1103 +#: builtin/rebase.c:1313 #, c-format msgid "" "It seems that there is already a %s directory, and\n" @@ -15226,335 +16131,325 @@ msgstr "" "và chạy TÔI lần nữa. TÔI dừng lại trong trÆ°á»ng hợp bạn vẫn\n" "có má»™t số thứ quý giá ở đây.\n" -#: builtin/rebase.c:1124 +#: builtin/rebase.c:1334 msgid "switch `C' expects a numerical value" msgstr "tùy chá»n “%c†cần má»™t giá trị bằng số" -#: builtin/rebase.c:1161 +#: builtin/rebase.c:1375 #, c-format msgid "Unknown mode: %s" msgstr "Không hiểu chế Ä‘á»™: %s" -#: builtin/rebase.c:1183 +#: builtin/rebase.c:1397 msgid "--strategy requires --merge or --interactive" msgstr "--strategy cần --merge hay --interactive" -#: builtin/rebase.c:1226 -#, c-format -msgid "" -"error: cannot combine interactive options (--interactive, --exec, --rebase-" -"merges, --preserve-merges, --keep-empty, --root + --onto) with am options " -"(%s)" +#: builtin/rebase.c:1446 +msgid "cannot combine am options with either interactive or merge options" msgstr "" -"lá»—i: không thể tổ hợp các tùy chá»n tÆ°Æ¡ng tác (--interactive, --exec, --" -"rebase-merges, --preserve-merges, --keep-empty, --root + --onto) vá»›i các tùy " -"chá»n am (%s)" +"không thể tổ hợp các tùy chá»n am vá»›i các tùy chá»n tÆ°Æ¡ng tác hay hòa trá»™n" -#: builtin/rebase.c:1231 -#, c-format -msgid "" -"error: cannot combine merge options (--merge, --strategy, --strategy-option) " -"with am options (%s)" -msgstr "" -"lá»—i: không thể kết hợp các tùy chá»n hòa trá»™n (--merge, --strategy, --" -"strategy-option) vá»›i má»™t tùy chá»n am (%s)" +#: builtin/rebase.c:1465 +msgid "cannot combine '--preserve-merges' with '--rebase-merges'" +msgstr "không thể kết hợp “--preserve-merges†vá»›i “--rebase-mergesâ€" -#: builtin/rebase.c:1251 git-legacy-rebase.sh:536 -msgid "error: cannot combine '--preserve-merges' with '--rebase-merges'" -msgstr "lá»—i: không thể kết hợp “--preserve_merges†vá»›i “--rebase-mergesâ€" +#: builtin/rebase.c:1469 git-legacy-rebase.sh:544 +msgid "" +"error: cannot combine '--preserve-merges' with '--reschedule-failed-exec'" +msgstr "không thể kết hợp “--preserve-merges†vá»›i “--reschedule-failed-execâ€" -#: builtin/rebase.c:1256 git-legacy-rebase.sh:542 -msgid "error: cannot combine '--rebase-merges' with '--strategy-option'" -msgstr "lá»—i: không thể kết hợp “--rebase_merges†vá»›i “--strategy-optionâ€" +#: builtin/rebase.c:1475 +msgid "cannot combine '--rebase-merges' with '--strategy-option'" +msgstr "không thể kết hợp “--rebase-merges†vá»›i “--strategy-optionâ€" -#: builtin/rebase.c:1259 git-legacy-rebase.sh:544 -msgid "error: cannot combine '--rebase-merges' with '--strategy'" -msgstr "lá»—i: không thể kết hợp “--rebase-merges†vá»›i “--strategyâ€" +#: builtin/rebase.c:1478 +msgid "cannot combine '--rebase-merges' with '--strategy'" +msgstr "không thể kết hợp “--rebase-merges†vá»›i “--strategyâ€" -#: builtin/rebase.c:1283 +#: builtin/rebase.c:1502 #, c-format msgid "invalid upstream '%s'" msgstr "thượng nguồn không hợp lệ “%sâ€" -#: builtin/rebase.c:1289 +#: builtin/rebase.c:1508 msgid "Could not create new root commit" msgstr "Không thể tạo lần chuyển giao gốc má»›i" -#: builtin/rebase.c:1307 +#: builtin/rebase.c:1526 #, c-format msgid "'%s': need exactly one merge base" msgstr "“%sâ€: cần chÃnh xác má»™t cÆ¡ sở hòa trá»™n" -#: builtin/rebase.c:1314 +#: builtin/rebase.c:1533 #, c-format msgid "Does not point to a valid commit '%s'" msgstr "Không chỉ đến má»™t lần chuyển giao không hợp lệ “%sâ€" -#: builtin/rebase.c:1339 +#: builtin/rebase.c:1558 #, c-format msgid "fatal: no such branch/commit '%s'" msgstr "nghiêm trá»ng: không có nhánh/lần chuyển giao “%s†nhÆ° thế" -#: builtin/rebase.c:1347 builtin/submodule--helper.c:37 -#: builtin/submodule--helper.c:1930 +#: builtin/rebase.c:1566 builtin/submodule--helper.c:38 +#: builtin/submodule--helper.c:1934 #, c-format msgid "No such ref: %s" msgstr "Không có tham chiếu nà o nhÆ° thế: %s" -#: builtin/rebase.c:1359 +#: builtin/rebase.c:1578 msgid "Could not resolve HEAD to a revision" msgstr "Không thể phân giải lần chuyển giao HEAD đến má»™t Ä‘iểm xét duyệt" -#: builtin/rebase.c:1399 git-legacy-rebase.sh:665 +#: builtin/rebase.c:1619 git-legacy-rebase.sh:673 msgid "Cannot autostash" msgstr "Không thể autostash" -#: builtin/rebase.c:1402 +#: builtin/rebase.c:1622 #, c-format msgid "Unexpected stash response: '%s'" msgstr "Gặp đáp ứng stash không cần: “%sâ€" -#: builtin/rebase.c:1408 +#: builtin/rebase.c:1628 #, c-format msgid "Could not create directory for '%s'" msgstr "Không thể tạo thÆ° mục cho “%sâ€" -#: builtin/rebase.c:1411 +#: builtin/rebase.c:1631 #, c-format msgid "Created autostash: %s\n" msgstr "Äã tạo autostash: %s\n" -#: builtin/rebase.c:1414 +#: builtin/rebase.c:1634 msgid "could not reset --hard" msgstr "không thể reset --hard" -#: builtin/rebase.c:1415 builtin/reset.c:113 +#: builtin/rebase.c:1635 builtin/reset.c:114 #, c-format msgid "HEAD is now at %s" msgstr "HEAD hiện giá» tại %s" -#: builtin/rebase.c:1431 git-legacy-rebase.sh:674 +#: builtin/rebase.c:1651 git-legacy-rebase.sh:682 msgid "Please commit or stash them." msgstr "Xin hãy chuyển giao hoặc tạm cất (stash) chúng." -#: builtin/rebase.c:1458 +#: builtin/rebase.c:1678 #, c-format msgid "could not parse '%s'" msgstr "không thể phân tÃch cú pháp “%sâ€" -#: builtin/rebase.c:1470 +#: builtin/rebase.c:1691 #, c-format msgid "could not switch to %s" msgstr "không thể chuyển đến %s" -#: builtin/rebase.c:1481 git-legacy-rebase.sh:697 +#: builtin/rebase.c:1702 git-legacy-rebase.sh:705 #, sh-format msgid "HEAD is up to date." msgstr "HEAD đã cáºp nháºt." -#: builtin/rebase.c:1483 +#: builtin/rebase.c:1704 #, c-format msgid "Current branch %s is up to date.\n" msgstr "Nhánh hiện tại %s đã được cáºp nháºt rồi.\n" -#: builtin/rebase.c:1491 git-legacy-rebase.sh:707 +#: builtin/rebase.c:1712 git-legacy-rebase.sh:715 #, sh-format msgid "HEAD is up to date, rebase forced." msgstr "HEAD hiện đã được cáºp nháºt rồi, bị ép buá»™c rebase." -#: builtin/rebase.c:1493 +#: builtin/rebase.c:1714 #, c-format msgid "Current branch %s is up to date, rebase forced.\n" msgstr "Nhánh hiện tại %s đã được cáºp nháºt rồi, lệnh rebase ép buá»™c.\n" -#: builtin/rebase.c:1501 git-legacy-rebase.sh:208 +#: builtin/rebase.c:1722 git-legacy-rebase.sh:215 msgid "The pre-rebase hook refused to rebase." msgstr "Móc (hook) pre-rebase từ chối rebase." -#: builtin/rebase.c:1508 +#: builtin/rebase.c:1729 #, c-format msgid "Changes to %s:\n" msgstr "Thay đổi thà nh %s:\n" -#: builtin/rebase.c:1511 +#: builtin/rebase.c:1732 #, c-format msgid "Changes from %s to %s:\n" msgstr "Thay đổi từ %s thà nh %s:\n" -#: builtin/rebase.c:1536 +#: builtin/rebase.c:1757 #, c-format msgid "First, rewinding head to replay your work on top of it...\n" msgstr "" "TrÆ°á»›c tiên, di chuyển head để xem lại các công việc trên đỉnh của nó…\n" -#: builtin/rebase.c:1543 +#: builtin/rebase.c:1765 msgid "Could not detach HEAD" msgstr "Không thể tách rá»i HEAD" -#: builtin/rebase.c:1552 +#: builtin/rebase.c:1774 #, c-format msgid "Fast-forwarded %s to %s.\n" msgstr "Chuyển-tiếp-nhanh %s đến %s.\n" -#: builtin/rebase--interactive.c:24 +#: builtin/rebase--interactive.c:25 msgid "no HEAD?" msgstr "không HEAD?" -#: builtin/rebase--interactive.c:51 +#: builtin/rebase--interactive.c:52 #, c-format msgid "could not create temporary %s" msgstr "không thể tạo %s tạm thá»i" -#: builtin/rebase--interactive.c:57 +#: builtin/rebase--interactive.c:58 msgid "could not mark as interactive" msgstr "không thể đánh dấu là tÆ°Æ¡ng tác" -#: builtin/rebase--interactive.c:101 +#: builtin/rebase--interactive.c:102 #, c-format msgid "could not open %s" msgstr "không thể mở %s" -#: builtin/rebase--interactive.c:114 +#: builtin/rebase--interactive.c:115 msgid "could not generate todo list" msgstr "không thể tạo danh sách cần là m" -#: builtin/rebase--interactive.c:129 +#: builtin/rebase--interactive.c:131 msgid "git rebase--interactive [<options>]" msgstr "git rebase--interactive [<các tùy chá»n>]" -#: builtin/rebase--interactive.c:148 +#: builtin/rebase--interactive.c:150 msgid "keep empty commits" msgstr "giữ lại các lần chuyển giao rá»—ng" -#: builtin/rebase--interactive.c:150 builtin/revert.c:124 +#: builtin/rebase--interactive.c:152 builtin/revert.c:125 msgid "allow commits with empty messages" msgstr "chấp nháºn chuyển giao mà không ghi chú gì" -#: builtin/rebase--interactive.c:151 +#: builtin/rebase--interactive.c:153 msgid "rebase merge commits" msgstr "cải tổ các lần chuyển giao hòa trá»™n" -#: builtin/rebase--interactive.c:153 +#: builtin/rebase--interactive.c:155 msgid "keep original branch points of cousins" msgstr "giữ các Ä‘iểm nhánh nguyên bản của các anh em há»" -#: builtin/rebase--interactive.c:155 +#: builtin/rebase--interactive.c:157 msgid "move commits that begin with squash!/fixup!" msgstr "di chuyển các lần chuyển giao bắt đầu bằng squash!/fixup!" -#: builtin/rebase--interactive.c:156 +#: builtin/rebase--interactive.c:158 msgid "sign commits" msgstr "ký các lần chuyển giao" -#: builtin/rebase--interactive.c:158 +#: builtin/rebase--interactive.c:160 msgid "continue rebase" msgstr "tiếp tục cải tổ" -#: builtin/rebase--interactive.c:160 +#: builtin/rebase--interactive.c:162 msgid "skip commit" msgstr "bá» qua lần chuyển giao" -#: builtin/rebase--interactive.c:161 +#: builtin/rebase--interactive.c:163 msgid "edit the todo list" msgstr "sá»a danh sách cần là m" -#: builtin/rebase--interactive.c:163 +#: builtin/rebase--interactive.c:165 msgid "show the current patch" msgstr "hiển thị miếng vá hiện hà nh" -#: builtin/rebase--interactive.c:166 +#: builtin/rebase--interactive.c:168 msgid "shorten commit ids in the todo list" msgstr "rút ngắn mã chuyển giao trong danh sách cần là m" -#: builtin/rebase--interactive.c:168 +#: builtin/rebase--interactive.c:170 msgid "expand commit ids in the todo list" msgstr "khai triển mã chuyển giao trong danh sách cần là m" -#: builtin/rebase--interactive.c:170 +#: builtin/rebase--interactive.c:172 msgid "check the todo list" msgstr "kiểm tra danh sách cần là m" -#: builtin/rebase--interactive.c:172 +#: builtin/rebase--interactive.c:174 msgid "rearrange fixup/squash lines" msgstr "sắp xếp lại các dòng fixup/squash" -#: builtin/rebase--interactive.c:174 +#: builtin/rebase--interactive.c:176 msgid "insert exec commands in todo list" msgstr "chèn các lệnh thá»±c thi trong danh sách cần là m" -#: builtin/rebase--interactive.c:175 +#: builtin/rebase--interactive.c:177 msgid "onto" msgstr "lên trên" -#: builtin/rebase--interactive.c:177 +#: builtin/rebase--interactive.c:179 msgid "restrict-revision" msgstr "Ä‘iểm-xét-duyệt-hạn-chế" -#: builtin/rebase--interactive.c:177 +#: builtin/rebase--interactive.c:179 msgid "restrict revision" msgstr "Ä‘iểm xét duyệt hạn chế" -#: builtin/rebase--interactive.c:178 +#: builtin/rebase--interactive.c:180 msgid "squash-onto" msgstr "squash-lên-trên" -#: builtin/rebase--interactive.c:179 +#: builtin/rebase--interactive.c:181 msgid "squash onto" msgstr "squash lên trên" -#: builtin/rebase--interactive.c:181 +#: builtin/rebase--interactive.c:183 msgid "the upstream commit" msgstr "lần chuyển giao thượng nguồn" -#: builtin/rebase--interactive.c:182 +#: builtin/rebase--interactive.c:184 msgid "head-name" msgstr "tên-đầu" -#: builtin/rebase--interactive.c:182 +#: builtin/rebase--interactive.c:184 msgid "head name" msgstr "tên đầu" -#: builtin/rebase--interactive.c:187 +#: builtin/rebase--interactive.c:189 msgid "rebase strategy" msgstr "chiến lược cải tổ" -#: builtin/rebase--interactive.c:188 +#: builtin/rebase--interactive.c:190 msgid "strategy-opts" msgstr "tùy-chá»n-chiến-lược" -#: builtin/rebase--interactive.c:189 +#: builtin/rebase--interactive.c:191 msgid "strategy options" msgstr "các tùy chá»n chiến lược" -#: builtin/rebase--interactive.c:190 +#: builtin/rebase--interactive.c:192 msgid "switch-to" msgstr "chuyển-đến" -#: builtin/rebase--interactive.c:191 +#: builtin/rebase--interactive.c:193 msgid "the branch or commit to checkout" msgstr "nhánh hay lần chuyển giao lần lấy ra" -#: builtin/rebase--interactive.c:192 +#: builtin/rebase--interactive.c:194 msgid "onto-name" msgstr "onto-name" -#: builtin/rebase--interactive.c:192 +#: builtin/rebase--interactive.c:194 msgid "onto name" msgstr "tên lên trên" -#: builtin/rebase--interactive.c:193 +#: builtin/rebase--interactive.c:195 msgid "cmd" msgstr "lệnh" -#: builtin/rebase--interactive.c:193 +#: builtin/rebase--interactive.c:195 msgid "the command to run" msgstr "lệnh muốn chạy" -#: builtin/rebase--interactive.c:220 +#: builtin/rebase--interactive.c:224 msgid "--[no-]rebase-cousins has no effect without --rebase-merges" msgstr "--[no-]rebase-cousins không có tác dụng khi không có --rebase-merges" -#: builtin/rebase--interactive.c:226 +#: builtin/rebase--interactive.c:230 msgid "a base commit must be provided with --upstream or --onto" msgstr "lần chuyển giao cÆ¡ sá» phải được chỉ định vá»›i --upstream hoặc --onto" @@ -15621,11 +16516,66 @@ msgstr "im lặng" msgid "You must specify a directory." msgstr "Bạn phải chỉ định thÆ° mục." -#: builtin/reflog.c:563 builtin/reflog.c:568 +#: builtin/reflog.c:17 +msgid "" +"git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--" +"rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] " +"<refs>..." +msgstr "" +"git reflog expire [--expire=<time>] [--expire-unreachable=<time>] [--" +"rewrite] [--updateref] [--stale-fix] [--dry-run | -n] [--verbose] [--all] " +"<các tham chiếu>…" + +#: builtin/reflog.c:22 +msgid "" +"git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] " +"<refs>..." +msgstr "" +"git reflog delete [--rewrite] [--updateref] [--dry-run | -n] [--verbose] " +"<các tham chiếu>…" + +#: builtin/reflog.c:25 +msgid "git reflog exists <ref>" +msgstr "git reflog exists <tham_chiếu>" + +#: builtin/reflog.c:567 builtin/reflog.c:572 #, c-format msgid "'%s' is not a valid timestamp" msgstr "“%s†không phải là dấu thá»i gian hợp lệ" +#: builtin/reflog.c:605 +#, c-format +msgid "Marking reachable objects..." +msgstr "Äánh dấu các đối tượng tiếp cáºn được…" + +#: builtin/reflog.c:643 +#, c-format +msgid "%s points nowhere!" +msgstr "%s chẳng chỉ đến đâu cả!" + +#: builtin/reflog.c:695 +msgid "no reflog specified to delete" +msgstr "chÆ°a chỉ ra reflog để xóa" + +#: builtin/reflog.c:704 +#, c-format +msgid "not a reflog: %s" +msgstr "không phải má»™t reflog: %s" + +#: builtin/reflog.c:709 +#, c-format +msgid "no reflog for '%s'" +msgstr "không reflog cho “%sâ€" + +#: builtin/reflog.c:755 +#, c-format +msgid "invalid ref format: %s" +msgstr "định dạng tham chiếu không hợp lệ: %s" + +#: builtin/reflog.c:764 +msgid "git reflog [ show | expire | delete | exists ]" +msgstr "git reflog [ show | expire | delete | exists ]" + #: builtin/remote.c:16 msgid "git remote [-v | --verbose]" msgstr "git remote [-v | --verbose]" @@ -16140,6 +17090,22 @@ msgstr "" "Gia tăng repack là không tÆ°Æ¡ng thÃch vá»›i chỉ mục bitmap. Dùng\n" "--no-write-bitmap-index hay tắt cấu hình pack.writebitmaps." +#: builtin/repack.c:200 +msgid "could not start pack-objects to repack promisor objects" +msgstr "" +"không thể lấy thông tin thống kê pack-objects để mà đóng gói lại các đối " +"tượng hứa hẹn" + +#: builtin/repack.c:239 builtin/repack.c:411 +msgid "repack: Expecting full hex object ID lines only from pack-objects." +msgstr "" +"repack: Äang chỉ cần các dòng ID đối tượng dạng tháºp lục phân đầy dủ từ pack-" +"objects." + +#: builtin/repack.c:256 +msgid "could not finish pack-objects to repack promisor objects" +msgstr "không thể hoà n tất pack-objects để đóng gói các đối tượng hứa hẹn" + #: builtin/repack.c:294 msgid "pack everything in a single pack" msgstr "đóng gói má»i thứ trong má»™t gói Ä‘Æ¡n" @@ -16228,7 +17194,30 @@ msgstr "không thể xóa các gói trong má»™t kho đối_tượng_vÄ©_đại" msgid "--keep-unreachable and -A are incompatible" msgstr "--keep-unreachable và -A xung khắc nhau" -#: builtin/repack.c:527 +#: builtin/repack.c:420 +msgid "Nothing new to pack." +msgstr "Không có gì má»›i để mà đóng gói." + +#: builtin/repack.c:481 +#, c-format +msgid "" +"WARNING: Some packs in use have been renamed by\n" +"WARNING: prefixing old- to their name, in order to\n" +"WARNING: replace them with the new version of the\n" +"WARNING: file. But the operation failed, and the\n" +"WARNING: attempt to rename them back to their\n" +"WARNING: original names also failed.\n" +"WARNING: Please rename them in %s manually:\n" +msgstr "" +"CẢNH BÃO: Má»™t số gói Ä‘ang dùng vừa được đổi tên bằng cách\n" +"CẢNH BÃO: đánh tiá»n tố old- và o tên của chúng, mục Ä‘Ãch là \n" +"CẢNH BÃO: thay chúng bằng phiên bản má»›i của táºp\n" +"CẢNH BÃO: tin. NhÆ°ng thao tác lại gặp lá»—i, và ná»—\n" +"CẢNH BÃO: lá»±c để đổi ngược lại tên chúng cho đúng vá»›i tên\n" +"CẢNH BÃO: nguyên gốc của nó cÅ©ng gặp lá»—i.\n" +"CẢNH BÃO: Vui lòng đổi tên chúng trong %s bằng tay:\n" + +#: builtin/repack.c:529 #, c-format msgid "failed to remove '%s'" msgstr "gặp lá»—i khi gỡ bỠ“%sâ€" @@ -16410,7 +17399,7 @@ msgid "" "could not convert the following graft(s):\n" "%s" msgstr "" -"Không thể chuyển đổi các graft sau đây:\n" +"không thể chuyển đổi các graft sau đây:\n" "%s" #: builtin/replace.c:536 @@ -16494,126 +17483,126 @@ msgstr "sổ ghi dá»n sạch các phân giải trong bản mục lục" msgid "'git rerere forget' without paths is deprecated" msgstr "“git rerere forget†mà không có các Ä‘Æ°á»ng dẫn là đã lạc háºu" -#: builtin/rerere.c:111 +#: builtin/rerere.c:113 #, c-format msgid "unable to generate diff for '%s'" msgstr "không thể tạo khác biệt cho “%sâ€" -#: builtin/reset.c:31 +#: builtin/reset.c:32 msgid "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" msgstr "" "git reset [--mixed | --soft | --hard | --merge | --keep] [-q] [<commit>]" -#: builtin/reset.c:32 +#: builtin/reset.c:33 msgid "git reset [-q] [<tree-ish>] [--] <paths>..." msgstr "git reset [-q] [<tree-ish>] [--] <Ä‘Æ°á»ng-dẫn>…" -#: builtin/reset.c:33 +#: builtin/reset.c:34 msgid "git reset --patch [<tree-ish>] [--] [<paths>...]" msgstr "git reset --patch [<tree-ish>] [--] [<các-Ä‘Æ°á»ng-dẫn>…]" -#: builtin/reset.c:39 +#: builtin/reset.c:40 msgid "mixed" msgstr "pha trá»™n" -#: builtin/reset.c:39 +#: builtin/reset.c:40 msgid "soft" msgstr "má»m" -#: builtin/reset.c:39 +#: builtin/reset.c:40 msgid "hard" msgstr "cứng" -#: builtin/reset.c:39 +#: builtin/reset.c:40 msgid "merge" msgstr "hòa trá»™n" -#: builtin/reset.c:39 +#: builtin/reset.c:40 msgid "keep" msgstr "giữ lại" -#: builtin/reset.c:80 +#: builtin/reset.c:81 msgid "You do not have a valid HEAD." msgstr "Bạn không có HEAD nà o hợp lệ." -#: builtin/reset.c:82 +#: builtin/reset.c:83 msgid "Failed to find tree of HEAD." msgstr "Gặp lá»—i khi tìm cây của HEAD." -#: builtin/reset.c:88 +#: builtin/reset.c:89 #, c-format msgid "Failed to find tree of %s." msgstr "Gặp lá»—i khi tìm cây của %s." -#: builtin/reset.c:192 +#: builtin/reset.c:193 #, c-format msgid "Cannot do a %s reset in the middle of a merge." msgstr "Không thể thá»±c hiện má»™t %s reset ở giữa của quá trình hòa trá»™n." -#: builtin/reset.c:292 +#: builtin/reset.c:293 msgid "be quiet, only report errors" msgstr "là m việc ở chế Ä‘á»™ im lặng, chỉ hiển thị khi có lá»—i" -#: builtin/reset.c:294 +#: builtin/reset.c:295 msgid "reset HEAD and index" msgstr "đặt lại (reset) HEAD và bảng mục lục" -#: builtin/reset.c:295 +#: builtin/reset.c:296 msgid "reset only HEAD" msgstr "chỉ đặt lại (reset) HEAD" -#: builtin/reset.c:297 builtin/reset.c:299 +#: builtin/reset.c:298 builtin/reset.c:300 msgid "reset HEAD, index and working tree" msgstr "đặt lại HEAD, bảng mục lục và cây là m việc" -#: builtin/reset.c:301 +#: builtin/reset.c:302 msgid "reset HEAD but keep local changes" msgstr "đặt lại HEAD nhÆ°ng giữ lại các thay đổi ná»™i bá»™" -#: builtin/reset.c:307 +#: builtin/reset.c:308 msgid "record only the fact that removed paths will be added later" msgstr "chỉ ghi lại những Ä‘Æ°á»ng dẫn thá»±c sá»± sẽ được thêm và o sau nà y" -#: builtin/reset.c:325 +#: builtin/reset.c:326 #, c-format msgid "Failed to resolve '%s' as a valid revision." msgstr "Gặp lá»—i khi phân giải “%s†nhÆ° là điểm xét duyệt hợp lệ." -#: builtin/reset.c:333 +#: builtin/reset.c:334 #, c-format msgid "Failed to resolve '%s' as a valid tree." msgstr "Gặp lá»—i khi phân giải “%s†nhÆ° là má»™t cây (tree) hợp lệ." -#: builtin/reset.c:342 +#: builtin/reset.c:343 msgid "--patch is incompatible with --{hard,mixed,soft}" msgstr "--patch xung khắc vá»›i --{hard,mixed,soft}" -#: builtin/reset.c:351 +#: builtin/reset.c:352 msgid "--mixed with paths is deprecated; use 'git reset -- <paths>' instead." msgstr "" "--mixed vá»›i các Ä‘Æ°á»ng dẫn không còn dùng nữa; hãy thay thế bằng lệnh “git " "reset -- <Ä‘Æ°á»ng_dẫn>â€." -#: builtin/reset.c:353 +#: builtin/reset.c:354 #, c-format msgid "Cannot do %s reset with paths." msgstr "Không thể thá»±c hiện lệnh %s reset vá»›i các Ä‘Æ°á»ng dẫn." -#: builtin/reset.c:363 +#: builtin/reset.c:364 #, c-format msgid "%s reset is not allowed in a bare repository" msgstr "%s reset không được phép trên kho thuần" -#: builtin/reset.c:367 +#: builtin/reset.c:368 msgid "-N can only be used with --mixed" msgstr "-N chỉ được dùng khi có --mixed" -#: builtin/reset.c:387 +#: builtin/reset.c:388 msgid "Unstaged changes after reset:" msgstr "Những thay đổi được Ä‘Æ°a ra khá»i bệ phóng sau khi reset:" -#: builtin/reset.c:390 +#: builtin/reset.c:391 #, c-format msgid "" "\n" @@ -16627,53 +17616,53 @@ msgstr "" "Bạn có thể sá» dụng để tránh việc nà y. Äặt reset.quiet thà nh true trong\n" "cà i đặt config nếu bạn muốn thá»±c hiện nó nhÆ° là mặc định.\n" -#: builtin/reset.c:400 +#: builtin/reset.c:401 #, c-format msgid "Could not reset index file to revision '%s'." msgstr "Không thể đặt lại (reset) bảng mục lục thà nh Ä‘iểm xét duyệt “%sâ€." -#: builtin/reset.c:404 +#: builtin/reset.c:405 msgid "Could not write new index file." msgstr "Không thể ghi táºp tin lÆ°u bảng mục lục má»›i." -#: builtin/rev-list.c:403 +#: builtin/rev-list.c:406 msgid "cannot combine --exclude-promisor-objects and --missing" msgstr "không thể tổ hợp --exclude-promisor-objects và --missing" -#: builtin/rev-list.c:461 +#: builtin/rev-list.c:464 msgid "object filtering requires --objects" msgstr "lá»c đối tượng yêu cầu --objects" -#: builtin/rev-list.c:464 +#: builtin/rev-list.c:467 #, c-format msgid "invalid sparse value '%s'" msgstr "giá trị sparse không hợp lệ “%sâ€" -#: builtin/rev-list.c:505 +#: builtin/rev-list.c:508 msgid "rev-list does not support display of notes" msgstr "rev-list không há»— trợ hiển thị các ghi chú" -#: builtin/rev-list.c:508 +#: builtin/rev-list.c:511 msgid "cannot combine --use-bitmap-index with object filtering" msgstr "không thể tổ hợp --use-bitmap-index vá»›i lá»c đối tượng" -#: builtin/rev-parse.c:407 +#: builtin/rev-parse.c:408 msgid "git rev-parse --parseopt [<options>] -- [<args>...]" msgstr "git rev-parse --parseopt [<các-tùy-chá»n>] -- [<các tham số>…]" -#: builtin/rev-parse.c:412 +#: builtin/rev-parse.c:413 msgid "keep the `--` passed as an arg" msgstr "giữ lại “--†chuyển sang là m tham số" -#: builtin/rev-parse.c:414 +#: builtin/rev-parse.c:415 msgid "stop parsing after the first non-option argument" msgstr "dừng phân tÃch sau đối số đầu tiên không có tùy chá»n" -#: builtin/rev-parse.c:417 +#: builtin/rev-parse.c:418 msgid "output in stuck long form" msgstr "kết xuất trong định dạng gáºy dà i" -#: builtin/rev-parse.c:550 +#: builtin/rev-parse.c:551 msgid "" "git rev-parse --parseopt [<options>] -- [<args>...]\n" " or: git rev-parse --sq-quote [<arg>...]\n" @@ -16703,72 +17692,77 @@ msgstr "git cherry-pick [<các-tùy-chá»n>] <commit-ish>…" msgid "git cherry-pick <subcommand>" msgstr "git cherry-pick <lệnh-con>" -#: builtin/revert.c:91 +#: builtin/revert.c:72 +#, c-format +msgid "option `%s' expects a number greater than zero" +msgstr "tùy chá»n “%s†cần má»™t giá trị bằng số lá»›n hÆ¡n không" + +#: builtin/revert.c:92 #, c-format msgid "%s: %s cannot be used with %s" msgstr "%s: %s không thể được sá» dụng vá»›i %s" -#: builtin/revert.c:100 +#: builtin/revert.c:101 msgid "end revert or cherry-pick sequence" msgstr "kết thúc cherry-pick hay hoà n nguyên liên tiếp nhau" -#: builtin/revert.c:101 +#: builtin/revert.c:102 msgid "resume revert or cherry-pick sequence" msgstr "phục hồi lại cherry-pick hay hoà n nguyên liên tiếp nhau" -#: builtin/revert.c:102 +#: builtin/revert.c:103 msgid "cancel revert or cherry-pick sequence" msgstr "không cherry-pick hay hoà n nguyên liên tiếp nhau" -#: builtin/revert.c:103 +#: builtin/revert.c:104 msgid "don't automatically commit" -msgstr "không chuyển giao má»™t cách tá»± Ä‘á»™ng." +msgstr "đừng chuyển giao má»™t cách tá»± Ä‘á»™ng" -#: builtin/revert.c:104 +#: builtin/revert.c:105 msgid "edit the commit message" msgstr "sá»a lại chú thÃch cho lần chuyển giao" -#: builtin/revert.c:107 +#: builtin/revert.c:108 msgid "parent-number" msgstr "số-cha-mẹ" -#: builtin/revert.c:108 +#: builtin/revert.c:109 msgid "select mainline parent" msgstr "chá»n cha mẹ luồng chÃnh" -#: builtin/revert.c:110 +#: builtin/revert.c:111 msgid "merge strategy" msgstr "chiến lược hòa trá»™n" -#: builtin/revert.c:112 +#: builtin/revert.c:113 msgid "option for merge strategy" msgstr "tùy chá»n cho chiến lược hòa trá»™n" -#: builtin/revert.c:121 +#: builtin/revert.c:122 msgid "append commit name" msgstr "nối thêm tên lần chuyển giao" -#: builtin/revert.c:123 +#: builtin/revert.c:124 msgid "preserve initially empty commits" msgstr "cấm khởi tạo lần chuyển giao trống rá»—ng" -#: builtin/revert.c:125 +#: builtin/revert.c:126 msgid "keep redundant, empty commits" msgstr "giữ lại các lần chuyển giao dÆ° thừa, rá»—ng" -#: builtin/revert.c:219 +#: builtin/revert.c:220 msgid "revert failed" msgstr "hoà n nguyên gặp lá»—i" -#: builtin/revert.c:232 +#: builtin/revert.c:233 msgid "cherry-pick failed" msgstr "cherry-pick gặp lá»—i" -#: builtin/rm.c:18 +#: builtin/rm.c:19 msgid "git rm [<options>] [--] <file>..." msgstr "git rm [<các-tùy-chá»n>] [--] <táºp-tin>…" -#: builtin/rm.c:206 +#: builtin/rm.c:207 msgid "" "the following file has staged content different from both the\n" "file and the HEAD:" @@ -16779,7 +17773,7 @@ msgstr[0] "" "các táºp tin sau đây có khác biệt ná»™i dung đã Ä‘Æ°a lên bệ phóng\n" "từ cả táºp tin và cả HEAD:" -#: builtin/rm.c:211 +#: builtin/rm.c:212 msgid "" "\n" "(use -f to force removal)" @@ -16787,12 +17781,12 @@ msgstr "" "\n" "(dùng -f để buá»™c gỡ bá»)" -#: builtin/rm.c:215 +#: builtin/rm.c:216 msgid "the following file has changes staged in the index:" msgid_plural "the following files have changes staged in the index:" msgstr[0] "các táºp tin sau đây có thay đổi trạng thái trong bảng mục lục:" -#: builtin/rm.c:219 builtin/rm.c:228 +#: builtin/rm.c:220 builtin/rm.c:229 msgid "" "\n" "(use --cached to keep the file, or -f to force removal)" @@ -16800,42 +17794,42 @@ msgstr "" "\n" "(dùng tùy chá»n --cached để giữ táºp tin, hoặc -f để ép buá»™c gỡ bá»)" -#: builtin/rm.c:225 +#: builtin/rm.c:226 msgid "the following file has local modifications:" msgid_plural "the following files have local modifications:" msgstr[0] "những táºp tin sau đây có những thay đổi ná»™i bá»™:" -#: builtin/rm.c:241 +#: builtin/rm.c:242 msgid "do not list removed files" msgstr "không liệt kê các táºp tin đã gỡ bá»" -#: builtin/rm.c:242 +#: builtin/rm.c:243 msgid "only remove from the index" msgstr "chỉ gỡ bá» từ mục lục" -#: builtin/rm.c:243 +#: builtin/rm.c:244 msgid "override the up-to-date check" msgstr "ghi đè lên kiểm tra cáºp nháºt" -#: builtin/rm.c:244 +#: builtin/rm.c:245 msgid "allow recursive removal" msgstr "cho phép gỡ bỠđệ qui" -#: builtin/rm.c:246 +#: builtin/rm.c:247 msgid "exit with a zero status even if nothing matched" msgstr "thoát ra vá»›i trạng thái khác không tháºm chà nếu không có gì khá»›p" -#: builtin/rm.c:288 +#: builtin/rm.c:289 msgid "please stage your changes to .gitmodules or stash them to proceed" msgstr "" "hãy Ä‘Æ°a các thay đổi của bạn và o .gitmodules hay tạm cất chúng Ä‘i để xá» lý" -#: builtin/rm.c:306 +#: builtin/rm.c:307 #, c-format msgid "not removing '%s' recursively without -r" msgstr "không thể gỡ bỠ“%s†má»™t cách đệ qui mà không có tùy chá»n -r" -#: builtin/rm.c:345 +#: builtin/rm.c:346 #, c-format msgid "git rm: unable to remove %s" msgstr "git rm: không thể gỡ bá» %s" @@ -16912,7 +17906,7 @@ msgstr "<w>[,<i1>[,<i2>]]" msgid "Linewrap output" msgstr "Ngắt dòng khi quá dà i" -#: builtin/shortlog.c:299 +#: builtin/shortlog.c:301 msgid "too many arguments given outside repository" msgstr "quá nhiá»u tham số Ä‘Æ°a ra ngoà i kho chứa" @@ -17054,8 +18048,8 @@ msgid "" "git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --" "hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<pattern>...]" msgstr "" -"git show-ref [-q | --quiet] [--verify] [--head] [-d|--dereference] [-s|--" -"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<mẫu>…] " +"git show-ref [-q | --quiet] [--verify] [--head] [-d | --dereference] [-s | --" +"hash[=<n>]] [--abbrev[=<n>]] [--tags] [--heads] [--] [<mẫu>…]" #: builtin/show-ref.c:12 msgid "git show-ref --exclude-existing[=<pattern>]" @@ -17105,48 +18099,48 @@ msgstr "git stripspace [-s | --strip-comments]" msgid "git stripspace [-c | --comment-lines]" msgstr "git stripspace [-c | --comment-lines]" -#: builtin/stripspace.c:36 +#: builtin/stripspace.c:37 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ú" -#: builtin/stripspace.c:39 +#: builtin/stripspace.c:40 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" -#: builtin/submodule--helper.c:44 builtin/submodule--helper.c:1939 +#: builtin/submodule--helper.c:45 builtin/submodule--helper.c:1943 #, 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 nháºn được %s" -#: builtin/submodule--helper.c:61 +#: builtin/submodule--helper.c:62 msgid "submodule--helper print-default-remote takes no arguments" msgstr "submodule--helper print-default-remote takes không nháºn tham số" -#: builtin/submodule--helper.c:99 +#: builtin/submodule--helper.c:100 #, c-format msgid "cannot strip one component off url '%s'" msgstr "không thể cắt bá» má»™t thà nh phần ra khá»i “%s†url" -#: builtin/submodule--helper.c:407 builtin/submodule--helper.c:1363 +#: builtin/submodule--helper.c:408 builtin/submodule--helper.c:1367 msgid "alternative anchor for relative paths" msgstr "Ä‘iểm neo thay thế cho các Ä‘Æ°á»ng dẫn tÆ°Æ¡ng đối" -#: builtin/submodule--helper.c:412 +#: builtin/submodule--helper.c:413 msgid "git submodule--helper list [--prefix=<path>] [<path>...]" msgstr "git submodule--helper list [--prefix=</Ä‘Æ°á»ng/dẫn>] [</Ä‘Æ°á»ng/dẫn>…]" -#: builtin/submodule--helper.c:469 builtin/submodule--helper.c:626 -#: builtin/submodule--helper.c:649 +#: builtin/submodule--helper.c:470 builtin/submodule--helper.c:627 +#: builtin/submodule--helper.c:650 #, 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" -#: builtin/submodule--helper.c:521 +#: builtin/submodule--helper.c:522 #, c-format msgid "Entering '%s'\n" msgstr "Äang và o “%sâ€\n" -#: builtin/submodule--helper.c:524 +#: builtin/submodule--helper.c:525 #, c-format msgid "" "run_command returned non-zero status for %s\n" @@ -17155,7 +18149,7 @@ msgstr "" "run_command trả vá» trạng thái khác không cho %s\n" "." -#: builtin/submodule--helper.c:545 +#: builtin/submodule--helper.c:546 #, c-format msgid "" "run_command returned non-zero status while recursing in the nested " @@ -17166,19 +18160,19 @@ msgstr "" "con lồng nhau của %s\n" "." -#: builtin/submodule--helper.c:561 +#: builtin/submodule--helper.c:562 msgid "Suppress output of entering each submodule command" msgstr "Chặn kết xuất của từng lệnh mô-Ä‘un-con" -#: builtin/submodule--helper.c:563 builtin/submodule--helper.c:1048 +#: builtin/submodule--helper.c:564 builtin/submodule--helper.c:1049 msgid "Recurse into nested submodules" msgstr "Äệ quy và o trong các mô-Ä‘un-con lồng nhau" -#: builtin/submodule--helper.c:568 +#: builtin/submodule--helper.c:569 msgid "git submodule--helper foreach [--quiet] [--recursive] <command>" msgstr "git submodule--helper foreach [--quiet] [--recursive] <lệnh>" -#: builtin/submodule--helper.c:595 +#: builtin/submodule--helper.c:596 #, c-format msgid "" "could not look up configuration '%s'. Assuming this repository is its own " @@ -17187,56 +18181,56 @@ msgstr "" "không thể tìm thấy cấu hình “%sâ€. Coi rằng đây là kho thượng nguồn có quyá»n " "sở hữu chÃnh nó." -#: builtin/submodule--helper.c:663 +#: builtin/submodule--helper.c:664 #, c-format msgid "Failed to register url for submodule path '%s'" msgstr "Gặp lá»—i khi đăng ký url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:667 +#: builtin/submodule--helper.c:668 #, c-format msgid "Submodule '%s' (%s) registered for path '%s'\n" msgstr "Mô-Ä‘un-con “%s†(%s) được đăng ký cho Ä‘Æ°á»ng dẫn “%sâ€\n" -#: builtin/submodule--helper.c:677 +#: builtin/submodule--helper.c:678 #, c-format msgid "warning: command update mode suggested for submodule '%s'\n" msgstr "cảnh báo: chế Ä‘á»™ lệnh cáºp nháºt được gợi ý cho mô-Ä‘un-con “%sâ€\n" -#: builtin/submodule--helper.c:684 +#: builtin/submodule--helper.c:685 #, c-format msgid "Failed to register update mode for submodule path '%s'" msgstr "Gặp lá»—i khi đăng ký chế Ä‘á»™ cáºp nháºt cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:706 +#: builtin/submodule--helper.c:707 msgid "Suppress output for initializing a submodule" msgstr "Chặn kết xuất cho khởi tạo má»™t mô-Ä‘un-con" -#: builtin/submodule--helper.c:711 +#: builtin/submodule--helper.c:712 msgid "git submodule--helper init [<path>]" msgstr "git submodule--helper init [</Ä‘Æ°á»ng/dẫn>]" -#: builtin/submodule--helper.c:783 builtin/submodule--helper.c:909 +#: builtin/submodule--helper.c:784 builtin/submodule--helper.c:910 #, c-format msgid "no submodule mapping found in .gitmodules for path '%s'" msgstr "" -"Không tìm thấy ánh xạ (mapping) mô-Ä‘un-con trong .gitmodules cho Ä‘Æ°á»ng dẫn " +"không tìm thấy ánh xạ (mapping) mô-Ä‘un-con trong .gitmodules cho Ä‘Æ°á»ng dẫn " "“%sâ€" -#: builtin/submodule--helper.c:822 +#: builtin/submodule--helper.c:823 #, c-format msgid "could not resolve HEAD ref inside the submodule '%s'" msgstr "không thể phân giải tham chiếu HEAD bên trong mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:849 builtin/submodule--helper.c:1018 +#: builtin/submodule--helper.c:850 builtin/submodule--helper.c:1019 #, c-format msgid "failed to recurse into submodule '%s'" msgstr "gặp lá»—i khi đệ quy và o trong mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:873 builtin/submodule--helper.c:1182 +#: builtin/submodule--helper.c:874 builtin/submodule--helper.c:1185 msgid "Suppress submodule status output" msgstr "Chặn két xuất tình trạng mô-Ä‘un-con" -#: builtin/submodule--helper.c:874 +#: builtin/submodule--helper.c:875 msgid "" "Use commit stored in the index instead of the one stored in the submodule " "HEAD" @@ -17244,48 +18238,48 @@ msgstr "" "Dùng lần chuyển giao lÆ°u trong mục lục thay cho cái được lÆ°u trong HEAD mô-" "Ä‘un-con" -#: builtin/submodule--helper.c:875 +#: builtin/submodule--helper.c:876 msgid "recurse into nested submodules" msgstr "đệ quy và o trong mô-Ä‘un-con lồng nhau" -#: builtin/submodule--helper.c:880 +#: builtin/submodule--helper.c:881 msgid "git submodule status [--quiet] [--cached] [--recursive] [<path>...]" msgstr "" "git submodule status [--quiet] [--cached] [--recursive] [</Ä‘Æ°á»ng/dẫn>…]" -#: builtin/submodule--helper.c:904 +#: builtin/submodule--helper.c:905 msgid "git submodule--helper name <path>" msgstr "git submodule--helper name </Ä‘Æ°á»ng/dẫn>" -#: builtin/submodule--helper.c:968 +#: builtin/submodule--helper.c:969 #, c-format msgid "Synchronizing submodule url for '%s'\n" -msgstr "url mô-Ä‘un-con đồng bá»™ hóa cho “%sâ€\n" +msgstr "Url mô-Ä‘un-con đồng bá»™ hóa cho “%sâ€\n" -#: builtin/submodule--helper.c:974 +#: builtin/submodule--helper.c:975 #, c-format msgid "failed to register url for submodule path '%s'" msgstr "gặp lá»—i khi đăng ký url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:988 +#: builtin/submodule--helper.c:989 #, c-format msgid "failed to get the default remote for submodule '%s'" msgstr "gặp lá»—i khi lấy máy chủ mặc định cho mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:999 +#: builtin/submodule--helper.c:1000 #, c-format msgid "failed to update remote for submodule '%s'" msgstr "gặp lá»—i khi cáºp nháºt cho mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:1046 +#: builtin/submodule--helper.c:1047 msgid "Suppress output of synchronizing submodule url" msgstr "Chặn kết xuất cho đồng bá»™ url mô-Ä‘un-con" -#: builtin/submodule--helper.c:1053 +#: builtin/submodule--helper.c:1054 msgid "git submodule--helper sync [--quiet] [--recursive] [<path>]" msgstr "git submodule--helper sync [--quiet] [--recursive] [</Ä‘Æ°á»ng/dẫn>]" -#: builtin/submodule--helper.c:1107 +#: builtin/submodule--helper.c:1108 #, c-format msgid "" "Submodule work tree '%s' contains a .git directory (use 'rm -rf' if you " @@ -17294,7 +18288,7 @@ msgstr "" "Cây là m việc mô-Ä‘un-con “%s†có chứa thÆ° mục .git (dùng “rm -rf†nếu bạn " "thá»±c sá»± muốn gỡ bá» nó cùng vá»›i toà n bá»™ lịch sá» của chúng)" -#: builtin/submodule--helper.c:1119 +#: builtin/submodule--helper.c:1120 #, c-format msgid "" "Submodule work tree '%s' contains local modifications; use '-f' to discard " @@ -17303,80 +18297,80 @@ msgstr "" "Cây là m việc mô-Ä‘un-con “%s†chứa các thay đổi ná»™i bá»™; hãy dùng “-f†để loại " "bá» chúng Ä‘i" -#: builtin/submodule--helper.c:1127 +#: builtin/submodule--helper.c:1128 #, c-format msgid "Cleared directory '%s'\n" msgstr "Äã xóa thÆ° mục “%sâ€\n" -#: builtin/submodule--helper.c:1129 +#: builtin/submodule--helper.c:1130 #, c-format msgid "Could not remove submodule work tree '%s'\n" msgstr "Không thể gỡ bá» cây là m việc mô-Ä‘un-con “%sâ€\n" -#: builtin/submodule--helper.c:1138 +#: builtin/submodule--helper.c:1141 #, c-format msgid "could not create empty submodule directory %s" msgstr "không thể tạo thÆ° mục mô-Ä‘un-con rá»—ng “%sâ€" -#: builtin/submodule--helper.c:1154 +#: builtin/submodule--helper.c:1157 #, c-format msgid "Submodule '%s' (%s) unregistered for path '%s'\n" msgstr "Mô-Ä‘un-con “%s†(%s) được đăng ký cho Ä‘Æ°á»ng dẫn “%sâ€\n" -#: builtin/submodule--helper.c:1183 +#: builtin/submodule--helper.c:1186 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á»™" -#: builtin/submodule--helper.c:1184 +#: builtin/submodule--helper.c:1187 msgid "Unregister all submodules" msgstr "BỠđăng ký tất cả các trong mô-Ä‘un-con" -#: builtin/submodule--helper.c:1189 +#: builtin/submodule--helper.c:1192 msgid "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [<path>...]]" msgstr "" "git submodule deinit [--quiet] [-f | --force] [--all | [--] [</Ä‘Æ°á»ng/dẫn>…]]" -#: builtin/submodule--helper.c:1203 +#: builtin/submodule--helper.c:1206 msgid "Use '--all' if you really want to deinitialize all submodules" msgstr "Dùng “--all†nếu bạn thá»±c sá»± muốn hủy khởi tạo má»i mô-Ä‘un-con" -#: builtin/submodule--helper.c:1297 builtin/submodule--helper.c:1300 +#: builtin/submodule--helper.c:1301 builtin/submodule--helper.c:1304 #, c-format msgid "submodule '%s' cannot add alternate: %s" msgstr "mô-Ä‘un-con “%s†không thể thêm thay thế: %s" -#: builtin/submodule--helper.c:1336 +#: builtin/submodule--helper.c:1340 #, c-format msgid "Value '%s' for submodule.alternateErrorStrategy is not recognized" msgstr "Giá trị “%s†cho submodule.alternateErrorStrategy không được thừa nháºn" -#: builtin/submodule--helper.c:1343 +#: builtin/submodule--helper.c:1347 #, c-format msgid "Value '%s' for submodule.alternateLocation is not recognized" msgstr "Giá trị “%s†cho submodule.alternateLocation không được thừa nháºn" -#: builtin/submodule--helper.c:1366 +#: builtin/submodule--helper.c:1370 msgid "where the new submodule will be cloned to" msgstr "nhân bản mô-Ä‘un-con má»›i và o chá»— nà o" -#: builtin/submodule--helper.c:1369 +#: builtin/submodule--helper.c:1373 msgid "name of the new submodule" msgstr "tên của mô-Ä‘un-con má»›i" -#: builtin/submodule--helper.c:1372 +#: builtin/submodule--helper.c:1376 msgid "url where to clone the submodule from" msgstr "url nÆ¡i mà nhân bản mô-Ä‘un-con từ đó" -#: builtin/submodule--helper.c:1380 +#: builtin/submodule--helper.c:1384 msgid "depth for shallow clones" msgstr "chiá»u sâu lịch sá» khi tạo bản sao" -#: builtin/submodule--helper.c:1383 builtin/submodule--helper.c:1868 +#: builtin/submodule--helper.c:1387 builtin/submodule--helper.c:1872 msgid "force cloning progress" msgstr "ép buá»™c tiến trình nhân bản" -#: builtin/submodule--helper.c:1388 +#: builtin/submodule--helper.c:1392 msgid "" "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference " "<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>" @@ -17384,95 +18378,95 @@ msgstr "" "git submodule--helper clone [--prefix=</Ä‘Æ°á»ng/dẫn>] [--quiet] [--reference " "<kho>] [--name <tên>] [--depth <sâu>] [--url <url>] [</Ä‘Æ°á»ng/dẫn>…]" -#: builtin/submodule--helper.c:1419 +#: builtin/submodule--helper.c:1423 #, c-format msgid "clone of '%s' into submodule path '%s' failed" -msgstr "Nhân bản “%s†và o Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%s†gặp lá»—i" +msgstr "việc sao “%s†và o Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%s†gặp lá»—i" -#: builtin/submodule--helper.c:1433 +#: builtin/submodule--helper.c:1437 #, c-format msgid "could not get submodule directory for '%s'" msgstr "không thể lấy thÆ° mục mô-Ä‘un-con cho “%sâ€" -#: builtin/submodule--helper.c:1469 +#: builtin/submodule--helper.c:1473 #, c-format msgid "Invalid update mode '%s' for submodule path '%s'" msgstr "Chế Ä‘á»™ cáºp nháºt “%s†không hợp lệ cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:1473 +#: builtin/submodule--helper.c:1477 #, c-format msgid "Invalid update mode '%s' configured for submodule path '%s'" msgstr "" "Chế Ä‘á»™ cáºp nháºt “%s†không hợp lệ được cấu hình cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:1566 +#: builtin/submodule--helper.c:1570 #, c-format msgid "Submodule path '%s' not initialized" msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “%s†chÆ°a được khởi tạo" -#: builtin/submodule--helper.c:1570 +#: builtin/submodule--helper.c:1574 msgid "Maybe you want to use 'update --init'?" msgstr "Có lẽ bạn là bạn muốn dùng \"update --init\" phải không?" -#: builtin/submodule--helper.c:1600 +#: builtin/submodule--helper.c:1604 #, c-format msgid "Skipping unmerged submodule %s" msgstr "Bá» qua các mô-Ä‘un-con chÆ°a được hòa trá»™n %s" -#: builtin/submodule--helper.c:1629 +#: builtin/submodule--helper.c:1633 #, c-format msgid "Skipping submodule '%s'" msgstr "Bá» qua mô-Ä‘un-con “%sâ€" -#: builtin/submodule--helper.c:1773 +#: builtin/submodule--helper.c:1777 #, c-format msgid "Failed to clone '%s'. Retry scheduled" msgstr "Gặp lá»—i khi nhân bản “%sâ€. Thá» lại lịch trình" -#: builtin/submodule--helper.c:1784 +#: builtin/submodule--helper.c:1788 #, c-format msgid "Failed to clone '%s' a second time, aborting" msgstr "Gặp lá»—i khi nhân bản “%s†lần thứ hai nên bãi bá»" -#: builtin/submodule--helper.c:1847 builtin/submodule--helper.c:2089 +#: builtin/submodule--helper.c:1851 builtin/submodule--helper.c:2093 msgid "path into the working tree" msgstr "Ä‘Æ°á»ng dẫn đến cây là m việc" -#: builtin/submodule--helper.c:1850 +#: builtin/submodule--helper.c:1854 msgid "path into the working tree, across nested submodule boundaries" msgstr "Ä‘Æ°á»ng dẫn đến cây là m việc, chéo biên giá»›i mô-Ä‘un-con lồng nhau" -#: builtin/submodule--helper.c:1854 +#: builtin/submodule--helper.c:1858 msgid "rebase, merge, checkout or none" msgstr "rebase, merge, checkout hoặc không là m gì cả" -#: builtin/submodule--helper.c:1860 +#: builtin/submodule--helper.c:1864 msgid "Create a shallow clone truncated to the specified number of revisions" msgstr "" "Tạo má»™t bản sao nông được cắt ngắn thà nh số lượng Ä‘iểm xét duyệt đã cho" -#: builtin/submodule--helper.c:1863 +#: builtin/submodule--helper.c:1867 msgid "parallel jobs" msgstr "công việc đồng thá»i" -#: builtin/submodule--helper.c:1865 +#: builtin/submodule--helper.c:1869 msgid "whether the initial clone should follow the shallow recommendation" msgstr "nhân bản lần đầu có nên theo khuyến nghị là nông hay không" -#: builtin/submodule--helper.c:1866 +#: builtin/submodule--helper.c:1870 msgid "don't print cloning progress" msgstr "đừng in tiến trình nhân bản" -#: builtin/submodule--helper.c:1873 +#: builtin/submodule--helper.c:1877 msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]" msgstr "" "git submodule--helper update_clone [--prefix=</Ä‘Æ°á»ng/dẫn>] [</Ä‘Æ°á»ng/dẫn>…]" -#: builtin/submodule--helper.c:1886 +#: builtin/submodule--helper.c:1890 msgid "bad value for update parameter" msgstr "giá trị cho tham số cáºp nháºt bị sai" -#: builtin/submodule--helper.c:1934 +#: builtin/submodule--helper.c:1938 #, c-format msgid "" "Submodule (%s) branch configured to inherit branch from superproject, but " @@ -17481,42 +18475,42 @@ msgstr "" "Nhánh mô-Ä‘un-con (%s) được cấu hình kế thừa nhánh từ siêu dá»± án, nhÆ°ng siêu " "dá»± án lại không trên bất kỳ nhánh nà o" -#: builtin/submodule--helper.c:2057 +#: builtin/submodule--helper.c:2061 #, 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â€" -#: builtin/submodule--helper.c:2090 +#: builtin/submodule--helper.c:2094 msgid "recurse into submodules" msgstr "đệ quy và o trong mô-Ä‘un-con" -#: builtin/submodule--helper.c:2096 +#: builtin/submodule--helper.c:2100 msgid "git submodule--helper embed-git-dir [<path>...]" msgstr "git submodule--helper embed-git-dir [</Ä‘Æ°á»ng/dẫn>…]" -#: builtin/submodule--helper.c:2152 +#: builtin/submodule--helper.c:2156 msgid "check if it is safe to write to the .gitmodules file" msgstr "chá»n nếu nó là an toà n để ghi và o táºp tin .gitmodules" -#: builtin/submodule--helper.c:2157 +#: builtin/submodule--helper.c:2161 msgid "git submodule--helper config name [value]" msgstr "git submodule--helper config tên [giá trị]" -#: builtin/submodule--helper.c:2158 +#: builtin/submodule--helper.c:2162 msgid "git submodule--helper config --check-writeable" msgstr "git submodule--helper config --check-writeable" -#: builtin/submodule--helper.c:2175 git-submodule.sh:169 +#: builtin/submodule--helper.c:2179 git-submodule.sh:169 #, sh-format msgid "please make sure that the .gitmodules file is in the working tree" msgstr "hãy đảm bảo rằng táºp tin .gitmodules có trong cây là m việc" -#: builtin/submodule--helper.c:2225 +#: builtin/submodule--helper.c:2229 git.c:413 git.c:658 #, c-format msgid "%s doesn't support --super-prefix" msgstr "%s không há»— trợ --super-prefix" -#: builtin/submodule--helper.c:2231 +#: builtin/submodule--helper.c:2235 #, c-format msgid "'%s' is not a valid submodule--helper subcommand" msgstr "“%s†không phải là lệnh con submodule--helper hợp lệ" @@ -17751,7 +18745,7 @@ msgstr "“%s†không phải thẻ hợp lệ." #: builtin/tag.c:534 #, c-format msgid "tag '%s' already exists" -msgstr "Thẻ “%s†đã tồn tại rồi" +msgstr "thẻ “%s†đã tồn tại rồi" #: builtin/tag.c:565 #, c-format @@ -17762,202 +18756,202 @@ msgstr "Äã cáºp nháºt thẻ “%s†(trÆ°á»›c là %s)\n" msgid "Unpacking objects" msgstr "Äang giải nén các đối tượng" -#: builtin/update-index.c:82 +#: builtin/update-index.c:83 #, c-format msgid "failed to create directory %s" msgstr "tạo thÆ° mục \"%s\" gặp lá»—i" -#: builtin/update-index.c:98 +#: builtin/update-index.c:99 #, c-format msgid "failed to create file %s" msgstr "gặp lá»—i khi tạo táºp tin %s" -#: builtin/update-index.c:106 +#: builtin/update-index.c:107 #, c-format msgid "failed to delete file %s" msgstr "gặp lá»—i khi xóa táºp tin %s" -#: builtin/update-index.c:113 builtin/update-index.c:219 +#: builtin/update-index.c:114 builtin/update-index.c:220 #, c-format msgid "failed to delete directory %s" msgstr "gặp lá»—i khi xóa thÆ° mục %s" -#: builtin/update-index.c:138 +#: builtin/update-index.c:139 #, c-format msgid "Testing mtime in '%s' " -msgstr "Äang kiểm thá» mtime trong “%sâ€" +msgstr "Äang kiểm thá» mtime trong “%s†" -#: builtin/update-index.c:152 +#: builtin/update-index.c:153 msgid "directory stat info does not change after adding a new file" msgstr "thông tin thống kê thÆ° mục không thay đổi sau khi thêm táºp tin má»›i" -#: builtin/update-index.c:165 +#: builtin/update-index.c:166 msgid "directory stat info does not change after adding a new directory" msgstr "thông tin thống kê thÆ° mục không thay đổi sau khi thêm thÆ° mục má»›i" -#: builtin/update-index.c:178 +#: builtin/update-index.c:179 msgid "directory stat info changes after updating a file" msgstr "thông tin thống kê thÆ° mục thay đổi sau khi cáºp nháºt táºp tin" -#: builtin/update-index.c:189 +#: builtin/update-index.c:190 msgid "directory stat info changes after adding a file inside subdirectory" msgstr "" "thông tin thống kê thÆ° mục thay đổi sau khi thêm táºp tin má»›i và o trong thÆ° " "mục con" -#: builtin/update-index.c:200 +#: builtin/update-index.c:201 msgid "directory stat info does not change after deleting a file" msgstr "thông tin thống kê thÆ° mục không thay đổi sau khi xóa táºp tin" -#: builtin/update-index.c:213 +#: builtin/update-index.c:214 msgid "directory stat info does not change after deleting a directory" msgstr "thông tin thống kê thÆ° mục không thay đổi sau khi xóa thÆ° mục" -#: builtin/update-index.c:220 +#: builtin/update-index.c:221 msgid " OK" msgstr " Äồng ý" -#: builtin/update-index.c:588 +#: builtin/update-index.c:589 msgid "git update-index [<options>] [--] [<file>...]" msgstr "git update-index [<các-tùy-chá»n>] [--] [<táºp-tin>…]" -#: builtin/update-index.c:961 +#: builtin/update-index.c:962 msgid "continue refresh even when index needs update" msgstr "tiếp tục là m má»›i ngay cả khi bảng mục lục cần được cáºp nháºt" -#: builtin/update-index.c:964 +#: builtin/update-index.c:965 msgid "refresh: ignore submodules" msgstr "refresh: lá» Ä‘i mô-Ä‘un-con" -#: builtin/update-index.c:967 +#: builtin/update-index.c:968 msgid "do not ignore new files" msgstr "không bá» qua các táºp tin má»›i tạo" -#: builtin/update-index.c:969 +#: builtin/update-index.c:970 msgid "let files replace directories and vice-versa" msgstr "để các táºp tin thay thế các thÆ° mục và “vice-versaâ€" -#: builtin/update-index.c:971 +#: builtin/update-index.c:972 msgid "notice files missing from worktree" msgstr "thông báo các táºp-tin thiếu trong thÆ°-mục là m việc" -#: builtin/update-index.c:973 +#: builtin/update-index.c:974 msgid "refresh even if index contains unmerged entries" msgstr "" "là m tÆ°Æ¡i má»›i tháºm chà khi bảng mục lục chứa các mục tin chÆ°a được hòa trá»™n" -#: builtin/update-index.c:976 +#: builtin/update-index.c:977 msgid "refresh stat information" msgstr "lấy lại thông tin thống kê" -#: builtin/update-index.c:980 +#: builtin/update-index.c:981 msgid "like --refresh, but ignore assume-unchanged setting" msgstr "giống --refresh, nhÆ°ng bá» qua các cà i đặt “assume-unchangedâ€" -#: builtin/update-index.c:984 +#: builtin/update-index.c:985 msgid "<mode>,<object>,<path>" msgstr "<chế_Ä‘á»™>,<đối_tượng>,<Ä‘Æ°á»ng_dẫn>" -#: builtin/update-index.c:985 +#: builtin/update-index.c:986 msgid "add the specified entry to the index" msgstr "thêm các táºp tin đã chỉ ra và o bảng mục lục" -#: builtin/update-index.c:994 +#: builtin/update-index.c:995 msgid "mark files as \"not changing\"" -msgstr "Äánh dấu các táºp tin là \"không thay đổi\"" +msgstr "đánh dấu các táºp tin là \"không thay đổi\"" -#: builtin/update-index.c:997 +#: builtin/update-index.c:998 msgid "clear assumed-unchanged bit" msgstr "xóa bÃt assumed-unchanged (giả định là không thay đổi)" -#: builtin/update-index.c:1000 +#: builtin/update-index.c:1001 msgid "mark files as \"index-only\"" msgstr "đánh dấu các táºp tin là “chỉ-Ä‘á»câ€" -#: builtin/update-index.c:1003 +#: builtin/update-index.c:1004 msgid "clear skip-worktree bit" msgstr "xóa bÃt skip-worktree" -#: builtin/update-index.c:1006 +#: builtin/update-index.c:1007 msgid "add to index only; do not add content to object database" msgstr "" "chỉ thêm và o bảng mục lục; không thêm ná»™i dung và o cÆ¡ sở dữ liệu đối tượng" -#: builtin/update-index.c:1008 +#: builtin/update-index.c:1009 msgid "remove named paths even if present in worktree" msgstr "" "gỡ bá» các Ä‘Æ°á»ng dẫn được đặt tên tháºm chà cả khi nó hiện diện trong thÆ° mục " "là m việc" -#: builtin/update-index.c:1010 +#: builtin/update-index.c:1011 msgid "with --stdin: input lines are terminated by null bytes" msgstr "vá»›i tùy chá»n --stdin: các dòng đầu và o được chấm dứt bởi ký tá»± null" -#: builtin/update-index.c:1012 +#: builtin/update-index.c:1013 msgid "read list of paths to be updated from standard input" msgstr "Ä‘á»c danh sách Ä‘Æ°á»ng dẫn cần cáºp nháºt từ đầu và o tiêu chuẩn" -#: builtin/update-index.c:1016 +#: builtin/update-index.c:1017 msgid "add entries from standard input to the index" msgstr "không thể Ä‘á»c các mục từ đầu và o tiêu chuẩn và o bảng mục lục" -#: builtin/update-index.c:1020 +#: builtin/update-index.c:1021 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ê" -#: builtin/update-index.c:1024 +#: builtin/update-index.c:1025 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" -#: builtin/update-index.c:1028 +#: builtin/update-index.c:1029 msgid "ignore files missing from worktree" msgstr "bá» qua các táºp-tin thiếu trong thÆ°-mục là m việc" -#: builtin/update-index.c:1031 +#: builtin/update-index.c:1032 msgid "report actions to standard output" msgstr "báo cáo các thao tác ra thiết bị xuất chuẩn" -#: builtin/update-index.c:1033 +#: builtin/update-index.c:1034 msgid "(for porcelains) forget saved unresolved conflicts" msgstr "(cho “porcelainsâ€) quên các xung Ä‘á»™t chÆ°a được giải quyết đã ghi" -#: builtin/update-index.c:1037 +#: builtin/update-index.c:1038 msgid "write index in this format" msgstr "ghi mục lục ở định dạng nà y" -#: builtin/update-index.c:1039 +#: builtin/update-index.c:1040 msgid "enable or disable split index" msgstr "báºt/tắt chia cắt bảng mục lục" -#: builtin/update-index.c:1041 +#: builtin/update-index.c:1042 msgid "enable/disable untracked cache" msgstr "báºt/tắt bá»™ đệm không theo vết" -#: builtin/update-index.c:1043 +#: builtin/update-index.c:1044 msgid "test if the filesystem supports untracked cache" msgstr "kiểm tra xem hệ thống táºp tin có há»— trợ đệm không theo dõi hay không" -#: builtin/update-index.c:1045 +#: builtin/update-index.c:1046 msgid "enable untracked cache without testing the filesystem" msgstr "báºt bá»™ đệm không theo vết mà không kiểm tra hệ thống táºp tin" -#: builtin/update-index.c:1047 +#: builtin/update-index.c:1048 msgid "write out the index even if is not flagged as changed" msgstr "ghi ra mục lục ngay cả khi không được đánh cá» là có thay đổi" -#: builtin/update-index.c:1049 +#: builtin/update-index.c:1050 msgid "enable or disable file system monitor" msgstr "báºt/tắt theo dõi hệ thống táºp tin" -#: builtin/update-index.c:1051 +#: builtin/update-index.c:1052 msgid "mark files as fsmonitor valid" msgstr "đánh dấu các táºp tin là hợp lệ fsmonitor" -#: builtin/update-index.c:1054 +#: builtin/update-index.c:1055 msgid "clear fsmonitor valid bit" msgstr "xóa bÃt hợp lệ fsmonitor" -#: builtin/update-index.c:1153 +#: builtin/update-index.c:1156 msgid "" "core.splitIndex is set to false; remove or change it, if you really want to " "enable split index" @@ -17965,7 +18959,7 @@ msgstr "" "core.splitIndex được đặt là sai; xóa bá» hay thay đổi nó, nếu bạn thá»±c sá»± " "muốn báºt chia tách mục lục" -#: builtin/update-index.c:1162 +#: builtin/update-index.c:1165 msgid "" "core.splitIndex is set to true; remove or change it, if you really want to " "disable split index" @@ -17973,7 +18967,7 @@ msgstr "" "core.splitIndex được đặt là đúng; xóa bá» hay thay đổi nó, nếu bạn thá»±c sá»± " "muốn tắt chia tách mục lục" -#: builtin/update-index.c:1173 +#: builtin/update-index.c:1176 msgid "" "core.untrackedCache is set to true; remove or change it, if you really want " "to disable the untracked cache" @@ -17981,11 +18975,11 @@ msgstr "" "core.untrackedCache được đặt là đúng; xóa bá» hay thay đổi nó, nếu bạn thá»±c " "sá»± muốn tắt bá»™ đệm chÆ°a theo dõi" -#: builtin/update-index.c:1177 +#: builtin/update-index.c:1180 msgid "Untracked cache disabled" msgstr "Nhá»› đệm không theo vết bị tắt" -#: builtin/update-index.c:1185 +#: builtin/update-index.c:1188 msgid "" "core.untrackedCache is set to false; remove or change it, if you really want " "to enable the untracked cache" @@ -17993,29 +18987,29 @@ msgstr "" "core.untrackedCache được đặt là sai; xóa bá» hay thay đổi nó, nếu bạn thá»±c sá»± " "muốn báºt bá»™ đệm chÆ°a theo dõi" -#: builtin/update-index.c:1189 +#: builtin/update-index.c:1192 #, c-format msgid "Untracked cache enabled for '%s'" msgstr "Nhá»› đệm không theo vết được báºt cho “%sâ€" -#: builtin/update-index.c:1197 +#: builtin/update-index.c:1200 msgid "core.fsmonitor is unset; set it if you really want to enable fsmonitor" msgstr "" "core.fsmonitor chÆ°a được đặt; đặt nó nếu bạn thá»±c sá»± muốn báºt theo dõi hệ " "thống táºp tin" -#: builtin/update-index.c:1201 +#: builtin/update-index.c:1204 msgid "fsmonitor enabled" msgstr "fsmonitor được báºt" -#: builtin/update-index.c:1204 +#: builtin/update-index.c:1207 msgid "" "core.fsmonitor is set; remove it if you really want to disable fsmonitor" msgstr "" "core.fsmonitor đã được đặt; bỠđặt nó nếu bạn thá»±c sá»± muốn báºt theo dõi hệ " "thống táºp tin" -#: builtin/update-index.c:1208 +#: builtin/update-index.c:1211 msgid "fsmonitor disabled" msgstr "fsmonitor bị tắt" @@ -18103,90 +19097,90 @@ msgstr "git verify-tag [-v | --verbose] [--format=<định_dạng>] <thẻ>…" msgid "print tag contents" msgstr "hiển thị ná»™i dung của thẻ" -#: builtin/worktree.c:17 +#: builtin/worktree.c:18 msgid "git worktree add [<options>] <path> [<commit-ish>]" msgstr "git worktree add [<các-tùy-chá»n>] <Ä‘Æ°á»ng-dẫn> [<commit-ish>]" -#: builtin/worktree.c:18 +#: builtin/worktree.c:19 msgid "git worktree list [<options>]" msgstr "git worktree list [<các-tùy-chá»n>]" -#: builtin/worktree.c:19 +#: builtin/worktree.c:20 msgid "git worktree lock [<options>] <path>" msgstr "git worktree lock [<các-tùy-chá»n>] </Ä‘Æ°á»ng/dẫn>" -#: builtin/worktree.c:20 +#: builtin/worktree.c:21 msgid "git worktree move <worktree> <new-path>" msgstr "git worktree move <worktree> </Ä‘Æ°á»ng/dẫn/má»›i>" -#: builtin/worktree.c:21 +#: builtin/worktree.c:22 msgid "git worktree prune [<options>]" msgstr "git worktree prune [<các-tùy-chá»n>]" -#: builtin/worktree.c:22 +#: builtin/worktree.c:23 msgid "git worktree remove [<options>] <worktree>" msgstr "git worktree remove [<các-tùy-chá»n>] <worktree>" -#: builtin/worktree.c:23 +#: builtin/worktree.c:24 msgid "git worktree unlock <path>" msgstr "git worktree unlock </Ä‘Æ°á»ng/dẫn>" -#: builtin/worktree.c:60 builtin/worktree.c:871 +#: builtin/worktree.c:61 builtin/worktree.c:888 #, c-format msgid "failed to delete '%s'" msgstr "gặp lá»—i khi xóa “%sâ€" -#: builtin/worktree.c:79 +#: builtin/worktree.c:80 #, c-format msgid "Removing worktrees/%s: not a valid directory" msgstr "Gỡ bá» cây là m việc/%s: không phải là thÆ° mục hợp lệ" -#: builtin/worktree.c:85 +#: builtin/worktree.c:86 #, c-format msgid "Removing worktrees/%s: gitdir file does not exist" msgstr "Gỡ bá» cây là m việc/%s: không có táºp tin gitdir" -#: builtin/worktree.c:90 builtin/worktree.c:99 +#: builtin/worktree.c:91 builtin/worktree.c:100 #, c-format msgid "Removing worktrees/%s: unable to read gitdir file (%s)" msgstr "Gỡ bá» cây là m việc/%s: không thể Ä‘á»c táºp tin gitdir (%s)" -#: builtin/worktree.c:109 +#: builtin/worktree.c:110 #, c-format msgid "" "Removing worktrees/%s: short read (expected %<PRIuMAX> bytes, read " "%<PRIuMAX>)" msgstr "Gỡ bá» cây là m việc/%s: Ä‘á»c ngắn (cần %<PRIuMAX> byte, Ä‘á»c %<PRIuMAX>)" -#: builtin/worktree.c:117 +#: builtin/worktree.c:118 #, c-format msgid "Removing worktrees/%s: invalid gitdir file" msgstr "Gỡ bá» cây là m việc/%s: táºp tin gitdir không hợp lệ" -#: builtin/worktree.c:126 +#: builtin/worktree.c:127 #, c-format msgid "Removing worktrees/%s: gitdir file points to non-existent location" msgstr "Gỡ bá» cây là m việc/%s: táºp tin gitdir chỉ đến vị trà không tồn tại" -#: builtin/worktree.c:165 +#: builtin/worktree.c:166 msgid "report pruned working trees" msgstr "báo cáo các cây là m việc đã prune" -#: builtin/worktree.c:167 +#: builtin/worktree.c:168 msgid "expire working trees older than <time>" msgstr "các cây là m việc hết hạn cÅ© hÆ¡n khoảng <thá»i gian>" -#: builtin/worktree.c:234 +#: builtin/worktree.c:235 #, c-format msgid "'%s' already exists" msgstr "“%s†đã có từ trÆ°á»›c rồi" -#: builtin/worktree.c:251 +#: builtin/worktree.c:252 #, c-format msgid "unable to re-add worktree '%s'" msgstr "không thể thêm-lại cây “%sâ€" -#: builtin/worktree.c:256 +#: builtin/worktree.c:257 #, c-format msgid "" "'%s' is a missing but locked worktree;\n" @@ -18195,7 +19189,7 @@ msgstr "" "“%s†bị mất nhÆ°ng cây là m việc bị khóa;\n" "dùng “add -f -f†để ghi đè, hoặc “unlock†và “prune†hay “remove†để xóa" -#: builtin/worktree.c:258 +#: builtin/worktree.c:259 #, c-format msgid "" "'%s' is a missing but already registered worktree;\n" @@ -18204,120 +19198,120 @@ msgstr "" "“%s†bị mất nhÆ°ng cây là m việc đã được đăng ký;\n" "dùng “add -f†để ghi đè, hoặc “prune†hay “remove†để xóa" -#: builtin/worktree.c:309 +#: builtin/worktree.c:310 #, c-format msgid "could not create directory of '%s'" msgstr "không thể tạo thÆ° mục của “%sâ€" -#: builtin/worktree.c:428 builtin/worktree.c:434 +#: builtin/worktree.c:429 builtin/worktree.c:435 #, c-format msgid "Preparing worktree (new branch '%s')" msgstr "Äang chuẩn bị cây là m việc (nhánh má»›i “%sâ€)" -#: builtin/worktree.c:430 +#: builtin/worktree.c:431 #, c-format msgid "Preparing worktree (resetting branch '%s'; was at %s)" msgstr "Äang chuẩn bị cây là m việc (Ä‘ang cà i đặt nhánh “%sâ€, trÆ°á»›c đây tại %s)" -#: builtin/worktree.c:439 +#: builtin/worktree.c:440 #, c-format msgid "Preparing worktree (checking out '%s')" msgstr "Äang chuẩn bị cây là m việc (Ä‘ang lấy ra “%sâ€)" -#: builtin/worktree.c:445 +#: builtin/worktree.c:446 #, 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â€)" -#: builtin/worktree.c:486 +#: builtin/worktree.c:487 msgid "checkout <branch> even if already checked out in other worktree" msgstr "lấy ra <nhánh> ngay cả khi nó đã được lấy ra ở cây là m việc khác" -#: builtin/worktree.c:489 +#: builtin/worktree.c:490 msgid "create a new branch" msgstr "tạo nhánh má»›i" -#: builtin/worktree.c:491 +#: builtin/worktree.c:492 msgid "create or reset a branch" msgstr "tạo hay đặt lại má»™t nhánh" -#: builtin/worktree.c:493 +#: builtin/worktree.c:494 msgid "populate the new working tree" msgstr "di chuyển cây là m việc má»›i" -#: builtin/worktree.c:494 +#: builtin/worktree.c:495 msgid "keep the new working tree locked" msgstr "giữ cây là m việc má»›i bị khóa" -#: builtin/worktree.c:497 +#: builtin/worktree.c:498 msgid "set up tracking mode (see git-branch(1))" msgstr "cà i đặt chế Ä‘á»™ theo dõi (xem git-branch(1))" -#: builtin/worktree.c:500 +#: builtin/worktree.c:501 msgid "try to match the new branch name with a remote-tracking branch" msgstr "có khá»›p tên tên nhánh má»›i vá»›i má»™t nhánh theo dõi máy chủ" -#: builtin/worktree.c:508 +#: builtin/worktree.c:509 msgid "-b, -B, and --detach are mutually exclusive" msgstr "Các tùy chá»n -b, -B, và --detach loại từ lẫn nhau" -#: builtin/worktree.c:569 +#: builtin/worktree.c:570 msgid "--[no-]track can only be used if a new branch is created" msgstr "--[no-]track chỉ có thể được dùng nếu má»™t nhánh má»›i được tạo" -#: builtin/worktree.c:669 +#: builtin/worktree.c:670 msgid "reason for locking" msgstr "lý do khóa" -#: builtin/worktree.c:681 builtin/worktree.c:714 builtin/worktree.c:772 -#: builtin/worktree.c:899 +#: builtin/worktree.c:682 builtin/worktree.c:715 builtin/worktree.c:789 +#: builtin/worktree.c:916 #, c-format msgid "'%s' is not a working tree" msgstr "%s không phải là cây là m việc" -#: builtin/worktree.c:683 builtin/worktree.c:716 +#: builtin/worktree.c:684 builtin/worktree.c:717 msgid "The main working tree cannot be locked or unlocked" msgstr "Cây thÆ° mục là m việc chÃnh không thể khóa hay bá» khóa được" -#: builtin/worktree.c:688 +#: builtin/worktree.c:689 #, c-format msgid "'%s' is already locked, reason: %s" msgstr "“%s†đã được khóa rồi, lý do: %s" -#: builtin/worktree.c:690 +#: builtin/worktree.c:691 #, c-format msgid "'%s' is already locked" msgstr "“%s†đã được khóa rồi" -#: builtin/worktree.c:718 +#: builtin/worktree.c:719 #, c-format msgid "'%s' is not locked" msgstr "“%s†chÆ°a bị khóa" -#: builtin/worktree.c:743 +#: builtin/worktree.c:760 msgid "working trees containing submodules cannot be moved or removed" msgstr "cây là m việc có chứa mô-Ä‘un-con không thể di chuyển hay xóa bá»" -#: builtin/worktree.c:751 +#: builtin/worktree.c:768 msgid "force move even if worktree is dirty or locked" msgstr "ép buá»™c ngay cả khi cây là m việc Ä‘ang bẩn hay bị khóa" -#: builtin/worktree.c:774 builtin/worktree.c:901 +#: builtin/worktree.c:791 builtin/worktree.c:918 #, c-format msgid "'%s' is a main working tree" msgstr "“%s†là cây là m việc chÃnh" -#: builtin/worktree.c:779 +#: builtin/worktree.c:796 #, c-format msgid "could not figure out destination name from '%s'" msgstr "không thể phác há»a ra tên Ä‘Ãch đến “%sâ€" -#: builtin/worktree.c:785 +#: builtin/worktree.c:802 #, c-format msgid "target '%s' already exists" msgstr "Ä‘Ãch “%s†đã tồn tại rồi" -#: builtin/worktree.c:793 +#: builtin/worktree.c:810 #, c-format msgid "" "cannot move a locked working tree, lock reason: %s\n" @@ -18326,7 +19320,7 @@ msgstr "" "không thể di chuyển má»™t cây-là m-việc bị khóa, khóa vì: %s\n" "dùng “move -f -f†để ghi đè hoặc mở khóa trÆ°á»›c đã" -#: builtin/worktree.c:795 +#: builtin/worktree.c:812 msgid "" "cannot move a locked working tree;\n" "use 'move -f -f' to override or unlock first" @@ -18334,36 +19328,36 @@ msgstr "" "không thể di chuyển má»™t cây-là m-việc bị khóa;\n" "dùng “move -f -f†để ghi đè hoặc mở khóa trÆ°á»›c đã" -#: builtin/worktree.c:798 +#: builtin/worktree.c:815 #, 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" -#: builtin/worktree.c:803 +#: builtin/worktree.c:820 #, c-format msgid "failed to move '%s' to '%s'" msgstr "gặp lá»—i khi chuyển “%s†sang “%sâ€" -#: builtin/worktree.c:851 +#: builtin/worktree.c:868 #, c-format msgid "failed to run 'git status' on '%s'" msgstr "gặp lá»—i khi chạy “git status†và o “%sâ€" -#: builtin/worktree.c:855 +#: builtin/worktree.c:872 #, c-format msgid "'%s' is dirty, use --force to delete it" msgstr "“%s†đang bẩn, hãy dùng --force để xóa nó" -#: builtin/worktree.c:860 +#: builtin/worktree.c:877 #, c-format msgid "failed to run 'git status' on '%s', code %d" msgstr "gặp lá»—i khi chạy “git status†trong “%sâ€, mã %d" -#: builtin/worktree.c:883 +#: builtin/worktree.c:900 msgid "force removal even if worktree is dirty or locked" msgstr "ép buá»™c di chuyển tháºm chà cả khi cây là m việc Ä‘ang bẩn hay bị khóa" -#: builtin/worktree.c:906 +#: builtin/worktree.c:923 #, c-format msgid "" "cannot remove a locked working tree, lock reason: %s\n" @@ -18372,7 +19366,7 @@ msgstr "" "không thể xóa bá» má»™t cây-là m-việc bị khóa, khóa vì: %s\n" "dùng “remove -f -f†để ghi đè hoặc mở khóa trÆ°á»›c đã" -#: builtin/worktree.c:908 +#: builtin/worktree.c:925 msgid "" "cannot remove a locked working tree;\n" "use 'remove -f -f' to override or unlock first" @@ -18380,28 +19374,28 @@ msgstr "" "không thể xóa bá» má»™t cây-là m-việc bị khóa;\n" "dùng “remove -f -f†để ghi đè hoặc mở khóa trÆ°á»›c đã" -#: builtin/worktree.c:911 +#: builtin/worktree.c:928 #, 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" -#: builtin/write-tree.c:14 +#: builtin/write-tree.c:15 msgid "git write-tree [--missing-ok] [--prefix=<prefix>/]" msgstr "git write-tree [--missing-ok] [--prefix=<tiá»n-tố>/]" -#: builtin/write-tree.c:27 +#: builtin/write-tree.c:28 msgid "<prefix>/" msgstr "<tiá»n tố>/" -#: builtin/write-tree.c:28 +#: builtin/write-tree.c:29 msgid "write tree object for a subdirectory <prefix>" msgstr "ghi đối tượng cây (tree) cho <tiá»n tố> thÆ° mục con" -#: builtin/write-tree.c:30 +#: builtin/write-tree.c:31 msgid "only useful for debugging" msgstr "chỉ hữu Ãch khi cần gỡ lá»—i" -#: credential-cache--daemon.c:222 +#: credential-cache--daemon.c:223 #, c-format msgid "" "The permissions on your socket directory are too loose; other\n" @@ -18414,7 +19408,7 @@ msgstr "" "\n" "\tchmod 0700 %s" -#: credential-cache--daemon.c:271 +#: credential-cache--daemon.c:272 msgid "print debugging messages to stderr" msgstr "in thông tin gỡ lá»—i ra đầu ra lá»—i tiêu chuẩn" @@ -18455,98 +19449,148 @@ msgstr "" "hÆ°á»›ng dẫn vá» khái niệm. Xem “git help <lệnh>†hay “git help <khái-niệm>â€\n" "để xem các đặc tả cho lệnh hay khái niệm cụ thể." -#: git.c:173 +#: git.c:174 #, c-format msgid "no directory given for --git-dir\n" msgstr "chÆ°a chỉ ra thÆ° mục cho --git-dir\n" -#: git.c:187 +#: git.c:188 #, c-format msgid "no namespace given for --namespace\n" msgstr "chÆ°a Ä‘Æ°a ra không gian là m việc cho --namespace\n" -#: git.c:201 +#: git.c:202 #, c-format msgid "no directory given for --work-tree\n" msgstr "chÆ°a Ä‘Æ°a ra cây là m việc cho --work-tree\n" -#: git.c:215 +#: git.c:216 #, c-format msgid "no prefix given for --super-prefix\n" msgstr "chÆ°a Ä‘Æ°a ra tiá»n tố cho --super-prefix\n" -#: git.c:237 +#: git.c:238 #, c-format msgid "-c expects a configuration string\n" msgstr "-c cần má»™t chuá»—i cấu hình\n" -#: git.c:275 +#: git.c:276 #, c-format msgid "no directory given for -C\n" msgstr "chÆ°a Ä‘Æ°a ra thÆ° mục cho -C\n" -#: git.c:300 +#: git.c:301 #, c-format msgid "unknown option: %s\n" msgstr "không hiểu tùy chá»n: %s\n" -#: git.c:719 +#: git.c:342 +#, c-format +msgid "while expanding alias '%s': '%s'" +msgstr "trong khi triển khai bà danh “%sâ€: “%sâ€" + +#: git.c:351 +#, c-format +msgid "" +"alias '%s' changes environment variables.\n" +"You can use '!git' in the alias to do this" +msgstr "" +"bà danh “%s†thay đổi biến môi trÆ°á»ng.\n" +"Bạn có thể sá» dụng “!git†trong đặt bà danh để là m việc nà y" + +#: git.c:359 +#, c-format +msgid "empty alias for %s" +msgstr "là m trống bà danh cho %s" + +#: git.c:362 +#, c-format +msgid "recursive alias: %s" +msgstr "đệ quy các bà danh: %s" + +#: git.c:437 +msgid "write failure on standard output" +msgstr "lá»—i ghi nghiêm trong trên đầu ra tiêu chuẩn" + +#: git.c:439 +msgid "unknown write failure on standard output" +msgstr "lá»—i nghiêm trá»ng chÆ°a biết khi ghi ra đầu ra tiêu chuẩn" + +#: git.c:441 +msgid "close failed on standard output" +msgstr "gặp lá»—i khi đóng đầu ra tiêu chuẩn" + +#: git.c:720 #, c-format msgid "alias loop detected: expansion of '%s' does not terminate:%s" msgstr "" "dò tìm thấy các bà danh quẩn tròn: biểu thức của “%s†không có Ä‘iểm kết:%s" -#: git.c:802 +#: git.c:770 +#, c-format +msgid "cannot handle %s as a builtin" +msgstr "không thể xá» lý %s nhÆ° là má»™t phần bổ sung" + +#: git.c:783 +#, c-format +msgid "" +"usage: %s\n" +"\n" +msgstr "" +"cách dùng: %s\n" +"\n" + +#: git.c:803 #, c-format msgid "expansion of alias '%s' failed; '%s' is not a git command\n" msgstr "gặp lá»—i khi khai triển bà danh “%sâ€; “%s†không phải là lệnh git\n" -#: git.c:814 +#: git.c:815 #, c-format msgid "failed to run command '%s': %s\n" msgstr "gặp lá»—i khi chạy lệnh “%sâ€: %s\n" -#: http.c:374 +#: http.c:378 #, c-format msgid "negative value for http.postbuffer; defaulting to %d" msgstr "giá trị âm cho http.postbuffer; đặt thà nh mặc định là %d" -#: http.c:395 +#: http.c:399 msgid "Delegation control is not supported with cURL < 7.22.0" msgstr "Äiá»u khiển giao quyá»n không được há»— trợ vá»›i cURL < 7.22.0" -#: http.c:404 +#: http.c:408 msgid "Public key pinning not supported with cURL < 7.44.0" msgstr "Chốt khóa công không được há»— trợ vá»›i cURL < 7.44.0" -#: http.c:837 +#: http.c:876 msgid "CURLSSLOPT_NO_REVOKE not supported with cURL < 7.44.0" msgstr "CURLSSLOPT_NO_REVOKE không được há»— trợ vá»›i cURL < 7.44.0" -#: http.c:910 +#: http.c:949 msgid "Protocol restrictions not supported with cURL < 7.19.4" msgstr "Các hạn chế giao thức không được há»— trợ vá»›i cURL < 7.19.4" -#: http.c:1046 +#: http.c:1085 #, 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 " "sau:" -#: http.c:1053 +#: http.c:1092 #, c-format msgid "Could not set SSL backend to '%s': cURL was built without SSL backends" msgstr "" "Không thể đặt ứng dụng chạy SSL phÃa sau “%sâ€: cURL được biên dịch không có " "sá»± há»— trợ ứng dụng chạy phÃa sau SSL" -#: http.c:1057 +#: http.c:1096 #, c-format msgid "Could not set SSL backend to '%s': already set" msgstr "Không thể đặt ứng dụng chạy sau SSL cho “%sâ€: đã đặt rồi" -#: http.c:1921 +#: http.c:1959 #, c-format msgid "" "unable to update url base from redirection:\n" @@ -18557,19 +19601,11 @@ msgstr "" " há»i cho: %s\n" " chuyển hÆ°á»›ng: %s" -#: remote-curl.c:401 +#: remote-curl.c:455 #, c-format msgid "redirecting to %s" msgstr "chuyển hÆ°á»›ng đến %s" -#: list-objects-filter-options.h:60 -msgid "args" -msgstr "các_tham_số" - -#: list-objects-filter-options.h:61 -msgid "object filtering" -msgstr "lá»c đối tượng" - #: parse-options.h:154 msgid "expiry-date" msgstr "ngà y hết hạn" @@ -18578,15 +19614,15 @@ msgstr "ngà y hết hạn" msgid "no-op (backward compatibility)" msgstr "no-op (tÆ°Æ¡ng thÃch ngược)" -#: parse-options.h:261 +#: parse-options.h:259 msgid "be more verbose" msgstr "chi tiết hÆ¡n nữa" -#: parse-options.h:263 +#: parse-options.h:261 msgid "be more quiet" msgstr "im lặng hÆ¡n nữa" -#: parse-options.h:269 +#: parse-options.h:267 msgid "use <n> digits to display SHA-1s" msgstr "sá» dụng <n> chữ số để hiển thị SHA-1s" @@ -18743,8 +19779,8 @@ msgstr "" #: command-list.h:86 msgid "Show changes between commits, commit and working tree, etc" msgstr "" -"Xem các thay đổi giữa những lần chuyển giao, giữa má»™t lần chuyển giao và cây " -"là m việc, v.v.." +"Hiển thị các thay đổi giữa những lần chuyển giao, giữa má»™t lần chuyển giao " +"và cây là m việc, v.v.." #: command-list.h:87 msgid "Compares files in the working tree and the index" @@ -18939,7 +19975,7 @@ msgstr "Tìm các tên liên kết má»m cho Ä‘iểm xét đã cho" #: command-list.h:133 msgid "Add or inspect object notes" -msgstr "thêm hoặc Ä‘iá»u tra đối tượng ghi chú" +msgstr "Thêm hoặc Ä‘iá»u tra đối tượng ghi chú" #: command-list.h:134 msgid "Import from and submit to Perforce repositories" @@ -19220,7 +20256,7 @@ msgstr "Äịnh nghÄ©a thuá»™c tÃnh mô-Ä‘un-con" #: command-list.h:203 msgid "Git namespaces" -msgstr "không gian tên Git" +msgstr "Không gian tên Git" #: command-list.h:204 msgid "Git Repository Layout" @@ -19240,7 +20276,15 @@ msgstr "HÆ°á»›ng dẫn cách dùng Git" #: command-list.h:208 msgid "An overview of recommended workflows with Git" -msgstr "Tổng quan vá» luồng công việc khuyến nghị nên dùng vá»›i Git." +msgstr "Tổng quan vá» luồng công việc khuyến nghị nên dùng vá»›i Git" + +#: list-objects-filter-options.h:63 +msgid "args" +msgstr "các_tham_số" + +#: list-objects-filter-options.h:64 +msgid "object filtering" +msgstr "lá»c đối tượng" #: rerere.h:44 msgid "update the index with reused conflict resolution if possible" @@ -19257,137 +20301,49 @@ msgstr "Bạn cần khởi đầu bằng \"git bisect start\"" msgid "Do you want me to do it for you [Y/n]? " msgstr "Bạn có muốn tôi thá»±c hiện Ä‘iá»u nà y cho bạn không [Y/n]? " -#: git-bisect.sh:121 -#, sh-format -msgid "unrecognised option: '$arg'" -msgstr "không công nháºn tùy chá»n: “$argâ€" - -#: git-bisect.sh:125 -#, sh-format -msgid "'$arg' does not appear to be a valid revision" -msgstr "â€$arg†không có vẻ nhÆ° là má»™t Ä‘iểm xét duyệt hợp lệ" - -#: git-bisect.sh:154 -msgid "Bad HEAD - I need a HEAD" -msgstr "HEAD sai - Tôi cần má»™t HEAD" - -#: git-bisect.sh:167 -#, sh-format -msgid "" -"Checking out '$start_head' failed. Try 'git bisect reset <valid-branch>'." -msgstr "" -"Việc lấy “$start_head†ra gặp lá»—i. Hãy thá» \"git bisect reset <nhánh_hợp_lệ>" -"\"." - -#: git-bisect.sh:177 -msgid "won't bisect on cg-seek'ed tree" -msgstr "sẽ không di chuyển ná»a bÆ°á»›c trên cây được cg-seek" - -#: git-bisect.sh:181 -msgid "Bad HEAD - strange symbolic ref" -msgstr "HEAD sai - tham chiếu má»m kỳ lạ" - -#: git-bisect.sh:233 -#, sh-format -msgid "Bad bisect_write argument: $state" -msgstr "Äối số bisect_write sai: $state" - -#: git-bisect.sh:246 +#: git-bisect.sh:101 #, sh-format msgid "Bad rev input: $arg" msgstr "Äầu và o rev sai: $arg" -#: git-bisect.sh:265 +#: git-bisect.sh:121 #, sh-format msgid "Bad rev input: $bisected_head" msgstr "Äầu và o rev sai: $bisected_head" -#: git-bisect.sh:274 +#: git-bisect.sh:130 #, sh-format msgid "Bad rev input: $rev" msgstr "Äầu và o rev sai: $rev" -#: git-bisect.sh:283 +#: git-bisect.sh:139 #, sh-format msgid "'git bisect $TERM_BAD' can take only one argument." msgstr "“git bisect $TERM_BAD†có thể lấy chỉ má»™t đối số." -#: git-bisect.sh:306 -#, sh-format -msgid "Warning: bisecting only with a $TERM_BAD commit." -msgstr "Cảnh báo: chỉ thá»±c hiện việc bisect vá»›i má»™t lần chuyển giao $TERM_BAD." - -#. TRANSLATORS: Make sure to include [Y] and [n] in your -#. translation. The program will only accept English input -#. at this point. -#: git-bisect.sh:312 -msgid "Are you sure [Y/n]? " -msgstr "Bạn có chắc chắn chÆ°a [Y/n]? " - -#: git-bisect.sh:324 -#, sh-format -msgid "" -"You need to give me at least one $bad_syn and one $good_syn revision.\n" -"(You can use \"git bisect $bad_syn\" and \"git bisect $good_syn\" for that.)" -msgstr "" -"Bạn phải chỉ cho tôi Ãt nhất má»™t Ä‘iểm $bad_syn và má»™t $good_syn.\n" -"(Bạn có thể sá» dụng \"git bisect $bad_syn\" và \"git bisect $good_syn\" cho " -"cái đó.)" - -#: git-bisect.sh:327 -#, sh-format -msgid "" -"You need to start by \"git bisect start\".\n" -"You then need to give me at least one $good_syn and one $bad_syn revision.\n" -"(You can use \"git bisect $bad_syn\" and \"git bisect $good_syn\" for that.)" -msgstr "" -"Bạn cần bắt đầu bằng lệnh \"git bisect start\".\n" -"Bạn sau đó cần phải chỉ cho tôi Ãt nhất má»™t Ä‘iểm xét duyệt $good_syn và má»™t " -"$bad_syn.\n" -"(Bạn có thể sá» dụng \"git bisect $bad_syn\" và \"git bisect $good_syn\" cho " -"chúng.)" - -#: git-bisect.sh:398 git-bisect.sh:512 -msgid "We are not bisecting." -msgstr "Chúng tôi không bisect." - -#: git-bisect.sh:405 -#, sh-format -msgid "'$invalid' is not a valid commit" -msgstr "â€$invalid†không phải là lần chuyển giao hợp lệ" - -#: git-bisect.sh:414 -#, sh-format -msgid "" -"Could not check out original HEAD '$branch'.\n" -"Try 'git bisect reset <commit>'." -msgstr "" -"Không thể check-out HEAD nguyên thủy của “$branchâ€.\n" -"Hãy thỠ“git bisect reset <lần-chuyển-giao>â€." - -#: git-bisect.sh:422 +#: git-bisect.sh:209 msgid "No logfile given" msgstr "ChÆ°a chỉ ra táºp tin ghi nháºt ký" -#: git-bisect.sh:423 +#: git-bisect.sh:210 #, sh-format msgid "cannot read $file for replaying" msgstr "không thể Ä‘á»c $file để thao diá»…n lại" -#: git-bisect.sh:444 +#: git-bisect.sh:232 msgid "?? what are you talking about?" msgstr "?? bạn Ä‘ang nói gì thế?" -#: git-bisect.sh:453 +#: git-bisect.sh:241 msgid "bisect run failed: no command provided." msgstr "bisect chạy gặp lá»—i: không Ä‘Æ°a ra lệnh." -#: git-bisect.sh:458 +#: git-bisect.sh:246 #, sh-format msgid "running $command" msgstr "Ä‘ang chạy lệnh $command" -#: git-bisect.sh:465 +#: git-bisect.sh:253 #, sh-format msgid "" "bisect run failed:\n" @@ -19396,11 +20352,11 @@ msgstr "" "chạy bisect gặp lá»—i:\n" "mã trả vá» $res từ lệnh “$command†là < 0 hoặc >= 128" -#: git-bisect.sh:491 +#: git-bisect.sh:279 msgid "bisect run cannot continue any more" msgstr "bisect không thể tiếp tục thêm được nữa" -#: git-bisect.sh:497 +#: git-bisect.sh:285 #, sh-format msgid "" "bisect run failed:\n" @@ -19409,27 +20365,13 @@ msgstr "" "chạy bisect gặp lá»—i:\n" "â€bisect_state $state†đã thoát ra vá»›i mã lá»—i $res" -#: git-bisect.sh:504 +#: git-bisect.sh:292 msgid "bisect run success" msgstr "bisect chạy thà nh công" -#: git-bisect.sh:533 -#, sh-format -msgid "Invalid command: you're currently in a $TERM_BAD/$TERM_GOOD bisect." -msgstr "Lệnh không hợp lệ: bạn hiện Ä‘ang ở bisect $TERM_BAD/$TERM_GOOD." - -#: git-bisect.sh:567 -msgid "no terms defined" -msgstr "chÆ°a định nghÄ©a thá»i kỳ nà o" - -#: git-bisect.sh:584 -#, sh-format -msgid "" -"invalid argument $arg for 'git bisect terms'.\n" -"Supported options are: --term-good|--term-old and --term-bad|--term-new." -msgstr "" -"tham số không hợp lệ $arg cho “git bisect termsâ€.\n" -"Các tùy chá»n há»— trợ là : --term-good|--term-old và --term-bad|--term-new." +#: git-bisect.sh:300 +msgid "We are not bisecting." +msgstr "Chúng tôi không bisect." #: git-merge-octopus.sh:46 msgid "" @@ -19471,12 +20413,12 @@ msgstr "Äang thá» hòa trá»™n Ä‘Æ¡n giản vá»›i $pretty_name" msgid "Simple merge did not work, trying automatic merge." msgstr "Hòa trá»™n Ä‘Æ¡n giản không là m việc, thá» hòa trá»™n tá»± Ä‘á»™ng." -#: git-legacy-rebase.sh:434 +#: git-legacy-rebase.sh:445 #, sh-format msgid "Could not move back to $head_name" msgstr "Không thể quay trở lại $head_name" -#: git-legacy-rebase.sh:460 +#: git-legacy-rebase.sh:471 #, sh-format msgid "" "It seems that there is already a $state_dir_base directory, and\n" @@ -19497,213 +20439,235 @@ msgstr "" "và chạy TÔI lần nữa. TÔI dừng lại trong trÆ°á»ng hợp bạn vẫn\n" "có má»™t số thứ quý giá ở đây." -#: git-legacy-rebase.sh:525 -msgid "error: cannot combine '--signoff' with '--preserve-merges'" -msgstr "lá»—i: không thể kết hợp “--signoff†vá»›i “--preserve-mergesâ€" +#: git-legacy-rebase.sh:523 +msgid "" +"fatal: cannot combine am options with either interactive or merge options" +msgstr "" +"lá»—i nghiêm trá»ng: không thể tổ hợp các tùy chá»n am vá»›i các tùy chá»n tÆ°Æ¡ng " +"tác hay hòa trá»™n" + +#: git-legacy-rebase.sh:530 +msgid "fatal: cannot combine '--signoff' with '--preserve-merges'" +msgstr "" +"lá»—i nghiêm trá»ng: không thể kết hợp “--signoff†vá»›i “--preserve-mergesâ€" + +#: git-legacy-rebase.sh:541 +msgid "fatal: cannot combine '--preserve-merges' with '--rebase-merges'" +msgstr "" +"lá»—i nghiêm trá»ng: không thể kết hợp “--preserve-merges†vá»›i “--rebase-mergesâ€" + +#: git-legacy-rebase.sh:550 +msgid "fatal: cannot combine '--rebase-merges' with '--strategy-option'" +msgstr "" +"lá»—i nghiêm trá»ng: không thể kết hợp “--rebase-merges†vá»›i “--strategy-optionâ€" + +#: git-legacy-rebase.sh:552 +msgid "fatal: cannot combine '--rebase-merges' with '--strategy'" +msgstr "lá»—i nghiêm trá»ng: không thể kết hợp “--rebase-merges†vá»›i “--strategyâ€" -#: git-legacy-rebase.sh:570 +#: git-legacy-rebase.sh:578 #, sh-format msgid "invalid upstream '$upstream_name'" msgstr "thượng nguồn không hợp lệ “$upstream_nameâ€" -#: git-legacy-rebase.sh:594 +#: git-legacy-rebase.sh:602 #, sh-format msgid "$onto_name: there are more than one merge bases" msgstr "$onto_name: ở đây có nhiá»u hÆ¡n má»™t ná»n móng hòa trá»™n" -#: git-legacy-rebase.sh:597 git-legacy-rebase.sh:601 +#: git-legacy-rebase.sh:605 git-legacy-rebase.sh:609 #, sh-format msgid "$onto_name: there is no merge base" msgstr "$onto_name: ở đây không có ná»n móng hòa trá»™n nà o" -#: git-legacy-rebase.sh:606 +#: git-legacy-rebase.sh:614 #, sh-format msgid "Does not point to a valid commit: $onto_name" msgstr "Không chỉ đến má»™t lần chuyển giao không hợp lệ: $onto_name" -#: git-legacy-rebase.sh:632 +#: git-legacy-rebase.sh:640 #, sh-format msgid "fatal: no such branch/commit '$branch_name'" msgstr "nghiêm trá»ng: không có nhánh nhÆ° thế: “$branch_nameâ€" -#: git-legacy-rebase.sh:670 +#: git-legacy-rebase.sh:678 #, sh-format msgid "Created autostash: $stash_abbrev" msgstr "Äã tạo autostash: $stash_abbrev" -#: git-legacy-rebase.sh:699 +#: git-legacy-rebase.sh:707 #, sh-format msgid "Current branch $branch_name is up to date." msgstr "Nhánh hiện tại $branch_name đã được cáºp nháºt rồi." -#: git-legacy-rebase.sh:709 +#: git-legacy-rebase.sh:717 #, sh-format msgid "Current branch $branch_name is up to date, rebase forced." msgstr "Nhánh hiện tại $branch_name đã được cáºp nháºt rồi, lệnh rebase ép buá»™c." -#: git-legacy-rebase.sh:723 +#: git-legacy-rebase.sh:731 #, sh-format msgid "Changes to $onto:" msgstr "Thay đổi thà nh $onto:" -#: git-legacy-rebase.sh:725 +#: git-legacy-rebase.sh:733 #, sh-format msgid "Changes from $mb to $onto:" msgstr "Thay đổi từ $mb thà nh $onto:" -#: git-legacy-rebase.sh:736 -msgid "First, rewinding head to replay your work on top of it..." -msgstr "TrÆ°á»›c tiên, di chuyển head để xem lại các công việc trên đỉnh của nó…" - -#: git-legacy-rebase.sh:746 +#: git-legacy-rebase.sh:743 #, sh-format msgid "Fast-forwarded $branch_name to $onto_name." msgstr "Chuyển-tiếp-nhanh $branch_name thà nh $onto_name." -#: git-stash.sh:61 +#: git-legacy-rebase.sh:757 +msgid "First, rewinding head to replay your work on top of it..." +msgstr "TrÆ°á»›c tiên, di chuyển head để xem lại các công việc trên đỉnh của nó…" + +#: git-stash.sh:75 msgid "git stash clear with parameters is unimplemented" msgstr "" "git stash clear vá»›i các tham số là chÆ°a được thá»±c hiện (không nháºn đối số)" -#: git-stash.sh:108 +#: git-stash.sh:125 msgid "You do not have the initial commit yet" msgstr "Bạn chÆ°a còn có lần chuyển giao khởi tạo" -#: git-stash.sh:123 +#: git-stash.sh:140 msgid "Cannot save the current index state" msgstr "Không thể ghi lại trạng thái bảng mục lục hiện hà nh" -#: git-stash.sh:138 +#: git-stash.sh:155 msgid "Cannot save the untracked files" msgstr "Không thể ghi lại các táºp tin chÆ°a theo dõi" -#: git-stash.sh:158 git-stash.sh:171 +#: git-stash.sh:175 git-stash.sh:188 msgid "Cannot save the current worktree state" msgstr "Không thể ghi lại trạng thái cây-là m-việc hiện hà nh" -#: git-stash.sh:175 +#: git-stash.sh:192 msgid "No changes selected" msgstr "ChÆ°a có thay đổi nà o được chá»n" -#: git-stash.sh:178 +#: git-stash.sh:195 msgid "Cannot remove temporary index (can't happen)" msgstr "Không thể gỡ bá» bảng mục lục tạm thá»i (không thể xảy ra)" -#: git-stash.sh:191 +#: git-stash.sh:208 msgid "Cannot record working tree state" msgstr "Không thể ghi lại trạng thái cây là m việc hiện hà nh" -#: git-stash.sh:229 +#: git-stash.sh:246 #, sh-format msgid "Cannot update $ref_stash with $w_commit" msgstr "Không thể cáºp nháºt $ref_stash vá»›i $w_commit" -#: git-stash.sh:281 +#: git-stash.sh:298 #, sh-format msgid "error: unknown option for 'stash push': $option" msgstr "lá»—i: không hiểu tùy chá»n cho “stash pushâ€: $option" -#: git-stash.sh:295 +#: git-stash.sh:312 msgid "Can't use --patch and --include-untracked or --all at the same time" -msgstr "Không thể dùng --patch và --include-untracked hay --all cùng má»™t lúc." +msgstr "Không thể dùng --patch và --include-untracked hay --all cùng má»™t lúc" -#: git-stash.sh:303 +#: git-stash.sh:320 msgid "No local changes to save" msgstr "Không có thay đổi ná»™i bá»™ nà o được ghi lại" -#: git-stash.sh:308 +#: git-stash.sh:325 msgid "Cannot initialize stash" msgstr "Không thể khởi tạo stash" -#: git-stash.sh:312 +#: git-stash.sh:329 msgid "Cannot save the current status" msgstr "Không thể ghi lại trạng thái hiện hà nh" -#: git-stash.sh:313 +#: git-stash.sh:330 #, sh-format msgid "Saved working directory and index state $stash_msg" msgstr "Äã ghi lại thÆ° mục là m việc và trạng thái mục lục $stash_msg" -#: git-stash.sh:342 +#: git-stash.sh:359 msgid "Cannot remove worktree changes" msgstr "Không thể gỡ bá» các thay đổi cây-là m-việc" -#: git-stash.sh:490 +#: git-stash.sh:507 #, sh-format msgid "unknown option: $opt" msgstr "không hiểu tùy chá»n: $opt" -#: git-stash.sh:503 +#: git-stash.sh:520 msgid "No stash entries found." msgstr "Không tìm thấy các mục tạm cất (stash) nà o." -#: git-stash.sh:510 +#: git-stash.sh:527 #, sh-format msgid "Too many revisions specified: $REV" msgstr "Chỉ ra quá nhiá»u Ä‘iểm xét duyệt: $REV" -#: git-stash.sh:525 +#: git-stash.sh:542 #, sh-format msgid "$reference is not a valid reference" msgstr "$reference không phải là tham chiếu hợp lệ" -#: git-stash.sh:553 +#: git-stash.sh:570 #, sh-format msgid "'$args' is not a stash-like commit" msgstr "“$args†không phải là lần chuyển giao kiểu-stash (cất Ä‘i)" -#: git-stash.sh:564 +#: git-stash.sh:581 #, sh-format msgid "'$args' is not a stash reference" msgstr "â€$args†không phải tham chiếu đến stash" -#: git-stash.sh:572 +#: git-stash.sh:589 msgid "unable to refresh index" msgstr "không thể là m tÆ°Æ¡i má»›i bảng mục lục" -#: git-stash.sh:576 +#: git-stash.sh:593 msgid "Cannot apply a stash in the middle of a merge" msgstr "Không thể áp dụng má»™t stash ở giữa của quá trình hòa trá»™n" -#: git-stash.sh:584 +#: git-stash.sh:601 msgid "Conflicts in index. Try without --index." msgstr "Xung Ä‘á»™t trong bảng mục lục. Hãy thá» mà không dùng tùy chá»n --index." -#: git-stash.sh:586 +#: git-stash.sh:603 msgid "Could not save index tree" msgstr "Không thể ghi lại cây chỉ mục" -#: git-stash.sh:595 +#: git-stash.sh:612 msgid "Could not restore untracked files from stash entry" msgstr "Không thể phục hồi các táºp tin chÆ°a theo dõi từ mục cất Ä‘i (stash)" -#: git-stash.sh:620 +#: git-stash.sh:637 msgid "Cannot unstage modified files" msgstr "Không thể bá» ra khá»i bệ phóng các táºp tin đã được sá»a chữa" -#: git-stash.sh:635 +#: git-stash.sh:652 msgid "Index was not unstashed." msgstr "Bảng mục lục đã không được bá» stash." -#: git-stash.sh:649 +#: git-stash.sh:666 msgid "The stash entry is kept in case you need it again." msgstr "Các mục tạm cất (stash) được giữ trong trÆ°á»ng hợp bạn lại cần nó." -#: git-stash.sh:658 +#: git-stash.sh:675 #, sh-format msgid "Dropped ${REV} ($s)" msgstr "Äã xóa ${REV} ($s)" -#: git-stash.sh:659 +#: git-stash.sh:676 #, sh-format msgid "${REV}: Could not drop stash entry" msgstr "${REV}: Không thể xóa bá» mục stash" -#: git-stash.sh:667 +#: git-stash.sh:684 msgid "No branch name specified" msgstr "ChÆ°a chỉ ra tên của nhánh" -#: git-stash.sh:746 +#: git-stash.sh:763 msgid "(To restore them type \"git stash apply\")" msgstr "(Äể phục hồi lại chúng hãy gõ \"git stash apply\")" @@ -20711,7 +21675,7 @@ msgstr "nhảy đến hunk nà o (<ret> để xem thêm)? " #: git-add--interactive.perl:1531 msgid "go to which hunk? " -msgstr "nhảy đến hunk nà o?" +msgstr "nhảy đến hunk nà o? " #: git-add--interactive.perl:1540 #, perl-format @@ -21010,7 +21974,7 @@ msgstr "Là m gì vá»›i địa chỉ nà y? (thoát[q]|xóa[d]|sá»a[e]): " #: git-send-email.perl:1329 #, perl-format msgid "CA path \"%s\" does not exist" -msgstr "Ä‘Æ°á»ng dẫn CA “%s†không tồn tại" +msgstr "ÄÆ°á»ng dẫn CA “%s†không tồn tại" #: git-send-email.perl:1412 msgid "" @@ -21167,15 +22131,67 @@ msgstr "Bá» qua %s vá»›i háºu tố sao lÆ°u dá»± phòng “%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): " +#, fuzzy +#~ msgid "--reschedule-failed-exec requires an interactive rebase" +#~ msgstr "%s cần má»™t cải tổ kiểu tÆ°Æ¡ng tác" + +#~ msgid "ignoring unknown color-moved-ws mode '%s'" +#~ msgstr "bá» qua chế Ä‘á»™ color-moved-ws chÆ°a biết “%sâ€" + +#~ msgid "only 'tree:0' is supported" +#~ msgstr "chỉ “tree:0†là được há»— trợ" + +#~ msgid "Renaming %s to %s and %s to %s instead" +#~ msgstr "Äang đổi tên %s thà nh %s thay vì %s thà nh %s" + +#~ msgid "Adding merged %s" +#~ msgstr "Thêm hòa trá»™n %s" + +#~ msgid "Internal error" +#~ msgstr "Lá»—i ná»™i bá»™" + +#~ msgid "mainline was specified but commit %s is not a merge." +#~ msgstr "" +#~ "luồng chÃnh đã được chỉ ra nhÆ°ng lần chuyển giao %s không phải là má»™t lần " +#~ "hòa trá»™n." + +#~ msgid "unable to write sha1 filename %s" +#~ msgstr "không thể ghi và o tên táºp tin sha1 %s" + +#~ msgid "unable to write sha1 file" +#~ msgstr "không thể ghi và o táºp tin sha1" + +#~ msgid "cannot read sha1_file for %s" +#~ msgstr "không thể Ä‘á»c sha1_file cho %s" + +#~ msgid "" +#~ "error: cannot combine interactive options (--interactive, --exec, --" +#~ "rebase-merges, --preserve-merges, --keep-empty, --root + --onto) with am " +#~ "options (%s)" +#~ msgstr "" +#~ "lá»—i: không thể tổ hợp các tùy chá»n tÆ°Æ¡ng tác (--interactive, --exec, --" +#~ "rebase-merges, --preserve-merges, --keep-empty, --root + --onto) vá»›i các " +#~ "tùy chá»n am (%s)" + +#~ msgid "" +#~ "error: cannot combine merge options (--merge, --strategy, --strategy-" +#~ "option) with am options (%s)" +#~ msgstr "" +#~ "lá»—i: không thể kết hợp các tùy chá»n hòa trá»™n (--merge, --strategy, --" +#~ "strategy-option) vá»›i má»™t tùy chá»n am (%s)" + +#~ msgid "unrecognised option: '$arg'" +#~ msgstr "không công nháºn tùy chá»n: “$argâ€" + +#~ msgid "'$invalid' is not a valid commit" +#~ msgstr "â€$invalid†không phải là lần chuyển giao hợp lệ" + #~ msgid "could not parse '%s' (looking for '%s')" #~ msgstr "không thể phân tÃch “%s†(Ä‘ang tìm kiếm cho “%sâ€)" #~ msgid "bad quoting on %s value in '%s'" #~ msgstr "sai trÃch dẫn trên %s giá trị trong “%sâ€" -#~ msgid "Could not unset core.worktree setting in submodule '%s'" -#~ msgstr "Không thể đặt core.worktree trong mô-Ä‘un-con “%sâ€" - #~ msgid "deprecated synonym for --create-reflog" #~ msgstr "đồng nghÄ©a đã lạc háºu cho --create-reflog" @@ -21297,9 +22313,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "could not truncate '%s'" #~ msgstr "không thể cắt cụt “%sâ€" -#~ msgid "could not finish '%s'" -#~ msgstr "không thể hoà n thà nh “%sâ€" - #~ msgid "could not close %s" #~ msgstr "không thể đóng %s" @@ -21396,9 +22409,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid_plural "%s, %" #~ msgstr[0] "%s, %" -#~ msgid "Could not open file '%s'" -#~ msgstr "Không thể mở táºp tin “%sâ€" - #~ msgid "in %0.1f seconds automatically..." #~ msgstr "trong %0.1f giây má»™t cách tá»± Ä‘á»™ng…" @@ -21466,9 +22476,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "ref '%s' does not have %ld components to :strip" #~ msgstr "tham chiếu “%s†không có %ld thà nh phần để mà :strip" -#~ msgid "unknown %.*s format %s" -#~ msgstr "Không hiểu định dạng %.*s %s" - #~ msgid "[%s: gone]" #~ msgstr "[%s: đã ra Ä‘i]" @@ -21557,9 +22564,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "%s: %s" #~ msgstr "%s: %s" -#~ msgid "cannot open %s: %s" -#~ msgstr "không thể mở %s: %s" - #~ msgid "You need to set your committer info first" #~ msgstr "Bạn cần đặt thông tin vá» ngÆ°á»i chuyển giao mã nguồn trÆ°á»›c đã" @@ -21804,9 +22808,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "failed to remove: %s" #~ msgstr "gặp lá»—i khi gỡ bá»: %s" -#~ msgid "The --exec option must be used with the --interactive option" -#~ msgstr "Tùy chá»n --exec phải được sá» dụng cùng vá»›i tùy chá»n --interactive" - #~ msgid "" #~ "Submodule path '$displaypath' not initialized\n" #~ "Maybe you want to use 'update --init'?" @@ -22034,9 +23035,6 @@ msgstr "Bạn có thá»±c sá»± muốn gá»i %s? [y|N](có/KHÔNG): " #~ msgid "%s: cannot lock the ref" #~ msgstr "%s: không thể khóa ref (tham chiếu)" -#~ msgid "%s: cannot update the ref" -#~ msgstr "%s: không thể cáºp nháºt ref (tham chiếu)" - #~ msgid "Failed to lock HEAD during fast_forward_to" #~ msgstr "Gặp lá»—i khi khóa HEAD trong quá trình fast_forward_to" @@ -98,6 +98,10 @@ static void setup_commit_formats(void) { "fuller", CMIT_FMT_FULLER, 0, 8 }, { "full", CMIT_FMT_FULL, 0, 8 }, { "oneline", CMIT_FMT_ONELINE, 1, 0 } + /* + * Please update $__git_log_pretty_formats in + * git-completion.bash when you add new formats. + */ }; commit_formats_len = ARRAY_SIZE(builtin_formats); builtin_formats_len = commit_formats_len; @@ -1057,13 +1061,26 @@ static size_t parse_padding_placeholder(struct strbuf *sb, return 0; } -static int match_placeholder_arg(const char *to_parse, const char *candidate, - const char **end) +static int match_placeholder_arg_value(const char *to_parse, const char *candidate, + const char **end, const char **valuestart, + size_t *valuelen) { const char *p; if (!(skip_prefix(to_parse, candidate, &p))) return 0; + if (valuestart) { + if (*p == '=') { + *valuestart = p + 1; + *valuelen = strcspn(*valuestart, ",)"); + p = *valuestart + *valuelen; + } else { + if (*p != ',' && *p != ')') + return 0; + *valuestart = NULL; + *valuelen = 0; + } + } if (*p == ',') { *end = p + 1; return 1; @@ -1075,6 +1092,47 @@ static int match_placeholder_arg(const char *to_parse, const char *candidate, return 0; } +static int match_placeholder_bool_arg(const char *to_parse, const char *candidate, + const char **end, int *val) +{ + const char *argval; + char *strval; + size_t arglen; + int v; + + if (!match_placeholder_arg_value(to_parse, candidate, end, &argval, &arglen)) + return 0; + + if (!argval) { + *val = 1; + return 1; + } + + strval = xstrndup(argval, arglen); + v = git_parse_maybe_bool(strval); + free(strval); + + if (v == -1) + return 0; + + *val = v; + + return 1; +} + +static int format_trailer_match_cb(const struct strbuf *key, void *ud) +{ + const struct string_list *list = ud; + const struct string_list_item *item; + + for_each_string_list_item (item, list) { + if (key->len == (uintptr_t)item->util && + !strncasecmp(item->string, key->buf, key->len)) + return 1; + } + return 0; +} + static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const char *placeholder, void *context) @@ -1084,10 +1142,14 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ const char *msg = c->message; struct commit_list *p; const char *arg; - int ch; + size_t res; char **slot; /* these are independent of the commit */ + res = strbuf_expand_literal_cb(sb, placeholder, NULL); + if (res) + return res; + switch (placeholder[0]) { case 'C': if (starts_with(placeholder + 1, "(auto)")) { @@ -1106,16 +1168,6 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ */ return ret; } - case 'n': /* newline */ - strbuf_addch(sb, '\n'); - return 1; - case 'x': - /* %x00 == NUL, %x0a == LF, etc. */ - ch = hex2chr(placeholder + 1); - if (ch < 0) - return 0; - strbuf_addch(sb, ch); - return 3; case 'w': if (placeholder[1] == '(') { unsigned long width = 0, indent1 = 0, indent2 = 0; @@ -1322,24 +1374,53 @@ static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ if (skip_prefix(placeholder, "(trailers", &arg)) { struct process_trailer_options opts = PROCESS_TRAILER_OPTIONS_INIT; + struct string_list filter_list = STRING_LIST_INIT_NODUP; + struct strbuf sepbuf = STRBUF_INIT; + size_t ret = 0; opts.no_divider = 1; if (*arg == ':') { arg++; for (;;) { - if (match_placeholder_arg(arg, "only", &arg)) + const char *argval; + size_t arglen; + + if (match_placeholder_arg_value(arg, "key", &arg, &argval, &arglen)) { + uintptr_t len = arglen; + + if (!argval) + goto trailer_out; + + if (len && argval[len - 1] == ':') + len--; + string_list_append(&filter_list, argval)->util = (char *)len; + + opts.filter = format_trailer_match_cb; + opts.filter_data = &filter_list; opts.only_trailers = 1; - else if (match_placeholder_arg(arg, "unfold", &arg)) - opts.unfold = 1; - else + } else if (match_placeholder_arg_value(arg, "separator", &arg, &argval, &arglen)) { + char *fmt; + + strbuf_reset(&sepbuf); + fmt = xstrndup(argval, arglen); + strbuf_expand(&sepbuf, fmt, strbuf_expand_literal_cb, NULL); + free(fmt); + opts.separator = &sepbuf; + } else if (!match_placeholder_bool_arg(arg, "only", &arg, &opts.only_trailers) && + !match_placeholder_bool_arg(arg, "unfold", &arg, &opts.unfold) && + !match_placeholder_bool_arg(arg, "valueonly", &arg, &opts.value_only)) break; } } if (*arg == ')') { format_trailers_from_commit(sb, msg + c->subject_off, &opts); - return arg - placeholder + 1; + ret = arg - placeholder + 1; } + trailer_out: + string_list_clear(&filter_list, 0); + strbuf_release(&sepbuf); + return ret; } return 0; /* unknown placeholder */ diff --git a/reachable.c b/reachable.c index 6e9b810d2a..0d00a91de4 100644 --- a/reachable.c +++ b/reachable.c @@ -12,6 +12,7 @@ #include "packfile.h" #include "worktree.h" #include "object-store.h" +#include "pack-bitmap.h" struct connectivity_progress { struct progress *progress; @@ -158,10 +159,44 @@ int add_unseen_recent_objects_to_traversal(struct rev_info *revs, FOR_EACH_OBJECT_LOCAL_ONLY); } +static void *lookup_object_by_type(struct repository *r, + const struct object_id *oid, + enum object_type type) +{ + switch (type) { + case OBJ_COMMIT: + return lookup_commit(r, oid); + case OBJ_TREE: + return lookup_tree(r, oid); + case OBJ_TAG: + return lookup_tag(r, oid); + case OBJ_BLOB: + return lookup_blob(r, oid); + default: + die("BUG: unknown object type %d", type); + } +} + +static int mark_object_seen(const struct object_id *oid, + enum object_type type, + int exclude, + uint32_t name_hash, + struct packed_git *found_pack, + off_t found_offset) +{ + struct object *obj = lookup_object_by_type(the_repository, oid, type); + if (!obj) + die("unable to create object '%s'", oid_to_hex(oid)); + + obj->flags |= SEEN; + return 0; +} + void mark_reachable_objects(struct rev_info *revs, int mark_reflog, timestamp_t mark_recent, struct progress *progress) { struct connectivity_progress cp; + struct bitmap_index *bitmap_git; /* * Set up revision parsing, and mark us as being interested @@ -188,6 +223,13 @@ void mark_reachable_objects(struct rev_info *revs, int mark_reflog, cp.progress = progress; cp.count = 0; + bitmap_git = prepare_bitmap_walk(revs); + if (bitmap_git) { + traverse_bitmap_commit_list(bitmap_git, mark_object_seen); + free_bitmap_index(bitmap_git); + return; + } + /* * Set up the revision walk - this will move all commits * from the pending list to the commit walking list. diff --git a/read-cache.c b/read-cache.c index 0e0c93edc9..4dc6de1b55 100644 --- a/read-cache.c +++ b/read-cache.c @@ -588,13 +588,19 @@ int remove_index_entry_at(struct index_state *istate, int pos) * CE_REMOVE is set in ce_flags. This is much more effective than * calling remove_index_entry_at() for each entry to be removed. */ -void remove_marked_cache_entries(struct index_state *istate) +void remove_marked_cache_entries(struct index_state *istate, int invalidate) { struct cache_entry **ce_array = istate->cache; unsigned int i, j; for (i = j = 0; i < istate->cache_nr; i++) { if (ce_array[i]->ce_flags & CE_REMOVE) { + if (invalidate) { + cache_tree_invalidate_path(istate, + ce_array[i]->name); + untracked_cache_remove_from_index(istate, + ce_array[i]->name); + } remove_name_hash(istate, ce_array[i]); save_or_free_index_entry(istate, ce_array[i]); } @@ -2220,6 +2226,16 @@ int do_read_index(struct index_state *istate, const char *path, int must_exist) load_index_extensions(&p); } munmap((void *)mmap, mmap_size); + + /* + * TODO trace2: replace "the_repository" with the actual repo instance + * that is associated with the given "istate". + */ + trace2_data_intmax("index", the_repository, "read/version", + istate->version); + trace2_data_intmax("index", the_repository, "read/cache_nr", + istate->cache_nr); + return istate->cache_nr; unmap: @@ -2251,9 +2267,17 @@ int read_index_from(struct index_state *istate, const char *path, if (istate->initialized) return istate->cache_nr; + /* + * TODO trace2: replace "the_repository" with the actual repo instance + * that is associated with the given "istate". + */ + trace2_region_enter_printf("index", "do_read_index", the_repository, + "%s", path); trace_performance_enter(); ret = do_read_index(istate, path, 0); trace_performance_leave("read cache %s", path); + trace2_region_leave_printf("index", "do_read_index", the_repository, + "%s", path); split_index = istate->split_index; if (!split_index || is_null_oid(&split_index->base_oid)) { @@ -2269,7 +2293,11 @@ int read_index_from(struct index_state *istate, const char *path, base_oid_hex = oid_to_hex(&split_index->base_oid); base_path = xstrfmt("%s/sharedindex.%s", gitdir, base_oid_hex); + trace2_region_enter_printf("index", "shared/do_read_index", + the_repository, "%s", base_path); ret = do_read_index(split_index->base, base_path, 1); + trace2_region_leave_printf("index", "shared/do_read_index", + the_repository, "%s", base_path); if (!oideq(&split_index->base_oid, &split_index->base->oid)) die(_("broken index, expect %s in %s, got %s"), base_oid_hex, base_path, @@ -2894,7 +2922,8 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, return -1; } - if (!strip_extensions && istate->split_index) { + if (!strip_extensions && istate->split_index && + !is_null_oid(&istate->split_index->base_oid)) { struct strbuf sb = STRBUF_INIT; err = write_link_extension(&sb, istate) < 0 || @@ -2976,6 +3005,16 @@ static int do_write_index(struct index_state *istate, struct tempfile *tempfile, istate->timestamp.sec = (unsigned int)st.st_mtime; istate->timestamp.nsec = ST_MTIME_NSEC(st); trace_performance_since(start, "write index, changed mask = %x", istate->cache_changed); + + /* + * TODO trace2: replace "the_repository" with the actual repo instance + * that is associated with the given "istate". + */ + trace2_data_intmax("index", the_repository, "write/version", + istate->version); + trace2_data_intmax("index", the_repository, "write/cache_nr", + istate->cache_nr); + return 0; } @@ -2995,7 +3034,18 @@ static int commit_locked_index(struct lock_file *lk) static int do_write_locked_index(struct index_state *istate, struct lock_file *lock, unsigned flags) { - int ret = do_write_index(istate, lock->tempfile, 0); + int ret; + + /* + * TODO trace2: replace "the_repository" with the actual repo instance + * that is associated with the given "istate". + */ + trace2_region_enter_printf("index", "do_write_index", the_repository, + "%s", lock->tempfile->filename.buf); + ret = do_write_index(istate, lock->tempfile, 0); + trace2_region_leave_printf("index", "do_write_index", the_repository, + "%s", lock->tempfile->filename.buf); + if (ret) return ret; if (flags & COMMIT_LOCK) @@ -3080,7 +3130,13 @@ static int write_shared_index(struct index_state *istate, int ret; move_cache_to_base_index(istate); + + trace2_region_enter_printf("index", "shared/do_write_index", + the_repository, "%s", (*temp)->filename.buf); ret = do_write_index(si->base, *temp, 1); + trace2_region_enter_printf("index", "shared/do_write_index", + the_repository, "%s", (*temp)->filename.buf); + if (ret) return ret; ret = adjust_shared_perm(get_tempfile_path(*temp)); @@ -3189,7 +3245,7 @@ int write_locked_index(struct index_state *istate, struct lock_file *lock, ret = write_split_index(istate, lock, flags); /* Freshen the shared index only if the split-index was written */ - if (!ret && !new_shared_index) { + if (!ret && !new_shared_index && !is_null_oid(&si->base_oid)) { const char *shared_index = git_path("sharedindex.%s", oid_to_hex(&si->base_oid)); freshen_shared_index(shared_index, 1); diff --git a/ref-filter.c b/ref-filter.c index 422a9c9ae3..3aca105307 100644 --- a/ref-filter.c +++ b/ref-filter.c @@ -485,6 +485,10 @@ static struct { { "if", SOURCE_NONE, FIELD_STR, if_atom_parser }, { "then", SOURCE_NONE }, { "else", SOURCE_NONE }, + /* + * Please update $__git_ref_fieldlist in git-completion.bash + * when you add new atoms + */ }; #define REF_FORMATTING_STATE_INIT { 0, NULL } @@ -913,7 +917,7 @@ static void grab_common_values(struct atom_value *val, int deref, struct expand_ } /* See grab_values */ -static void grab_tag_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) +static void grab_tag_values(struct atom_value *val, int deref, struct object *obj) { int i; struct tag *tag = (struct tag *) obj; @@ -935,7 +939,7 @@ static void grab_tag_values(struct atom_value *val, int deref, struct object *ob } /* See grab_values */ -static void grab_commit_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) +static void grab_commit_values(struct atom_value *val, int deref, struct object *obj) { int i; struct commit *commit = (struct commit *) obj; @@ -968,7 +972,7 @@ static void grab_commit_values(struct atom_value *val, int deref, struct object } } -static const char *find_wholine(const char *who, int wholen, const char *buf, unsigned long sz) +static const char *find_wholine(const char *who, int wholen, const char *buf) { const char *eol; while (*buf) { @@ -1064,7 +1068,7 @@ static void grab_date(const char *buf, struct atom_value *v, const char *atomnam } /* See grab_values */ -static void grab_person(const char *who, struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) +static void grab_person(const char *who, struct atom_value *val, int deref, void *buf) { int i; int wholen = strlen(who); @@ -1085,7 +1089,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru !starts_with(name + wholen, "date")) continue; if (!wholine) - wholine = find_wholine(who, wholen, buf, sz); + wholine = find_wholine(who, wholen, buf); if (!wholine) return; /* no point looking for it */ if (name[wholen] == 0) @@ -1105,7 +1109,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru if (strcmp(who, "tagger") && strcmp(who, "committer")) return; /* "author" for commit object is not wanted */ if (!wholine) - wholine = find_wholine(who, wholen, buf, sz); + wholine = find_wholine(who, wholen, buf); if (!wholine) return; for (i = 0; i < used_atom_cnt; i++) { @@ -1123,7 +1127,7 @@ static void grab_person(const char *who, struct atom_value *val, int deref, stru } } -static void find_subpos(const char *buf, unsigned long sz, +static void find_subpos(const char *buf, const char **sub, unsigned long *sublen, const char **body, unsigned long *bodylen, unsigned long *nonsiglen, @@ -1192,7 +1196,7 @@ static void append_lines(struct strbuf *out, const char *buf, unsigned long size } /* See grab_values */ -static void grab_sub_body_contents(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) +static void grab_sub_body_contents(struct atom_value *val, int deref, void *buf) { int i; const char *subpos = NULL, *bodypos = NULL, *sigpos = NULL; @@ -1212,7 +1216,7 @@ static void grab_sub_body_contents(struct atom_value *val, int deref, struct obj !starts_with(name, "contents")) continue; if (!subpos) - find_subpos(buf, sz, + find_subpos(buf, &subpos, &sublen, &bodypos, &bodylen, &nonsiglen, &sigpos, &siglen); @@ -1265,19 +1269,19 @@ static void fill_missing_values(struct atom_value *val) * pointed at by the ref itself; otherwise it is the object the * ref (which is a tag) refers to. */ -static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf, unsigned long sz) +static void grab_values(struct atom_value *val, int deref, struct object *obj, void *buf) { switch (obj->type) { case OBJ_TAG: - grab_tag_values(val, deref, obj, buf, sz); - grab_sub_body_contents(val, deref, obj, buf, sz); - grab_person("tagger", val, deref, obj, buf, sz); + grab_tag_values(val, deref, obj); + grab_sub_body_contents(val, deref, buf); + grab_person("tagger", val, deref, buf); break; case OBJ_COMMIT: - grab_commit_values(val, deref, obj, buf, sz); - grab_sub_body_contents(val, deref, obj, buf, sz); - grab_person("author", val, deref, obj, buf, sz); - grab_person("committer", val, deref, obj, buf, sz); + grab_commit_values(val, deref, obj); + grab_sub_body_contents(val, deref, buf); + grab_person("author", val, deref, buf); + grab_person("committer", val, deref, buf); break; case OBJ_TREE: /* grab_tree_values(val, deref, obj, buf, sz); */ @@ -1516,7 +1520,7 @@ static int get_object(struct ref_array_item *ref, int deref, struct object **obj return strbuf_addf_ret(err, -1, _("parse_object_buffer failed on %s for %s"), oid_to_hex(&oi->oid), ref->refname); } - grab_values(ref->value, deref, *obj, oi->content, oi->size); + grab_values(ref->value, deref, *obj, oi->content); } grab_common_values(ref->value, deref, oi); diff --git a/refs/files-backend.c b/refs/files-backend.c index dd8abe9185..ef053f716c 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -2254,8 +2254,7 @@ static int split_head_update(struct ref_update *update, * Note that the new update will itself be subject to splitting when * the iteration gets to it. */ -static int split_symref_update(struct files_ref_store *refs, - struct ref_update *update, +static int split_symref_update(struct ref_update *update, const char *referent, struct ref_transaction *transaction, struct string_list *affected_refnames, @@ -2449,7 +2448,7 @@ static int lock_ref_for_update(struct files_ref_store *refs, * of processing the split-off update, so we * don't have to do it here. */ - ret = split_symref_update(refs, update, + ret = split_symref_update(update, referent.buf, transaction, affected_refnames, err); if (ret) diff --git a/remote-curl.c b/remote-curl.c index bb7421023b..5b44794922 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -505,8 +505,6 @@ static void output_refs(struct ref *refs) struct rpc_state { const char *service_name; - const char **argv; - struct strbuf *stdin_preamble; char *service_url; char *hdr_content_type; char *hdr_accept; @@ -518,25 +516,121 @@ struct rpc_state { int in; int out; int any_written; - struct strbuf result; unsigned gzip_request : 1; unsigned initial_buffer : 1; + + /* + * Whenever a pkt-line is read into buf, append the 4 characters + * denoting its length before appending the payload. + */ + unsigned write_line_lengths : 1; + + /* + * Used by rpc_out; initialize to 0. This is true if a flush has been + * read, but the corresponding line length (if write_line_lengths is + * true) and EOF have not been sent to libcurl. Since each flush marks + * the end of a request, each flush must be completely sent before any + * further reading occurs. + */ + unsigned flush_read_but_not_sent : 1; }; +/* + * Appends the result of reading from rpc->out to the string represented by + * rpc->buf and rpc->len if there is enough space. Returns 1 if there was + * enough space, 0 otherwise. + * + * If rpc->write_line_lengths is true, appends the line length as a 4-byte + * hexadecimal string before appending the result described above. + * + * Writes the total number of bytes appended into appended. + */ +static int rpc_read_from_out(struct rpc_state *rpc, int options, + size_t *appended, + enum packet_read_status *status) { + size_t left; + char *buf; + int pktlen_raw; + + if (rpc->write_line_lengths) { + left = rpc->alloc - rpc->len - 4; + buf = rpc->buf + rpc->len + 4; + } else { + left = rpc->alloc - rpc->len; + buf = rpc->buf + rpc->len; + } + + if (left < LARGE_PACKET_MAX) + return 0; + + *status = packet_read_with_status(rpc->out, NULL, NULL, buf, + left, &pktlen_raw, options); + if (*status != PACKET_READ_EOF) { + *appended = pktlen_raw + (rpc->write_line_lengths ? 4 : 0); + rpc->len += *appended; + } + + if (rpc->write_line_lengths) { + switch (*status) { + case PACKET_READ_EOF: + if (!(options & PACKET_READ_GENTLE_ON_EOF)) + die("shouldn't have EOF when not gentle on EOF"); + break; + case PACKET_READ_NORMAL: + set_packet_header(buf - 4, *appended); + break; + case PACKET_READ_DELIM: + memcpy(buf - 4, "0001", 4); + break; + case PACKET_READ_FLUSH: + memcpy(buf - 4, "0000", 4); + break; + } + } + + return 1; +} + static size_t rpc_out(void *ptr, size_t eltsize, size_t nmemb, void *buffer_) { size_t max = eltsize * nmemb; struct rpc_state *rpc = buffer_; size_t avail = rpc->len - rpc->pos; + enum packet_read_status status; if (!avail) { rpc->initial_buffer = 0; - avail = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0); - if (!avail) - return 0; + rpc->len = 0; rpc->pos = 0; - rpc->len = avail; + if (!rpc->flush_read_but_not_sent) { + if (!rpc_read_from_out(rpc, 0, &avail, &status)) + BUG("The entire rpc->buf should be larger than LARGE_PACKET_MAX"); + if (status == PACKET_READ_FLUSH) + rpc->flush_read_but_not_sent = 1; + } + /* + * If flush_read_but_not_sent is true, we have already read one + * full request but have not fully sent it + EOF, which is why + * we need to refrain from reading. + */ + } + if (rpc->flush_read_but_not_sent) { + if (!avail) { + /* + * The line length either does not need to be sent at + * all or has already been completely sent. Now we can + * return 0, indicating EOF, meaning that the flush has + * been fully sent. + */ + rpc->flush_read_but_not_sent = 0; + return 0; + } + /* + * If avail is non-zerp, the line length for the flush still + * hasn't been fully sent. Proceed with sending the line + * length. + */ } if (max < avail) @@ -664,7 +758,11 @@ static curl_off_t xcurl_off_t(size_t len) return (curl_off_t)size; } -static int post_rpc(struct rpc_state *rpc) +/* + * If flush_received is true, do not attempt to read any more; just use what's + * in rpc->buf. + */ +static int post_rpc(struct rpc_state *rpc, int flush_received) { struct active_request_slot *slot; struct curl_slist *headers = http_copy_default_headers(); @@ -679,21 +777,19 @@ static int post_rpc(struct rpc_state *rpc) * allocated buffer space we can use HTTP/1.0 and avoid the * chunked encoding mess. */ - while (1) { - size_t left = rpc->alloc - rpc->len; - char *buf = rpc->buf + rpc->len; - int n; - - if (left < LARGE_PACKET_MAX) { - large_request = 1; - use_gzip = 0; - break; + if (!flush_received) { + while (1) { + size_t n; + enum packet_read_status status; + + if (!rpc_read_from_out(rpc, 0, &n, &status)) { + large_request = 1; + use_gzip = 0; + break; + } + if (status == PACKET_READ_FLUSH) + break; } - - n = packet_read(rpc->out, NULL, NULL, buf, left, 0); - if (!n) - break; - rpc->len += n; } if (large_request) { @@ -829,22 +925,22 @@ retry: return err; } -static int rpc_service(struct rpc_state *rpc, struct discovery *heads) +static int rpc_service(struct rpc_state *rpc, struct discovery *heads, + const char **client_argv, const struct strbuf *preamble, + struct strbuf *rpc_result) { const char *svc = rpc->service_name; struct strbuf buf = STRBUF_INIT; - struct strbuf *preamble = rpc->stdin_preamble; struct child_process client = CHILD_PROCESS_INIT; int err = 0; client.in = -1; client.out = -1; client.git_cmd = 1; - client.argv = rpc->argv; + client.argv = client_argv; if (start_command(&client)) exit(1); - if (preamble) - write_or_die(client.in, preamble->buf, preamble->len); + write_or_die(client.in, preamble->buf, preamble->len); if (heads) write_or_die(client.in, heads->buf, heads->len); @@ -852,7 +948,6 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) rpc->buf = xmalloc(rpc->alloc); rpc->in = client.in; rpc->out = client.out; - strbuf_init(&rpc->result, 0); strbuf_addf(&buf, "%s%s", url.buf, svc); rpc->service_url = strbuf_detach(&buf, NULL); @@ -874,13 +969,13 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) break; rpc->pos = 0; rpc->len = n; - err |= post_rpc(rpc); + err |= post_rpc(rpc, 0); } close(client.in); client.in = -1; if (!err) { - strbuf_read(&rpc->result, client.out, 0); + strbuf_read(rpc_result, client.out, 0); } else { char buf[4096]; for (;;) @@ -933,6 +1028,7 @@ static int fetch_git(struct discovery *heads, struct strbuf preamble = STRBUF_INIT; int i, err; struct argv_array args = ARGV_ARRAY_INIT; + struct strbuf rpc_result = STRBUF_INIT; argv_array_pushl(&args, "fetch-pack", "--stateless-rpc", "--stdin", "--lock-pack", NULL); @@ -978,14 +1074,12 @@ static int fetch_git(struct discovery *heads, memset(&rpc, 0, sizeof(rpc)); rpc.service_name = "git-upload-pack", - rpc.argv = args.argv; - rpc.stdin_preamble = &preamble; rpc.gzip_request = 1; - err = rpc_service(&rpc, heads); - if (rpc.result.len) - write_or_die(1, rpc.result.buf, rpc.result.len); - strbuf_release(&rpc.result); + err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + if (rpc_result.len) + write_or_die(1, rpc_result.buf, rpc_result.len); + strbuf_release(&rpc_result); strbuf_release(&preamble); argv_array_clear(&args); return err; @@ -1080,6 +1174,7 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) struct argv_array args; struct string_list_item *cas_option; struct strbuf preamble = STRBUF_INIT; + struct strbuf rpc_result = STRBUF_INIT; argv_array_init(&args); argv_array_pushl(&args, "send-pack", "--stateless-rpc", "--helper-status", @@ -1112,13 +1207,11 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) memset(&rpc, 0, sizeof(rpc)); rpc.service_name = "git-receive-pack", - rpc.argv = args.argv; - rpc.stdin_preamble = &preamble; - err = rpc_service(&rpc, heads); - if (rpc.result.len) - write_or_die(1, rpc.result.buf, rpc.result.len); - strbuf_release(&rpc.result); + err = rpc_service(&rpc, heads, args.argv, &preamble, &rpc_result); + if (rpc_result.len) + write_or_die(1, rpc_result.buf, rpc_result.len); + strbuf_release(&rpc_result); strbuf_release(&preamble); argv_array_clear(&args); return err; @@ -1170,165 +1263,11 @@ static void parse_push(struct strbuf *buf) free(specs); } -/* - * Used to represent the state of a connection to an HTTP server when - * communicating using git's wire-protocol version 2. - */ -struct proxy_state { - char *service_name; - char *service_url; - struct curl_slist *headers; - struct strbuf request_buffer; - int in; - int out; - struct packet_reader reader; - size_t pos; - int seen_flush; -}; - -static void proxy_state_init(struct proxy_state *p, const char *service_name, - enum protocol_version version) -{ - struct strbuf buf = STRBUF_INIT; - - memset(p, 0, sizeof(*p)); - p->service_name = xstrdup(service_name); - - p->in = 0; - p->out = 1; - strbuf_init(&p->request_buffer, 0); - - strbuf_addf(&buf, "%s%s", url.buf, p->service_name); - p->service_url = strbuf_detach(&buf, NULL); - - p->headers = http_copy_default_headers(); - - strbuf_addf(&buf, "Content-Type: application/x-%s-request", p->service_name); - p->headers = curl_slist_append(p->headers, buf.buf); - strbuf_reset(&buf); - - strbuf_addf(&buf, "Accept: application/x-%s-result", p->service_name); - p->headers = curl_slist_append(p->headers, buf.buf); - strbuf_reset(&buf); - - p->headers = curl_slist_append(p->headers, "Transfer-Encoding: chunked"); - - /* Add the Git-Protocol header */ - if (get_protocol_http_header(version, &buf)) - p->headers = curl_slist_append(p->headers, buf.buf); - - packet_reader_init(&p->reader, p->in, NULL, 0, - PACKET_READ_GENTLE_ON_EOF | - PACKET_READ_DIE_ON_ERR_PACKET); - - strbuf_release(&buf); -} - -static void proxy_state_clear(struct proxy_state *p) -{ - free(p->service_name); - free(p->service_url); - curl_slist_free_all(p->headers); - strbuf_release(&p->request_buffer); -} - -/* - * CURLOPT_READFUNCTION callback function. - * Attempts to copy over a single packet-line at a time into the - * curl provided buffer. - */ -static size_t proxy_in(char *buffer, size_t eltsize, - size_t nmemb, void *userdata) -{ - size_t max; - struct proxy_state *p = userdata; - size_t avail = p->request_buffer.len - p->pos; - - - if (eltsize != 1) - BUG("curl read callback called with size = %"PRIuMAX" != 1", - (uintmax_t)eltsize); - max = nmemb; - - if (!avail) { - if (p->seen_flush) { - p->seen_flush = 0; - return 0; - } - - strbuf_reset(&p->request_buffer); - switch (packet_reader_read(&p->reader)) { - case PACKET_READ_EOF: - die("unexpected EOF when reading from parent process"); - case PACKET_READ_NORMAL: - packet_buf_write_len(&p->request_buffer, p->reader.line, - p->reader.pktlen); - break; - case PACKET_READ_DELIM: - packet_buf_delim(&p->request_buffer); - break; - case PACKET_READ_FLUSH: - packet_buf_flush(&p->request_buffer); - p->seen_flush = 1; - break; - } - p->pos = 0; - avail = p->request_buffer.len; - } - - if (max < avail) - avail = max; - memcpy(buffer, p->request_buffer.buf + p->pos, avail); - p->pos += avail; - return avail; -} - -static size_t proxy_out(char *buffer, size_t eltsize, - size_t nmemb, void *userdata) -{ - size_t size; - struct proxy_state *p = userdata; - - if (eltsize != 1) - BUG("curl read callback called with size = %"PRIuMAX" != 1", - (uintmax_t)eltsize); - size = nmemb; - - write_or_die(p->out, buffer, size); - return size; -} - -/* Issues a request to the HTTP server configured in `p` */ -static int proxy_request(struct proxy_state *p) -{ - struct active_request_slot *slot; - - slot = get_active_slot(); - - curl_easy_setopt(slot->curl, CURLOPT_ENCODING, ""); - curl_easy_setopt(slot->curl, CURLOPT_NOBODY, 0); - curl_easy_setopt(slot->curl, CURLOPT_POST, 1); - curl_easy_setopt(slot->curl, CURLOPT_URL, p->service_url); - curl_easy_setopt(slot->curl, CURLOPT_HTTPHEADER, p->headers); - - /* Setup function to read request from client */ - curl_easy_setopt(slot->curl, CURLOPT_READFUNCTION, proxy_in); - curl_easy_setopt(slot->curl, CURLOPT_READDATA, p); - - /* Setup function to write server response to client */ - curl_easy_setopt(slot->curl, CURLOPT_WRITEFUNCTION, proxy_out); - curl_easy_setopt(slot->curl, CURLOPT_WRITEDATA, p); - - if (run_slot(slot, NULL) != HTTP_OK) - return -1; - - return 0; -} - static int stateless_connect(const char *service_name) { struct discovery *discover; - struct proxy_state p; + struct rpc_state rpc; + struct strbuf buf = STRBUF_INIT; /* * Run the info/refs request and see if the server supports protocol @@ -1348,23 +1287,58 @@ static int stateless_connect(const char *service_name) fflush(stdout); } - proxy_state_init(&p, service_name, discover->version); + rpc.service_name = service_name; + rpc.service_url = xstrfmt("%s%s", url.buf, rpc.service_name); + rpc.hdr_content_type = xstrfmt("Content-Type: application/x-%s-request", rpc.service_name); + rpc.hdr_accept = xstrfmt("Accept: application/x-%s-result", rpc.service_name); + if (get_protocol_http_header(discover->version, &buf)) { + rpc.protocol_header = strbuf_detach(&buf, NULL); + } else { + rpc.protocol_header = NULL; + strbuf_release(&buf); + } + rpc.buf = xmalloc(http_post_buffer); + rpc.alloc = http_post_buffer; + rpc.len = 0; + rpc.pos = 0; + rpc.in = 1; + rpc.out = 0; + rpc.any_written = 0; + rpc.gzip_request = 1; + rpc.initial_buffer = 0; + rpc.write_line_lengths = 1; + rpc.flush_read_but_not_sent = 0; /* * Dump the capability listing that we got from the server earlier * during the info/refs request. */ - write_or_die(p.out, discover->buf, discover->len); + write_or_die(rpc.in, discover->buf, discover->len); - /* Peek the next packet line. Until we see EOF keep sending POSTs */ - while (packet_reader_peek(&p.reader) != PACKET_READ_EOF) { - if (proxy_request(&p)) { + /* Until we see EOF keep sending POSTs */ + while (1) { + size_t avail; + enum packet_read_status status; + + if (!rpc_read_from_out(&rpc, PACKET_READ_GENTLE_ON_EOF, &avail, + &status)) + BUG("The entire rpc->buf should be larger than LARGE_PACKET_MAX"); + if (status == PACKET_READ_EOF) + break; + if (post_rpc(&rpc, status == PACKET_READ_FLUSH)) /* We would have an err here */ break; - } + /* Reset the buffer for next request */ + rpc.len = 0; } - proxy_state_clear(&p); + free(rpc.service_url); + free(rpc.hdr_content_type); + free(rpc.hdr_accept); + free(rpc.protocol_header); + free(rpc.buf); + strbuf_release(&buf); + return 0; } @@ -1385,6 +1359,13 @@ int cmd_main(int argc, const char **argv) string_list_init(&options.deepen_not, 1); string_list_init(&options.push_options, 1); + /* + * Just report "remote-curl" here (folding all the various aliases + * ("git-remote-http", "git-remote-https", and etc.) here since they + * are all just copies of the same actual executable. + */ + trace2_cmd_name("remote-curl"); + remote = remote_get(argv[1]); if (argc > 2) { diff --git a/repository.c b/repository.c index 65e6f8b8fd..5cad2dcc86 100644 --- a/repository.c +++ b/repository.c @@ -126,6 +126,8 @@ out: void repo_set_worktree(struct repository *repo, const char *path) { repo->worktree = real_pathdup(path, 1); + + trace2_def_repo(repo); } static int read_and_verify_repository_format(struct repository_format *format, diff --git a/repository.h b/repository.h index 8981649d43..4fb6a5885f 100644 --- a/repository.h +++ b/repository.h @@ -92,6 +92,9 @@ struct repository { /* Repository's current hash algorithm, as serialized on disk. */ const struct git_hash_algo *hash_algo; + /* A unique-id for tracing purposes. */ + int trace2_repo_id; + /* Configurations */ /* Indicate if a repository has a different 'commondir' from 'gitdir' */ diff --git a/revision.c b/revision.c index 162d511d46..eb8e51bc63 100644 --- a/revision.c +++ b/revision.c @@ -2151,6 +2151,9 @@ static int handle_revision_opt(struct rev_info *revs, int argc, const char **arg revs->diff = 1; revs->dense_combined_merges = 0; revs->combine_merges = 1; + } else if (!strcmp(arg, "--combined-all-paths")) { + revs->diff = 1; + revs->combined_all_paths = 1; } else if (!strcmp(arg, "--cc")) { revs->diff = 1; revs->dense_combined_merges = 1; @@ -2647,6 +2650,9 @@ int setup_revisions(int argc, const char **argv, struct rev_info *revs, struct s } if (revs->combine_merges) revs->ignore_merges = 0; + if (revs->combined_all_paths && !revs->combine_merges) + die("--combined-all-paths makes no sense without -c or --cc"); + revs->diffopt.abbrev = revs->abbrev; if (revs->line_level_traverse) { diff --git a/revision.h b/revision.h index d32d62abc6..4134dc6029 100644 --- a/revision.h +++ b/revision.h @@ -172,6 +172,7 @@ struct rev_info { verbose_header:1, ignore_merges:1, combine_merges:1, + combined_all_paths:1, dense_combined_merges:1, always_show_header:1; diff --git a/run-command.c b/run-command.c index 3db26b7b0e..3449db319b 100644 --- a/run-command.c +++ b/run-command.c @@ -219,9 +219,29 @@ static int exists_in_PATH(const char *file) int sane_execvp(const char *file, char * const argv[]) { +#ifndef GIT_WINDOWS_NATIVE + /* + * execvp() doesn't return, so we all we can do is tell trace2 + * what we are about to do and let it leave a hint in the log + * (unless of course the execvp() fails). + * + * we skip this for Windows because the compat layer already + * has to emulate the execvp() call anyway. + */ + int exec_id = trace2_exec(file, (const char **)argv); +#endif + if (!execvp(file, argv)) return 0; /* cannot happen ;-) */ +#ifndef GIT_WINDOWS_NATIVE + { + int ec = errno; + trace2_exec_result(exec_id, ec); + errno = ec; + } +#endif + /* * When a command can't be found because one of the directories * listed in $PATH is unsearchable, execvp reports EACCES, but @@ -712,6 +732,7 @@ fail_pipe: cmd->err = fderr[0]; } + trace2_child_start(cmd); trace_run_command(cmd); fflush(NULL); @@ -926,6 +947,8 @@ end_of_spawn: #endif if (cmd->pid < 0) { + trace2_child_exit(cmd, -1); + if (need_in) close_pair(fdin); else if (cmd->in) @@ -964,13 +987,16 @@ end_of_spawn: int finish_command(struct child_process *cmd) { int ret = wait_or_whine(cmd->pid, cmd->argv[0], 0); + trace2_child_exit(cmd, ret); child_process_clear(cmd); return ret; } int finish_command_in_signal(struct child_process *cmd) { - return wait_or_whine(cmd->pid, cmd->argv[0], 1); + int ret = wait_or_whine(cmd->pid, cmd->argv[0], 1); + trace2_child_exit(cmd, ret); + return ret; } @@ -992,8 +1018,19 @@ int run_command_v_opt(const char **argv, int opt) return run_command_v_opt_cd_env(argv, opt, NULL, NULL); } +int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class) +{ + return run_command_v_opt_cd_env_tr2(argv, opt, NULL, NULL, tr2_class); +} + int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env) { + return run_command_v_opt_cd_env_tr2(argv, opt, dir, env, NULL); +} + +int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir, + const char *const *env, const char *tr2_class) +{ struct child_process cmd = CHILD_PROCESS_INIT; cmd.argv = argv; cmd.no_stdin = opt & RUN_COMMAND_NO_STDIN ? 1 : 0; @@ -1004,6 +1041,7 @@ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const cmd.clean_on_exit = opt & RUN_CLEAN_ON_EXIT ? 1 : 0; cmd.dir = dir; cmd.env = env; + cmd.trace2_child_class = tr2_class; return run_command(&cmd); } @@ -1319,6 +1357,7 @@ int run_hook_ve(const char *const *env, const char *name, va_list args) hook.env = env; hook.no_stdin = 1; hook.stdout_to_stderr = 1; + hook.trace2_hook_name = name; return run_command(&hook); } @@ -1807,3 +1846,21 @@ int run_processes_parallel(int n, pp_cleanup(&pp); return 0; } + +int run_processes_parallel_tr2(int n, get_next_task_fn get_next_task, + start_failure_fn start_failure, + task_finished_fn task_finished, void *pp_cb, + const char *tr2_category, const char *tr2_label) +{ + int result; + + trace2_region_enter_printf(tr2_category, tr2_label, NULL, "max:%d", + ((n < 1) ? online_cpus() : n)); + + result = run_processes_parallel(n, get_next_task, start_failure, + task_finished, pp_cb); + + trace2_region_leave(tr2_category, tr2_label, NULL); + + return result; +} diff --git a/run-command.h b/run-command.h index 68f5369fc2..a6950691c0 100644 --- a/run-command.h +++ b/run-command.h @@ -10,6 +10,12 @@ struct child_process { struct argv_array args; struct argv_array env_array; pid_t pid; + + int trace2_child_id; + uint64_t trace2_child_us_start; + const char *trace2_child_class; + const char *trace2_hook_name; + /* * Using .in, .out, .err: * - Specify 0 for no redirections (child inherits stdin, stdout, @@ -73,12 +79,14 @@ extern int run_hook_ve(const char *const *env, const char *name, va_list args); #define RUN_USING_SHELL 16 #define RUN_CLEAN_ON_EXIT 32 int run_command_v_opt(const char **argv, int opt); - +int run_command_v_opt_tr2(const char **argv, int opt, const char *tr2_class); /* * env (the environment) is to be formatted like environ: "VAR=VALUE". * To unset an environment variable use just "VAR". */ int run_command_v_opt_cd_env(const char **argv, int opt, const char *dir, const char *const *env); +int run_command_v_opt_cd_env_tr2(const char **argv, int opt, const char *dir, + const char *const *env, const char *tr2_class); /** * Execute the given command, sending "in" to its stdin, and capturing its @@ -220,5 +228,8 @@ int run_processes_parallel(int n, start_failure_fn, task_finished_fn, void *pp_cb); +int run_processes_parallel_tr2(int n, get_next_task_fn, start_failure_fn, + task_finished_fn, void *pp_cb, + const char *tr2_category, const char *tr2_label); #endif diff --git a/sequencer.c b/sequencer.c index 0db410d590..95dda23eee 100644 --- a/sequencer.c +++ b/sequencer.c @@ -837,7 +837,7 @@ static const char *read_author_ident(struct strbuf *buf) } strbuf_reset(&out); - strbuf_addstr(&out, fmt_ident(name, email, date, 0)); + strbuf_addstr(&out, fmt_ident(name, email, WANT_AUTHOR_IDENT, date, 0)); strbuf_swap(buf, &out); strbuf_release(&out); free(name); @@ -1103,6 +1103,7 @@ static int run_rewrite_hook(const struct object_id *oldoid, proc.argv = argv; proc.in = -1; proc.stdout_to_stderr = 1; + proc.trace2_hook_name = "post-rewrite"; code = start_command(&proc); if (code) @@ -3786,6 +3787,7 @@ cleanup_head_ref: hook.in = open(rebase_path_rewritten_list(), O_RDONLY); hook.stdout_to_stderr = 1; + hook.trace2_hook_name = "post-rewrite"; argv_array_push(&hook.args, post_rewrite_hook); argv_array_push(&hook.args, "rebase"); /* we don't care if this hook failed */ @@ -4098,8 +4100,7 @@ void append_signoff(struct strbuf *msgbuf, size_t ignore_footer, unsigned flag) int has_footer; strbuf_addstr(&sob, sign_off_header); - strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"), - getenv("GIT_COMMITTER_EMAIL"))); + strbuf_addstr(&sob, fmt_name(WANT_COMMITTER_IDENT)); strbuf_addch(&sob, '\n'); if (!ignore_footer) diff --git a/sh-i18n--envsubst.c b/sh-i18n--envsubst.c index 09c6b445b9..cecfdd36c7 100644 --- a/sh-i18n--envsubst.c +++ b/sh-i18n--envsubst.c @@ -14,6 +14,7 @@ */ #include "git-compat-util.h" +#include "trace2.h" /* Substitution of environment variables in shell format strings. Copyright (C) 2003-2007 Free Software Foundation, Inc. @@ -67,6 +68,8 @@ cmd_main (int argc, const char *argv[]) /* Default values for command line options. */ /* unsigned short int show_variables = 0; */ + trace2_cmd_name("sh-i18n--envsubst"); + switch (argc) { case 1: diff --git a/split-index.c b/split-index.c index 5820412dc5..e6154e4ea9 100644 --- a/split-index.c +++ b/split-index.c @@ -162,7 +162,7 @@ void merge_base_index(struct index_state *istate) ewah_each_bit(si->replace_bitmap, replace_entry, istate); ewah_each_bit(si->delete_bitmap, mark_entry_for_delete, istate); if (si->nr_deletions) - remove_marked_cache_entries(istate); + remove_marked_cache_entries(istate, 0); for (i = si->nr_replacements; i < si->saved_cache_nr; i++) { if (!ce_namelen(si->saved_cache[i])) @@ -440,24 +440,26 @@ void add_split_index(struct index_state *istate) void remove_split_index(struct index_state *istate) { if (istate->split_index) { - /* - * When removing the split index, we need to move - * ownership of the mem_pool associated with the - * base index to the main index. There may be cache entries - * allocated from the base's memory pool that are shared with - * the_index.cache[]. - */ - mem_pool_combine(istate->ce_mem_pool, istate->split_index->base->ce_mem_pool); + if (istate->split_index->base) { + /* + * When removing the split index, we need to move + * ownership of the mem_pool associated with the + * base index to the main index. There may be cache entries + * allocated from the base's memory pool that are shared with + * the_index.cache[]. + */ + mem_pool_combine(istate->ce_mem_pool, + istate->split_index->base->ce_mem_pool); - /* - * The split index no longer owns the mem_pool backing - * its cache array. As we are discarding this index, - * mark the index as having no cache entries, so it - * will not attempt to clean up the cache entries or - * validate them. - */ - if (istate->split_index->base) + /* + * The split index no longer owns the mem_pool backing + * its cache array. As we are discarding this index, + * mark the index as having no cache entries, so it + * will not attempt to clean up the cache entries or + * validate them. + */ istate->split_index->base->cache_nr = 0; + } /* * We can discard the split index because its @@ -380,6 +380,27 @@ void strbuf_expand(struct strbuf *sb, const char *format, expand_fn_t fn, } } +size_t strbuf_expand_literal_cb(struct strbuf *sb, + const char *placeholder, + void *context) +{ + int ch; + + switch (placeholder[0]) { + case 'n': /* newline */ + strbuf_addch(sb, '\n'); + return 1; + case 'x': + /* %x00 == NUL, %x0a == LF, etc. */ + ch = hex2chr(placeholder + 1); + if (ch < 0) + return 0; + strbuf_addch(sb, ch); + return 3; + } + return 0; +} + size_t strbuf_expand_dict_cb(struct strbuf *sb, const char *placeholder, void *context) { @@ -321,6 +321,14 @@ void strbuf_expand(struct strbuf *sb, void *context); /** + * Used as callback for `strbuf_expand` to only expand literals + * (i.e. %n and %xNN). The context argument is ignored. + */ +size_t strbuf_expand_literal_cb(struct strbuf *sb, + const char *placeholder, + void *context); + +/** * Used as callback for `strbuf_expand()`, expects an array of * struct strbuf_expand_dict_entry as context, i.e. pairs of * placeholder and replacement string. The array needs to be diff --git a/sub-process.c b/sub-process.c index 8d2a1707cf..3f4af93555 100644 --- a/sub-process.c +++ b/sub-process.c @@ -88,6 +88,7 @@ int subprocess_start(struct hashmap *hashmap, struct subprocess_entry *entry, co process->out = -1; process->clean_on_exit = 1; process->clean_on_exit_handler = subprocess_exit_handler; + process->trace2_child_class = "subprocess"; err = start_command(process); if (err) { diff --git a/submodule-config.c b/submodule-config.c index 52702c62d9..66653e86b9 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -281,7 +281,10 @@ static int parse_fetch_recurse(const char *opt, const char *arg, default: if (!strcmp(arg, "on-demand")) return RECURSE_SUBMODULES_ON_DEMAND; - + /* + * Please update $__git_fetch_recurse_submodules in + * git-completion.bash when you add new options. + */ if (die_on_error) die("bad %s argument: %s", opt, arg); else @@ -362,6 +365,10 @@ static int parse_push_recurse(const char *opt, const char *arg, return RECURSE_SUBMODULES_CHECK; else if (!strcmp(arg, "only")) return RECURSE_SUBMODULES_ONLY; + /* + * Please update $__git_push_recurse_submodules in + * git-completion.bash when you add new modes. + */ else if (die_on_error) die("bad %s argument: %s", opt, arg); else diff --git a/submodule.c b/submodule.c index 934ecfa294..21cf50ca15 100644 --- a/submodule.c +++ b/submodule.c @@ -432,6 +432,10 @@ void handle_ignore_submodules_arg(struct diff_options *diffopt, diffopt->flags.ignore_dirty_submodules = 1; else if (strcmp(arg, "none")) die("bad --ignore-submodules argument: %s", arg); + /* + * Please update _git_status() in git-completion.bash when you + * add new options + */ } static int prepare_submodule_summary(struct rev_info *rev, const char *path, @@ -1609,11 +1613,12 @@ int fetch_populated_submodules(struct repository *r, calculate_changed_submodule_paths(r, &spf.changed_submodule_names); string_list_sort(&spf.changed_submodule_names); - run_processes_parallel(max_parallel_jobs, - get_next_submodule, - fetch_start_failure, - fetch_finish, - &spf); + run_processes_parallel_tr2(max_parallel_jobs, + get_next_submodule, + fetch_start_failure, + fetch_finish, + &spf, + "submodule", "parallel/fetch"); argv_array_clear(&spf.args); out: @@ -932,6 +932,15 @@ library for your script to use. test_oid_init or test_oid_cache. Providing an unknown key is an error. + - yes [<string>] + + This is often seen in modern UNIX but some platforms lack it, so + the test harness overrides the platform implementation with a + more limited one. Use this only when feeding a handful lines of + output to the downstream---unlike the real version, it generates + only up to 99 lines. + + Prerequisites ------------- diff --git a/t/helper/test-parse-options.c b/t/helper/test-parse-options.c index 47fee660b8..cc88fba057 100644 --- a/t/helper/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -2,6 +2,7 @@ #include "cache.h" #include "parse-options.h" #include "string-list.h" +#include "trace2.h" static int boolean = 0; static int integer = 0; @@ -153,6 +154,8 @@ int cmd__parse_options(int argc, const char **argv) int i; int ret = 0; + trace2_cmd_name("_parse_"); + argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0); if (length_cb.called) { diff --git a/t/helper/test-tool.c b/t/helper/test-tool.c index 99db7409b8..53c06932c4 100644 --- a/t/helper/test-tool.c +++ b/t/helper/test-tool.c @@ -1,5 +1,6 @@ #include "git-compat-util.h" #include "test-tool.h" +#include "trace2.h" struct test_cmd { const char *name; @@ -51,6 +52,7 @@ static struct test_cmd cmds[] = { { "submodule-config", cmd__submodule_config }, { "submodule-nested-repo-config", cmd__submodule_nested_repo_config }, { "subprocess", cmd__subprocess }, + { "trace2", cmd__trace2 }, { "urlmatch-normalization", cmd__urlmatch_normalization }, { "xml-encode", cmd__xml_encode }, { "wildmatch", cmd__wildmatch }, @@ -82,6 +84,8 @@ int cmd_main(int argc, const char **argv) if (!strcmp(cmds[i].name, argv[1])) { argv++; argc--; + trace2_cmd_name(cmds[i].name); + trace2_cmd_list_config(); return cmds[i].fn(argc, argv); } } diff --git a/t/helper/test-tool.h b/t/helper/test-tool.h index 25abed1cf2..ffab4d19d7 100644 --- a/t/helper/test-tool.h +++ b/t/helper/test-tool.h @@ -48,6 +48,7 @@ int cmd__string_list(int argc, const char **argv); int cmd__submodule_config(int argc, const char **argv); int cmd__submodule_nested_repo_config(int argc, const char **argv); int cmd__subprocess(int argc, const char **argv); +int cmd__trace2(int argc, const char **argv); int cmd__urlmatch_normalization(int argc, const char **argv); int cmd__xml_encode(int argc, const char **argv); int cmd__wildmatch(int argc, const char **argv); diff --git a/t/helper/test-trace2.c b/t/helper/test-trace2.c new file mode 100644 index 0000000000..197819c872 --- /dev/null +++ b/t/helper/test-trace2.c @@ -0,0 +1,273 @@ +#include "test-tool.h" +#include "cache.h" +#include "argv-array.h" +#include "run-command.h" +#include "exec-cmd.h" +#include "config.h" + +typedef int(fn_unit_test)(int argc, const char **argv); + +struct unit_test { + fn_unit_test *ut_fn; + const char *ut_name; + const char *ut_usage; +}; + +#define MyOk 0 +#define MyError 1 + +static int get_i(int *p_value, const char *data) +{ + char *endptr; + + if (!data || !*data) + return MyError; + + *p_value = strtol(data, &endptr, 10); + if (*endptr || errno == ERANGE) + return MyError; + + return MyOk; +} + +/* + * Cause process to exit with the requested value via "return". + * + * Rely on test-tool.c:cmd_main() to call trace2_cmd_exit() + * with our result. + * + * Test harness can confirm: + * [] the process-exit value. + * [] the "code" field in the "exit" trace2 event. + * [] the "code" field in the "atexit" trace2 event. + * [] the "name" field in the "cmd_name" trace2 event. + * [] "def_param" events for all of the "interesting" pre-defined + * config settings. + */ +static int ut_001return(int argc, const char **argv) +{ + int rc; + + if (get_i(&rc, argv[0])) + die("expect <exit_code>"); + + return rc; +} + +/* + * Cause the process to exit with the requested value via "exit()". + * + * Test harness can confirm: + * [] the "code" field in the "exit" trace2 event. + * [] the "code" field in the "atexit" trace2 event. + * [] the "name" field in the "cmd_name" trace2 event. + * [] "def_param" events for all of the "interesting" pre-defined + * config settings. + */ +static int ut_002exit(int argc, const char **argv) +{ + int rc; + + if (get_i(&rc, argv[0])) + die("expect <exit_code>"); + + exit(rc); +} + +/* + * Send an "error" event with each value in argv. Normally, git only issues + * a single "error" event immediately before issuing an "exit" event (such + * as in die() or BUG()), but multiple "error" events are allowed. + * + * Test harness can confirm: + * [] a trace2 "error" event for each value in argv. + * [] the "name" field in the "cmd_name" trace2 event. + * [] (optional) the file:line in the "exit" event refers to this function. + */ +static int ut_003error(int argc, const char **argv) +{ + int k; + + if (!argv[0] || !*argv[0]) + die("expect <error_message>"); + + for (k = 0; k < argc; k++) + error("%s", argv[k]); + + return 0; +} + +/* + * Run a child process and wait for it to finish and exit with its return code. + * test-tool trace2 004child [<child-command-line>] + * + * For example: + * test-tool trace2 004child git version + * test-tool trace2 004child test-tool trace2 001return 0 + * test-tool trace2 004child test-tool trace2 004child test-tool trace2 004child + * test-tool trace2 004child git -c alias.xyz=version xyz + * + * Test harness can confirm: + * [] the "name" field in the "cmd_name" trace2 event. + * [] that the outer process has a single component SID (or depth "d0" in + * the PERF stream). + * [] that "child_start" and "child_exit" events are generated for the child. + * [] if the child process is an instrumented executable: + * [] that "version", "start", ..., "exit", and "atexit" events are + * generated by the child process. + * [] that the child process events have a multiple component SID (or + * depth "dN+1" in the PERF stream). + * [] that the child exit code is propagated to the parent process "exit" + * and "atexit" events.. + * [] (optional) that the "t_abs" field in the child process "atexit" event + * is less than the "t_rel" field in the "child_exit" event of the parent + * process. + * [] if the child process is like the alias example above, + * [] (optional) the child process attempts to run "git-xyx" as a dashed + * command. + * [] the child process emits an "alias" event with "xyz" => "version" + * [] the child process runs "git version" as a child process. + * [] the child process has a 3 component SID (or depth "d2" in the PERF + * stream). + */ +static int ut_004child(int argc, const char **argv) +{ + int result; + + /* + * Allow empty <child_command_line> so we can do arbitrarily deep + * command nesting and let the last one be null. + */ + if (!argc) + return 0; + + result = run_command_v_opt(argv, 0); + exit(result); +} + +/* + * Exec a git command. This may either create a child process (Windows) + * or replace the existing process. + * test-tool trace2 005exec <git_command_args> + * + * For example: + * test-tool trace2 005exec version + * + * Test harness can confirm (on Windows): + * [] the "name" field in the "cmd_name" trace2 event. + * [] that the outer process has a single component SID (or depth "d0" in + * the PERF stream). + * [] that "exec" and "exec_result" events are generated for the child + * process (since the Windows compatibility layer fakes an exec() with + * a CreateProcess(), WaitForSingleObject(), and exit()). + * [] that the child process has multiple component SID (or depth "dN+1" + * in the PERF stream). + * + * Test harness can confirm (on platforms with a real exec() function): + * [] TODO talk about process replacement and how it affects SID. + */ +static int ut_005exec(int argc, const char **argv) +{ + int result; + + if (!argc) + return 0; + + result = execv_git_cmd(argv); + return result; +} + +static int ut_006data(int argc, const char **argv) +{ + const char *usage_error = + "expect <cat0> <k0> <v0> [<cat1> <k1> <v1> [...]]"; + + if (argc % 3 != 0) + die("%s", usage_error); + + while (argc) { + if (!argv[0] || !*argv[0] || !argv[1] || !*argv[1] || + !argv[2] || !*argv[2]) + die("%s", usage_error); + + trace2_data_string(argv[0], the_repository, argv[1], argv[2]); + argv += 3; + argc -= 3; + } + + return 0; +} + +/* + * Usage: + * test-tool trace2 <ut_name_1> <ut_usage_1> + * test-tool trace2 <ut_name_2> <ut_usage_2> + * ... + */ +#define USAGE_PREFIX "test-tool trace2" + +/* clang-format off */ +static struct unit_test ut_table[] = { + { ut_001return, "001return", "<exit_code>" }, + { ut_002exit, "002exit", "<exit_code>" }, + { ut_003error, "003error", "<error_message>+" }, + { ut_004child, "004child", "[<child_command_line>]" }, + { ut_005exec, "005exec", "<git_command_args>" }, + { ut_006data, "006data", "[<category> <key> <value>]+" }, +}; +/* clang-format on */ + +/* clang-format off */ +#define for_each_ut(k, ut_k) \ + for (k = 0, ut_k = &ut_table[k]; \ + k < ARRAY_SIZE(ut_table); \ + k++, ut_k = &ut_table[k]) +/* clang-format on */ + +static int print_usage(void) +{ + int k; + struct unit_test *ut_k; + + fprintf(stderr, "usage:\n"); + for_each_ut (k, ut_k) + fprintf(stderr, "\t%s %s %s\n", USAGE_PREFIX, ut_k->ut_name, + ut_k->ut_usage); + + return 129; +} + +/* + * Issue various trace2 events for testing. + * + * We assume that these trace2 routines has already been called: + * [] trace2_initialize() [common-main.c:main()] + * [] trace2_cmd_start() [common-main.c:main()] + * [] trace2_cmd_name() [test-tool.c:cmd_main()] + * [] tracd2_cmd_list_config() [test-tool.c:cmd_main()] + * So that: + * [] the various trace2 streams are open. + * [] the process SID has been created. + * [] the "version" event has been generated. + * [] the "start" event has been generated. + * [] the "cmd_name" event has been generated. + * [] this writes various "def_param" events for interesting config values. + * + * We further assume that if we return (rather than exit()), trace2_cmd_exit() + * will be called by test-tool.c:cmd_main(). + */ +int cmd__trace2(int argc, const char **argv) +{ + int k; + struct unit_test *ut_k; + + argc--; /* skip over "trace2" arg */ + argv++; + + if (argc) + for_each_ut (k, ut_k) + if (!strcmp(argv[0], ut_k->ut_name)) + return ut_k->ut_fn(argc - 1, argv + 1); + + return print_usage(); +} diff --git a/t/perf/p5304-prune.sh b/t/perf/p5304-prune.sh new file mode 100755 index 0000000000..83baedb8a4 --- /dev/null +++ b/t/perf/p5304-prune.sh @@ -0,0 +1,35 @@ +#!/bin/sh + +test_description='performance tests of prune' +. ./perf-lib.sh + +test_perf_default_repo + +test_expect_success 'remove reachable loose objects' ' + git repack -ad +' + +test_expect_success 'remove unreachable loose objects' ' + git prune +' + +test_expect_success 'confirm there are no loose objects' ' + git count-objects | grep ^0 +' + +test_perf 'prune with no objects' ' + git prune +' + +test_expect_success 'repack with bitmaps' ' + git repack -adb +' + +# We have to create the object in each trial run, since otherwise +# runs after the first see no object and just skip the traversal entirely! +test_perf 'prune with bitmaps' ' + echo "probably not present in repo" | git hash-object -w --stdin && + git prune +' + +test_done diff --git a/t/t0001-init.sh b/t/t0001-init.sh index 42a263cada..5e27604b24 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -93,6 +93,7 @@ test_expect_success 'No extra GIT_* on alias scripts' ' sed -n \ -e "/^GIT_PREFIX=/d" \ -e "/^GIT_TEXTDOMAINDIR=/d" \ + -e "/^GIT_TR2_PARENT/d" \ -e "/^GIT_/s/=.*//p" | sort EOF diff --git a/t/t0210-trace2-normal.sh b/t/t0210-trace2-normal.sh new file mode 100755 index 0000000000..03a0aedb1d --- /dev/null +++ b/t/t0210-trace2-normal.sh @@ -0,0 +1,135 @@ +#!/bin/sh + +test_description='test trace2 facility (normal target)' +. ./test-lib.sh + +# Add t/helper directory to PATH so that we can use a relative +# path to run nested instances of test-tool.exe (see 004child). +# This helps with HEREDOC comparisons later. +TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR +PATH="$TTDIR:$PATH" && export PATH + +# Warning: use of 'test_cmp' may run test-tool.exe and/or git.exe +# Warning: to do the actual diff/comparison, so the HEREDOCs here +# Warning: only cover our actual calls to test-tool and/or git. +# Warning: So you may see extra lines in artifact files when +# Warning: interactively debugging. + +# Turn off any inherited trace2 settings for this test. +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT +unset GIT_TR2_BRIEF +unset GIT_TR2_CONFIG_PARAMS + +V=$(git version | sed -e 's/^git version //') && export V + +# There are multiple trace2 targets: normal, perf, and event. +# Trace2 events will/can be written to each active target (subject +# to whatever filtering that target decides to do). +# This script tests the normal target in isolation. +# +# Defer setting GIT_TR2 until the actual command line we want to test +# because hidden git and test-tool commands run by the test harness +# can contaminate our output. + +# Enable "brief" feature which turns off "<clock> <file>:<line> " prefix. +GIT_TR2_BRIEF=1 && export GIT_TR2_BRIEF + +# Basic tests of the trace2 normal stream. Since this stream is used +# primarily with printf-style debugging/tracing, we do limited testing +# here. +# +# We do confirm the following API features: +# [] the 'version <v>' event +# [] the 'start <argv>' event +# [] the 'cmd_name <name>' event +# [] the 'exit <time> code:<code>' event +# [] the 'atexit <time> code:<code>' event +# +# Fields of the form _FIELD_ are tokens that have been replaced (such +# as the elapsed time). + +# Verb 001return +# +# Implicit return from cmd_<verb> function propagates <code>. + +test_expect_success 'normal stream, return code 0' ' + test_when_finished "rm trace.normal actual expect" && + GIT_TR2="$(pwd)/trace.normal" test-tool trace2 001return 0 && + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 001return 0 + cmd_name trace2 (trace2) + exit elapsed:_TIME_ code:0 + atexit elapsed:_TIME_ code:0 + EOF + test_cmp expect actual +' + +test_expect_success 'normal stream, return code 1' ' + test_when_finished "rm trace.normal actual expect" && + test_must_fail env GIT_TR2="$(pwd)/trace.normal" test-tool trace2 001return 1 && + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 001return 1 + cmd_name trace2 (trace2) + exit elapsed:_TIME_ code:1 + atexit elapsed:_TIME_ code:1 + EOF + test_cmp expect actual +' + +# Verb 002exit +# +# Explicit exit(code) from within cmd_<verb> propagates <code>. + +test_expect_success 'normal stream, exit code 0' ' + test_when_finished "rm trace.normal actual expect" && + GIT_TR2="$(pwd)/trace.normal" test-tool trace2 002exit 0 && + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 002exit 0 + cmd_name trace2 (trace2) + exit elapsed:_TIME_ code:0 + atexit elapsed:_TIME_ code:0 + EOF + test_cmp expect actual +' + +test_expect_success 'normal stream, exit code 1' ' + test_when_finished "rm trace.normal actual expect" && + test_must_fail env GIT_TR2="$(pwd)/trace.normal" test-tool trace2 002exit 1 && + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 002exit 1 + cmd_name trace2 (trace2) + exit elapsed:_TIME_ code:1 + atexit elapsed:_TIME_ code:1 + EOF + test_cmp expect actual +' + +# Verb 003error +# +# To the above, add multiple 'error <msg>' events + +test_expect_success 'normal stream, error event' ' + test_when_finished "rm trace.normal actual expect" && + GIT_TR2="$(pwd)/trace.normal" test-tool trace2 003error "hello world" "this is a test" && + perl "$TEST_DIRECTORY/t0210/scrub_normal.perl" <trace.normal >actual && + cat >expect <<-EOF && + version $V + start _EXE_ trace2 003error '\''hello world'\'' '\''this is a test'\'' + cmd_name trace2 (trace2) + error hello world + error this is a test + exit elapsed:_TIME_ code:0 + atexit elapsed:_TIME_ code:0 + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t0210/scrub_normal.perl b/t/t0210/scrub_normal.perl new file mode 100644 index 0000000000..c65d1a815e --- /dev/null +++ b/t/t0210/scrub_normal.perl @@ -0,0 +1,48 @@ +#!/usr/bin/perl +# +# Scrub the variable fields from the normal trace2 output to +# make testing easier. + +use strict; +use warnings; + +my $float = '[0-9]*\.[0-9]+([eE][-+]?[0-9]+)?'; + +# This code assumes that the trace2 data was written with bare +# turned on (which omits the "<clock> <file>:<line>" prefix. + +while (<>) { + # Various messages include an elapsed time in the middle + # of the message. Replace the time with a placeholder to + # simplify our HEREDOC in the test script. + s/elapsed:$float/elapsed:_TIME_/g; + + my $line = $_; + + # we expect: + # start <argv0> [<argv1> [<argv2> [...]]] + # + # where argv0 might be a relative or absolute path, with + # or without quotes, and platform dependent. Replace argv0 + # with a token for HEREDOC matching in the test script. + + if ($line =~ m/^start/) { + $line =~ /^start\s+(.*)/; + my $argv = $1; + $argv =~ m/(\'[^\']*\'|[^ ]+)\s+(.*)/; + my $argv_0 = $1; + my $argv_rest = $2; + + print "start _EXE_ $argv_rest\n"; + } + elsif ($line =~ m/^cmd_path/) { + # Likewise, the 'cmd_path' message breaks out argv[0]. + # + # This line is only emitted when RUNTIME_PREFIX is defined, + # so just omit it for testing purposes. + # print "cmd_path _EXE_\n"; + } + else { + print "$line"; + } +} diff --git a/t/t0211-trace2-perf.sh b/t/t0211-trace2-perf.sh new file mode 100755 index 0000000000..953e2f7847 --- /dev/null +++ b/t/t0211-trace2-perf.sh @@ -0,0 +1,153 @@ +#!/bin/sh + +test_description='test trace2 facility (perf target)' +. ./test-lib.sh + +# Add t/helper directory to PATH so that we can use a relative +# path to run nested instances of test-tool.exe (see 004child). +# This helps with HEREDOC comparisons later. +TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR +PATH="$TTDIR:$PATH" && export PATH + +# Warning: use of 'test_cmp' may run test-tool.exe and/or git.exe +# Warning: to do the actual diff/comparison, so the HEREDOCs here +# Warning: only cover our actual calls to test-tool and/or git. +# Warning: So you may see extra lines in artifact files when +# Warning: interactively debugging. + +# Turn off any inherited trace2 settings for this test. +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT +unset GIT_TR2_PERF_BRIEF +unset GIT_TR2_CONFIG_PARAMS + +V=$(git version | sed -e 's/^git version //') && export V + +# There are multiple trace2 targets: normal, perf, and event. +# Trace2 events will/can be written to each active target (subject +# to whatever filtering that target decides to do). +# Test each target independently. +# +# Defer setting GIT_TR2_PERF until the actual command we want to +# test because hidden git and test-tool commands in the test +# harness can contaminate our output. + +# Enable "brief" feature which turns off the prefix: +# "<clock> <file>:<line> | <nr_parents> | " +GIT_TR2_PERF_BRIEF=1 && export GIT_TR2_PERF_BRIEF + +# Repeat some of the t0210 tests using the perf target stream instead of +# the normal stream. +# +# Tokens here of the form _FIELD_ have been replaced in the observed output. + +# Verb 001return +# +# Implicit return from cmd_<verb> function propagates <code>. + +test_expect_success 'perf stream, return code 0' ' + test_when_finished "rm trace.perf actual expect" && + GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 0 && + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && + cat >expect <<-EOF && + d0|main|version|||||$V + d0|main|start|||||_EXE_ trace2 001return 0 + d0|main|cmd_name|||||trace2 (trace2) + d0|main|exit||_T_ABS_|||code:0 + d0|main|atexit||_T_ABS_|||code:0 + EOF + test_cmp expect actual +' + +test_expect_success 'perf stream, return code 1' ' + test_when_finished "rm trace.perf actual expect" && + test_must_fail env GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 001return 1 && + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && + cat >expect <<-EOF && + d0|main|version|||||$V + d0|main|start|||||_EXE_ trace2 001return 1 + d0|main|cmd_name|||||trace2 (trace2) + d0|main|exit||_T_ABS_|||code:1 + d0|main|atexit||_T_ABS_|||code:1 + EOF + test_cmp expect actual +' + +# Verb 003error +# +# To the above, add multiple 'error <msg>' events + +test_expect_success 'perf stream, error event' ' + test_when_finished "rm trace.perf actual expect" && + GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 003error "hello world" "this is a test" && + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && + cat >expect <<-EOF && + d0|main|version|||||$V + d0|main|start|||||_EXE_ trace2 003error '\''hello world'\'' '\''this is a test'\'' + d0|main|cmd_name|||||trace2 (trace2) + d0|main|error|||||hello world + d0|main|error|||||this is a test + d0|main|exit||_T_ABS_|||code:0 + d0|main|atexit||_T_ABS_|||code:0 + EOF + test_cmp expect actual +' + +# Verb 004child +# +# Test nested spawning of child processes. +# +# Conceptually, this looks like: +# P1: TT trace2 004child +# P2: |--- TT trace2 004child +# P3: |--- TT trace2 001return 0 +# +# Which should generate events: +# P1: version +# P1: start +# P1: cmd_name +# P1: child_start +# P2: version +# P2: start +# P2: cmd_name +# P2: child_start +# P3: version +# P3: start +# P3: cmd_name +# P3: exit +# P3: atexit +# P2: child_exit +# P2: exit +# P2: atexit +# P1: child_exit +# P1: exit +# P1: atexit + +test_expect_success 'perf stream, child processes' ' + test_when_finished "rm trace.perf actual expect" && + GIT_TR2_PERF="$(pwd)/trace.perf" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && + perl "$TEST_DIRECTORY/t0211/scrub_perf.perl" <trace.perf >actual && + cat >expect <<-EOF && + d0|main|version|||||$V + d0|main|start|||||_EXE_ trace2 004child test-tool trace2 004child test-tool trace2 001return 0 + d0|main|cmd_name|||||trace2 (trace2) + d0|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 004child test-tool trace2 001return 0 + d1|main|version|||||$V + d1|main|start|||||_EXE_ trace2 004child test-tool trace2 001return 0 + d1|main|cmd_name|||||trace2 (trace2/trace2) + d1|main|child_start||_T_ABS_|||[ch0] class:? argv: test-tool trace2 001return 0 + d2|main|version|||||$V + d2|main|start|||||_EXE_ trace2 001return 0 + d2|main|cmd_name|||||trace2 (trace2/trace2/trace2) + d2|main|exit||_T_ABS_|||code:0 + d2|main|atexit||_T_ABS_|||code:0 + d1|main|child_exit||_T_ABS_|_T_REL_||[ch0] pid:_PID_ code:0 + d1|main|exit||_T_ABS_|||code:0 + d1|main|atexit||_T_ABS_|||code:0 + d0|main|child_exit||_T_ABS_|_T_REL_||[ch0] pid:_PID_ code:0 + d0|main|exit||_T_ABS_|||code:0 + d0|main|atexit||_T_ABS_|||code:0 + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t0211/scrub_perf.perl b/t/t0211/scrub_perf.perl new file mode 100644 index 0000000000..351af7844e --- /dev/null +++ b/t/t0211/scrub_perf.perl @@ -0,0 +1,76 @@ +#!/usr/bin/perl +# +# Scrub the variable fields from the perf trace2 output to +# make testing easier. + +use strict; +use warnings; + +my $qpath = '\'[^\']*\'|[^ ]*'; + +my $col_depth=0; +my $col_thread=1; +my $col_event=2; +my $col_repo=3; +my $col_t_abs=4; +my $col_t_rel=5; +my $col_category=6; +my $col_rest=7; + +# This code assumes that the trace2 data was written with bare +# turned on (which omits the "<clock> <file>:<line> | <parents>" +# prefix. + +while (<>) { + my @tokens = split /\|/; + + foreach my $col (@tokens) { $col =~ s/^\s+|\s+$//g; } + + if ($tokens[$col_event] =~ m/^start/) { + # The 'start' message lists the contents of argv in $col_rest. + # On some platforms (Windows), argv[0] is *sometimes* a canonical + # absolute path to the EXE rather than the value passed in the + # shell script. Replace it with a placeholder to simplify our + # HEREDOC in the test script. + my $argv0; + my $argvRest; + $tokens[$col_rest] =~ s/^($qpath)\W*(.*)/_EXE_ $2/; + } + elsif ($tokens[$col_event] =~ m/cmd_path/) { + # Likewise, the 'cmd_path' message breaks out argv[0]. + # + # This line is only emitted when RUNTIME_PREFIX is defined, + # so just omit it for testing purposes. + # $tokens[$col_rest] = "_EXE_"; + goto SKIP_LINE; + } + elsif ($tokens[$col_event] =~ m/child_exit/) { + $tokens[$col_rest] =~ s/ pid:\d* / pid:_PID_ /; + } + elsif ($tokens[$col_event] =~ m/data/) { + if ($tokens[$col_category] =~ m/process/) { + # 'data' and 'data_json' events containing 'process' + # category data are assumed to be platform-specific + # and highly variable. Just omit them. + goto SKIP_LINE; + } + } + + # t_abs and t_rel are either blank or a float. Replace the float + # with a constant for matching the HEREDOC in the test script. + if ($tokens[$col_t_abs] =~ m/\d/) { + $tokens[$col_t_abs] = "_T_ABS_"; + } + if ($tokens[$col_t_rel] =~ m/\d/) { + $tokens[$col_t_rel] = "_T_REL_"; + } + + my $out; + + $out = join('|', @tokens); + print "$out\n"; + + SKIP_LINE: +} + + diff --git a/t/t0212-trace2-event.sh b/t/t0212-trace2-event.sh new file mode 100755 index 0000000000..028b6c5671 --- /dev/null +++ b/t/t0212-trace2-event.sh @@ -0,0 +1,236 @@ +#!/bin/sh + +test_description='test trace2 facility' +. ./test-lib.sh + +perl -MJSON::PP -e 0 >/dev/null 2>&1 && test_set_prereq JSON_PP + +# Add t/helper directory to PATH so that we can use a relative +# path to run nested instances of test-tool.exe (see 004child). +# This helps with HEREDOC comparisons later. +TTDIR="$GIT_BUILD_DIR/t/helper/" && export TTDIR +PATH="$TTDIR:$PATH" && export PATH + +# Warning: use of 'test_cmp' may run test-tool.exe and/or git.exe +# Warning: to do the actual diff/comparison, so the HEREDOCs here +# Warning: only cover our actual calls to test-tool and/or git. +# Warning: So you may see extra lines in artifact files when +# Warning: interactively debugging. + +# Turn off any inherited trace2 settings for this test. +unset GIT_TR2 GIT_TR2_PERF GIT_TR2_EVENT +unset GIT_TR2_BARE +unset GIT_TR2_CONFIG_PARAMS + +V=$(git version | sed -e 's/^git version //') && export V + +# There are multiple trace2 targets: normal, perf, and event. +# Trace2 events will/can be written to each active target (subject +# to whatever filtering that target decides to do). +# Test each target independently. +# +# Defer setting GIT_TR2_PERF until the actual command we want to +# test because hidden git and test-tool commands in the test +# harness can contaminate our output. + +# We don't bother repeating the 001return and 002exit tests, since they +# have coverage in the normal and perf targets. + +# Verb 003error +# +# To the above, add multiple 'error <msg>' events + +test_expect_success JSON_PP 'event stream, error event' ' + test_when_finished "rm trace.event actual expect" && + GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 003error "hello world" "this is a test" && + perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && + sed -e "s/^|//" >expect <<-EOF && + |VAR1 = { + | "_SID0_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "003error", + | "hello world", + | "this is a test" + | ], + | "errors":[ + | "%s", + | "%s" + | ], + | "exit_code":0, + | "hierarchy":"trace2", + | "name":"trace2", + | "version":"$V" + | } + |}; + EOF + test_cmp expect actual +' + +# Verb 004child +# +# Test nested spawning of child processes. +# +# Conceptually, this looks like: +# P1: TT trace2 004child +# P2: |--- TT trace2 004child +# P3: |--- TT trace2 001return 0 + +test_expect_success JSON_PP 'event stream, return code 0' ' + test_when_finished "rm trace.event actual expect" && + GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 004child test-tool trace2 004child test-tool trace2 001return 0 && + perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && + sed -e "s/^|//" >expect <<-EOF && + |VAR1 = { + | "_SID0_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "004child", + | "test-tool", + | "trace2", + | "004child", + | "test-tool", + | "trace2", + | "001return", + | "0" + | ], + | "child":{ + | "0":{ + | "child_argv":[ + | "_EXE_", + | "trace2", + | "004child", + | "test-tool", + | "trace2", + | "001return", + | "0" + | ], + | "child_class":"?", + | "child_code":0, + | "use_shell":0 + | } + | }, + | "exit_code":0, + | "hierarchy":"trace2", + | "name":"trace2", + | "version":"$V" + | }, + | "_SID0_/_SID1_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "004child", + | "test-tool", + | "trace2", + | "001return", + | "0" + | ], + | "child":{ + | "0":{ + | "child_argv":[ + | "_EXE_", + | "trace2", + | "001return", + | "0" + | ], + | "child_class":"?", + | "child_code":0, + | "use_shell":0 + | } + | }, + | "exit_code":0, + | "hierarchy":"trace2/trace2", + | "name":"trace2", + | "version":"$V" + | }, + | "_SID0_/_SID1_/_SID2_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "001return", + | "0" + | ], + | "exit_code":0, + | "hierarchy":"trace2/trace2/trace2", + | "name":"trace2", + | "version":"$V" + | } + |}; + EOF + test_cmp expect actual +' + +# Test listing of all "interesting" config settings. + +test_expect_success JSON_PP 'event stream, list config' ' + test_when_finished "rm trace.event actual expect" && + git config --local t0212.abc 1 && + git config --local t0212.def "hello world" && + GIT_TR2_EVENT="$(pwd)/trace.event" GIT_TR2_CONFIG_PARAMS="t0212.*" test-tool trace2 001return 0 && + perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && + sed -e "s/^|//" >expect <<-EOF && + |VAR1 = { + | "_SID0_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "001return", + | "0" + | ], + | "exit_code":0, + | "hierarchy":"trace2", + | "name":"trace2", + | "params":[ + | { + | "param":"t0212.abc", + | "value":"1" + | }, + | { + | "param":"t0212.def", + | "value":"hello world" + | } + | ], + | "version":"$V" + | } + |}; + EOF + test_cmp expect actual +' + +test_expect_success JSON_PP 'basic trace2_data' ' + test_when_finished "rm trace.event actual expect" && + GIT_TR2_EVENT="$(pwd)/trace.event" test-tool trace2 006data test_category k1 v1 test_category k2 v2 && + perl "$TEST_DIRECTORY/t0212/parse_events.perl" <trace.event >actual && + sed -e "s/^|//" >expect <<-EOF && + |VAR1 = { + | "_SID0_":{ + | "argv":[ + | "_EXE_", + | "trace2", + | "006data", + | "test_category", + | "k1", + | "v1", + | "test_category", + | "k2", + | "v2" + | ], + | "data":{ + | "test_category":{ + | "k1":"v1", + | "k2":"v2" + | } + | }, + | "exit_code":0, + | "hierarchy":"trace2", + | "name":"trace2", + | "version":"$V" + | } + |}; + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t0212/parse_events.perl b/t/t0212/parse_events.perl new file mode 100644 index 0000000000..a2776ba216 --- /dev/null +++ b/t/t0212/parse_events.perl @@ -0,0 +1,251 @@ +#!/usr/bin/perl +# +# Parse event stream and convert individual events into a summary +# record for the process. +# +# Git.exe generates one or more "event" records for each API method, +# such as "start <argv>" and "exit <code>", during the life of the git +# process. Additionally, the input may contain interleaved events +# from multiple concurrent git processes and/or multiple threads from +# within a git process. +# +# Accumulate events for each process (based on its unique SID) in a +# dictionary and emit process summary records. +# +# Convert some of the variable fields (such as elapsed time) into +# placeholders (or omit them) to make HEREDOC comparisons easier in +# the test scripts. +# +# We may also omit fields not (currently) useful for testing purposes. + +use strict; +use warnings; +use JSON::PP; +use Data::Dumper; +use Getopt::Long; + +# The version of the trace2 event target format that we understand. +# This is reported in the 'version' event in the 'evt' field. +# It comes from the GIT_TR2_EVENT_VERSION macro in trace2/tr2_tgt_event.c +my $evt_version = '1'; + +my $show_children = 1; +my $show_exec = 1; +my $show_threads = 1; + +# A hack to generate test HEREDOC data for pasting into the test script. +# Usage: +# cd "t/trash directory.t0212-trace2-event" +# $TT trace ... >trace.event +# VV=$(../../git.exe version | sed -e 's/^git version //') +# perl ../t0212/parse_events.perl --HEREDOC --VERSION=$VV <trace.event >heredoc +# Then paste heredoc into your new test. + +my $gen_heredoc = 0; +my $gen_version = ''; + +GetOptions("children!" => \$show_children, + "exec!" => \$show_exec, + "threads!" => \$show_threads, + "HEREDOC!" => \$gen_heredoc, + "VERSION=s" => \$gen_version ) + or die("Error in command line arguments\n"); + + +# SIDs contains timestamps and PIDs of the process and its parents. +# This makes it difficult to match up in a HEREDOC in the test script. +# Build a map from actual SIDs to predictable constant values and yet +# keep the parent/child relationships. For example: +# {..., "sid":"1539706952458276-8652", ...} +# {..., "sid":"1539706952458276-8652/1539706952649493-15452", ...} +# becomes: +# {..., "sid":"_SID1_", ...} +# {..., "sid":"_SID1_/_SID2_", ...} +my $sid_map; +my $sid_count = 0; + +my $processes; + +while (<>) { + my $line = decode_json( $_ ); + + my $sid = ""; + my $sid_sep = ""; + + my $raw_sid = $line->{'sid'}; + my @raw_sid_parts = split /\//, $raw_sid; + foreach my $raw_sid_k (@raw_sid_parts) { + if (!exists $sid_map->{$raw_sid_k}) { + $sid_map->{$raw_sid_k} = '_SID' . $sid_count . '_'; + $sid_count++; + } + $sid = $sid . $sid_sep . $sid_map->{$raw_sid_k}; + $sid_sep = '/'; + } + + my $event = $line->{'event'}; + + if ($event eq 'version') { + $processes->{$sid}->{'version'} = $line->{'exe'}; + if ($gen_heredoc == 1 && $gen_version eq $line->{'exe'}) { + # If we are generating data FOR the test script, replace + # the reported git.exe version with a reference to an + # environment variable. When our output is pasted into + # the test script, it will then be expanded in future + # test runs to the THEN current version of git.exe. + # We assume that the test script uses env var $V. + $processes->{$sid}->{'version'} = "\$V"; + } + } + + elsif ($event eq 'start') { + $processes->{$sid}->{'argv'} = $line->{'argv'}; + $processes->{$sid}->{'argv'}[0] = "_EXE_"; + } + + elsif ($event eq 'exit') { + $processes->{$sid}->{'exit_code'} = $line->{'code'}; + } + + elsif ($event eq 'atexit') { + $processes->{$sid}->{'exit_code'} = $line->{'code'}; + } + + elsif ($event eq 'error') { + # For HEREDOC purposes, use the error message format string if + # available, rather than the formatted message (which probably + # has an absolute pathname). + if (exists $line->{'fmt'}) { + push( @{$processes->{$sid}->{'errors'}}, $line->{'fmt'} ); + } + elsif (exists $line->{'msg'}) { + push( @{$processes->{$sid}->{'errors'}}, $line->{'msg'} ); + } + } + + elsif ($event eq 'cmd_path') { + ## $processes->{$sid}->{'path'} = $line->{'path'}; + # + # Like in the 'start' event, we need to replace the value of + # argv[0] with a token for HEREDOC purposes. However, the + # event is only emitted when RUNTIME_PREFIX is defined, so + # just omit it for testing purposes. + # $processes->{$sid}->{'path'} = "_EXE_"; + } + + elsif ($event eq 'cmd_name') { + $processes->{$sid}->{'name'} = $line->{'name'}; + $processes->{$sid}->{'hierarchy'} = $line->{'hierarchy'}; + } + + elsif ($event eq 'alias') { + $processes->{$sid}->{'alias'}->{'key'} = $line->{'alias'}; + $processes->{$sid}->{'alias'}->{'argv'} = $line->{'argv'}; + } + + elsif ($event eq 'def_param') { + my $kv; + $kv->{'param'} = $line->{'param'}; + $kv->{'value'} = $line->{'value'}; + push( @{$processes->{$sid}->{'params'}}, $kv ); + } + + elsif ($event eq 'child_start') { + if ($show_children == 1) { + $processes->{$sid}->{'child'}->{$line->{'child_id'}}->{'child_class'} = $line->{'child_class'}; + $processes->{$sid}->{'child'}->{$line->{'child_id'}}->{'child_argv'} = $line->{'argv'}; + $processes->{$sid}->{'child'}->{$line->{'child_id'}}->{'child_argv'}[0] = "_EXE_"; + $processes->{$sid}->{'child'}->{$line->{'child_id'}}->{'use_shell'} = $line->{'use_shell'} ? 1 : 0; + } + } + + elsif ($event eq 'child_exit') { + if ($show_children == 1) { + $processes->{$sid}->{'child'}->{$line->{'child_id'}}->{'child_code'} = $line->{'code'}; + } + } + + # TODO decide what information we want to test from thread events. + + elsif ($event eq 'thread_start') { + if ($show_threads == 1) { + } + } + + elsif ($event eq 'thread_exit') { + if ($show_threads == 1) { + } + } + + # TODO decide what information we want to test from exec events. + + elsif ($event eq 'exec') { + if ($show_exec == 1) { + } + } + + elsif ($event eq 'exec_result') { + if ($show_exec == 1) { + } + } + + elsif ($event eq 'def_param') { + # Accumulate parameter key/value pairs by key rather than in an array + # so that we get overwrite (last one wins) effects. + $processes->{$sid}->{'params'}->{$line->{'param'}} = $line->{'value'}; + } + + elsif ($event eq 'def_repo') { + # $processes->{$sid}->{'repos'}->{$line->{'repo'}} = $line->{'worktree'}; + $processes->{$sid}->{'repos'}->{$line->{'repo'}} = "_WORKTREE_"; + } + + # A series of potentially nested and threaded region and data events + # is fundamentally incompatibile with the type of summary record we + # are building in this script. Since they are intended for + # perf-trace-like analysis rather than a result summary, we ignore + # most of them here. + + # elsif ($event eq 'region_enter') { + # } + # elsif ($event eq 'region_leave') { + # } + + elsif ($event eq 'data') { + my $cat = $line->{'category'}; + if ($cat eq 'test_category') { + + my $key = $line->{'key'}; + my $value = $line->{'value'}; + $processes->{$sid}->{'data'}->{$cat}->{$key} = $value; + } + } + + # This trace2 target does not emit 'printf' events. + # + # elsif ($event eq 'printf') { + # } +} + +# Dump the resulting hash into something that we can compare against +# in the test script. These options make Dumper output look a little +# bit like JSON. Also convert variable references of the form "$VAR*" +# so that the matching HEREDOC doesn't need to escape it. + +$Data::Dumper::Sortkeys = 1; +$Data::Dumper::Indent = 1; +$Data::Dumper::Purity = 1; +$Data::Dumper::Pair = ':'; + +my $out = Dumper($processes); +$out =~ s/'/"/g; +$out =~ s/\$VAR/VAR/g; + +# Finally, if we're running this script to generate (manually confirmed) +# data to add to the test script, guard the indentation. + +if ($gen_heredoc == 1) { + $out =~ s/^/\t\|/gms; +} + +print $out; diff --git a/t/t1700-split-index.sh b/t/t1700-split-index.sh index 4667e1a190..4f2f84f309 100755 --- a/t/t1700-split-index.sh +++ b/t/t1700-split-index.sh @@ -472,4 +472,22 @@ test_expect_success 'writing split index with null sha1 does not write cache tre test_line_count = 0 cache-tree.out ' +test_expect_success 'do not refresh null base index' ' + test_create_repo merge && + ( + cd merge && + test_commit initial && + git checkout -b side-branch && + test_commit extra && + git checkout master && + git update-index --split-index && + test_commit more && + # must not write a new shareindex, or we wont catch the problem + git -c splitIndex.maxPercentChange=100 merge --no-edit side-branch 2>err && + # i.e. do not expect warnings like + # could not freshen shared index .../shareindex.00000... + test_must_be_empty err + ) +' + test_done diff --git a/t/t2025-checkout-no-overlay.sh b/t/t2025-checkout-no-overlay.sh new file mode 100755 index 0000000000..76330cb5ab --- /dev/null +++ b/t/t2025-checkout-no-overlay.sh @@ -0,0 +1,47 @@ +#!/bin/sh + +test_description='checkout --no-overlay <tree-ish> -- <pathspec>' + +. ./test-lib.sh + +test_expect_success 'setup' ' + git commit --allow-empty -m "initial" +' + +test_expect_success 'checkout --no-overlay deletes files not in <tree-ish>' ' + >file && + mkdir dir && + >dir/file1 && + git add file dir/file1 && + git checkout --no-overlay HEAD -- file && + test_path_is_missing file && + test_path_is_file dir/file1 +' + +test_expect_success 'checkout --no-overlay removing last file from directory' ' + git checkout --no-overlay HEAD -- dir/file1 && + test_path_is_missing dir +' + +test_expect_success 'checkout -p --overlay is disallowed' ' + test_must_fail git checkout -p --overlay HEAD 2>actual && + test_i18ngrep "fatal: -p and --overlay are mutually exclusive" actual +' + +test_expect_success '--no-overlay --theirs with D/F conflict deletes file' ' + test_commit file1 file1 && + test_commit file2 file2 && + git rm --cached file1 && + echo 1234 >file1 && + F1=$(git rev-parse HEAD:file1) && + F2=$(git rev-parse HEAD:file2) && + { + echo "100644 $F1 1 file1" && + echo "100644 $F2 2 file1" + } | git update-index --index-info && + test_path_is_file file1 && + git checkout --theirs --no-overlay -- file1 && + test_path_is_missing file1 +' + +test_done diff --git a/t/t2025-worktree-add.sh b/t/t2400-worktree-add.sh index 286bba35d8..286bba35d8 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2400-worktree-add.sh diff --git a/t/t2026-worktree-prune.sh b/t/t2401-worktree-prune.sh index b7d6d5d45a..b7d6d5d45a 100755 --- a/t/t2026-worktree-prune.sh +++ b/t/t2401-worktree-prune.sh diff --git a/t/t2027-worktree-list.sh b/t/t2402-worktree-list.sh index bb6fb9b12c..bb6fb9b12c 100755 --- a/t/t2027-worktree-list.sh +++ b/t/t2402-worktree-list.sh diff --git a/t/t2028-worktree-move.sh b/t/t2403-worktree-move.sh index 939d18d728..939d18d728 100755 --- a/t/t2028-worktree-move.sh +++ b/t/t2403-worktree-move.sh diff --git a/t/t2029-worktree-config.sh b/t/t2404-worktree-config.sh index 286121d8de..286121d8de 100755 --- a/t/t2029-worktree-config.sh +++ b/t/t2404-worktree-config.sh diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index ee6787614c..be55148930 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -100,6 +100,50 @@ test_expect_success 'git branch -v pattern does not show branch summaries' ' test_must_fail git branch -v branch* ' +test_expect_success 'git branch `--show-current` shows current branch' ' + cat >expect <<-\EOF && + branch-two + EOF + git checkout branch-two && + git branch --show-current >actual && + test_cmp expect actual +' + +test_expect_success 'git branch `--show-current` is silent when detached HEAD' ' + git checkout HEAD^0 && + git branch --show-current >actual && + test_must_be_empty actual +' + +test_expect_success 'git branch `--show-current` works properly when tag exists' ' + cat >expect <<-\EOF && + branch-and-tag-name + EOF + test_when_finished " + git checkout branch-one + git branch -D branch-and-tag-name + " && + git checkout -b branch-and-tag-name && + test_when_finished "git tag -d branch-and-tag-name" && + git tag branch-and-tag-name && + git branch --show-current >actual && + test_cmp expect actual +' + +test_expect_success 'git branch `--show-current` works properly with worktrees' ' + cat >expect <<-\EOF && + branch-one + branch-two + EOF + git checkout branch-one && + git worktree add worktree branch-two && + { + git branch --show-current && + git -C worktree branch --show-current + } >actual && + test_cmp expect actual +' + test_expect_success 'git branch shows detached HEAD properly' ' cat >expect <<EOF && * (HEAD detached at $(git rev-parse --short HEAD^0)) diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index e2824d3437..07b49f6d6d 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -435,4 +435,92 @@ test_expect_success 'combine diff gets tree sorting right' ' test_cmp expect actual ' +test_expect_success 'setup for --combined-all-paths' ' + git branch side1c && + git branch side2c && + git checkout side1c && + test_seq 1 10 >filename-side1c && + git add filename-side1c && + git commit -m with && + git checkout side2c && + test_seq 1 9 >filename-side2c && + echo ten >>filename-side2c && + git add filename-side2c && + git commit -m iam && + git checkout -b mergery side1c && + git merge --no-commit side2c && + git rm filename-side1c && + echo eleven >>filename-side2c && + git mv filename-side2c filename-merged && + git add filename-merged && + git commit +' + +test_expect_success '--combined-all-paths and --raw' ' + cat <<-\EOF >expect && + ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR filename-side1c filename-side2c filename-merged + EOF + git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp && + sed 1d <actual.tmp >actual && + test_cmp expect actual +' + +test_expect_success '--combined-all-paths and --cc' ' + cat <<-\EOF >expect && + --- a/filename-side1c + --- a/filename-side2c + +++ b/filename-merged + EOF + git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp && + grep ^[-+][-+][-+] <actual.tmp >actual && + test_cmp expect actual +' + +test_expect_success FUNNYNAMES 'setup for --combined-all-paths with funny names' ' + git branch side1d && + git branch side2d && + git checkout side1d && + test_seq 1 10 >$(printf "file\twith\ttabs") && + git add file* && + git commit -m with && + git checkout side2d && + test_seq 1 9 >$(printf "i\tam\ttabbed") && + echo ten >>$(printf "i\tam\ttabbed") && + git add *tabbed && + git commit -m iam && + git checkout -b funny-names-mergery side1d && + git merge --no-commit side2d && + git rm *tabs && + echo eleven >>$(printf "i\tam\ttabbed") && + git mv "$(printf "i\tam\ttabbed")" "$(printf "fickle\tnaming")" && + git add fickle* && + git commit +' + +test_expect_success FUNNYNAMES '--combined-all-paths and --raw and funny names' ' + cat <<-\EOF >expect && + ::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR "file\twith\ttabs" "i\tam\ttabbed" "fickle\tnaming" + EOF + git diff-tree -c -M --raw --combined-all-paths HEAD >actual.tmp && + sed 1d <actual.tmp >actual && + test_cmp expect actual +' + +test_expect_success FUNNYNAMES '--combined-all-paths and --raw -and -z and funny names' ' + printf "aaf8087c3cbd4db8e185a2d074cf27c53cfb75d7\0::100644 100644 100644 f00c965d8307308469e537302baa73048488f162 088bd5d92c2a8e0203ca8e7e4c2a5c692f6ae3f7 333b9c62519f285e1854830ade0fe1ef1d40ee1b RR\0file\twith\ttabs\0i\tam\ttabbed\0fickle\tnaming\0" >expect && + git diff-tree -c -M --raw --combined-all-paths -z HEAD >actual && + test_cmp -a expect actual +' + +test_expect_success FUNNYNAMES '--combined-all-paths and --cc and funny names' ' + cat <<-\EOF >expect && + --- "a/file\twith\ttabs" + --- "a/i\tam\ttabbed" + +++ "b/fickle\tnaming" + EOF + git diff-tree --cc -M --combined-all-paths HEAD >actual.tmp && + grep ^[-+][-+][-+] <actual.tmp >actual && + test_cmp expect actual +' + test_done diff --git a/t/t4053-diff-no-index.sh b/t/t4053-diff-no-index.sh index 6e0dd6f9e5..4331b3118a 100755 --- a/t/t4053-diff-no-index.sh +++ b/t/t4053-diff-no-index.sh @@ -137,4 +137,12 @@ test_expect_success 'diff --no-index from repo subdir with absolute paths' ' test_cmp expect actual ' +test_expect_success 'diff --no-index allows external diff' ' + test_expect_code 1 \ + env GIT_EXTERNAL_DIFF="echo external ;:" \ + git diff --no-index non/git/a non/git/b >actual && + echo external >expect && + test_cmp expect actual +' + test_done diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index 7df8c3d4ec..f42a69faa2 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -578,6 +578,24 @@ test_expect_success '%(trailers:only) shows only "key: value" trailers' ' test_cmp expect actual ' +test_expect_success '%(trailers:only=yes) shows only "key: value" trailers' ' + git log --no-walk --pretty=format:"%(trailers:only=yes)" >actual && + grep -v patch.description <trailers >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:only=no) shows all trailers' ' + git log --no-walk --pretty=format:"%(trailers:only=no)" >actual && + cat trailers >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:only=no,only=true) shows only "key: value" trailers' ' + git log --no-walk --pretty=format:"%(trailers:only=yes)" >actual && + grep -v patch.description <trailers >expect && + test_cmp expect actual +' + test_expect_success '%(trailers:unfold) unfolds trailers' ' git log --no-walk --pretty="%(trailers:unfold)" >actual && { @@ -598,6 +616,105 @@ test_expect_success ':only and :unfold work together' ' test_cmp expect actual ' +test_expect_success 'pretty format %(trailers:key=foo) shows that trailer' ' + git log --no-walk --pretty="format:%(trailers:key=Acked-by)" >actual && + echo "Acked-by: A U Thor <author@example.com>" >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:key=foo) is case insensitive' ' + git log --no-walk --pretty="format:%(trailers:key=AcKed-bY)" >actual && + echo "Acked-by: A U Thor <author@example.com>" >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:key=foo:) trailing colon also works' ' + git log --no-walk --pretty="format:%(trailers:key=Acked-by:)" >actual && + echo "Acked-by: A U Thor <author@example.com>" >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:key=foo) multiple keys' ' + git log --no-walk --pretty="format:%(trailers:key=Acked-by:,key=Signed-off-By)" >actual && + grep -v patch.description <trailers >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:key=nonexistant) becomes empty' ' + git log --no-walk --pretty="x%(trailers:key=Nacked-by)x" >actual && + echo "xx" >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:key=foo) handles multiple lines even if folded' ' + git log --no-walk --pretty="format:%(trailers:key=Signed-Off-by)" >actual && + grep -v patch.description <trailers | grep -v Acked-by >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:key=foo,unfold) properly unfolds' ' + git log --no-walk --pretty="format:%(trailers:key=Signed-Off-by,unfold)" >actual && + unfold <trailers | grep Signed-off-by >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:key=foo,only=no) also includes nontrailer lines' ' + git log --no-walk --pretty="format:%(trailers:key=Acked-by,only=no)" >actual && + { + echo "Acked-by: A U Thor <author@example.com>" && + grep patch.description <trailers + } >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:key) without value is error' ' + git log --no-walk --pretty="tformat:%(trailers:key)" >actual && + echo "%(trailers:key)" >expect && + test_cmp expect actual +' + +test_expect_success '%(trailers:key=foo,valueonly) shows only value' ' + git log --no-walk --pretty="format:%(trailers:key=Acked-by,valueonly)" >actual && + echo "A U Thor <author@example.com>" >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers:separator) changes separator' ' + git log --no-walk --pretty=format:"X%(trailers:separator=%x00,unfold)X" >actual && + printf "XSigned-off-by: A U Thor <author@example.com>\0Acked-by: A U Thor <author@example.com>\0[ v2 updated patch description ]\0Signed-off-by: A U Thor <author@example.com>X" >expect && + test_cmp expect actual +' + +test_expect_success 'pretty format %(trailers) combining separator/key/valueonly' ' + git commit --allow-empty -F - <<-\EOF && + Important fix + + The fix is explained here + + Closes: #1234 + EOF + + git commit --allow-empty -F - <<-\EOF && + Another fix + + The fix is explained here + + Closes: #567 + Closes: #890 + EOF + + git commit --allow-empty -F - <<-\EOF && + Does not close any tickets + EOF + + git log --pretty="%s% (trailers:separator=%x2c%x20,key=Closes,valueonly)" HEAD~3.. >actual && + test_write_lines \ + "Does not close any tickets" \ + "Another fix #567, #890" \ + "Important fix #1234" >expect && + test_cmp expect actual +' + test_expect_success 'trailer parsing not fooled by --- line' ' git commit --allow-empty -F - <<-\EOF && this is the subject diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index 270da21ac3..1eeb828a15 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -118,10 +118,10 @@ test_expect_success 'prune: do not prune detached HEAD with no reflog' ' test_expect_success 'prune: prune former HEAD after checking out branch' ' - head_sha1=$(git rev-parse HEAD) && + head_oid=$(git rev-parse HEAD) && git checkout --quiet master && git prune -v >prune_actual && - grep "$head_sha1" prune_actual + grep "$head_oid" prune_actual ' @@ -265,15 +265,27 @@ EOF ' test_expect_success 'prune .git/shallow' ' - SHA1=$(echo hi|git commit-tree HEAD^{tree}) && - echo $SHA1 >.git/shallow && + oid=$(echo hi|git commit-tree HEAD^{tree}) && + echo $oid >.git/shallow && git prune --dry-run >out && - grep $SHA1 .git/shallow && - grep $SHA1 out && + grep $oid .git/shallow && + grep $oid out && git prune && test_path_is_missing .git/shallow ' +test_expect_success 'prune .git/shallow when there are no loose objects' ' + oid=$(echo hi|git commit-tree HEAD^{tree}) && + echo $oid >.git/shallow && + git update-ref refs/heads/shallow-tip $oid && + git repack -ad && + # verify assumption that all loose objects are gone + git count-objects | grep ^0 && + git prune && + echo $oid >expect && + test_cmp expect .git/shallow +' + test_expect_success 'prune: handle alternate object database' ' test_create_repo A && git -C A commit --allow-empty -m "initial commit" && @@ -314,8 +326,8 @@ test_expect_success 'prune: handle HEAD reflog in multiple worktrees' ' git reset --hard HEAD^ ) && git prune --expire=now && - SHA1=`git hash-object expected` && - git -C third-worktree show "$SHA1" >actual && + oid=`git hash-object expected` && + git -C third-worktree show "$oid" >actual && test_cmp expected actual ' diff --git a/t/t5323-pack-redundant.sh b/t/t5323-pack-redundant.sh new file mode 100755 index 0000000000..6b4d1ca353 --- /dev/null +++ b/t/t5323-pack-redundant.sh @@ -0,0 +1,467 @@ +#!/bin/sh +# +# Copyright (c) 2018 Jiang Xin +# + +test_description='Test git pack-redundant + +In order to test git-pack-redundant, we will create a number of objects and +packs in the repository `master.git`. The relationship between packs (P1-P8) +and objects (T, A-R) is showed in the following chart. Objects of a pack will +be marked with letter x, while objects of redundant packs will be marked with +exclamation point, and redundant pack itself will be marked with asterisk. + + | T A B C D E F G H I J K L M N O P Q R + ----+-------------------------------------- + P1 | x x x x x x x x + P2* | ! ! ! ! ! ! ! + P3 | x x x x x x + P4* | ! ! ! ! ! + P5 | x x x x + P6* | ! ! ! + P7 | x x + P8* | ! + ----+-------------------------------------- + ALL | x x x x x x x x x x x x x x x x x x x + +Another repository `shared.git` has unique objects (X-Z), while other objects +(marked with letter s) are shared through alt-odb (of `master.git`). The +relationship between packs and objects is as follows: + + | T A B C D E F G H I J K L M N O P Q R X Y Z + ----+---------------------------------------------- + Px1 | s s s x x x + Px2 | s s s x x x +' + +. ./test-lib.sh + +master_repo=master.git +shared_repo=shared.git + +# Create commits in <repo> and assign each commit's oid to shell variables +# given in the arguments (A, B, and C). E.g.: +# +# create_commits_in <repo> A B C +# +# NOTE: Avoid calling this function from a subshell since variable +# assignments will disappear when subshell exits. +create_commits_in () { + repo="$1" && + if ! parent=$(git -C "$repo" rev-parse HEAD^{} 2>/dev/null) + then + parent= + fi && + T=$(git -C "$repo" write-tree) && + shift && + while test $# -gt 0 + do + name=$1 && + test_tick && + if test -z "$parent" + then + oid=$(echo $name | git -C "$repo" commit-tree $T) + else + oid=$(echo $name | git -C "$repo" commit-tree -p $parent $T) + fi && + eval $name=$oid && + parent=$oid && + shift || + return 1 + done && + git -C "$repo" update-ref refs/heads/master $oid +} + +# Create pack in <repo> and assign pack id to variable given in the 2nd argument +# (<name>). Commits in the pack will be read from stdin. E.g.: +# +# create_pack_in <repo> <name> <<-EOF +# ... +# EOF +# +# NOTE: commits from stdin should be given using heredoc, not using pipe, and +# avoid calling this function from a subshell since variable assignments will +# disappear when subshell exits. +create_pack_in () { + repo="$1" && + name="$2" && + pack=$(git -C "$repo/objects/pack" pack-objects -q pack) && + eval $name=$pack && + eval P$pack=$name:$pack +} + +format_packfiles () { + sed \ + -e "s#.*/pack-\(.*\)\.idx#\1#" \ + -e "s#.*/pack-\(.*\)\.pack#\1#" | + sort -u | + while read p + do + if test -z "$(eval echo \${P$p})" + then + echo $p + else + eval echo "\${P$p}" + fi + done | + sort +} + +test_expect_success 'setup master repo' ' + git init --bare "$master_repo" && + create_commits_in "$master_repo" A B C D E F G H I J K L M N O P Q R +' + +############################################################################# +# Chart of packs and objects for this test case +# +# | T A B C D E F G H I J K L M N O P Q R +# ----+-------------------------------------- +# P1 | x x x x x x x x +# P2 | x x x x x x x +# P3 | x x x x x x +# ----+-------------------------------------- +# ALL | x x x x x x x x x x x x x x x +# +############################################################################# +test_expect_success 'master: no redundant for pack 1, 2, 3' ' + create_pack_in "$master_repo" P1 <<-EOF && + $T + $A + $B + $C + $D + $E + $F + $R + EOF + create_pack_in "$master_repo" P2 <<-EOF && + $B + $C + $D + $E + $G + $H + $I + EOF + create_pack_in "$master_repo" P3 <<-EOF && + $F + $I + $J + $K + $L + $M + EOF + ( + cd "$master_repo" && + git pack-redundant --all >out && + test_must_be_empty out + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# | T A B C D E F G H I J K L M N O P Q R +# ----+-------------------------------------- +# P1 | x x x x x x x x +# P2 | x x x x x x x +# P3* | ! ! ! ! ! ! +# P4 | x x x x x +# P5 | x x x x +# ----+-------------------------------------- +# ALL | x x x x x x x x x x x x x x x x x x +# +############################################################################# +test_expect_success 'master: one of pack-2/pack-3 is redundant' ' + create_pack_in "$master_repo" P4 <<-EOF && + $J + $K + $L + $M + $P + EOF + create_pack_in "$master_repo" P5 <<-EOF && + $G + $H + $N + $O + EOF + ( + cd "$master_repo" && + cat >expect <<-EOF && + P3:$P3 + EOF + git pack-redundant --all >out && + format_packfiles <out >actual && + test_cmp expect actual + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# | T A B C D E F G H I J K L M N O P Q R +# ----+-------------------------------------- +# P1 | x x x x x x x x +# P2* | ! ! ! ! ! ! ! +# P3 | x x x x x x +# P4* | ! ! ! ! ! +# P5 | x x x x +# P6* | ! ! ! +# P7 | x x +# ----+-------------------------------------- +# ALL | x x x x x x x x x x x x x x x x x x x +# +############################################################################# +test_expect_success 'master: pack 2, 4, and 6 are redundant' ' + create_pack_in "$master_repo" P6 <<-EOF && + $N + $O + $Q + EOF + create_pack_in "$master_repo" P7 <<-EOF && + $P + $Q + EOF + ( + cd "$master_repo" && + cat >expect <<-EOF && + P2:$P2 + P4:$P4 + P6:$P6 + EOF + git pack-redundant --all >out && + format_packfiles <out >actual && + test_cmp expect actual + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# | T A B C D E F G H I J K L M N O P Q R +# ----+-------------------------------------- +# P1 | x x x x x x x x +# P2* | ! ! ! ! ! ! ! +# P3 | x x x x x x +# P4* | ! ! ! ! ! +# P5 | x x x x +# P6* | ! ! ! +# P7 | x x +# P8* | ! +# ----+-------------------------------------- +# ALL | x x x x x x x x x x x x x x x x x x x +# +############################################################################# +test_expect_success 'master: pack-8 (subset of pack-1) is also redundant' ' + create_pack_in "$master_repo" P8 <<-EOF && + $A + EOF + ( + cd "$master_repo" && + cat >expect <<-EOF && + P2:$P2 + P4:$P4 + P6:$P6 + P8:$P8 + EOF + git pack-redundant --all >out && + format_packfiles <out >actual && + test_cmp expect actual + ) +' + +test_expect_success 'master: clean loose objects' ' + ( + cd "$master_repo" && + git prune-packed && + find objects -type f | sed -e "/objects\/pack\//d" >out && + test_must_be_empty out + ) +' + +test_expect_success 'master: remove redundant packs and pass fsck' ' + ( + cd "$master_repo" && + git pack-redundant --all | xargs rm && + git fsck && + git pack-redundant --all >out && + test_must_be_empty out + ) +' + +# The following test cases will execute inside `shared.git`, instead of +# inside `master.git`. +test_expect_success 'setup shared.git' ' + git clone --mirror "$master_repo" "$shared_repo" && + ( + cd "$shared_repo" && + printf "../../$master_repo/objects\n" >objects/info/alternates + ) +' + +test_expect_success 'shared: all packs are redundant, but no output without --alt-odb' ' + ( + cd "$shared_repo" && + git pack-redundant --all >out && + test_must_be_empty out + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# ================ master.git =============== +# | T A B C D E F G H I J K L M N O P Q R <----------+ +# ----+-------------------------------------- | +# P1 | x x x x x x x x | +# P3 | x x x x x x | +# P5 | x x x x | +# P7 | x x | +# ----+-------------------------------------- | +# ALL | x x x x x x x x x x x x x x x x x x x | +# | +# | +# ================ shared.git =============== | +# | T A B C D E F G H I J K L M N O P Q R <objects/info/alternates> +# ----+-------------------------------------- +# P1* | s s s s s s s s +# P3* | s s s s s s +# P5* | s s s s +# P7* | s s +# ----+-------------------------------------- +# ALL | x x x x x x x x x x x x x x x x x x x +# +############################################################################# +test_expect_success 'shared: show redundant packs in stderr for verbose mode' ' + ( + cd "$shared_repo" && + cat >expect <<-EOF && + P1:$P1 + P3:$P3 + P5:$P5 + P7:$P7 + EOF + git pack-redundant --all --verbose >out 2>out.err && + test_must_be_empty out && + grep "pack$" out.err | format_packfiles >actual && + test_cmp expect actual + ) +' + +test_expect_success 'shared: remove redundant packs, no packs left' ' + ( + cd "$shared_repo" && + cat >expect <<-EOF && + fatal: Zero packs found! + EOF + git pack-redundant --all --alt-odb | xargs rm && + git fsck && + test_must_fail git pack-redundant --all --alt-odb >actual 2>&1 && + test_cmp expect actual + ) +' + +test_expect_success 'shared: create new objects and packs' ' + create_commits_in "$shared_repo" X Y Z && + create_pack_in "$shared_repo" Px1 <<-EOF && + $X + $Y + $Z + $A + $B + $C + EOF + create_pack_in "$shared_repo" Px2 <<-EOF + $X + $Y + $Z + $D + $E + $F + EOF +' + +test_expect_success 'shared: no redundant without --alt-odb' ' + ( + cd "$shared_repo" && + git pack-redundant --all >out && + test_must_be_empty out + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# ================ master.git =============== +# | T A B C D E F G H I J K L M N O P Q R <----------------+ +# ----+-------------------------------------- | +# P1 | x x x x x x x x | +# P3 | x x x x x x | +# P5 | x x x x | +# P7 | x x | +# ----+-------------------------------------- | +# ALL | x x x x x x x x x x x x x x x x x x x | +# | +# | +# ================ shared.git ======================= | +# | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates> +# ----+---------------------------------------------- +# Px1 | s s s x x x +# Px2*| s s s ! ! ! +# ----+---------------------------------------------- +# ALL | s s s s s s s s s s s s s s s s s s s x x x +# +############################################################################# +test_expect_success 'shared: one pack is redundant with --alt-odb' ' + ( + cd "$shared_repo" && + git pack-redundant --all --alt-odb >out && + format_packfiles <out >actual && + test_line_count = 1 actual + ) +' + +############################################################################# +# Chart of packs and objects for this test case +# +# ================ master.git =============== +# | T A B C D E F G H I J K L M N O P Q R <----------------+ +# ----+-------------------------------------- | +# P1 | x x x x x x x x | +# P3 | x x x x x x | +# P5 | x x x x | +# P7 | x x | +# ----+-------------------------------------- | +# ALL | x x x x x x x x x x x x x x x x x x x | +# | +# | +# ================ shared.git ======================= | +# | T A B C D E F G H I J K L M N O P Q R X Y Z <objects/info/alternates> +# ----+---------------------------------------------- +# Px1*| s s s i i i +# Px2*| s s s i i i +# ----+---------------------------------------------- +# ALL | s s s s s s s s s s s s s s s s s s s i i i +# (ignored objects, marked with i) +# +############################################################################# +test_expect_success 'shared: ignore unique objects and all two packs are redundant' ' + ( + cd "$shared_repo" && + cat >expect <<-EOF && + Px1:$Px1 + Px2:$Px2 + EOF + git pack-redundant --all --alt-odb >out <<-EOF && + $X + $Y + $Z + EOF + format_packfiles <out >actual && + test_cmp expect actual + ) +' + +test_done diff --git a/t/t5702-protocol-v2.sh b/t/t5702-protocol-v2.sh index db4ae09f2f..e112b6086c 100755 --- a/t/t5702-protocol-v2.sh +++ b/t/t5702-protocol-v2.sh @@ -542,7 +542,38 @@ test_expect_success 'clone with http:// using protocol v2' ' # Client requested to use protocol v2 grep "Git-Protocol: version=2" log && # Server responded using protocol v2 - grep "git< version 2" log + grep "git< version 2" log && + # Verify that the chunked encoding sending codepath is NOT exercised + ! grep "Send header: Transfer-Encoding: chunked" log +' + +test_expect_success 'clone big repository with http:// using protocol v2' ' + test_when_finished "rm -f log" && + + git init "$HTTPD_DOCUMENT_ROOT_PATH/big" && + # Ensure that the list of wants is greater than http.postbuffer below + for i in $(test_seq 1 1500) + do + # do not use here-doc, because it requires a process + # per loop iteration + echo "commit refs/heads/too-many-refs-$i" && + echo "committer git <git@example.com> $i +0000" && + echo "data 0" && + echo "M 644 inline bla.txt" && + echo "data 4" && + echo "bla" + done | git -C "$HTTPD_DOCUMENT_ROOT_PATH/big" fast-import && + + GIT_TRACE_PACKET="$(pwd)/log" GIT_TRACE_CURL="$(pwd)/log" git \ + -c protocol.version=2 -c http.postbuffer=65536 \ + clone "$HTTPD_URL/smart/big" big_child && + + # Client requested to use protocol v2 + grep "Git-Protocol: version=2" log && + # Server responded using protocol v2 + grep "git< version 2" log && + # Verify that the chunked encoding sending codepath is exercised + grep "Send header: Transfer-Encoding: chunked" log ' test_expect_success 'fetch with http:// using protocol v2' ' diff --git a/t/t7517-per-repo-email.sh b/t/t7517-per-repo-email.sh index 231b8cc19d..b2401cec3e 100755 --- a/t/t7517-per-repo-email.sh +++ b/t/t7517-per-repo-email.sh @@ -85,4 +85,78 @@ test_expect_success REBASE_P \ test_must_fail git rebase -p master ' +test_expect_success 'author.name overrides user.name' ' + test_config user.name user && + test_config user.email user@example.com && + test_config author.name author && + test_commit author-name-override-user && + echo author user@example.com > expected-author && + echo user user@example.com > expected-committer && + git log --format="%an %ae" -1 > actual-author && + git log --format="%cn %ce" -1 > actual-committer && + test_cmp expected-author actual-author && + test_cmp expected-committer actual-committer +' + +test_expect_success 'author.email overrides user.email' ' + test_config user.name user && + test_config user.email user@example.com && + test_config author.email author@example.com && + test_commit author-email-override-user && + echo user author@example.com > expected-author && + echo user user@example.com > expected-committer && + git log --format="%an %ae" -1 > actual-author && + git log --format="%cn %ce" -1 > actual-committer && + test_cmp expected-author actual-author && + test_cmp expected-committer actual-committer +' + +test_expect_success 'committer.name overrides user.name' ' + test_config user.name user && + test_config user.email user@example.com && + test_config committer.name committer && + test_commit committer-name-override-user && + echo user user@example.com > expected-author && + echo committer user@example.com > expected-committer && + git log --format="%an %ae" -1 > actual-author && + git log --format="%cn %ce" -1 > actual-committer && + test_cmp expected-author actual-author && + test_cmp expected-committer actual-committer +' + +test_expect_success 'committer.email overrides user.email' ' + test_config user.name user && + test_config user.email user@example.com && + test_config committer.email committer@example.com && + test_commit committer-email-override-user && + echo user user@example.com > expected-author && + echo user committer@example.com > expected-committer && + git log --format="%an %ae" -1 > actual-author && + git log --format="%cn %ce" -1 > actual-committer && + test_cmp expected-author actual-author && + test_cmp expected-committer actual-committer +' + +test_expect_success 'author and committer environment variables override config settings' ' + test_config user.name user && + test_config user.email user@example.com && + test_config author.name author && + test_config author.email author@example.com && + test_config committer.name committer && + test_config committer.email committer@example.com && + GIT_AUTHOR_NAME=env_author && export GIT_AUTHOR_NAME && + GIT_AUTHOR_EMAIL=env_author@example.com && export GIT_AUTHOR_EMAIL && + GIT_COMMITTER_NAME=env_commit && export GIT_COMMITTER_NAME && + GIT_COMMITTER_EMAIL=env_commit@example.com && export GIT_COMMITTER_EMAIL && + test_commit env-override-conf && + echo env_author env_author@example.com > expected-author && + echo env_commit env_commit@example.com > expected-committer && + git log --format="%an %ae" -1 > actual-author && + git log --format="%cn %ce" -1 > actual-committer && + sane_unset GIT_AUTHOR_NAME GIT_AUTHOR_EMAIL && + sane_unset GIT_COMMITTER_NAME GIT_COMMITTER_EMAIL && + test_cmp expected-author actual-author && + test_cmp expected-committer actual-committer +' + test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 22b9199d59..bb9a7f4ff9 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -546,7 +546,7 @@ do done >actual EOF -test_expect_success SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' ' +test_expect_success SYMLINKS 'difftool --dir-diff --symlinks without unstaged changes' ' cat >expect <<-EOF && file $PWD/file @@ -555,7 +555,7 @@ test_expect_success SYMLINKS 'difftool --dir-diff --symlink without unstaged cha sub/sub $PWD/sub/sub EOF - git difftool --dir-diff --symlink \ + git difftool --dir-diff --symlinks \ --extcmd "./.git/CHECK_SYMLINKS" branch HEAD && test_cmp expect actual ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index 3a2c6326d8..f5e21bf970 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -1437,6 +1437,7 @@ test_expect_success 'double dash "git checkout"' ' --guess Z --no-guess Z --no-... Z + --overlay Z EOF ' diff --git a/t/test-lib.sh b/t/test-lib.sh index 8665b0a9b6..4e79e140c9 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -1327,7 +1327,11 @@ then fi fi -# Provide an implementation of the 'yes' utility +# Provide an implementation of the 'yes' utility; the upper bound +# limit is there to help Windows that cannot stop this loop from +# wasting cycles when the downstream stops reading, so do not be +# tempted to turn it into an infinite loop. cf. 6129c930 ("test-lib: +# limit the output of the yes utility", 2016-02-02) yes () { if test $# = 0 then diff --git a/trace2.c b/trace2.c new file mode 100644 index 0000000000..ccccd4ef09 --- /dev/null +++ b/trace2.c @@ -0,0 +1,761 @@ +#include "cache.h" +#include "config.h" +#include "json-writer.h" +#include "quote.h" +#include "run-command.h" +#include "sigchain.h" +#include "thread-utils.h" +#include "version.h" +#include "trace2/tr2_cfg.h" +#include "trace2/tr2_cmd_name.h" +#include "trace2/tr2_dst.h" +#include "trace2/tr2_sid.h" +#include "trace2/tr2_tgt.h" +#include "trace2/tr2_tls.h" + +static int trace2_enabled; + +static int tr2_next_child_id; /* modify under lock */ +static int tr2_next_exec_id; /* modify under lock */ +static int tr2_next_repo_id = 1; /* modify under lock. zero is reserved */ + +/* + * A table of the builtin TRACE2 targets. Each of these may be independently + * enabled or disabled. Each TRACE2 API method will try to write an event to + * *each* of the enabled targets. + */ +/* clang-format off */ +static struct tr2_tgt *tr2_tgt_builtins[] = +{ + &tr2_tgt_normal, + &tr2_tgt_perf, + &tr2_tgt_event, + NULL +}; +/* clang-format on */ + +/* clang-format off */ +#define for_each_builtin(j, tgt_j) \ + for (j = 0, tgt_j = tr2_tgt_builtins[j]; \ + tgt_j; \ + j++, tgt_j = tr2_tgt_builtins[j]) +/* clang-format on */ + +/* clang-format off */ +#define for_each_wanted_builtin(j, tgt_j) \ + for_each_builtin(j, tgt_j) \ + if (tr2_dst_trace_want(tgt_j->pdst)) +/* clang-format on */ + +/* + * Force (rather than lazily) initialize any of the requested + * builtin TRACE2 targets at startup (and before we've seen an + * actual TRACE2 event call) so we can see if we need to setup + * the TR2 and TLS machinery. + * + * Return the number of builtin targets enabled. + */ +static int tr2_tgt_want_builtins(void) +{ + struct tr2_tgt *tgt_j; + int j; + int sum = 0; + + for_each_builtin (j, tgt_j) + if (tgt_j->pfn_init()) + sum++; + + return sum; +} + +/* + * Properly terminate each builtin target. Give each target + * a chance to write a summary event and/or flush if necessary + * and then close the fd. + */ +static void tr2_tgt_disable_builtins(void) +{ + struct tr2_tgt *tgt_j; + int j; + + for_each_builtin (j, tgt_j) + tgt_j->pfn_term(); +} + +static int tr2main_exit_code; + +/* + * Our atexit routine should run after everything has finished. + * + * Note that events generated here might not actually appear if + * we are writing to fd 1 or 2 and our atexit routine runs after + * the pager's atexit routine (since it closes them to shutdown + * the pipes). + */ +static void tr2main_atexit_handler(void) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + /* + * Clear any unbalanced regions so that our atexit message + * does not appear nested. This improves the appearance of + * the trace output if someone calls die(), for example. + */ + tr2tls_pop_unwind_self(); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_atexit) + tgt_j->pfn_atexit(us_elapsed_absolute, + tr2main_exit_code); + + tr2_tgt_disable_builtins(); + + tr2tls_release(); + tr2_sid_release(); + tr2_cmd_name_release(); + tr2_cfg_free_patterns(); + + trace2_enabled = 0; +} + +static void tr2main_signal_handler(int signo) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_signal) + tgt_j->pfn_signal(us_elapsed_absolute, signo); + + sigchain_pop(signo); + raise(signo); +} + +void trace2_initialize_fl(const char *file, int line) +{ + struct tr2_tgt *tgt_j; + int j; + + if (trace2_enabled) + return; + + if (!tr2_tgt_want_builtins()) + return; + trace2_enabled = 1; + + tr2_sid_get(); + + atexit(tr2main_atexit_handler); + sigchain_push(SIGPIPE, tr2main_signal_handler); + tr2tls_init(); + + /* + * Emit 'version' message on each active builtin target. + */ + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_version_fl) + tgt_j->pfn_version_fl(file, line); +} + +int trace2_is_enabled(void) +{ + return trace2_enabled; +} + +void trace2_cmd_start_fl(const char *file, int line, const char **argv) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_start_fl) + tgt_j->pfn_start_fl(file, line, argv); +} + +int trace2_cmd_exit_fl(const char *file, int line, int code) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + code &= 0xff; + + if (!trace2_enabled) + return code; + + tr2main_exit_code = code; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_exit_fl) + tgt_j->pfn_exit_fl(file, line, us_elapsed_absolute, + code); + + return code; +} + +void trace2_cmd_error_va_fl(const char *file, int line, const char *fmt, + va_list ap) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + /* + * We expect each target function to treat 'ap' as constant + * and use va_copy (because an 'ap' can only be walked once). + */ + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_error_va_fl) + tgt_j->pfn_error_va_fl(file, line, fmt, ap); +} + +void trace2_cmd_path_fl(const char *file, int line, const char *pathname) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_command_path_fl) + tgt_j->pfn_command_path_fl(file, line, pathname); +} + +void trace2_cmd_name_fl(const char *file, int line, const char *name) +{ + struct tr2_tgt *tgt_j; + const char *hierarchy; + int j; + + if (!trace2_enabled) + return; + + tr2_cmd_name_append_hierarchy(name); + hierarchy = tr2_cmd_name_get_hierarchy(); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_command_name_fl) + tgt_j->pfn_command_name_fl(file, line, name, hierarchy); +} + +void trace2_cmd_mode_fl(const char *file, int line, const char *mode) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_command_mode_fl) + tgt_j->pfn_command_mode_fl(file, line, mode); +} + +void trace2_cmd_alias_fl(const char *file, int line, const char *alias, + const char **argv) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_alias_fl) + tgt_j->pfn_alias_fl(file, line, alias, argv); +} + +void trace2_cmd_list_config_fl(const char *file, int line) +{ + if (!trace2_enabled) + return; + + tr2_cfg_list_config_fl(file, line); +} + +void trace2_cmd_set_config_fl(const char *file, int line, const char *key, + const char *value) +{ + if (!trace2_enabled) + return; + + tr2_cfg_set_fl(file, line, key, value); +} + +void trace2_child_start_fl(const char *file, int line, + struct child_process *cmd) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + cmd->trace2_child_id = tr2tls_locked_increment(&tr2_next_child_id); + cmd->trace2_child_us_start = us_now; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_child_start_fl) + tgt_j->pfn_child_start_fl(file, line, + us_elapsed_absolute, cmd); +} + +void trace2_child_exit_fl(const char *file, int line, struct child_process *cmd, + int child_exit_code) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + uint64_t us_elapsed_child; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + if (cmd->trace2_child_us_start) + us_elapsed_child = us_now - cmd->trace2_child_us_start; + else + us_elapsed_child = 0; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_child_exit_fl) + tgt_j->pfn_child_exit_fl(file, line, + us_elapsed_absolute, + cmd->trace2_child_id, cmd->pid, + child_exit_code, + us_elapsed_child); +} + +int trace2_exec_fl(const char *file, int line, const char *exe, + const char **argv) +{ + struct tr2_tgt *tgt_j; + int j; + int exec_id; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return -1; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + exec_id = tr2tls_locked_increment(&tr2_next_exec_id); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_exec_fl) + tgt_j->pfn_exec_fl(file, line, us_elapsed_absolute, + exec_id, exe, argv); + + return exec_id; +} + +void trace2_exec_result_fl(const char *file, int line, int exec_id, int code) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_exec_result_fl) + tgt_j->pfn_exec_result_fl( + file, line, us_elapsed_absolute, exec_id, code); +} + +void trace2_thread_start_fl(const char *file, int line, const char *thread_name) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return; + + if (tr2tls_is_main_thread()) { + /* + * We should only be called from the new thread's thread-proc, + * so this is technically a bug. But in those cases where the + * main thread also runs the thread-proc function (or when we + * are built with threading disabled), we need to allow it. + * + * Convert this call to a region-enter so the nesting looks + * correct. + */ + trace2_region_enter_printf_fl(file, line, NULL, NULL, NULL, + "thread-proc on main: %s", + thread_name); + return; + } + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + tr2tls_create_self(thread_name); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_thread_start_fl) + tgt_j->pfn_thread_start_fl(file, line, + us_elapsed_absolute); +} + +void trace2_thread_exit_fl(const char *file, int line) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + uint64_t us_elapsed_thread; + + if (!trace2_enabled) + return; + + if (tr2tls_is_main_thread()) { + /* + * We should only be called from the exiting thread's + * thread-proc, so this is technically a bug. But in + * those cases where the main thread also runs the + * thread-proc function (or when we are built with + * threading disabled), we need to allow it. + * + * Convert this call to a region-leave so the nesting + * looks correct. + */ + trace2_region_leave_printf_fl(file, line, NULL, NULL, NULL, + "thread-proc on main"); + return; + } + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + /* + * Clear any unbalanced regions and then get the relative time + * for the outer-most region (which we pushed when the thread + * started). This gives us the run time of the thread. + */ + tr2tls_pop_unwind_self(); + us_elapsed_thread = tr2tls_region_elasped_self(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_thread_exit_fl) + tgt_j->pfn_thread_exit_fl(file, line, + us_elapsed_absolute, + us_elapsed_thread); + + tr2tls_unset_self(); +} + +void trace2_def_param_fl(const char *file, int line, const char *param, + const char *value) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_param_fl) + tgt_j->pfn_param_fl(file, line, param, value); +} + +void trace2_def_repo_fl(const char *file, int line, struct repository *repo) +{ + struct tr2_tgt *tgt_j; + int j; + + if (!trace2_enabled) + return; + + if (repo->trace2_repo_id) + return; + + repo->trace2_repo_id = tr2tls_locked_increment(&tr2_next_repo_id); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_repo_fl) + tgt_j->pfn_repo_fl(file, line, repo); +} + +void trace2_region_enter_printf_va_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, va_list ap) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + /* + * Print the region-enter message at the current nesting + * (indentation) level and then push a new level. + * + * We expect each target function to treat 'ap' as constant + * and use va_copy. + */ + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_region_enter_printf_va_fl) + tgt_j->pfn_region_enter_printf_va_fl( + file, line, us_elapsed_absolute, category, + label, repo, fmt, ap); + + tr2tls_push_self(us_now); +} + +void trace2_region_enter_fl(const char *file, int line, const char *category, + const char *label, const struct repository *repo) +{ + trace2_region_enter_printf_va_fl(file, line, category, label, repo, + NULL, NULL); +} + +void trace2_region_enter_printf_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_region_enter_printf_va_fl(file, line, category, label, repo, fmt, + ap); + va_end(ap); +} + +#ifndef HAVE_VARIADIC_MACROS +void trace2_region_enter_printf(const char *category, const char *label, + const struct repository *repo, const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_region_enter_printf_va_fl(NULL, 0, category, label, repo, fmt, + ap); + va_end(ap); +} +#endif + +void trace2_region_leave_printf_va_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, va_list ap) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + uint64_t us_elapsed_region; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + /* + * Get the elapsed time in the current region before we + * pop it off the stack. Pop the stack. And then print + * the perf message at the new (shallower) level so that + * it lines up with the corresponding push/enter. + */ + us_elapsed_region = tr2tls_region_elasped_self(us_now); + + tr2tls_pop_self(); + + /* + * We expect each target function to treat 'ap' as constant + * and use va_copy. + */ + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_region_leave_printf_va_fl) + tgt_j->pfn_region_leave_printf_va_fl( + file, line, us_elapsed_absolute, + us_elapsed_region, category, label, repo, fmt, + ap); +} + +void trace2_region_leave_fl(const char *file, int line, const char *category, + const char *label, const struct repository *repo) +{ + trace2_region_leave_printf_va_fl(file, line, category, label, repo, + NULL, NULL); +} + +void trace2_region_leave_printf_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_region_leave_printf_va_fl(file, line, category, label, repo, fmt, + ap); + va_end(ap); +} + +#ifndef HAVE_VARIADIC_MACROS +void trace2_region_leave_printf(const char *category, const char *label, + const struct repository *repo, const char *fmt, + ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_region_leave_printf_va_fl(NULL, 0, category, label, repo, fmt, + ap); + va_end(ap); +} +#endif + +void trace2_data_string_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + const char *value) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + uint64_t us_elapsed_region; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + us_elapsed_region = tr2tls_region_elasped_self(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_data_fl) + tgt_j->pfn_data_fl(file, line, us_elapsed_absolute, + us_elapsed_region, category, repo, + key, value); +} + +void trace2_data_intmax_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + intmax_t value) +{ + struct strbuf buf_string = STRBUF_INIT; + + if (!trace2_enabled) + return; + + strbuf_addf(&buf_string, "%" PRIdMAX, value); + trace2_data_string_fl(file, line, category, repo, key, buf_string.buf); + strbuf_release(&buf_string); +} + +void trace2_data_json_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + const struct json_writer *value) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + uint64_t us_elapsed_region; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + us_elapsed_region = tr2tls_region_elasped_self(us_now); + + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_data_fl) + tgt_j->pfn_data_json_fl(file, line, us_elapsed_absolute, + us_elapsed_region, category, + repo, key, value); +} + +void trace2_printf_va_fl(const char *file, int line, const char *fmt, + va_list ap) +{ + struct tr2_tgt *tgt_j; + int j; + uint64_t us_now; + uint64_t us_elapsed_absolute; + + if (!trace2_enabled) + return; + + us_now = getnanotime() / 1000; + us_elapsed_absolute = tr2tls_absolute_elapsed(us_now); + + /* + * We expect each target function to treat 'ap' as constant + * and use va_copy. + */ + for_each_wanted_builtin (j, tgt_j) + if (tgt_j->pfn_printf_va_fl) + tgt_j->pfn_printf_va_fl(file, line, us_elapsed_absolute, + fmt, ap); +} + +void trace2_printf_fl(const char *file, int line, const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_printf_va_fl(file, line, fmt, ap); + va_end(ap); +} + +#ifndef HAVE_VARIADIC_MACROS +void trace2_printf(const char *fmt, ...) +{ + va_list ap; + + va_start(ap, fmt); + trace2_printf_va_fl(NULL, 0, fmt, ap); + va_end(ap); +} +#endif diff --git a/trace2.h b/trace2.h new file mode 100644 index 0000000000..ae5020d0e6 --- /dev/null +++ b/trace2.h @@ -0,0 +1,385 @@ +#ifndef TRACE2_H +#define TRACE2_H + +struct child_process; +struct repository; +struct json_writer; + +/* + * The public TRACE2 routines are grouped into the following groups: + * + * [] trace2_initialize -- initialization. + * [] trace2_cmd_* -- emit command/control messages. + * [] trace2_child* -- emit child start/stop messages. + * [] trace2_exec* -- emit exec start/stop messages. + * [] trace2_thread* -- emit thread start/stop messages. + * [] trace2_def* -- emit definition/parameter mesasges. + * [] trace2_region* -- emit region nesting messages. + * [] trace2_data* -- emit region/thread/repo data messages. + * [] trace2_printf* -- legacy trace[1] messages. + */ + +/* + * Initialize TRACE2 tracing facility if any of the builtin TRACE2 + * targets are enabled in the environment. Emits a 'version' event. + * + * Cleanup/Termination is handled automatically by a registered + * atexit() routine. + */ +void trace2_initialize_fl(const char *file, int line); + +#define trace2_initialize() trace2_initialize_fl(__FILE__, __LINE__) + +/* + * Return true if trace2 is enabled. + */ +int trace2_is_enabled(void); + +/* + * Emit a 'start' event with the original (unmodified) argv. + */ +void trace2_cmd_start_fl(const char *file, int line, const char **argv); + +#define trace2_cmd_start(argv) trace2_cmd_start_fl(__FILE__, __LINE__, (argv)) + +/* + * Emit an 'exit' event. + * + * Write the exit-code that will be passed to exit() or returned + * from main(). + * + * Use this prior to actually calling exit(). + * See "#define exit()" in git-compat-util.h + */ +int trace2_cmd_exit_fl(const char *file, int line, int code); + +#define trace2_cmd_exit(code) (trace2_cmd_exit_fl(__FILE__, __LINE__, (code))) + +/* + * Emit an 'error' event. + * + * Write an error message to the TRACE2 targets. + */ +void trace2_cmd_error_va_fl(const char *file, int line, const char *fmt, + va_list ap); + +#define trace2_cmd_error_va(fmt, ap) \ + trace2_cmd_error_va_fl(__FILE__, __LINE__, (fmt), (ap)) + +/* + * Emit a 'pathname' event with the canonical pathname of the current process + * This gives post-processors a simple field to identify the command without + * having to parse the argv. For example, to distinguish invocations from + * installed versus debug executables. + */ +void trace2_cmd_path_fl(const char *file, int line, const char *pathname); + +#define trace2_cmd_path(p) trace2_cmd_path_fl(__FILE__, __LINE__, (p)) + +/* + * Emit a 'cmd_name' event with the canonical name of the command. + * This gives post-processors a simple field to identify the command + * without having to parse the argv. + */ +void trace2_cmd_name_fl(const char *file, int line, const char *name); + +#define trace2_cmd_name(v) trace2_cmd_name_fl(__FILE__, __LINE__, (v)) + +/* + * Emit a 'cmd_mode' event to further describe the command being run. + * For example, "checkout" can checkout a single file or can checkout a + * different branch. This gives post-processors a simple field to compare + * equivalent commands without having to parse the argv. + */ +void trace2_cmd_mode_fl(const char *file, int line, const char *mode); + +#define trace2_cmd_mode(sv) trace2_cmd_mode_fl(__FILE__, __LINE__, (sv)) + +/* + * Emit an 'alias' expansion event. + */ +void trace2_cmd_alias_fl(const char *file, int line, const char *alias, + const char **argv); + +#define trace2_cmd_alias(alias, argv) \ + trace2_cmd_alias_fl(__FILE__, __LINE__, (alias), (argv)) + +/* + * Emit one or more 'def_param' events for "interesting" configuration + * settings. + * + * The environment variable "GIT_TR2_CONFIG_PARAMS" can be set to a + * list of patterns considered important. For example: + * + * GIT_TR2_CONFIG_PARAMS="core.*,remote.*.url" + * + * Note: this routine does a read-only iteration on the config data + * (using read_early_config()), so it must not be called until enough + * of the process environment has been established. This includes the + * location of the git and worktree directories, expansion of any "-c" + * and "-C" command line options, and etc. + */ +void trace2_cmd_list_config_fl(const char *file, int line); + +#define trace2_cmd_list_config() trace2_cmd_list_config_fl(__FILE__, __LINE__) + +/* + * Emit a "def_param" event for the given config key/value pair IF + * we consider the key to be "interesting". + * + * Use this for new/updated config settings created/updated after + * trace2_cmd_list_config() is called. + */ +void trace2_cmd_set_config_fl(const char *file, int line, const char *key, + const char *value); + +#define trace2_cmd_set_config(k, v) \ + trace2_cmd_set_config_fl(__FILE__, __LINE__, (k), (v)) + +/* + * Emit a 'child_start' event prior to spawning a child process. + * + * Before calling optionally set "cmd->trace2_child_class" to a string + * describing the type of the child process. For example, "editor" or + * "pager". + */ +void trace2_child_start_fl(const char *file, int line, + struct child_process *cmd); + +#define trace2_child_start(cmd) trace2_child_start_fl(__FILE__, __LINE__, (cmd)) + +/* + * Emit a 'child_exit' event after the child process completes. + */ +void trace2_child_exit_fl(const char *file, int line, struct child_process *cmd, + int child_exit_code); + +#define trace2_child_exit(cmd, code) \ + trace2_child_exit_fl(__FILE__, __LINE__, (cmd), (code)) + +/* + * Emit an 'exec' event prior to calling one of exec(), execv(), + * execvp(), and etc. On Unix-derived systems, this will be the + * last event emitted for the current process, unless the exec + * fails. On Windows, exec() behaves like 'child_start' and a + * waitpid(), so additional events may be emitted. + * + * Returns the "exec_id". + */ +int trace2_exec_fl(const char *file, int line, const char *exe, + const char **argv); + +#define trace2_exec(exe, argv) trace2_exec_fl(__FILE__, __LINE__, (exe), (argv)) + +/* + * Emit an 'exec_result' when possible. On Unix-derived systems, + * this should be called after exec() returns (which only happens + * when there is an error starting the new process). On Windows, + * this should be called after the waitpid(). + * + * The "exec_id" should be the value returned from trace2_exec(). + */ +void trace2_exec_result_fl(const char *file, int line, int exec_id, int code); + +#define trace2_exec_result(id, code) \ + trace2_exec_result_fl(__FILE__, __LINE__, (id), (code)) + +/* + * Emit a 'thread_start' event. This must be called from inside the + * thread-proc to set up the trace2 TLS data for the thread. + * + * Thread names should be descriptive, like "preload_index". + * Thread names will be decorated with an instance number automatically. + */ +void trace2_thread_start_fl(const char *file, int line, + const char *thread_name); + +#define trace2_thread_start(thread_name) \ + trace2_thread_start_fl(__FILE__, __LINE__, (thread_name)) + +/* + * Emit a 'thread_exit' event. This must be called from inside the + * thread-proc to report thread-specific data and cleanup TLS data + * for the thread. + */ +void trace2_thread_exit_fl(const char *file, int line); + +#define trace2_thread_exit() trace2_thread_exit_fl(__FILE__, __LINE__) + +/* + * Emit a 'param' event. + * + * Write a "<param> = <value>" pair describing some aspect of the + * run such as an important configuration setting or command line + * option that significantly changes command behavior. + */ +void trace2_def_param_fl(const char *file, int line, const char *param, + const char *value); + +#define trace2_def_param(param, value) \ + trace2_def_param_fl(__FILE__, __LINE__, (param), (value)) + +/* + * Tell trace2 about a newly instantiated repo object and assign + * a trace2-repo-id to be used in subsequent activity events. + * + * Emits a 'worktree' event for this repo instance. + */ +void trace2_def_repo_fl(const char *file, int line, struct repository *repo); + +#define trace2_def_repo(repo) trace2_def_repo_fl(__FILE__, __LINE__, repo) + +/* + * Emit a 'region_enter' event for <category>.<label> with optional + * repo-id and printf message. + * + * Enter a new nesting level on the current thread and remember the + * current time. This controls the indenting of all subsequent events + * on this thread. + */ +void trace2_region_enter_fl(const char *file, int line, const char *category, + const char *label, const struct repository *repo); + +#define trace2_region_enter(category, label, repo) \ + trace2_region_enter_fl(__FILE__, __LINE__, (category), (label), (repo)) + +void trace2_region_enter_printf_va_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, va_list ap); + +#define trace2_region_enter_printf_va(category, label, repo, fmt, ap) \ + trace2_region_enter_printf_va_fl(__FILE__, __LINE__, (category), \ + (label), (repo), (fmt), (ap)) + +void trace2_region_enter_printf_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, ...); + +#ifdef HAVE_VARIADIC_MACROS +#define trace2_region_enter_printf(category, label, repo, ...) \ + trace2_region_enter_printf_fl(__FILE__, __LINE__, (category), (label), \ + (repo), __VA_ARGS__) +#else +/* clang-format off */ +__attribute__((format (region_enter_printf, 4, 5))) +void trace2_region_enter_printf(const char *category, const char *label, + const struct repository *repo, const char *fmt, + ...); +/* clang-format on */ +#endif + +/* + * Emit a 'region_leave' event for <category>.<label> with optional + * repo-id and printf message. + * + * Leave current nesting level and report the elapsed time spent + * in this nesting level. + */ +void trace2_region_leave_fl(const char *file, int line, const char *category, + const char *label, const struct repository *repo); + +#define trace2_region_leave(category, label, repo) \ + trace2_region_leave_fl(__FILE__, __LINE__, (category), (label), (repo)) + +void trace2_region_leave_printf_va_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, va_list ap); + +#define trace2_region_leave_printf_va(category, label, repo, fmt, ap) \ + trace2_region_leave_printf_va_fl(__FILE__, __LINE__, (category), \ + (label), (repo), (fmt), (ap)) + +void trace2_region_leave_printf_fl(const char *file, int line, + const char *category, const char *label, + const struct repository *repo, + const char *fmt, ...); + +#ifdef HAVE_VARIADIC_MACROS +#define trace2_region_leave_printf(category, label, repo, ...) \ + trace2_region_leave_printf_fl(__FILE__, __LINE__, (category), (label), \ + (repo), __VA_ARGS__) +#else +/* clang-format off */ +__attribute__((format (region_leave_printf, 4, 5))) +void trace2_region_leave_printf(const char *category, const char *label, + const struct repository *repo, const char *fmt, + ...); +/* clang-format on */ +#endif + +/* + * Emit a key-value pair 'data' event of the form <category>.<key> = <value>. + * This event implicitly contains information about thread, nesting region, + * and optional repo-id. + * + * On event-based TRACE2 targets, this generates a 'data' event suitable + * for post-processing. On printf-based TRACE2 targets, this is converted + * into a fixed-format printf message. + */ +void trace2_data_string_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + const char *value); + +#define trace2_data_string(category, repo, key, value) \ + trace2_data_string_fl(__FILE__, __LINE__, (category), (repo), (key), \ + (value)) + +void trace2_data_intmax_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + intmax_t value); + +#define trace2_data_intmax(category, repo, key, value) \ + trace2_data_intmax_fl(__FILE__, __LINE__, (category), (repo), (key), \ + (value)) + +void trace2_data_json_fl(const char *file, int line, const char *category, + const struct repository *repo, const char *key, + const struct json_writer *jw); + +#define trace2_data_json(category, repo, key, value) \ + trace2_data_json_fl(__FILE__, __LINE__, (category), (repo), (key), \ + (value)) + +/* + * Emit a 'printf' event. + * + * Write an arbitrary formatted message to the TRACE2 targets. These + * text messages should be considered as human-readable strings without + * any formatting guidelines. Post-processors may choose to ignore + * them. + */ +void trace2_printf_va_fl(const char *file, int line, const char *fmt, + va_list ap); + +#define trace2_printf_va(fmt, ap) \ + trace2_printf_va_fl(__FILE__, __LINE__, (fmt), (ap)) + +void trace2_printf_fl(const char *file, int line, const char *fmt, ...); + +#ifdef HAVE_VARIADIC_MACROS +#define trace2_printf(...) trace2_printf_fl(__FILE__, __LINE__, __VA_ARGS__) +#else +/* clang-format off */ +__attribute__((format (printf, 1, 2))) +void trace2_printf(const char *fmt, ...); +/* clang-format on */ +#endif + +/* + * Optional platform-specific code to dump information about the + * current and any parent process(es). This is intended to allow + * post-processors to know who spawned this git instance and anything + * else the platform may be able to tell us about the current process. + */ +#if defined(GIT_WINDOWS_NATIVE) +void trace2_collect_process_info(void); +#else +#define trace2_collect_process_info() \ + do { \ + } while (0) +#endif + +#endif /* TRACE2_H */ diff --git a/trace2/tr2_cfg.c b/trace2/tr2_cfg.c new file mode 100644 index 0000000000..b329921ac5 --- /dev/null +++ b/trace2/tr2_cfg.c @@ -0,0 +1,90 @@ +#include "cache.h" +#include "config.h" +#include "tr2_cfg.h" + +#define TR2_ENVVAR_CFG_PARAM "GIT_TR2_CONFIG_PARAMS" + +static struct strbuf **tr2_cfg_patterns; +static int tr2_cfg_count_patterns; +static int tr2_cfg_loaded; + +/* + * Parse a string containing a comma-delimited list of config keys + * or wildcard patterns into a list of strbufs. + */ +static int tr2_cfg_load_patterns(void) +{ + struct strbuf **s; + const char *envvar; + + if (tr2_cfg_loaded) + return tr2_cfg_count_patterns; + tr2_cfg_loaded = 1; + + envvar = getenv(TR2_ENVVAR_CFG_PARAM); + if (!envvar || !*envvar) + return tr2_cfg_count_patterns; + + 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; +} + +void tr2_cfg_free_patterns(void) +{ + if (tr2_cfg_patterns) + strbuf_list_free(tr2_cfg_patterns); + tr2_cfg_count_patterns = 0; + tr2_cfg_loaded = 0; +} + +struct tr2_cfg_data { + const char *file; + int line; +}; + +/* + * See if the given config key matches any of our patterns of interest. + */ +static int tr2_cfg_cb(const char *key, const char *value, void *d) +{ + struct strbuf **s; + 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); + if (wm == WM_MATCH) { + trace2_def_param_fl(data->file, data->line, key, value); + return 0; + } + } + + return 0; +} + +void tr2_cfg_list_config_fl(const char *file, int line) +{ + struct tr2_cfg_data data = { file, line }; + + if (tr2_cfg_load_patterns() > 0) + read_early_config(tr2_cfg_cb, &data); +} + +void tr2_cfg_set_fl(const char *file, int line, const char *key, + const char *value) +{ + struct tr2_cfg_data data = { file, line }; + + if (tr2_cfg_load_patterns() > 0) + tr2_cfg_cb(key, value, &data); +} diff --git a/trace2/tr2_cfg.h b/trace2/tr2_cfg.h new file mode 100644 index 0000000000..d9c98f64dd --- /dev/null +++ b/trace2/tr2_cfg.h @@ -0,0 +1,19 @@ +#ifndef TR2_CFG_H +#define TR2_CFG_H + +/* + * Iterate over all config settings and emit 'def_param' events for the + * "interesting" ones to TRACE2. + */ +void tr2_cfg_list_config_fl(const char *file, int line); + +/* + * Emit a "def_param" event for the given key/value pair IF we consider + * the key to be "interesting". + */ +void tr2_cfg_set_fl(const char *file, int line, const char *key, + const char *value); + +void tr2_cfg_free_patterns(void); + +#endif /* TR2_CFG_H */ diff --git a/trace2/tr2_cmd_name.c b/trace2/tr2_cmd_name.c new file mode 100644 index 0000000000..e999592b4c --- /dev/null +++ b/trace2/tr2_cmd_name.c @@ -0,0 +1,30 @@ +#include "cache.h" +#include "trace2/tr2_cmd_name.h" + +#define TR2_ENVVAR_PARENT_NAME "GIT_TR2_PARENT_NAME" + +static struct strbuf tr2cmdname_hierarchy = STRBUF_INIT; + +void tr2_cmd_name_append_hierarchy(const char *name) +{ + const char *parent_name = getenv(TR2_ENVVAR_PARENT_NAME); + + strbuf_reset(&tr2cmdname_hierarchy); + if (parent_name && *parent_name) { + strbuf_addstr(&tr2cmdname_hierarchy, parent_name); + strbuf_addch(&tr2cmdname_hierarchy, '/'); + } + strbuf_addstr(&tr2cmdname_hierarchy, name); + + setenv(TR2_ENVVAR_PARENT_NAME, tr2cmdname_hierarchy.buf, 1); +} + +const char *tr2_cmd_name_get_hierarchy(void) +{ + return tr2cmdname_hierarchy.buf; +} + +void tr2_cmd_name_release(void) +{ + strbuf_release(&tr2cmdname_hierarchy); +} diff --git a/trace2/tr2_cmd_name.h b/trace2/tr2_cmd_name.h new file mode 100644 index 0000000000..ab70b67a8e --- /dev/null +++ b/trace2/tr2_cmd_name.h @@ -0,0 +1,24 @@ +#ifndef TR2_CMD_NAME_H +#define TR2_CMD_NAME_H + +/* + * Append the current command name to the list being maintained + * in the environment. + * + * The hierarchy for a top-level git command is just the current + * command name. For a child git process, the hierarchy includes the + * names of the parent processes. + * + * The hierarchy for the current process will be exported to the + * environment and inherited by child processes. + */ +void tr2_cmd_name_append_hierarchy(const char *name); + +/* + * Get the command name hierarchy for the current process. + */ +const char *tr2_cmd_name_get_hierarchy(void); + +void tr2_cmd_name_release(void); + +#endif /* TR2_CMD_NAME_H */ diff --git a/trace2/tr2_dst.c b/trace2/tr2_dst.c new file mode 100644 index 0000000000..fd490a43ad --- /dev/null +++ b/trace2/tr2_dst.c @@ -0,0 +1,252 @@ +#include "cache.h" +#include "trace2/tr2_dst.h" + +/* + * If a Trace2 target cannot be opened for writing, we should issue a + * warning to stderr, but this is very annoying if the target is a pipe + * or socket and beyond the user's control -- especially since every + * git command (and sub-command) will print the message. So we silently + * eat these warnings and just discard the trace data. + * + * Enable the following environment variable to see these warnings. + */ +#define TR2_ENVVAR_DST_DEBUG "GIT_TR2_DST_DEBUG" + +static int tr2_dst_want_warning(void) +{ + static int tr2env_dst_debug = -1; + + if (tr2env_dst_debug == -1) { + const char *env_value = getenv(TR2_ENVVAR_DST_DEBUG); + if (!env_value || !*env_value) + tr2env_dst_debug = 0; + else + tr2env_dst_debug = atoi(env_value) > 0; + } + + return tr2env_dst_debug; +} + +void tr2_dst_trace_disable(struct tr2_dst *dst) +{ + if (dst->need_close) + close(dst->fd); + dst->fd = 0; + dst->initialized = 1; + dst->need_close = 0; +} + +static int tr2_dst_try_path(struct tr2_dst *dst, const char *tgt_value) +{ + int fd = open(tgt_value, O_WRONLY | O_APPEND | O_CREAT, 0666); + if (fd == -1) { + if (tr2_dst_want_warning()) + warning("trace2: could not open '%s' for '%s' tracing: %s", + tgt_value, dst->env_var_name, strerror(errno)); + + tr2_dst_trace_disable(dst); + return 0; + } + + dst->fd = fd; + dst->need_close = 1; + dst->initialized = 1; + + return dst->fd; +} + +#ifndef NO_UNIX_SOCKETS +#define PREFIX_AF_UNIX "af_unix:" +#define PREFIX_AF_UNIX_STREAM "af_unix:stream:" +#define PREFIX_AF_UNIX_DGRAM "af_unix:dgram:" + +static int tr2_dst_try_uds_connect(const char *path, int sock_type, int *out_fd) +{ + int fd; + struct sockaddr_un sa; + + fd = socket(AF_UNIX, sock_type, 0); + if (fd == -1) + return errno; + + sa.sun_family = AF_UNIX; + strlcpy(sa.sun_path, path, sizeof(sa.sun_path)); + + if (connect(fd, (struct sockaddr *)&sa, sizeof(sa)) == -1) { + int e = errno; + close(fd); + return e; + } + + *out_fd = fd; + return 0; +} + +#define TR2_DST_UDS_TRY_STREAM (1 << 0) +#define TR2_DST_UDS_TRY_DGRAM (1 << 1) + +static int tr2_dst_try_unix_domain_socket(struct tr2_dst *dst, + const char *tgt_value) +{ + unsigned int uds_try = 0; + int fd; + int e; + const char *path = NULL; + + /* + * Allow "af_unix:[<type>:]<absolute_path>" + * + * Trace2 always writes complete individual messages (without + * chunking), so we can talk to either DGRAM or STREAM type sockets. + * + * Allow the user to explicitly request the socket type. + * + * If they omit the socket type, try one and then the other. + */ + + if (skip_prefix(tgt_value, PREFIX_AF_UNIX_STREAM, &path)) + uds_try |= TR2_DST_UDS_TRY_STREAM; + + else if (skip_prefix(tgt_value, PREFIX_AF_UNIX_DGRAM, &path)) + uds_try |= TR2_DST_UDS_TRY_DGRAM; + + else if (skip_prefix(tgt_value, PREFIX_AF_UNIX, &path)) + uds_try |= TR2_DST_UDS_TRY_STREAM | TR2_DST_UDS_TRY_DGRAM; + + if (!path || !*path) { + if (tr2_dst_want_warning()) + warning("trace2: invalid AF_UNIX value '%s' for '%s' tracing", + tgt_value, dst->env_var_name); + + tr2_dst_trace_disable(dst); + return 0; + } + + if (!is_absolute_path(path) || + strlen(path) >= sizeof(((struct sockaddr_un *)0)->sun_path)) { + if (tr2_dst_want_warning()) + warning("trace2: invalid AF_UNIX path '%s' for '%s' tracing", + path, dst->env_var_name); + + tr2_dst_trace_disable(dst); + return 0; + } + + if (uds_try & TR2_DST_UDS_TRY_STREAM) { + e = tr2_dst_try_uds_connect(path, SOCK_STREAM, &fd); + if (!e) + goto connected; + if (e != EPROTOTYPE) + goto error; + } + if (uds_try & TR2_DST_UDS_TRY_DGRAM) { + e = tr2_dst_try_uds_connect(path, SOCK_DGRAM, &fd); + if (!e) + goto connected; + } + +error: + if (tr2_dst_want_warning()) + warning("trace2: could not connect to socket '%s' for '%s' tracing: %s", + path, dst->env_var_name, strerror(e)); + + tr2_dst_trace_disable(dst); + return 0; + +connected: + dst->fd = fd; + dst->need_close = 1; + dst->initialized = 1; + + return dst->fd; +} +#endif + +static void tr2_dst_malformed_warning(struct tr2_dst *dst, + const char *tgt_value) +{ + struct strbuf buf = STRBUF_INIT; + + strbuf_addf(&buf, "trace2: unknown value for '%s': '%s'", + dst->env_var_name, tgt_value); + warning("%s", buf.buf); + + strbuf_release(&buf); +} + +int tr2_dst_get_trace_fd(struct tr2_dst *dst) +{ + const char *tgt_value; + + /* don't open twice */ + if (dst->initialized) + return dst->fd; + + dst->initialized = 1; + + tgt_value = getenv(dst->env_var_name); + + if (!tgt_value || !strcmp(tgt_value, "") || !strcmp(tgt_value, "0") || + !strcasecmp(tgt_value, "false")) { + dst->fd = 0; + return dst->fd; + } + + if (!strcmp(tgt_value, "1") || !strcasecmp(tgt_value, "true")) { + dst->fd = STDERR_FILENO; + return dst->fd; + } + + if (strlen(tgt_value) == 1 && isdigit(*tgt_value)) { + dst->fd = atoi(tgt_value); + return dst->fd; + } + + if (is_absolute_path(tgt_value)) + return tr2_dst_try_path(dst, tgt_value); + +#ifndef NO_UNIX_SOCKETS + if (starts_with(tgt_value, PREFIX_AF_UNIX)) + return tr2_dst_try_unix_domain_socket(dst, tgt_value); +#endif + + /* Always warn about malformed values. */ + tr2_dst_malformed_warning(dst, tgt_value); + tr2_dst_trace_disable(dst); + return 0; +} + +int tr2_dst_trace_want(struct tr2_dst *dst) +{ + return !!tr2_dst_get_trace_fd(dst); +} + +void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line) +{ + int fd = tr2_dst_get_trace_fd(dst); + + strbuf_complete_line(buf_line); /* ensure final NL on buffer */ + + /* + * We do not use write_in_full() because we do not want + * a short-write to try again. We are using O_APPEND mode + * files and the kernel handles the atomic seek+write. If + * another thread or git process is concurrently writing to + * this fd or file, our remainder-write may not be contiguous + * with our initial write of this message. And that will + * confuse readers. So just don't bother. + * + * It is assumed that TRACE2 messages are short enough that + * the system can write them in 1 attempt and we won't see + * a short-write. + * + * If we get an IO error, just close the trace dst. + */ + if (write(fd, buf_line->buf, buf_line->len) >= 0) + return; + + if (tr2_dst_want_warning()) + warning("unable to write trace to '%s': %s", dst->env_var_name, + strerror(errno)); + tr2_dst_trace_disable(dst); +} diff --git a/trace2/tr2_dst.h b/trace2/tr2_dst.h new file mode 100644 index 0000000000..9a64f05b02 --- /dev/null +++ b/trace2/tr2_dst.h @@ -0,0 +1,36 @@ +#ifndef TR2_DST_H +#define TR2_DST_H + +struct strbuf; + +struct tr2_dst { + const char *const env_var_name; + int fd; + unsigned int initialized : 1; + unsigned int need_close : 1; +}; + +/* + * Disable TRACE2 on the destination. In TRACE2 a destination (DST) + * wraps a file descriptor; it is associated with a TARGET which + * defines the formatting. + */ +void tr2_dst_trace_disable(struct tr2_dst *dst); + +/* + * Return the file descriptor for the DST. + * If 0, the dst is closed or disabled. + */ +int tr2_dst_get_trace_fd(struct tr2_dst *dst); + +/* + * Return true if the DST is opened for writing. + */ +int tr2_dst_trace_want(struct tr2_dst *dst); + +/* + * Write a single line/message to the trace file. + */ +void tr2_dst_write_line(struct tr2_dst *dst, struct strbuf *buf_line); + +#endif /* TR2_DST_H */ diff --git a/trace2/tr2_sid.c b/trace2/tr2_sid.c new file mode 100644 index 0000000000..984524a43c --- /dev/null +++ b/trace2/tr2_sid.c @@ -0,0 +1,67 @@ +#include "cache.h" +#include "trace2/tr2_sid.h" + +#define TR2_ENVVAR_PARENT_SID "GIT_TR2_PARENT_SID" + +static struct strbuf tr2sid_buf = STRBUF_INIT; +static int tr2sid_nr_git_parents; + +/* + * Compute a "unique" session id (SID) for the current process. This allows + * all events from this process to have a single label (much like a PID). + * + * Export this into our environment so that all child processes inherit it. + * + * If we were started by another git instance, use our parent's SID as a + * prefix. (This lets us track parent/child relationships even if there + * is an intermediate shell process.) + * + * Additionally, count the number of nested git processes. + */ +static void tr2_sid_compute(void) +{ + uint64_t us_now; + const char *parent_sid; + + if (tr2sid_buf.len) + return; + + parent_sid = getenv(TR2_ENVVAR_PARENT_SID); + if (parent_sid && *parent_sid) { + const char *p; + for (p = parent_sid; *p; p++) + if (*p == '/') + tr2sid_nr_git_parents++; + + strbuf_addstr(&tr2sid_buf, parent_sid); + strbuf_addch(&tr2sid_buf, '/'); + tr2sid_nr_git_parents++; + } + + us_now = getnanotime() / 1000; + strbuf_addf(&tr2sid_buf, "%" PRIuMAX "-%" PRIdMAX, (uintmax_t)us_now, + (intmax_t)getpid()); + + setenv(TR2_ENVVAR_PARENT_SID, tr2sid_buf.buf, 1); +} + +const char *tr2_sid_get(void) +{ + if (!tr2sid_buf.len) + tr2_sid_compute(); + + return tr2sid_buf.buf; +} + +int tr2_sid_depth(void) +{ + if (!tr2sid_buf.len) + tr2_sid_compute(); + + return tr2sid_nr_git_parents; +} + +void tr2_sid_release(void) +{ + strbuf_release(&tr2sid_buf); +} diff --git a/trace2/tr2_sid.h b/trace2/tr2_sid.h new file mode 100644 index 0000000000..9bef321708 --- /dev/null +++ b/trace2/tr2_sid.h @@ -0,0 +1,18 @@ +#ifndef TR2_SID_H +#define TR2_SID_H + +/* + * Get our session id. Compute if necessary. + */ +const char *tr2_sid_get(void); + +/* + * Get our process depth. A top-level git process invoked from the + * command line will have depth=0. A child git process will have + * depth=1 and so on. + */ +int tr2_sid_depth(void); + +void tr2_sid_release(void); + +#endif /* TR2_SID_H */ diff --git a/trace2/tr2_tbuf.c b/trace2/tr2_tbuf.c new file mode 100644 index 0000000000..0844910423 --- /dev/null +++ b/trace2/tr2_tbuf.c @@ -0,0 +1,32 @@ +#include "cache.h" +#include "tr2_tbuf.h" + +void tr2_tbuf_local_time(struct tr2_tbuf *tb) +{ + struct timeval tv; + struct tm tm; + time_t secs; + + gettimeofday(&tv, NULL); + secs = tv.tv_sec; + localtime_r(&secs, &tm); + + xsnprintf(tb->buf, sizeof(tb->buf), "%02d:%02d:%02d.%06ld", tm.tm_hour, + tm.tm_min, tm.tm_sec, (long)tv.tv_usec); +} + +void tr2_tbuf_utc_time(struct tr2_tbuf *tb) +{ + struct timeval tv; + struct tm tm; + time_t secs; + + gettimeofday(&tv, NULL); + secs = tv.tv_sec; + gmtime_r(&secs, &tm); + + xsnprintf(tb->buf, sizeof(tb->buf), + "%4d-%02d-%02d %02d:%02d:%02d.%06ld", tm.tm_year + 1900, + tm.tm_mon + 1, tm.tm_mday, tm.tm_hour, tm.tm_min, tm.tm_sec, + (long)tv.tv_usec); +} diff --git a/trace2/tr2_tbuf.h b/trace2/tr2_tbuf.h new file mode 100644 index 0000000000..9cdefa3957 --- /dev/null +++ b/trace2/tr2_tbuf.h @@ -0,0 +1,23 @@ +#ifndef TR2_TBUF_H +#define TR2_TBUF_H + +/* + * A simple wrapper around a fixed buffer to avoid C syntax + * quirks and the need to pass around an additional size_t + * argument. + */ +struct tr2_tbuf { + char buf[32]; +}; + +/* + * Fill buffer with formatted local time string. + */ +void tr2_tbuf_local_time(struct tr2_tbuf *tb); + +/* + * Fill buffer with formatted UTC time string. + */ +void tr2_tbuf_utc_time(struct tr2_tbuf *tb); + +#endif /* TR2_TBUF_H */ diff --git a/trace2/tr2_tgt.h b/trace2/tr2_tgt.h new file mode 100644 index 0000000000..297bb8ffbe --- /dev/null +++ b/trace2/tr2_tgt.h @@ -0,0 +1,133 @@ +#ifndef TR2_TGT_H +#define TR2_TGT_H + +struct child_process; +struct repository; +struct json_writer; + +/* + * Function prototypes for a TRACE2 "target" vtable. + */ + +typedef int(tr2_tgt_init_t)(void); +typedef void(tr2_tgt_term_t)(void); + +typedef void(tr2_tgt_evt_version_fl_t)(const char *file, int line); + +typedef void(tr2_tgt_evt_start_fl_t)(const char *file, int line, + const char **argv); +typedef void(tr2_tgt_evt_exit_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, int code); +typedef void(tr2_tgt_evt_signal_t)(uint64_t us_elapsed_absolute, int signo); +typedef void(tr2_tgt_evt_atexit_t)(uint64_t us_elapsed_absolute, int code); + +typedef void(tr2_tgt_evt_error_va_fl_t)(const char *file, int line, + const char *fmt, va_list ap); + +typedef void(tr2_tgt_evt_command_path_fl_t)(const char *file, int line, + const char *command_path); +typedef void(tr2_tgt_evt_command_name_fl_t)(const char *file, int line, + const char *name, + const char *hierarchy); +typedef void(tr2_tgt_evt_command_mode_fl_t)(const char *file, int line, + const char *mode); + +typedef void(tr2_tgt_evt_alias_fl_t)(const char *file, int line, + const char *alias, const char **argv); + +typedef void(tr2_tgt_evt_child_start_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + const struct child_process *cmd); +typedef void(tr2_tgt_evt_child_exit_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, int cid, + int pid, int code, + uint64_t us_elapsed_child); + +typedef void(tr2_tgt_evt_thread_start_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute); +typedef void(tr2_tgt_evt_thread_exit_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_thread); + +typedef void(tr2_tgt_evt_exec_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, int exec_id, + const char *exe, const char **argv); +typedef void(tr2_tgt_evt_exec_result_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + int exec_id, int code); + +typedef void(tr2_tgt_evt_param_fl_t)(const char *file, int line, + const char *param, const char *value); + +typedef void(tr2_tgt_evt_repo_fl_t)(const char *file, int line, + const struct repository *repo); + +typedef void(tr2_tgt_evt_region_enter_printf_va_fl_t)( + const char *file, int line, uint64_t us_elapsed_absolute, + const char *category, const char *label, const struct repository *repo, + const char *fmt, va_list ap); +typedef void(tr2_tgt_evt_region_leave_printf_va_fl_t)( + const char *file, int line, uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, const char *label, + const struct repository *repo, const char *fmt, va_list ap); + +typedef void(tr2_tgt_evt_data_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, + const char *category, + const struct repository *repo, + const char *key, const char *value); +typedef void(tr2_tgt_evt_data_json_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, + const char *category, + const struct repository *repo, + const char *key, + const struct json_writer *value); + +typedef void(tr2_tgt_evt_printf_va_fl_t)(const char *file, int line, + uint64_t us_elapsed_absolute, + const char *fmt, va_list ap); + +/* + * "vtable" for a TRACE2 target. Use NULL if a target does not want + * to emit that message. + */ +/* clang-format off */ +struct tr2_tgt { + struct tr2_dst *pdst; + + tr2_tgt_init_t *pfn_init; + tr2_tgt_term_t *pfn_term; + + tr2_tgt_evt_version_fl_t *pfn_version_fl; + tr2_tgt_evt_start_fl_t *pfn_start_fl; + tr2_tgt_evt_exit_fl_t *pfn_exit_fl; + tr2_tgt_evt_signal_t *pfn_signal; + tr2_tgt_evt_atexit_t *pfn_atexit; + tr2_tgt_evt_error_va_fl_t *pfn_error_va_fl; + tr2_tgt_evt_command_path_fl_t *pfn_command_path_fl; + tr2_tgt_evt_command_name_fl_t *pfn_command_name_fl; + tr2_tgt_evt_command_mode_fl_t *pfn_command_mode_fl; + tr2_tgt_evt_alias_fl_t *pfn_alias_fl; + tr2_tgt_evt_child_start_fl_t *pfn_child_start_fl; + tr2_tgt_evt_child_exit_fl_t *pfn_child_exit_fl; + tr2_tgt_evt_thread_start_fl_t *pfn_thread_start_fl; + tr2_tgt_evt_thread_exit_fl_t *pfn_thread_exit_fl; + tr2_tgt_evt_exec_fl_t *pfn_exec_fl; + tr2_tgt_evt_exec_result_fl_t *pfn_exec_result_fl; + tr2_tgt_evt_param_fl_t *pfn_param_fl; + tr2_tgt_evt_repo_fl_t *pfn_repo_fl; + tr2_tgt_evt_region_enter_printf_va_fl_t *pfn_region_enter_printf_va_fl; + tr2_tgt_evt_region_leave_printf_va_fl_t *pfn_region_leave_printf_va_fl; + tr2_tgt_evt_data_fl_t *pfn_data_fl; + tr2_tgt_evt_data_json_fl_t *pfn_data_json_fl; + tr2_tgt_evt_printf_va_fl_t *pfn_printf_va_fl; +}; +/* clang-format on */ + +extern struct tr2_tgt tr2_tgt_event; +extern struct tr2_tgt tr2_tgt_normal; +extern struct tr2_tgt tr2_tgt_perf; + +#endif /* TR2_TGT_H */ diff --git a/trace2/tr2_tgt_event.c b/trace2/tr2_tgt_event.c new file mode 100644 index 0000000000..107cb5317d --- /dev/null +++ b/trace2/tr2_tgt_event.c @@ -0,0 +1,588 @@ +#include "cache.h" +#include "config.h" +#include "json-writer.h" +#include "run-command.h" +#include "version.h" +#include "trace2/tr2_dst.h" +#include "trace2/tr2_tbuf.h" +#include "trace2/tr2_sid.h" +#include "trace2/tr2_tgt.h" +#include "trace2/tr2_tls.h" + +static struct tr2_dst tr2dst_event = { "GIT_TR2_EVENT", 0, 0, 0 }; + +/* + * The version number of the JSON data generated by the EVENT target + * in this source file. Update this if you make a significant change + * to the JSON fields or message structure. You probably do not need + * to update this if you just add another call to one of the existing + * TRACE2 API methods. + */ +#define TR2_EVENT_VERSION "1" + +/* + * Region nesting limit for messages written to the event target. + * + * The "region_enter" and "region_leave" messages (especially recursive + * messages such as those produced while diving the worktree or index) + * are primarily intended for the performance target during debugging. + * + * Some of the outer-most messages, however, may be of interest to the + * event target. Set this environment variable to a larger integer for + * more detail in the event target. + */ +#define TR2_ENVVAR_EVENT_NESTING "GIT_TR2_EVENT_NESTING" +static int tr2env_event_nesting_wanted = 2; + +/* + * Set this environment variable to true to omit the <time>, <file>, and + * <line> fields from most events. + */ +#define TR2_ENVVAR_EVENT_BRIEF "GIT_TR2_EVENT_BRIEF" +static int tr2env_event_brief; + +static int fn_init(void) +{ + int want = tr2_dst_trace_want(&tr2dst_event); + int want_nesting; + int want_brief; + char *nesting; + char *brief; + + if (!want) + return want; + + nesting = getenv(TR2_ENVVAR_EVENT_NESTING); + if (nesting && ((want_nesting = atoi(nesting)) > 0)) + tr2env_event_nesting_wanted = want_nesting; + + brief = getenv(TR2_ENVVAR_EVENT_BRIEF); + if (brief && ((want_brief = atoi(brief)) > 0)) + tr2env_event_brief = want_brief; + + return want; +} + +static void fn_term(void) +{ + tr2_dst_trace_disable(&tr2dst_event); +} + +/* + * Append common key-value pairs to the currently open JSON object. + * "event:"<event_name>" + * "sid":"<sid>" + * "thread":"<thread_name>" + * "time":"<time>" + * "file":"<filename>" + * "line":<line_number> + * "repo":<repo_id> + */ +static void event_fmt_prepare(const char *event_name, const char *file, + int line, const struct repository *repo, + struct json_writer *jw) +{ + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + struct tr2_tbuf tb_now; + + jw_object_string(jw, "event", event_name); + jw_object_string(jw, "sid", tr2_sid_get()); + jw_object_string(jw, "thread", ctx->thread_name.buf); + + /* + * In brief mode, only emit <time> on these 2 event types. + */ + if (!tr2env_event_brief || !strcmp(event_name, "version") || + !strcmp(event_name, "atexit")) { + tr2_tbuf_utc_time(&tb_now); + jw_object_string(jw, "time", tb_now.buf); + } + + if (!tr2env_event_brief && file && *file) { + jw_object_string(jw, "file", file); + jw_object_intmax(jw, "line", line); + } + + if (repo) + jw_object_intmax(jw, "repo", repo->trace2_repo_id); +} + +static void fn_version_fl(const char *file, int line) +{ + const char *event_name = "version"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "evt", TR2_EVENT_VERSION); + jw_object_string(&jw, "exe", git_version_string); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_start_fl(const char *file, int line, const char **argv) +{ + const char *event_name = "start"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_inline_begin_array(&jw, "argv"); + jw_array_argv(&jw, argv); + jw_end(&jw); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int code) +{ + const char *event_name = "exit"; + struct json_writer jw = JSON_WRITER_INIT; + double t_abs = (double)us_elapsed_absolute / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_double(&jw, "t_abs", 6, t_abs); + jw_object_intmax(&jw, "code", code); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_signal(uint64_t us_elapsed_absolute, int signo) +{ + const char *event_name = "signal"; + struct json_writer jw = JSON_WRITER_INIT; + double t_abs = (double)us_elapsed_absolute / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw); + jw_object_double(&jw, "t_abs", 6, t_abs); + jw_object_intmax(&jw, "signo", signo); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_atexit(uint64_t us_elapsed_absolute, int code) +{ + const char *event_name = "atexit"; + struct json_writer jw = JSON_WRITER_INIT; + double t_abs = (double)us_elapsed_absolute / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, __FILE__, __LINE__, NULL, &jw); + jw_object_double(&jw, "t_abs", 6, t_abs); + jw_object_intmax(&jw, "code", code); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void maybe_add_string_va(struct json_writer *jw, const char *field_name, + const char *fmt, va_list ap) +{ + if (fmt && *fmt && ap) { + va_list copy_ap; + struct strbuf buf = STRBUF_INIT; + + va_copy(copy_ap, ap); + strbuf_vaddf(&buf, fmt, copy_ap); + va_end(copy_ap); + + jw_object_string(jw, field_name, buf.buf); + strbuf_release(&buf); + return; + } + + if (fmt && *fmt) { + jw_object_string(jw, field_name, fmt); + return; + } +} + +static void fn_error_va_fl(const char *file, int line, const char *fmt, + va_list ap) +{ + const char *event_name = "error"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + maybe_add_string_va(&jw, "msg", fmt, ap); + /* + * Also emit the format string as a field in case + * post-processors want to aggregate common error + * messages by type without argument fields (such + * as pathnames or branch names) cluttering it up. + */ + if (fmt && *fmt) + jw_object_string(&jw, "fmt", fmt); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_command_path_fl(const char *file, int line, const char *pathname) +{ + const char *event_name = "cmd_path"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "path", pathname); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_command_name_fl(const char *file, int line, const char *name, + const char *hierarchy) +{ + const char *event_name = "cmd_name"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "name", name); + if (hierarchy && *hierarchy) + jw_object_string(&jw, "hierarchy", hierarchy); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_command_mode_fl(const char *file, int line, const char *mode) +{ + const char *event_name = "cmd_mode"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "name", mode); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_alias_fl(const char *file, int line, const char *alias, + const char **argv) +{ + const char *event_name = "alias"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "alias", alias); + jw_object_inline_begin_array(&jw, "argv"); + jw_array_argv(&jw, argv); + jw_end(&jw); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_child_start_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + const struct child_process *cmd) +{ + const char *event_name = "child_start"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_intmax(&jw, "child_id", cmd->trace2_child_id); + if (cmd->trace2_hook_name) { + jw_object_string(&jw, "child_class", "hook"); + jw_object_string(&jw, "hook_name", cmd->trace2_hook_name); + } else { + const char *child_class = + cmd->trace2_child_class ? cmd->trace2_child_class : "?"; + jw_object_string(&jw, "child_class", child_class); + } + if (cmd->dir) + jw_object_string(&jw, "cd", cmd->dir); + jw_object_bool(&jw, "use_shell", cmd->use_shell); + jw_object_inline_begin_array(&jw, "argv"); + if (cmd->git_cmd) + jw_array_string(&jw, "git"); + jw_array_argv(&jw, cmd->argv); + jw_end(&jw); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_child_exit_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int cid, int pid, + int code, uint64_t us_elapsed_child) +{ + const char *event_name = "child_exit"; + struct json_writer jw = JSON_WRITER_INIT; + double t_rel = (double)us_elapsed_child / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_intmax(&jw, "child_id", cid); + jw_object_intmax(&jw, "pid", pid); + jw_object_intmax(&jw, "code", code); + jw_object_double(&jw, "t_rel", 6, t_rel); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + + jw_release(&jw); +} + +static void fn_thread_start_fl(const char *file, int line, + uint64_t us_elapsed_absolute) +{ + const char *event_name = "thread_start"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_thread_exit_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_thread) +{ + const char *event_name = "thread_exit"; + struct json_writer jw = JSON_WRITER_INIT; + double t_rel = (double)us_elapsed_thread / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_double(&jw, "t_rel", 6, t_rel); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int exec_id, const char *exe, const char **argv) +{ + const char *event_name = "exec"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_intmax(&jw, "exec_id", exec_id); + if (exe) + jw_object_string(&jw, "exe", exe); + jw_object_inline_begin_array(&jw, "argv"); + jw_array_argv(&jw, argv); + jw_end(&jw); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_exec_result_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int exec_id, + int code) +{ + const char *event_name = "exec_result"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_intmax(&jw, "exec_id", exec_id); + jw_object_intmax(&jw, "code", code); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_param_fl(const char *file, int line, const char *param, + const char *value) +{ + const char *event_name = "def_param"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, NULL, &jw); + jw_object_string(&jw, "param", param); + jw_object_string(&jw, "value", value); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_repo_fl(const char *file, int line, + const struct repository *repo) +{ + const char *event_name = "def_repo"; + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, repo, &jw); + jw_object_string(&jw, "worktree", repo->worktree); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); +} + +static void fn_region_enter_printf_va_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + const char *category, + const char *label, + const struct repository *repo, + const char *fmt, va_list ap) +{ + const char *event_name = "region_enter"; + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) { + struct json_writer jw = JSON_WRITER_INIT; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, repo, &jw); + jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); + if (category) + jw_object_string(&jw, "category", category); + if (label) + jw_object_string(&jw, "label", label); + maybe_add_string_va(&jw, "msg", fmt, ap); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); + } +} + +static void fn_region_leave_printf_va_fl( + const char *file, int line, uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, const char *label, + const struct repository *repo, const char *fmt, va_list ap) +{ + const char *event_name = "region_leave"; + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) { + struct json_writer jw = JSON_WRITER_INIT; + double t_rel = (double)us_elapsed_region / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, repo, &jw); + jw_object_double(&jw, "t_rel", 6, t_rel); + jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); + if (category) + jw_object_string(&jw, "category", category); + if (label) + jw_object_string(&jw, "label", label); + maybe_add_string_va(&jw, "msg", fmt, ap); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); + } +} + +static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, + const struct repository *repo, const char *key, + const char *value) +{ + const char *event_name = "data"; + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) { + struct json_writer jw = JSON_WRITER_INIT; + double t_abs = (double)us_elapsed_absolute / 1000000.0; + double t_rel = (double)us_elapsed_region / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, repo, &jw); + jw_object_double(&jw, "t_abs", 6, t_abs); + jw_object_double(&jw, "t_rel", 6, t_rel); + jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); + jw_object_string(&jw, "category", category); + jw_object_string(&jw, "key", key); + jw_object_string(&jw, "value", value); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); + } +} + +static void fn_data_json_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, + const struct repository *repo, const char *key, + const struct json_writer *value) +{ + const char *event_name = "data_json"; + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + if (ctx->nr_open_regions <= tr2env_event_nesting_wanted) { + struct json_writer jw = JSON_WRITER_INIT; + double t_abs = (double)us_elapsed_absolute / 1000000.0; + double t_rel = (double)us_elapsed_region / 1000000.0; + + jw_object_begin(&jw, 0); + event_fmt_prepare(event_name, file, line, repo, &jw); + jw_object_double(&jw, "t_abs", 6, t_abs); + jw_object_double(&jw, "t_rel", 6, t_rel); + jw_object_intmax(&jw, "nesting", ctx->nr_open_regions); + jw_object_string(&jw, "category", category); + jw_object_string(&jw, "key", key); + jw_object_sub_jw(&jw, "value", value); + jw_end(&jw); + + tr2_dst_write_line(&tr2dst_event, &jw.json); + jw_release(&jw); + } +} + +struct tr2_tgt tr2_tgt_event = { + &tr2dst_event, + + fn_init, + fn_term, + + fn_version_fl, + fn_start_fl, + fn_exit_fl, + fn_signal, + fn_atexit, + fn_error_va_fl, + fn_command_path_fl, + fn_command_name_fl, + fn_command_mode_fl, + fn_alias_fl, + fn_child_start_fl, + fn_child_exit_fl, + fn_thread_start_fl, + fn_thread_exit_fl, + fn_exec_fl, + fn_exec_result_fl, + fn_param_fl, + fn_repo_fl, + fn_region_enter_printf_va_fl, + fn_region_leave_printf_va_fl, + fn_data_fl, + fn_data_json_fl, + NULL, /* printf */ +}; diff --git a/trace2/tr2_tgt_normal.c b/trace2/tr2_tgt_normal.c new file mode 100644 index 0000000000..547183d5b6 --- /dev/null +++ b/trace2/tr2_tgt_normal.c @@ -0,0 +1,323 @@ +#include "cache.h" +#include "config.h" +#include "run-command.h" +#include "quote.h" +#include "version.h" +#include "trace2/tr2_dst.h" +#include "trace2/tr2_tbuf.h" +#include "trace2/tr2_tgt.h" +#include "trace2/tr2_tls.h" + +static struct tr2_dst tr2dst_normal = { "GIT_TR2", 0, 0, 0 }; + +/* + * Set this environment variable to true to omit the "<time> <file>:<line>" + * fields from each line written to the builtin normal target. + * + * Unit tests may want to use this to help with testing. + */ +#define TR2_ENVVAR_NORMAL_BRIEF "GIT_TR2_BRIEF" +static int tr2env_normal_brief; + +#define TR2FMT_NORMAL_FL_WIDTH (50) + +static int fn_init(void) +{ + int want = tr2_dst_trace_want(&tr2dst_normal); + int want_brief; + char *brief; + + if (!want) + return want; + + brief = getenv(TR2_ENVVAR_NORMAL_BRIEF); + if (brief && *brief && + ((want_brief = git_parse_maybe_bool(brief)) != -1)) + tr2env_normal_brief = want_brief; + + return want; +} + +static void fn_term(void) +{ + tr2_dst_trace_disable(&tr2dst_normal); +} + +static void normal_fmt_prepare(const char *file, int line, struct strbuf *buf) +{ + strbuf_setlen(buf, 0); + + if (!tr2env_normal_brief) { + struct tr2_tbuf tb_now; + + tr2_tbuf_local_time(&tb_now); + strbuf_addstr(buf, tb_now.buf); + strbuf_addch(buf, ' '); + + if (file && *file) + strbuf_addf(buf, "%s:%d ", file, line); + while (buf->len < TR2FMT_NORMAL_FL_WIDTH) + strbuf_addch(buf, ' '); + } +} + +static void normal_io_write_fl(const char *file, int line, + const struct strbuf *buf_payload) +{ + struct strbuf buf_line = STRBUF_INIT; + + normal_fmt_prepare(file, line, &buf_line); + strbuf_addbuf(&buf_line, buf_payload); + tr2_dst_write_line(&tr2dst_normal, &buf_line); + strbuf_release(&buf_line); +} + +static void fn_version_fl(const char *file, int line) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "version %s", git_version_string); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_start_fl(const char *file, int line, const char **argv) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, "start "); + sq_quote_argv_pretty(&buf_payload, argv); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int code) +{ + struct strbuf buf_payload = STRBUF_INIT; + double elapsed = (double)us_elapsed_absolute / 1000000.0; + + strbuf_addf(&buf_payload, "exit elapsed:%.6f code:%d", elapsed, code); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_signal(uint64_t us_elapsed_absolute, int signo) +{ + struct strbuf buf_payload = STRBUF_INIT; + double elapsed = (double)us_elapsed_absolute / 1000000.0; + + strbuf_addf(&buf_payload, "signal elapsed:%.6f code:%d", elapsed, + signo); + normal_io_write_fl(__FILE__, __LINE__, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_atexit(uint64_t us_elapsed_absolute, int code) +{ + struct strbuf buf_payload = STRBUF_INIT; + double elapsed = (double)us_elapsed_absolute / 1000000.0; + + strbuf_addf(&buf_payload, "atexit elapsed:%.6f code:%d", elapsed, code); + normal_io_write_fl(__FILE__, __LINE__, &buf_payload); + strbuf_release(&buf_payload); +} + +static void maybe_append_string_va(struct strbuf *buf, const char *fmt, + va_list ap) +{ + if (fmt && *fmt && ap) { + va_list copy_ap; + + va_copy(copy_ap, ap); + strbuf_vaddf(buf, fmt, copy_ap); + va_end(copy_ap); + return; + } + + if (fmt && *fmt) { + strbuf_addstr(buf, fmt); + return; + } +} + +static void fn_error_va_fl(const char *file, int line, const char *fmt, + va_list ap) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, "error "); + maybe_append_string_va(&buf_payload, fmt, ap); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_path_fl(const char *file, int line, const char *pathname) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "cmd_path %s", pathname); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_name_fl(const char *file, int line, const char *name, + const char *hierarchy) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "cmd_name %s", name); + if (hierarchy && *hierarchy) + strbuf_addf(&buf_payload, " (%s)", hierarchy); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_mode_fl(const char *file, int line, const char *mode) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "cmd_mode %s", mode); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_alias_fl(const char *file, int line, const char *alias, + const char **argv) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "alias %s ->", alias); + sq_quote_argv_pretty(&buf_payload, argv); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_child_start_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + const struct child_process *cmd) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "child_start[%d] ", cmd->trace2_child_id); + + if (cmd->dir) { + strbuf_addstr(&buf_payload, " cd"); + sq_quote_buf_pretty(&buf_payload, cmd->dir); + strbuf_addstr(&buf_payload, "; "); + } + + /* + * TODO if (cmd->env) { Consider dumping changes to environment. } + * See trace_add_env() in run-command.c as used by original trace.c + */ + + if (cmd->git_cmd) + strbuf_addstr(&buf_payload, "git"); + sq_quote_argv_pretty(&buf_payload, cmd->argv); + + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_child_exit_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int cid, int pid, + int code, uint64_t us_elapsed_child) +{ + struct strbuf buf_payload = STRBUF_INIT; + double elapsed = (double)us_elapsed_child / 1000000.0; + + strbuf_addf(&buf_payload, "child_exit[%d] pid:%d code:%d elapsed:%.6f", + cid, pid, code, elapsed); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int exec_id, const char *exe, const char **argv) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "exec[%d] ", exec_id); + if (exe) + strbuf_addstr(&buf_payload, exe); + sq_quote_argv_pretty(&buf_payload, argv); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exec_result_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int exec_id, + int code) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "exec_result[%d] code:%d", exec_id, code); + if (code > 0) + strbuf_addf(&buf_payload, " err:%s", strerror(code)); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_param_fl(const char *file, int line, const char *param, + const char *value) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "def_param %s=%s", param, value); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_repo_fl(const char *file, int line, + const struct repository *repo) +{ + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, "worktree "); + sq_quote_buf_pretty(&buf_payload, repo->worktree); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_printf_va_fl(const char *file, int line, + uint64_t us_elapsed_absolute, const char *fmt, + va_list ap) +{ + struct strbuf buf_payload = STRBUF_INIT; + + maybe_append_string_va(&buf_payload, fmt, ap); + normal_io_write_fl(file, line, &buf_payload); + strbuf_release(&buf_payload); +} + +struct tr2_tgt tr2_tgt_normal = { + &tr2dst_normal, + + fn_init, + fn_term, + + fn_version_fl, + fn_start_fl, + fn_exit_fl, + fn_signal, + fn_atexit, + fn_error_va_fl, + fn_command_path_fl, + fn_command_name_fl, + fn_command_mode_fl, + fn_alias_fl, + fn_child_start_fl, + fn_child_exit_fl, + NULL, /* thread_start */ + NULL, /* thread_exit */ + fn_exec_fl, + fn_exec_result_fl, + fn_param_fl, + fn_repo_fl, + NULL, /* region_enter */ + NULL, /* region_leave */ + NULL, /* data */ + NULL, /* data_json */ + fn_printf_va_fl, +}; diff --git a/trace2/tr2_tgt_perf.c b/trace2/tr2_tgt_perf.c new file mode 100644 index 0000000000..f0746fcf86 --- /dev/null +++ b/trace2/tr2_tgt_perf.c @@ -0,0 +1,534 @@ +#include "cache.h" +#include "config.h" +#include "run-command.h" +#include "quote.h" +#include "version.h" +#include "json-writer.h" +#include "trace2/tr2_dst.h" +#include "trace2/tr2_sid.h" +#include "trace2/tr2_tbuf.h" +#include "trace2/tr2_tgt.h" +#include "trace2/tr2_tls.h" + +static struct tr2_dst tr2dst_perf = { "GIT_TR2_PERF", 0, 0, 0 }; + +/* + * Set this environment variable to true to omit the "<time> <file>:<line>" + * fields from each line written to the builtin performance target. + * + * Unit tests may want to use this to help with testing. + */ +#define TR2_ENVVAR_PERF_BRIEF "GIT_TR2_PERF_BRIEF" +static int tr2env_perf_brief; + +#define TR2FMT_PERF_FL_WIDTH (50) +#define TR2FMT_PERF_MAX_EVENT_NAME (12) +#define TR2FMT_PERF_REPO_WIDTH (4) +#define TR2FMT_PERF_CATEGORY_WIDTH (10) + +#define TR2_DOTS_BUFFER_SIZE (100) +#define TR2_INDENT (2) +#define TR2_INDENT_LENGTH(ctx) (((ctx)->nr_open_regions - 1) * TR2_INDENT) + +static struct strbuf dots = STRBUF_INIT; + +static int fn_init(void) +{ + int want = tr2_dst_trace_want(&tr2dst_perf); + int want_brief; + char *brief; + + if (!want) + return want; + + strbuf_addchars(&dots, '.', TR2_DOTS_BUFFER_SIZE); + + brief = getenv(TR2_ENVVAR_PERF_BRIEF); + if (brief && *brief && + ((want_brief = git_parse_maybe_bool(brief)) != -1)) + tr2env_perf_brief = want_brief; + + return want; +} + +static void fn_term(void) +{ + tr2_dst_trace_disable(&tr2dst_perf); + + strbuf_release(&dots); +} + +/* + * Format trace line prefix in human-readable classic format for + * the performance target: + * "[<time> [<file>:<line>] <bar>] <nr_parents> <bar> + * <thread_name> <bar> <event_name> <bar> [<repo>] <bar> + * [<elapsed_absolute>] [<elapsed_relative>] <bar> + * [<category>] <bar> [<dots>] " + */ +static void perf_fmt_prepare(const char *event_name, + struct tr2tls_thread_ctx *ctx, const char *file, + int line, const struct repository *repo, + uint64_t *p_us_elapsed_absolute, + uint64_t *p_us_elapsed_relative, + const char *category, struct strbuf *buf) +{ + int len; + + strbuf_setlen(buf, 0); + + if (!tr2env_perf_brief) { + struct tr2_tbuf tb_now; + + tr2_tbuf_local_time(&tb_now); + strbuf_addstr(buf, tb_now.buf); + strbuf_addch(buf, ' '); + + if (file && *file) + strbuf_addf(buf, "%s:%d ", file, line); + while (buf->len < TR2FMT_PERF_FL_WIDTH) + strbuf_addch(buf, ' '); + + strbuf_addstr(buf, "| "); + } + + strbuf_addf(buf, "d%d | ", tr2_sid_depth()); + strbuf_addf(buf, "%-*s | %-*s | ", TR2_MAX_THREAD_NAME, + ctx->thread_name.buf, TR2FMT_PERF_MAX_EVENT_NAME, + event_name); + + len = buf->len + TR2FMT_PERF_REPO_WIDTH; + if (repo) + strbuf_addf(buf, "r%d ", repo->trace2_repo_id); + while (buf->len < len) + strbuf_addch(buf, ' '); + strbuf_addstr(buf, "| "); + + if (p_us_elapsed_absolute) + strbuf_addf(buf, "%9.6f | ", + ((double)(*p_us_elapsed_absolute)) / 1000000.0); + else + strbuf_addf(buf, "%9s | ", " "); + + if (p_us_elapsed_relative) + strbuf_addf(buf, "%9.6f | ", + ((double)(*p_us_elapsed_relative)) / 1000000.0); + else + strbuf_addf(buf, "%9s | ", " "); + + strbuf_addf(buf, "%-*s | ", TR2FMT_PERF_CATEGORY_WIDTH, + (category ? category : "")); + + if (ctx->nr_open_regions > 0) { + int len_indent = TR2_INDENT_LENGTH(ctx); + while (len_indent > dots.len) { + strbuf_addbuf(buf, &dots); + len_indent -= dots.len; + } + strbuf_addf(buf, "%.*s", len_indent, dots.buf); + } +} + +static void perf_io_write_fl(const char *file, int line, const char *event_name, + const struct repository *repo, + uint64_t *p_us_elapsed_absolute, + uint64_t *p_us_elapsed_relative, + const char *category, + const struct strbuf *buf_payload) +{ + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + struct strbuf buf_line = STRBUF_INIT; + + perf_fmt_prepare(event_name, ctx, file, line, repo, + p_us_elapsed_absolute, p_us_elapsed_relative, category, + &buf_line); + strbuf_addbuf(&buf_line, buf_payload); + tr2_dst_write_line(&tr2dst_perf, &buf_line); + strbuf_release(&buf_line); +} + +static void fn_version_fl(const char *file, int line) +{ + const char *event_name = "version"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, git_version_string); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_start_fl(const char *file, int line, const char **argv) +{ + const char *event_name = "start"; + struct strbuf buf_payload = STRBUF_INIT; + + sq_quote_argv_pretty(&buf_payload, argv); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exit_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int code) +{ + const char *event_name = "exit"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "code:%d", code); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_signal(uint64_t us_elapsed_absolute, int signo) +{ + const char *event_name = "signal"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "signo:%d", signo); + + perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, + &us_elapsed_absolute, NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_atexit(uint64_t us_elapsed_absolute, int code) +{ + const char *event_name = "atexit"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "code:%d", code); + + perf_io_write_fl(__FILE__, __LINE__, event_name, NULL, + &us_elapsed_absolute, NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void maybe_append_string_va(struct strbuf *buf, const char *fmt, + va_list ap) +{ + if (fmt && *fmt && ap) { + va_list copy_ap; + + va_copy(copy_ap, ap); + strbuf_vaddf(buf, fmt, copy_ap); + va_end(copy_ap); + return; + } + + if (fmt && *fmt) { + strbuf_addstr(buf, fmt); + return; + } +} + +static void fn_error_va_fl(const char *file, int line, const char *fmt, + va_list ap) +{ + const char *event_name = "error"; + struct strbuf buf_payload = STRBUF_INIT; + + maybe_append_string_va(&buf_payload, fmt, ap); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_path_fl(const char *file, int line, const char *pathname) +{ + const char *event_name = "cmd_path"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, pathname); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_name_fl(const char *file, int line, const char *name, + const char *hierarchy) +{ + const char *event_name = "cmd_name"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, name); + if (hierarchy && *hierarchy) + strbuf_addf(&buf_payload, " (%s)", hierarchy); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_command_mode_fl(const char *file, int line, const char *mode) +{ + const char *event_name = "cmd_mode"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, mode); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_alias_fl(const char *file, int line, const char *alias, + const char **argv) +{ + const char *event_name = "alias"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "alias:%s argv:", alias); + sq_quote_argv_pretty(&buf_payload, argv); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_child_start_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + const struct child_process *cmd) +{ + const char *event_name = "child_start"; + struct strbuf buf_payload = STRBUF_INIT; + + if (cmd->trace2_hook_name) { + strbuf_addf(&buf_payload, "[ch%d] class:hook hook:%s", + cmd->trace2_child_id, cmd->trace2_hook_name); + } else { + const char *child_class = + cmd->trace2_child_class ? cmd->trace2_child_class : "?"; + strbuf_addf(&buf_payload, "[ch%d] class:%s", + cmd->trace2_child_id, child_class); + } + + if (cmd->dir) { + strbuf_addstr(&buf_payload, " cd:"); + sq_quote_buf_pretty(&buf_payload, cmd->dir); + } + + strbuf_addstr(&buf_payload, " argv:"); + if (cmd->git_cmd) + strbuf_addstr(&buf_payload, " git"); + sq_quote_argv_pretty(&buf_payload, cmd->argv); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_child_exit_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int cid, int pid, + int code, uint64_t us_elapsed_child) +{ + const char *event_name = "child_exit"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "[ch%d] pid:%d code:%d", cid, pid, code); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + &us_elapsed_child, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_thread_start_fl(const char *file, int line, + uint64_t us_elapsed_absolute) +{ + const char *event_name = "thread_start"; + struct strbuf buf_payload = STRBUF_INIT; + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_thread_exit_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_thread) +{ + const char *event_name = "thread_exit"; + struct strbuf buf_payload = STRBUF_INIT; + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + &us_elapsed_thread, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exec_fl(const char *file, int line, uint64_t us_elapsed_absolute, + int exec_id, const char *exe, const char **argv) +{ + const char *event_name = "exec"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "id:%d ", exec_id); + strbuf_addstr(&buf_payload, "argv:"); + if (exe) + strbuf_addf(&buf_payload, " %s", exe); + sq_quote_argv_pretty(&buf_payload, argv); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_exec_result_fl(const char *file, int line, + uint64_t us_elapsed_absolute, int exec_id, + int code) +{ + const char *event_name = "exec_result"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "id:%d code:%d", exec_id, code); + if (code > 0) + strbuf_addf(&buf_payload, " err:%s", strerror(code)); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_param_fl(const char *file, int line, const char *param, + const char *value) +{ + const char *event_name = "def_param"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "%s:%s", param, value); + + perf_io_write_fl(file, line, event_name, NULL, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_repo_fl(const char *file, int line, + const struct repository *repo) +{ + const char *event_name = "def_repo"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addstr(&buf_payload, "worktree:"); + sq_quote_buf_pretty(&buf_payload, repo->worktree); + + perf_io_write_fl(file, line, event_name, repo, NULL, NULL, NULL, + &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_region_enter_printf_va_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + const char *category, + const char *label, + const struct repository *repo, + const char *fmt, va_list ap) +{ + const char *event_name = "region_enter"; + struct strbuf buf_payload = STRBUF_INIT; + + if (label) + strbuf_addf(&buf_payload, "label:%s ", label); + maybe_append_string_va(&buf_payload, fmt, ap); + + perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, + NULL, category, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_region_leave_printf_va_fl( + const char *file, int line, uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, const char *label, + const struct repository *repo, const char *fmt, va_list ap) +{ + const char *event_name = "region_leave"; + struct strbuf buf_payload = STRBUF_INIT; + + if (label) + strbuf_addf(&buf_payload, "label:%s ", label); + maybe_append_string_va(&buf_payload, fmt, ap); + + perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, + &us_elapsed_region, category, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_data_fl(const char *file, int line, uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, + const struct repository *repo, const char *key, + const char *value) +{ + const char *event_name = "data"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "%s:%s", key, value); + + perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, + &us_elapsed_region, category, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_data_json_fl(const char *file, int line, + uint64_t us_elapsed_absolute, + uint64_t us_elapsed_region, const char *category, + const struct repository *repo, const char *key, + const struct json_writer *value) +{ + const char *event_name = "data_json"; + struct strbuf buf_payload = STRBUF_INIT; + + strbuf_addf(&buf_payload, "%s:%s", key, value->json.buf); + + perf_io_write_fl(file, line, event_name, repo, &us_elapsed_absolute, + &us_elapsed_region, category, &buf_payload); + strbuf_release(&buf_payload); +} + +static void fn_printf_va_fl(const char *file, int line, + uint64_t us_elapsed_absolute, const char *fmt, + va_list ap) +{ + const char *event_name = "printf"; + struct strbuf buf_payload = STRBUF_INIT; + + maybe_append_string_va(&buf_payload, fmt, ap); + + perf_io_write_fl(file, line, event_name, NULL, &us_elapsed_absolute, + NULL, NULL, &buf_payload); + strbuf_release(&buf_payload); +} + +struct tr2_tgt tr2_tgt_perf = { + &tr2dst_perf, + + fn_init, + fn_term, + + fn_version_fl, + fn_start_fl, + fn_exit_fl, + fn_signal, + fn_atexit, + fn_error_va_fl, + fn_command_path_fl, + fn_command_name_fl, + fn_command_mode_fl, + fn_alias_fl, + fn_child_start_fl, + fn_child_exit_fl, + fn_thread_start_fl, + fn_thread_exit_fl, + fn_exec_fl, + fn_exec_result_fl, + fn_param_fl, + fn_repo_fl, + fn_region_enter_printf_va_fl, + fn_region_leave_printf_va_fl, + fn_data_fl, + fn_data_json_fl, + fn_printf_va_fl, +}; diff --git a/trace2/tr2_tls.c b/trace2/tr2_tls.c new file mode 100644 index 0000000000..8e65b0361d --- /dev/null +++ b/trace2/tr2_tls.c @@ -0,0 +1,164 @@ +#include "cache.h" +#include "thread-utils.h" +#include "trace2/tr2_tls.h" + +/* + * Initialize size of the thread stack for nested regions. + * This is used to store nested region start times. Note that + * this stack is per-thread and not per-trace-key. + */ +#define TR2_REGION_NESTING_INITIAL_SIZE (100) + +static struct tr2tls_thread_ctx *tr2tls_thread_main; +static uint64_t tr2tls_us_start_main; + +static pthread_mutex_t tr2tls_mutex; +static pthread_key_t tr2tls_key; + +static int tr2_next_thread_id; /* modify under lock */ + +struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name) +{ + uint64_t us_now = getnanotime() / 1000; + struct tr2tls_thread_ctx *ctx = xcalloc(1, sizeof(*ctx)); + + /* + * Implicitly "tr2tls_push_self()" to capture the thread's start + * time in array_us_start[0]. For the main thread this gives us the + * application run time. + */ + ctx->alloc = TR2_REGION_NESTING_INITIAL_SIZE; + ctx->array_us_start = (uint64_t *)xcalloc(ctx->alloc, sizeof(uint64_t)); + ctx->array_us_start[ctx->nr_open_regions++] = us_now; + + ctx->thread_id = tr2tls_locked_increment(&tr2_next_thread_id); + + strbuf_init(&ctx->thread_name, 0); + if (ctx->thread_id) + strbuf_addf(&ctx->thread_name, "th%02d:", ctx->thread_id); + strbuf_addstr(&ctx->thread_name, thread_name); + if (ctx->thread_name.len > TR2_MAX_THREAD_NAME) + strbuf_setlen(&ctx->thread_name, TR2_MAX_THREAD_NAME); + + pthread_setspecific(tr2tls_key, ctx); + + return ctx; +} + +struct tr2tls_thread_ctx *tr2tls_get_self(void) +{ + struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key); + + /* + * If the thread-proc did not call trace2_thread_start(), we won't + * have any TLS data associated with the current thread. Fix it + * here and silently continue. + */ + if (!ctx) + ctx = tr2tls_create_self("unknown"); + + return ctx; +} + +int tr2tls_is_main_thread(void) +{ + struct tr2tls_thread_ctx *ctx = pthread_getspecific(tr2tls_key); + + return ctx == tr2tls_thread_main; +} + +void tr2tls_unset_self(void) +{ + struct tr2tls_thread_ctx *ctx; + + ctx = tr2tls_get_self(); + + pthread_setspecific(tr2tls_key, NULL); + + free(ctx->array_us_start); + free(ctx); +} + +void tr2tls_push_self(uint64_t us_now) +{ + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + + ALLOC_GROW(ctx->array_us_start, ctx->nr_open_regions + 1, ctx->alloc); + ctx->array_us_start[ctx->nr_open_regions++] = us_now; +} + +void tr2tls_pop_self(void) +{ + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + + if (!ctx->nr_open_regions) + BUG("no open regions in thread '%s'", ctx->thread_name.buf); + + ctx->nr_open_regions--; +} + +void tr2tls_pop_unwind_self(void) +{ + struct tr2tls_thread_ctx *ctx = tr2tls_get_self(); + + while (ctx->nr_open_regions > 1) + tr2tls_pop_self(); +} + +uint64_t tr2tls_region_elasped_self(uint64_t us) +{ + struct tr2tls_thread_ctx *ctx; + uint64_t us_start; + + ctx = tr2tls_get_self(); + if (!ctx->nr_open_regions) + return 0; + + us_start = ctx->array_us_start[ctx->nr_open_regions - 1]; + + return us - us_start; +} + +uint64_t tr2tls_absolute_elapsed(uint64_t us) +{ + if (!tr2tls_thread_main) + return 0; + + return us - tr2tls_us_start_main; +} + +void tr2tls_init(void) +{ + pthread_key_create(&tr2tls_key, NULL); + init_recursive_mutex(&tr2tls_mutex); + + tr2tls_thread_main = tr2tls_create_self("main"); + /* + * Keep a copy of the absolute start time of the main thread + * in a fixed variable since other threads need to access it. + * This also eliminates the need to lock accesses to the main + * thread's array (because of reallocs). + */ + tr2tls_us_start_main = tr2tls_thread_main->array_us_start[0]; +} + +void tr2tls_release(void) +{ + tr2tls_unset_self(); + tr2tls_thread_main = NULL; + + pthread_mutex_destroy(&tr2tls_mutex); + pthread_key_delete(tr2tls_key); +} + +int tr2tls_locked_increment(int *p) +{ + int current_value; + + pthread_mutex_lock(&tr2tls_mutex); + current_value = *p; + *p = current_value + 1; + pthread_mutex_unlock(&tr2tls_mutex); + + return current_value; +} diff --git a/trace2/tr2_tls.h b/trace2/tr2_tls.h new file mode 100644 index 0000000000..bb80e3f8e7 --- /dev/null +++ b/trace2/tr2_tls.h @@ -0,0 +1,97 @@ +#ifndef TR2_TLS_H +#define TR2_TLS_H + +#include "strbuf.h" + +/* + * Arbitry limit for thread names for column alignment. + */ +#define TR2_MAX_THREAD_NAME (24) + +struct tr2tls_thread_ctx { + struct strbuf thread_name; + uint64_t *array_us_start; + int alloc; + int nr_open_regions; /* plays role of "nr" in ALLOC_GROW */ + int thread_id; +}; + +/* + * Create TLS data for the current thread. This gives us a place to + * put per-thread data, such as thread start time, function nesting + * and a per-thread label for our messages. + * + * We assume the first thread is "main". Other threads are given + * non-zero thread-ids to help distinguish messages from concurrent + * threads. + * + * Truncate the thread name if necessary to help with column alignment + * in printf-style messages. + * + * In this and all following functions the term "self" refers to the + * current thread. + */ +struct tr2tls_thread_ctx *tr2tls_create_self(const char *thread_name); + +/* + * Get our TLS data. + */ +struct tr2tls_thread_ctx *tr2tls_get_self(void); + +/* + * return true if the current thread is the main thread. + */ +int tr2tls_is_main_thread(void); + +/* + * Free our TLS data. + */ +void tr2tls_unset_self(void); + +/* + * Begin a new nested region and remember the start time. + */ +void tr2tls_push_self(uint64_t us_now); + +/* + * End the innermost nested region. + */ +void tr2tls_pop_self(void); + +/* + * Pop any extra (above the first) open regions on the current + * thread and discard. During a thread-exit, we should only + * have region[0] that was pushed in trace2_thread_start() if + * the thread exits normally. + */ +void tr2tls_pop_unwind_self(void); + +/* + * Compute the elapsed time since the innermost region in the + * current thread started and the given time (usually now). + */ +uint64_t tr2tls_region_elasped_self(uint64_t us); + +/* + * Compute the elapsed time since the main thread started + * and the given time (usually now). This is assumed to + * be the absolute run time of the process. + */ +uint64_t tr2tls_absolute_elapsed(uint64_t us); + +/* + * Initialize the tr2 TLS system. + */ +void tr2tls_init(void); + +/* + * Free all tr2 TLS resources. + */ +void tr2tls_release(void); + +/* + * Protected increment of an integer. + */ +int tr2tls_locked_increment(int *p); + +#endif /* TR2_TLS_H */ @@ -1129,10 +1129,11 @@ static void format_trailer_info(struct strbuf *out, const struct trailer_info *info, const struct process_trailer_options *opts) { + size_t origlen = out->len; size_t i; /* If we want the whole block untouched, we can take the fast path. */ - if (!opts->only_trailers && !opts->unfold) { + if (!opts->only_trailers && !opts->unfold && !opts->filter && !opts->separator) { strbuf_add(out, info->trailer_start, info->trailer_end - info->trailer_start); return; @@ -1147,15 +1148,29 @@ static void format_trailer_info(struct strbuf *out, struct strbuf val = STRBUF_INIT; parse_trailer(&tok, &val, NULL, trailer, separator_pos); - if (opts->unfold) - unfold_value(&val); - - strbuf_addf(out, "%s: %s\n", tok.buf, val.buf); + if (!opts->filter || opts->filter(&tok, opts->filter_data)) { + if (opts->unfold) + unfold_value(&val); + + if (opts->separator && out->len != origlen) + strbuf_addbuf(out, opts->separator); + if (!opts->value_only) + strbuf_addf(out, "%s: ", tok.buf); + strbuf_addbuf(out, &val); + if (!opts->separator) + strbuf_addch(out, '\n'); + } strbuf_release(&tok); strbuf_release(&val); } else if (!opts->only_trailers) { + if (opts->separator && out->len != origlen) { + strbuf_addbuf(out, opts->separator); + } strbuf_addstr(out, trailer); + if (opts->separator) { + strbuf_rtrim(out); + } } } @@ -72,6 +72,10 @@ struct process_trailer_options { int only_input; int unfold; int no_divider; + int value_only; + const struct strbuf *separator; + int (*filter)(const struct strbuf *, void *); + void *filter_data; }; #define PROCESS_TRAILER_OPTIONS_INIT {0} diff --git a/transport-helper.c b/transport-helper.c index 1f52c95fd8..cec83bd663 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -127,6 +127,8 @@ static struct child_process *get_helper(struct transport *transport) argv_array_pushf(&helper->env_array, "%s=%s", GIT_DIR_ENVIRONMENT, get_git_dir()); + helper->trace2_child_class = helper->args.argv[0]; /* "remote-<name>" */ + code = start_command(helper); if (code < 0 && errno == ENOENT) die(_("unable to find remote helper for '%s'"), data->name); diff --git a/transport.c b/transport.c index e078812897..d0608df5c9 100644 --- a/transport.c +++ b/transport.c @@ -1062,6 +1062,7 @@ static int run_pre_push_hook(struct transport *transport, proc.argv = argv; proc.in = -1; + proc.trace2_hook_name = "pre-push"; if (start_command(&proc)) { finish_command(&proc); diff --git a/unpack-trees.c b/unpack-trees.c index 3563daae1a..22c41a3ba8 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -299,25 +299,6 @@ static void load_gitmodules_file(struct index_state *index, } } -/* - * Unlink the last component and schedule the leading directories for - * removal, such that empty directories get removed. - */ -static void unlink_entry(const struct cache_entry *ce) -{ - const struct submodule *sub = submodule_from_ce(ce); - if (sub) { - /* state.force is set at the caller. */ - submodule_move_head(ce->name, "HEAD", NULL, - SUBMODULE_MOVE_HEAD_FORCE); - } - if (!check_leading_path(ce->name, ce_namelen(ce))) - return; - if (remove_or_warn(ce->ce_mode, ce->name)) - return; - schedule_dir_for_removal(ce->name, ce_namelen(ce)); -} - static struct progress *get_progress(struct unpack_trees_options *o) { unsigned cnt = 0, total = 0; @@ -410,7 +391,7 @@ static int check_updates(struct unpack_trees_options *o) unlink_entry(ce); } } - remove_marked_cache_entries(index); + remove_marked_cache_entries(index, 0); remove_scheduled_dirs(); if (should_update_submodules() && o->update && !o->dry_run) @@ -22,17 +22,48 @@ void vreportf(const char *prefix, const char *err, va_list params) static NORETURN void usage_builtin(const char *err, va_list params) { vreportf("usage: ", err, params); + + /* + * When we detect a usage error *before* the command dispatch in + * cmd_main(), we don't know what verb to report. Force it to this + * to facilitate post-processing. + */ + trace2_cmd_name("_usage_"); + + /* + * Currently, the (err, params) are usually just the static usage + * string which isn't very useful here. Usually, the call site + * manually calls fprintf(stderr,...) with the actual detailed + * syntax error before calling usage(). + * + * TODO It would be nice to update the call sites to pass both + * the static usage string and the detailed error message. + */ + exit(129); } static NORETURN void die_builtin(const char *err, va_list params) { + /* + * We call this trace2 function first and expect it to va_copy 'params' + * before using it (because an 'ap' can only be walked once). + */ + trace2_cmd_error_va(err, params); + vreportf("fatal: ", err, params); + exit(128); } static void error_builtin(const char *err, va_list params) { + /* + * We call this trace2 function first and expect it to va_copy 'params' + * before using it (because an 'ap' can only be walked once). + */ + trace2_cmd_error_va(err, params); + vreportf("error: ", err, params); } diff --git a/wt-status.c b/wt-status.c index 1f564b12d2..445a36204a 100644 --- a/wt-status.c +++ b/wt-status.c @@ -748,12 +748,23 @@ static int has_unmerged(struct wt_status *s) void wt_status_collect(struct wt_status *s) { + trace2_region_enter("status", "worktrees", s->repo); wt_status_collect_changes_worktree(s); - if (s->is_initial) + trace2_region_leave("status", "worktrees", s->repo); + + if (s->is_initial) { + trace2_region_enter("status", "initial", s->repo); wt_status_collect_changes_initial(s); - else + trace2_region_leave("status", "initial", s->repo); + } else { + trace2_region_enter("status", "index", s->repo); wt_status_collect_changes_index(s); + trace2_region_leave("status", "index", s->repo); + } + + trace2_region_enter("status", "untracked", s->repo); wt_status_collect_untracked(s); + trace2_region_leave("status", "untracked", s->repo); wt_status_get_state(s->repo, &s->state, s->branch && !strcmp(s->branch, "HEAD")); if (s->state.merge_in_progress && !has_unmerged(s)) @@ -2291,6 +2302,13 @@ static void wt_porcelain_v2_print(struct wt_status *s) void wt_status_print(struct wt_status *s) { + trace2_data_intmax("status", s->repo, "count/changed", s->change.nr); + trace2_data_intmax("status", s->repo, "count/untracked", + s->untracked.nr); + trace2_data_intmax("status", s->repo, "count/ignored", s->ignored.nr); + + trace2_region_enter("status", "print", s->repo); + switch (s->status_format) { case STATUS_FORMAT_SHORT: wt_shortstatus_print(s); @@ -2309,6 +2327,8 @@ void wt_status_print(struct wt_status *s) wt_longstatus_print(s); break; } + + trace2_region_leave("status", "print", s->repo); } /** diff --git a/xdiff-interface.c b/xdiff-interface.c index 80f060d278..8509f9ea22 100644 --- a/xdiff-interface.c +++ b/xdiff-interface.c @@ -306,6 +306,10 @@ int git_xmerge_config(const char *var, const char *value, void *cb) git_xmerge_style = XDL_MERGE_DIFF3; else if (!strcmp(value, "merge")) git_xmerge_style = 0; + /* + * Please update _git_checkout() in + * git-completion.bash when you add new merge config + */ else die("unknown style '%s' given for '%s'", value, var); |