summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.clang-format2
-rw-r--r--.travis.yml10
-rw-r--r--Documentation/RelNotes/2.22.0.txt101
-rw-r--r--Documentation/config/user.txt23
-rw-r--r--Documentation/diff-format.txt20
-rw-r--r--Documentation/diff-generate-patch.txt13
-rw-r--r--Documentation/diff-options.txt22
-rw-r--r--Documentation/git-branch.txt6
-rw-r--r--Documentation/git-checkout.txt10
-rw-r--r--Documentation/git-diff-tree.txt11
-rw-r--r--Documentation/git-gc.txt2
-rw-r--r--Documentation/git-rebase.txt2
-rw-r--r--Documentation/git-submodule.txt4
-rw-r--r--Documentation/gitattributes.txt2
-rw-r--r--Documentation/githooks.txt4
-rw-r--r--Documentation/merge-options.txt11
-rw-r--r--Documentation/pretty-formats.txt264
-rw-r--r--Documentation/rev-list-options.txt7
-rw-r--r--Documentation/technical/api-trace2.txt1349
-rw-r--r--Documentation/technical/protocol-capabilities.txt18
-rwxr-xr-xGIT-VERSION-GEN2
-rw-r--r--Makefile25
l---------RelNotes2
-rw-r--r--apply.c4
-rw-r--r--attr.c8
-rw-r--r--blame.c3
-rw-r--r--builtin/am.c6
-rw-r--r--builtin/blame.c2
-rw-r--r--builtin/branch.c25
-rw-r--r--builtin/checkout.c134
-rw-r--r--builtin/commit.c11
-rw-r--r--builtin/diff-tree.c6
-rw-r--r--builtin/diff.c20
-rw-r--r--builtin/help.c4
-rw-r--r--builtin/log.c8
-rw-r--r--builtin/merge.c9
-rw-r--r--builtin/pack-objects.c16
-rw-r--r--builtin/pack-redundant.c232
-rw-r--r--builtin/prune-packed.c5
-rw-r--r--builtin/prune.c44
-rw-r--r--builtin/pull.c4
-rw-r--r--builtin/rebase.c17
-rw-r--r--builtin/receive-pack.c27
-rw-r--r--builtin/replace.c4
-rw-r--r--builtin/reset.c6
-rw-r--r--builtin/submodule--helper.c9
-rw-r--r--builtin/update-index.c41
-rw-r--r--builtin/worktree.c1
-rw-r--r--cache.h21
-rw-r--r--check-racy.c28
-rwxr-xr-xci/run-windows-build.sh103
-rw-r--r--combine-diff.c76
-rw-r--r--common-main.c13
-rw-r--r--compat/bswap.h5
-rw-r--r--compat/mingw.c11
-rw-r--r--compat/mingw.h3
-rw-r--r--compat/win32/trace2_win32_process_info.c147
-rw-r--r--config.c6
-rw-r--r--config.mak.uname5
-rw-r--r--connect.c3
-rw-r--r--contrib/completion/git-completion.bash45
-rw-r--r--date.c4
-rw-r--r--diff-lib.c2
-rw-r--r--diff-no-index.c8
-rw-r--r--diff.c616
-rw-r--r--diff.h85
-rw-r--r--editor.c1
-rw-r--r--entry.c26
-rw-r--r--exec-cmd.c2
-rw-r--r--git-compat-util.h7
-rwxr-xr-xgit-send-email.perl6
-rwxr-xr-xgit-submodule.sh3
-rw-r--r--git.c65
-rw-r--r--gitk-git/po/bg.po660
-rw-r--r--ident.c92
-rw-r--r--list-objects-filter-options.c4
-rw-r--r--log-tree.c3
-rw-r--r--merge-recursive.c23
-rw-r--r--pack-objects.c3
-rw-r--r--pack-objects.h6
-rw-r--r--pager.c1
-rw-r--r--parse-options-cb.c7
-rw-r--r--parse-options.c152
-rw-r--r--parse-options.h108
-rw-r--r--pkt-line.c2
-rw-r--r--pkt-line.h1
-rw-r--r--po/ca.po6
-rw-r--r--po/fr.po1500
-rw-r--r--po/vi.po6954
-rw-r--r--pretty.c117
-rw-r--r--reachable.c42
-rw-r--r--read-cache.c64
-rw-r--r--ref-filter.c40
-rw-r--r--refs/files-backend.c5
-rw-r--r--remote-curl.c391
-rw-r--r--repository.c2
-rw-r--r--repository.h3
-rw-r--r--revision.c6
-rw-r--r--revision.h1
-rw-r--r--run-command.c59
-rw-r--r--run-command.h13
-rw-r--r--sequencer.c7
-rw-r--r--sh-i18n--envsubst.c3
-rw-r--r--split-index.c36
-rw-r--r--strbuf.c21
-rw-r--r--strbuf.h8
-rw-r--r--sub-process.c1
-rw-r--r--submodule-config.c9
-rw-r--r--submodule.c15
-rw-r--r--t/README9
-rw-r--r--t/helper/test-parse-options.c3
-rw-r--r--t/helper/test-tool.c4
-rw-r--r--t/helper/test-tool.h1
-rw-r--r--t/helper/test-trace2.c273
-rwxr-xr-xt/perf/p5304-prune.sh35
-rwxr-xr-xt/t0001-init.sh1
-rwxr-xr-xt/t0210-trace2-normal.sh135
-rw-r--r--t/t0210/scrub_normal.perl48
-rwxr-xr-xt/t0211-trace2-perf.sh153
-rw-r--r--t/t0211/scrub_perf.perl76
-rwxr-xr-xt/t0212-trace2-event.sh236
-rw-r--r--t/t0212/parse_events.perl251
-rwxr-xr-xt/t1700-split-index.sh18
-rwxr-xr-xt/t2025-checkout-no-overlay.sh47
-rwxr-xr-xt/t2400-worktree-add.sh (renamed from t/t2025-worktree-add.sh)0
-rwxr-xr-xt/t2401-worktree-prune.sh (renamed from t/t2026-worktree-prune.sh)0
-rwxr-xr-xt/t2402-worktree-list.sh (renamed from t/t2027-worktree-list.sh)0
-rwxr-xr-xt/t2403-worktree-move.sh (renamed from t/t2028-worktree-move.sh)0
-rwxr-xr-xt/t2404-worktree-config.sh (renamed from t/t2029-worktree-config.sh)0
-rwxr-xr-xt/t3203-branch-output.sh44
-rwxr-xr-xt/t4038-diff-combined.sh88
-rwxr-xr-xt/t4053-diff-no-index.sh8
-rwxr-xr-xt/t4205-log-pretty-formats.sh117
-rwxr-xr-xt/t5304-prune.sh28
-rwxr-xr-xt/t5323-pack-redundant.sh467
-rwxr-xr-xt/t5702-protocol-v2.sh33
-rwxr-xr-xt/t7517-per-repo-email.sh74
-rwxr-xr-xt/t7800-difftool.sh4
-rwxr-xr-xt/t9902-completion.sh1
-rw-r--r--t/test-lib.sh6
-rw-r--r--trace2.c761
-rw-r--r--trace2.h385
-rw-r--r--trace2/tr2_cfg.c90
-rw-r--r--trace2/tr2_cfg.h19
-rw-r--r--trace2/tr2_cmd_name.c30
-rw-r--r--trace2/tr2_cmd_name.h24
-rw-r--r--trace2/tr2_dst.c252
-rw-r--r--trace2/tr2_dst.h36
-rw-r--r--trace2/tr2_sid.c67
-rw-r--r--trace2/tr2_sid.h18
-rw-r--r--trace2/tr2_tbuf.c32
-rw-r--r--trace2/tr2_tbuf.h23
-rw-r--r--trace2/tr2_tgt.h133
-rw-r--r--trace2/tr2_tgt_event.c588
-rw-r--r--trace2/tr2_tgt_normal.c323
-rw-r--r--trace2/tr2_tgt_perf.c534
-rw-r--r--trace2/tr2_tls.c164
-rw-r--r--trace2/tr2_tls.h97
-rw-r--r--trailer.c25
-rw-r--r--trailer.h4
-rw-r--r--transport-helper.c2
-rw-r--r--transport.c1
-rw-r--r--unpack-trees.c21
-rw-r--r--usage.c31
-rw-r--r--wt-status.c24
-rw-r--r--xdiff-interface.c4
166 files changed, 14001 insertions, 6059 deletions
diff --git a/.clang-format b/.clang-format
index de1c8b5..41d4cd2 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 36cbdea..ffb1bc4 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 0000000..16d3110
--- /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 b5b2ba1..0557cbb 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 cdcc17f..4d846d7 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 231105c..f10ca41 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 554a340..5ebc568 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 3bd83a7..0cd87dd 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 8c3d412..f179b43 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 43daa7c..24f32e8 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 a744249..a7c1b0f 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 5629ba4..6363d67 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 ba3c4df..2794e29 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 9b41f81..bdd11a2 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 9590443..5bf653c 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 63a3fc0..92a7d93 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 7bfffae..0795983 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 cad711c..ca959a7 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 0000000..2de565f
--- /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 332d209..2b267c0 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 57fc1ab..3fc4065 100755
--- a/GIT-VERSION-GEN
+++ b/GIT-VERSION-GEN
@@ -1,7 +1,7 @@
#!/bin/sh
GVF=GIT-VERSION-FILE
-DEF_VER=v2.21.0-rc2
+DEF_VER=v2.21.GIT
LF='
'
diff --git a/Makefile b/Makefile
index 710a347..3e03290 100644
--- a/Makefile
+++ b/Makefile
@@ -754,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
@@ -822,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 \
@@ -998,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
@@ -1599,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
@@ -2366,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
@@ -2739,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))
diff --git a/RelNotes b/RelNotes
index 31e2135..0b6d9fd 120000
--- a/RelNotes
+++ b/RelNotes
@@ -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
diff --git a/apply.c b/apply.c
index 892ede5..f15afa9 100644
--- a/apply.c
+++ b/apply.c
@@ -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);
}
diff --git a/attr.c b/attr.c
index fdd110b..93dc16b 100644
--- a/attr.c
+++ b/attr.c
@@ -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.
diff --git a/blame.c b/blame.c
index da57233..5c07dec 100644
--- a/blame.c
+++ b/blame.c
@@ -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 58a2aef..4fb107a 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 581de0d..177c102 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 1be7272..4c83055 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", &copy, N_("copy a branch and its reflog"), 1),
OPT_BIT('C', NULL, &copy, 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 24b8593..0e6037b 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 2986553..f175374 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 a90681b..cb9ea79 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 9f61092..53d4234 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 7739a5c..e5590d7 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 5786926..ab859f5 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 e47d77b..5ce8946 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 a9fac7c..a154fc2 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 11bc514..68c1e54 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 a9e7b55..48c5e78 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 1ec9ddd..97613ec 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 701d147..33db889 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 7c7bc13..52114cb 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 d58b775..29f165d 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 5b80b7f..f570162 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 4d18a46..7882829 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 b80fc4b..6bcc4f1 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 02ace60..1b6c42f 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 3f9907f..6cc094a 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),
diff --git a/cache.h b/cache.h
index 27fe635..abd518a 100644
--- a/cache.h
+++ b/cache.h
@@ -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 24b6542..0000000
--- 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 a73a4ec..0000000
--- 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 23d8fab..3e49f3b 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 3728f66..d484aec 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 5078ce5..e4e2573 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 8141f77..6b04514 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 30d9fb3..4d73f8a 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 0000000..52bd620
--- /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();
+}
diff --git a/config.c b/config.c
index 24ad1a9..0f0cdd8 100644
--- a/config.c
+++ b/config.c
@@ -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.uname b/config.mak.uname
index b37fa84..41e85fa 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))
diff --git a/connect.c b/connect.c
index 4813f00..2778481 100644
--- a/connect.c
+++ b/connect.c
@@ -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 499e56f..976e4a6 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
diff --git a/date.c b/date.c
index 9c5870e..8126146 100644
--- a/date.c
+++ b/date.c
@@ -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 23c8d35..a838c21 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 9414e92..6001bae 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"))
diff --git a/diff.c b/diff.c
index 5306c48..ec5c095 100644
--- a/diff.c
+++ b/diff.c
@@ -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);
diff --git a/diff.h b/diff.h
index b512d04..c9db982 100644
--- a/diff.h
+++ b/diff.h
@@ -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,
diff --git a/editor.c b/editor.c
index c985eee..7154767 100644
--- a/editor.c
+++ b/editor.c
@@ -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);
diff --git a/entry.c b/entry.c
index 6fd72b3..0e4f2f2 100644
--- a/entry.c
+++ b/entry.c
@@ -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 4f81f44..7deeab3 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 6573808..31b4793 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 8eb63b5..8200d58 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 b5f2bee..514ede2 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>...)
diff --git a/git.c b/git.c
index 2dd5886..2014aab 100644
--- a/git.c
+++ b/git.c
@@ -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 407d555..87ab1fa 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:"
diff --git a/ident.c b/ident.c
index 33bcf40..9c2eb0a 100644
--- a/ident.c
+++ b/ident.c
@@ -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 b71bd1f..c0036f7 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 3cb1425..1e56df6 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 4851825..6c40c61 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 e7cd337..ce33b89 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 6bfacc7..6fde7ce 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
diff --git a/pager.c b/pager.c
index a768797..4168460 100644
--- a/pager.c
+++ b/pager.c
@@ -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 e2f3eae..2733393 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 9f84bac..cec7452 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 14fe324..7d83e29 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 d4b71d3..60329b3 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 ad9a4a2..c36cb78 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);
diff --git a/po/ca.po b/po/ca.po
index 7f0cec1..f0b7e2c 100644
--- a/po/ca.po
+++ b/po/ca.po
@@ -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:"
diff --git a/po/fr.po b/po/fr.po
index 7b15b76..0e084f5 100644
--- a/po/fr.po
+++ b/po/fr.po
@@ -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."
diff --git a/po/vi.po b/po/vi.po
index bbdeb5c..3068608 100644
--- a/po/vi.po
+++ b/po/vi.po
@@ -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"
diff --git a/pretty.c b/pretty.c
index 0ab45d1..f496f0f 100644
--- a/pretty.c
+++ b/pretty.c
@@ -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 6e9b810..0d00a91 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 0e0c93e..4dc6de1 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 422a9c9..3aca105 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 dd8abe9..ef053f7 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 bb74210..5b44794 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 65e6f8b..5cad2dc 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 8981649..4fb6a58 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 162d511..eb8e51b 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 d32d62a..4134dc6 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 3db26b7..3449db3 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 68f5369..a695069 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 0db410d..95dda23 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 09c6b44..cecfdd3 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 5820412..e6154e4 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
diff --git a/strbuf.c b/strbuf.c
index f6a6cf7..78eecd2 100644
--- a/strbuf.c
+++ b/strbuf.c
@@ -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)
{
diff --git a/strbuf.h b/strbuf.h
index fc40873..52e44c9 100644
--- a/strbuf.h
+++ b/strbuf.h
@@ -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 8d2a170..3f4af93 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 52702c6..66653e8 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 934ecfa..21cf50c 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:
diff --git a/t/README b/t/README
index 886bbec..7a3d582 100644
--- a/t/README
+++ b/t/README
@@ -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 47fee66..cc88fba 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 99db740..53c0693 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 25abed1..ffab4d1 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 0000000..197819c
--- /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 0000000..83baedb
--- /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 42a263c..5e27604 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 0000000..03a0aed
--- /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 0000000..c65d1a8
--- /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 0000000..953e2f7
--- /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 0000000..351af78
--- /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 0000000..028b6c5
--- /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 0000000..a2776ba
--- /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 4667e1a..4f2f84f 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 0000000..76330cb
--- /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 286bba3..286bba3 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 b7d6d5d..b7d6d5d 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 bb6fb9b..bb6fb9b 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 939d18d..939d18d 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 286121d..286121d 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 ee67876..be55148 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 e2824d3..07b49f6 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 6e0dd6f..4331b31 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 7df8c3d..f42a69f 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 270da21..1eeb828 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 0000000..6b4d1ca
--- /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 db4ae09..e112b60 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 231b8cc..b2401ce 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 22b9199..bb9a7f4 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 3a2c632..f5e21bf 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 8665b0a..4e79e14 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 0000000..ccccd4e
--- /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 0000000..ae5020d
--- /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 0000000..b329921
--- /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 0000000..d9c98f6
--- /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 0000000..e999592
--- /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 0000000..ab70b67
--- /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 0000000..fd490a4
--- /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 0000000..9a64f05
--- /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 0000000..984524a
--- /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 0000000..9bef321
--- /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 0000000..0844910
--- /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 0000000..9cdefa3
--- /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 0000000..297bb8f
--- /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 0000000..107cb53
--- /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 0000000..547183d
--- /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 0000000..f0746fc
--- /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 0000000..8e65b03
--- /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 0000000..bb80e3f
--- /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 */
diff --git a/trailer.c b/trailer.c
index 0796f32..0c414f2 100644
--- a/trailer.c
+++ b/trailer.c
@@ -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);
+ }
}
}
diff --git a/trailer.h b/trailer.h
index b997739..203acf4 100644
--- a/trailer.h
+++ b/trailer.h
@@ -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 1f52c95..cec83bd 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 e078812..d0608df 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 3563daa..22c41a3 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)
diff --git a/usage.c b/usage.c
index cc80333..2fdb200 100644
--- a/usage.c
+++ b/usage.c
@@ -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 1f564b1..445a362 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 80f060d..8509f9e 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);