diff options
301 files changed, 9612 insertions, 5487 deletions
diff --git a/.gitignore b/.gitignore index 5087ce1eb7..05cb58a3d4 100644 --- a/.gitignore +++ b/.gitignore @@ -179,39 +179,6 @@ /gitweb/gitweb.cgi /gitweb/static/gitweb.js /gitweb/static/gitweb.min.* -/test-chmtime -/test-ctype -/test-config -/test-date -/test-delta -/test-dump-cache-tree -/test-dump-split-index -/test-dump-untracked-cache -/test-fake-ssh -/test-scrap-cache-tree -/test-genrandom -/test-hashmap -/test-index-version -/test-line-buffer -/test-match-trees -/test-mergesort -/test-mktemp -/test-parse-options -/test-path-utils -/test-prio-queue -/test-read-cache -/test-regex -/test-revision-walking -/test-run-command -/test-sha1 -/test-sha1-array -/test-sigchain -/test-string-list -/test-submodule-config -/test-subprocess -/test-svn-fe -/test-urlmatch-normalization -/test-wildmatch /common-cmds.h *.tar.gz *.dsc @@ -51,6 +51,7 @@ Dirk SΓΌsserott <newsletter@dirk.my1.cc> Eric Blake <eblake@redhat.com> <ebb9@byu.net> Eric Hanchrow <eric.hanchrow@gmail.com> <offby1@blarg.net> Eric S. Raymond <esr@thyrsus.com> +Eric Wong <e@80x24.org> <normalperson@yhbt.net> Erik Faye-Lund <kusmabite@gmail.com> <kusmabite@googlemail.com> Eyvind Bernhardsen <eyvind.bernhardsen@gmail.com> <eyvind-git@orakel.ntnu.no> Florian Achleitner <florian.achleitner.2.6.31@gmail.com> <florian.achleitner2.6.31@gmail.com> diff --git a/.travis.yml b/.travis.yml index 78e433ba71..c20ec540c8 100644 --- a/.travis.yml +++ b/.travis.yml @@ -18,12 +18,16 @@ addons: apt: packages: - language-pack-is + - git-svn env: global: - DEVELOPER=1 - - P4_VERSION="15.2" - - GIT_LFS_VERSION="1.1.0" + # The Linux build installs the defined dependency versions below. + # The OS X build installs the latest available versions. Keep that + # in mind when you encounter a broken OS X build! + - LINUX_P4_VERSION="16.1" + - LINUX_GIT_LFS_VERSION="1.2.0" - DEFAULT_TEST_TARGET=prove - GIT_PROVE_OPTS="--timer --jobs 3 --state=failed,slow,save" - GIT_TEST_OPTS="--verbose --tee" @@ -32,23 +36,38 @@ env: # t9816 occasionally fails with "TAP out of sequence errors" on Travis CI OS X - GIT_SKIP_TESTS="t9810 t9816" +matrix: + include: + - env: Documentation + os: linux + compiler: clang + addons: + apt: + packages: + - asciidoc + - xmlto + before_install: + before_script: + script: ci/test-documentation.sh + after_failure: + before_install: - > case "${TRAVIS_OS_NAME:-linux}" in linux) mkdir --parents custom/p4 pushd custom/p4 - wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4d - wget --quiet http://filehost.perforce.com/perforce/r$P4_VERSION/bin.linux26x86_64/p4 + wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4d + wget --quiet http://filehost.perforce.com/perforce/r$LINUX_P4_VERSION/bin.linux26x86_64/p4 chmod u+x p4d chmod u+x p4 export PATH="$(pwd):$PATH" popd mkdir --parents custom/git-lfs pushd custom/git-lfs - wget --quiet https://github.com/github/git-lfs/releases/download/v$GIT_LFS_VERSION/git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz - tar --extract --gunzip --file "git-lfs-linux-amd64-$GIT_LFS_VERSION.tar.gz" - cp git-lfs-$GIT_LFS_VERSION/git-lfs . + wget --quiet https://github.com/github/git-lfs/releases/download/v$LINUX_GIT_LFS_VERSION/git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz + tar --extract --gunzip --file "git-lfs-linux-amd64-$LINUX_GIT_LFS_VERSION.tar.gz" + cp git-lfs-$LINUX_GIT_LFS_VERSION/git-lfs . export PATH="$(pwd):$PATH" popd ;; diff --git a/Documentation/Makefile b/Documentation/Makefile index 3e39e2815b..f6e288bc63 100644 --- a/Documentation/Makefile +++ b/Documentation/Makefile @@ -204,6 +204,7 @@ ifndef V QUIET_DBLATEX = @echo ' ' DBLATEX $@; QUIET_XSLTPROC = @echo ' ' XSLTPROC $@; QUIET_GEN = @echo ' ' GEN $@; + QUIET_LINT = @echo ' ' LINT $@; QUIET_STDERR = 2> /dev/null QUIET_SUBDIR0 = +@subdir= QUIET_SUBDIR1 = ;$(NO_SUBDIR) echo ' ' SUBDIR $$subdir; \ @@ -427,4 +428,7 @@ quick-install-html: require-htmlrepo print-man1: @for i in $(MAN1_TXT); do echo $$i; done +lint-docs:: + $(QUIET_LINT)$(PERL_PATH) lint-gitlink.perl + .PHONY: FORCE diff --git a/Documentation/RelNotes/2.8.2.txt b/Documentation/RelNotes/2.8.2.txt index 3db67f4c55..447b1933a8 100644 --- a/Documentation/RelNotes/2.8.2.txt +++ b/Documentation/RelNotes/2.8.2.txt @@ -52,4 +52,19 @@ Fixes since v2.8.1 nothing into an unborn history (which is arguably unusual usage, which perhaps was the reason why nobody noticed it). + * Build updates for MSVC. + + * "git diff -M" used to work better when two originally identical + files A and B got renamed to X/A and X/B by pairing A to X/A and B + to X/B, but this was broken in the 2.0 timeframe. + + * "git send-pack --all <there>" was broken when its command line + option parsing was written in the 2.6 timeframe. + + * When running "git blame $path" with unnormalized data in the index + for the path, the data in the working tree was blamed, even though + "git add" would not have changed what is already in the index, due + to "safe crlf" that disables the line-end conversion. It has been + corrected. + Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.8.3.txt b/Documentation/RelNotes/2.8.3.txt new file mode 100644 index 0000000000..fedd9968e5 --- /dev/null +++ b/Documentation/RelNotes/2.8.3.txt @@ -0,0 +1,101 @@ +Git v2.8.3 Release Notes +======================== + +Fixes since v2.8.2 +------------------ + + * "git send-email" now uses a more readable timestamps when + formulating a message ID. + + * The repository set-up sequence has been streamlined (the biggest + change is that there is no longer git_config_early()), so that we + do not attempt to look into refs/* when we know we do not have a + Git repository. + + * When "git worktree" feature is in use, "git branch -d" allowed + deletion of a branch that is checked out in another worktree + + * When "git worktree" feature is in use, "git branch -m" renamed a + branch that is checked out in another worktree without adjusting + the HEAD symbolic ref for the worktree. + + * "git format-patch --help" showed `-s` and `--no-patch` as if these + are valid options to the command. We already hide `--patch` option + from the documentation, because format-patch is about showing the + diff, and the documentation now hides these options as well. + + * A change back in version 2.7 to "git branch" broke display of a + symbolic ref in a non-standard place in the refs/ hierarchy (we + expect symbolic refs to appear in refs/remotes/*/HEAD to point at + the primary branch the remote has, and as .git/HEAD to point at the + branch we locally checked out). + + * A partial rewrite of "git submodule" in the 2.7 timeframe changed + the way the gitdir: pointer in the submodules point at the real + repository location to use absolute paths by accident. This has + been corrected. + + * "git commit" misbehaved in a few minor ways when an empty message + is given via -m '', all of which has been corrected. + + * Support for CRAM-MD5 authentication method in "git imap-send" did + not work well. + + * The socks5:// proxy support added back in 2.6.4 days was not aware + that socks5h:// proxies behave differently. + + * "git config" had a codepath that tried to pass a NULL to + printf("%s"), which nobody seems to have noticed. + + * On Cygwin, object creation uses the "create a temporary and then + rename it to the final name" pattern, not "create a temporary, + hardlink it to the final name and then unlink the temporary" + pattern. + + This is necessary to use Git on Windows shared directories, and is + already enabled for the MinGW and plain Windows builds. It also + has been used in Cygwin packaged versions of Git for quite a while. + See http://thread.gmane.org/gmane.comp.version-control.git/291853 + and http://thread.gmane.org/gmane.comp.version-control.git/275680. + + * "git replace -e" did not honour "core.editor" configuration. + + * Upcoming OpenSSL 1.1.0 will break compilation b updating a few APIs + we use in imap-send, which has been adjusted for the change. + + * "git submodule" reports the paths of submodules the command + recurses into, but this was incorrect when the command was not run + from the root level of the superproject. + + * The test scripts for "git p4" (but not "git p4" implementation + itself) has been updated so that they would work even on a system + where the installed version of Python is python 3. + + * The "user.useConfigOnly" configuration variable makes it an error + if users do not explicitly set user.name and user.email. However, + its check was not done early enough and allowed another error to + trigger, reporting that the default value we guessed from the + system setting was unusable. This was a suboptimal end-user + experience as we want the users to set user.name/user.email without + relying on the auto-detection at all. + + * "git mv old new" did not adjust the path for a submodule that lives + as a subdirectory inside old/ directory correctly. + + * "git push" from a corrupt repository that attempts to push a large + number of refs deadlocked; the thread to relay rejection notices + for these ref updates blocked on writing them to the main thread, + after the main thread at the receiving end notices that the push + failed and decides not to read these notices and return a failure. + + * A question by "git send-email" to ask the identity of the sender + has been updated. + + * Recent update to Git LFS broke "git p4" by changing the output from + its "lfs pointer" subcommand. + + * Some multi-byte encoding can have a backslash byte as a later part + of one letter, which would confuse "highlight" filter used in + gitweb. + +Also contains minor documentation updates and code clean-ups. diff --git a/Documentation/RelNotes/2.9.0.txt b/Documentation/RelNotes/2.9.0.txt index 6e10b8d662..a60e92e0dd 100644 --- a/Documentation/RelNotes/2.9.0.txt +++ b/Documentation/RelNotes/2.9.0.txt @@ -16,12 +16,20 @@ The output formats of "git log" that indents the commit log message by 4 spaces now expands HT in the log message by default. You can use the "--no-expand-tabs" option to disable this. +"git commit-tree" plumbing command required the user to always sign +its result when the user sets the commit.gpgsign configuration +variable, which was an ancient mistake, which this release corrects. +A script that drives commit-tree, if it relies on this mistake, now +needs to read commit.gpgsign and pass the -S option as necessary. + Updates since v2.8 ------------------ UI, Workflows & Features + * Comes with git-multimail 1.3.1 (in contrib/). + * The end-user facing Porcelain level commands like "diff" and "log" now enables the rename detection by default. @@ -56,6 +64,9 @@ UI, Workflows & Features to be used in a rare event that merges histories of two projects that started their lives independently. + * "git pull" has been taught to pass --allow-unrelated-histories + option to underlying "git merge". + * "git apply -v" learned to report paths in the patch that were skipped via --include/--exclude mechanism or being outside the current working directory. @@ -82,7 +93,63 @@ UI, Workflows & Features * "git send-email" now uses a more readable timestamps when formulating a message ID. - (merge f916ab0 ew/send-email-readable-message-id later to maint). + + * "git rerere" can encounter two or more files with the same conflict + signature that have to be resolved in different ways, but there was + no way to record these separate resolutions. + (merge d9d501b068 jc/rerere-multi later to maint). + + * "git p4" learned to record P4 jobs in Git commit that imports from + the history in Perforce. + + * "git describe --contains" often made a hard-to-justify choice of + tag to give name to a given commit, because it tried to come up + with a name with smallest number of hops from a tag, causing an old + commit whose close descendant that is recently tagged were not + described with respect to an old tag but with a newer tag. It did + not help that its computation of "hop" count was further tweaked to + penalize being on a side branch of a merge. The logic has been + updated to favor using the tag with the oldest tagger date, which + is a lot easier to explain to the end users: "We describe a commit + in terms of the (chronologically) oldest tag that contains the + commit." + (merge 7550424 js/name-rev-use-oldest-ref later to maint). + + * "git clone" learned "--shallow-submodules" option. + + * HTTP transport clients learned to throw extra HTTP headers at the + server, specified via http.extraHeader configuration variable. + + * Patch output from "git diff" and friends has been tweaked to be + more readable by using a blank line as a strong hint that the + contents before and after it belong to a logically separate unit. + + * A new configuration variable core.hooksPath allows customizing + where the hook directory is. + + * An earlier addition of "sanitize_submodule_env" with 14111fc4 (git: + submodule honor -c credential.* from command line, 2016-02-29) + turned out to be a convoluted no-op; implement what it wanted to do + correctly, and stop filtering settings given via "git -c var=val". + + * "git commit --dry-run" reported "No, no, you cannot commit." in one + case where "git commit" would have allowed you to commit, and this + improves it a little bit ("git commit --dry-run --short" still does + not give you the correct answer, for example). This is a stop-gap + measure in that "commit --short --dry-run" still gives an incorrect + result. + + * The experimental "multiple worktree" feature gains more safety to + forbid operations on a branch that is checked out or being actively + worked on elsewhere, by noticing that e.g. it is being rebased. + + * "git format-patch" learned a new "--base" option to record what + (public, well-known) commit the original series was built on in + its output. + + * "git commit" learned to pay attention to "commit.verbose" + configuration variable and act as if "--verbose" option was + given from the command line. Performance, Internal Implementation, Development Support etc. @@ -90,7 +157,6 @@ Performance, Internal Implementation, Development Support etc. * The embedded args argv-array in the child process is used to build the command line to run pack-objects instead of using a separate array of strings. - (merge 65a3629 mp/upload-pack-use-embedded-args later to maint). * A test for tags has been restructured so that more parts of it can easily be run on a platform without a working GnuPG. @@ -99,7 +165,6 @@ Performance, Internal Implementation, Development Support etc. repository (among other things), are now uniformly available to Git subcommand implementations, and Git avoids attempting to touch references when we are not in a repository. - (merge 11e6b3f jk/startup-info later to maint). * The command line argument parser for "receive-pack" has been rewritten to use parse-options. @@ -109,20 +174,70 @@ Performance, Internal Implementation, Development Support etc. parallel. * Rename bunch of tests on "git clone" for better organization. - (merge 8fbb03a sb/clone-t57-t56 later to maint). * The tests that involve running httpd leaked the system-wide configuration in /etc/gitconfig to the tested environment. - (merge 1fad503 jk/test-httpd-config-nosystem later to maint). * Build updates for MSVC. - (merge 0ef60af ss/msvc later to maint). * The repository set-up sequence has been streamlined (the biggest change is that there is no longer git_config_early()), so that we do not attempt to look into refs/* when we know we do not have a Git repository. - (merge 274db84 jk/check-repository-format later to maint). + + * Code restructuring around the "refs" area to prepare for pluggable + refs backends. + + * Sources to many test helper binaries (and the generated helpers) + have been moved to t/helper/ subdirectory to reduce clutter at the + top level of the tree. + + * Unify internal logic between "git tag -v" and "git verify-tag" + commands by making one directly call into the other. + (merge bef234b st/verify-tag later to maint). + + * "merge-recursive" strategy incorrectly checked if a path that is + involved in its internal merge exists in the working tree. + + * The test scripts for "git p4" (but not "git p4" implementation + itself) has been updated so that they would work even on a system + where the installed version of Python is python 3. + + * As nobody maintains our in-tree git.spec.in and distros use their + own spec file, we stopped pretending that we support "make rpm". + + * Move from unsigned char[20] to struct object_id continues. + + * Update of "git submodule" to move pieces of logic to C continues. + + * The code for warning_errno/die_errno has been refactored and a new + error_errno() reporting helper is introduced. + (merge 1da045f nd/error-errno later to maint). + + * Running tests with '-x' option to trace the individual command + executions is a useful way to debug test scripts, but some tests + that capture the standard error stream and check what the command + said can be broken with the trace output mixed in. When running + our tests under "bash", however, we can redirect the trace output + to another file descriptor to keep the standard error of programs + being tested intact. + (merge d88785e jk/test-send-sh-x-trace-elsewhere later to maint). + + * t0040 had too many unnecessary repetitions in its test data. Teach + test-parse-options program so that a caller can tell what it + expects in its output, so that these repetitions can be cleaned up. + + * Add perf test for "rebase -i" + + * Common mistakes when writing gitlink: in our documentation are + found by "make check-docs". + + * t9xxx series has been updated primarily for readability, while + fixing small bugs in it. A few scripted Porcelains have also been + updated to fix possible bugs around their use of "test -z" and + "test -n". + + * CI test was taught to run git-svn tests. Also contains various documentation updates and code clean-ups. @@ -138,110 +253,87 @@ notes for details). * "git config --get-urlmatch", unlike other variants of the "git config --get" family, did not signal error with its exit status when there was no matching configuration. - (merge 24990b2 jk/config-get-urlmatch later to maint). * The "--local-env-vars" and "--resolve-git-dir" options of "git rev-parse" failed to work outside a repository when the command's option parsing was rewritten in 1.8.5 era. - (merge fc7d47f jk/rev-parse-local-env-vars later to maint). * "git index-pack --keep[=<msg>] pack-$name.pack" simply did not work. - (merge 0e94242 jc/maint-index-pack-keep later to maint). * Fetching of history by naming a commit object name directly didn't work across remote-curl transport. - (merge 754ecb1 gf/fetch-pack-direct-object-fetch later to maint). * A small memory leak in an error codepath has been plugged in xdiff code. - (merge 87f1625 rj/xdiff-prepare-plug-leak-on-error-codepath later to maint). * strbuf_getwholeline() did not NUL-terminate the buffer on certain corner cases in its error codepath. - (merge b709043 jk/getwholeline-getdelim-empty later to maint). * "git mergetool" did not work well with conflicts that both sides deleted. - (merge a298604 da/mergetool-delete-delete-conflict later to maint). * "git send-email" had trouble parsing alias file in mailrc format when lines in it had trailing whitespaces on them. - (merge a277d1e jk/send-email-rtrim-mailrc-alias later to maint). * When "git merge --squash" stopped due to conflict, the concluding "git commit" failed to read in the SQUASH_MSG that shows the log messages from all the squashed commits. - (merge b64c1e0 ss/commit-squash-msg later to maint). * "git merge FETCH_HEAD" dereferenced NULL pointer when merging nothing into an unborn history (which is arguably unusual usage, which perhaps was the reason why nobody noticed it). - (merge b84e65d jv/merge-nothing-into-void later to maint). * When "git worktree" feature is in use, "git branch -d" allowed deletion of a branch that is checked out in another worktree, which was wrong. - (merge f292244 ky/branch-d-worktree later to maint). * When "git worktree" feature is in use, "git branch -m" renamed a branch that is checked out in another worktree without adjusting the HEAD symbolic ref for the worktree. - (merge 18eb3a9 ky/branch-m-worktree later to maint). * "git diff -M" used to work better when two originally identical files A and B got renamed to X/A and X/B by pairing A to X/A and B to X/B, but this was broken in the 2.0 timeframe. - (merge ca4e3ca sg/diff-multiple-identical-renames later to maint). * "git send-pack --all <there>" was broken when its command line option parsing was written in the 2.6 timeframe. - (merge c677756 sk/send-pack-all-fix later to maint). * "git format-patch --help" showed `-s` and `--no-patch` as if these are valid options to the command. We already hide `--patch` option from the documentation, because format-patch is about showing the diff, and the documentation now hides these options as well. - (merge b73a1bc es/format-patch-doc-hide-no-patch later to maint). * When running "git blame $path" with unnormalized data in the index for the path, the data in the working tree was blamed, even though "git add" would not have changed what is already in the index, due to "safe crlf" that disables the line-end conversion. It has been corrected. - (merge a08feb8 tb/blame-force-read-cache-to-workaround-safe-crlf later to maint). * A change back in version 2.7 to "git branch" broke display of a symbolic ref in a non-standard place in the refs/ hierarchy (we expect symbolic refs to appear in refs/remotes/*/HEAD to point at the primary branch the remote has, and as .git/HEAD to point at the branch we locally checked out). - (merge 95c38fb jk/branch-shortening-funny-symrefs later to maint). * A partial rewrite of "git submodule" in the 2.7 timeframe changed the way the gitdir: pointer in the submodules point at the real repository location to use absolute paths by accident. This has been corrected. - (merge 1f15ba1 sb/submodule-helper-clone-regression-fix later to maint). * "git commit" misbehaved in a few minor ways when an empty message is given via -m '', all of which has been corrected. - (merge 27014cb ad/commit-have-m-option later to maint). * Support for CRAM-MD5 authentication method in "git imap-send" did not work well. - (merge eb94ee7 ky/imap-send later to maint). * Upcoming OpenSSL 1.1.0 will break compilation b updating a few APIs we use in imap-send, which has been adjusted for the change. - (merge 1245c74 ky/imap-send-openssl-1.1.0 later to maint). * The socks5:// proxy support added back in 2.6.4 days was not aware that socks5h:// proxies behave differently. - (merge 87f8a0b jc/http-socks5h later to maint). * "git config" had a codepath that tried to pass a NULL to printf("%s"), which nobody seems to have noticed. - (merge 1cae428 jk/do-not-printf-NULL later to maint). * On Cygwin, object creation uses the "create a temporary and then rename it to the final name" pattern, not "create a temporary, @@ -252,25 +344,145 @@ notes for details). already enabled for the MinGW and plain Windows builds. It also has been used in Cygwin packaged versions of Git for quite a while. See http://thread.gmane.org/gmane.comp.version-control.git/291853 - (merge e53a64b ad/cygwin-wants-rename later to maint). + + * "merge-octopus" strategy did not ensure that the index is clean + when merge begins. + + * When "git merge" notices that the merge can be resolved purely at + the tree level (without having to merge blobs) and the resulting + tree happens to already exist in the object store, it forgot to + update the index, which lead to an inconsistent state for later + operations. + + * "git submodule" reports the paths of submodules the command + recurses into, but this was incorrect when the command was not run + from the root level of the superproject. + + * The "user.useConfigOnly" configuration variable makes it an error + if users do not explicitly set user.name and user.email. However, + its check was not done early enough and allowed another error to + trigger, reporting that the default value we guessed from the + system setting was unusable. This was a suboptimal end-user + experience as we want the users to set user.name/user.email without + relying on the auto-detection at all. + + * "git mv old new" did not adjust the path for a submodule that lives + as a subdirectory inside old/ directory correctly. + + * "git replace -e" did not honour "core.editor" configuration. + + * "git push" from a corrupt repository that attempts to push a large + number of refs deadlocked; the thread to relay rejection notices + for these ref updates blocked on writing them to the main thread, + after the main thread at the receiving end notices that the push + failed and decides not to read these notices and return a failure. + + * mmap emulation on Windows has been optimized and work better without + consuming paging store when not needed. + + * A question by "git send-email" to ask the identity of the sender + has been updated. + + * UI consistency improvements for "git mergetool". + + * "git rebase -m" could be asked to rebase an entire branch starting + from the root, but failed by assuming that there always is a parent + commit to the first commit on the branch. + (merge 79f4344 bw/rebase-merge-entire-branch later to maint). + + * Fix a broken "p4 lfs" test. + + * Recent update to Git LFS broke "git p4" by changing the output from + its "lfs pointer" subcommand. + + * "git fetch" test t5510 was flaky while running a (forced) automagic + garbage collection. + + * Documentation updates to help contributors setting up Travis CI + test for their patches. + + * Some multi-byte encoding can have a backslash byte as a later part + of one letter, which would confuse "highlight" filter used in + gitweb. + + * "git commit-tree" plumbing command required the user to always sign + its result when the user sets the commit.gpgsign configuration + variable, which was an ancient mistake. Rework "git rebase" that + relied on this mistake so that it reads commit.gpgsign and pass (or + not pass) the -S option to "git commit-tree" to keep the end-user + expectation the same, while teaching "git commit-tree" to ignore + the configuration variable. This will stop requiring the users to + sign commit objects used internally as an implementation detail of + "git stash". + (merge 6694856 jc/commit-tree-ignore-commit-gpgsign later to maint). + + * "http.cookieFile" configuration variable clearly wants a pathname, + but we forgot to treat it as such by e.g. applying tilde expansion. + (merge e5a39ad bn/http-cookiefile-config later to maint). + + * Consolidate description of tilde-expansion that is done to + configuration variables that take pathname to a single place. + (merge dca83ab jc/config-pathname-type later to maint). + + * Correct faulty recommendation to use "git submodule deinit ." when + de-initialising all submodules, which would result in a strange + error message in a pathological corner case. + (merge f6a5279 sb/submodule-deinit-all later to maint). + + * Many 'linkgit:<git documentation page>' references were broken, + which are all fixed with this. + (merge 1cca17d jc/linkgit-fix later to maint). + + * "git rerere" can get confused by conflict markers deliberately left + by the inner merge step, because they are indistinguishable from + the real conflict markers left by the outermost merge which are + what the end user and "rerere" need to look at. This was fixed by + making the conflict markers left by the inner merges a bit longer. + (merge 0f9fd5c jc/ll-merge-internal later to maint). + + * CI test was taught to build documentation pages. + (merge b98712b ls/travis-build-doc later to maint). + + * "git fsck" learned to catch NUL byte in a commit object as + potential error and warn. + (merge 6d2d780 jc/fsck-nul-in-commit later to maint). + + * Portability enhancement for "rebase -i" to help platforms whose + shell does not like "for i in <empty>" (which is not POSIX-kosher). + (merge 8e98b35 jk/rebase-interative-eval-fix later to maint). + + * On Windows, .git and optionally any files whose name starts with a + dot are now marked as hidden, with a core.hideDotFiles knob to + customize this behaviour. + (merge ebf31e7 js/windows-dotgit later to maint). + + * Documentation for "git merge --verify-signatures" has been updated + to clarify that the signature of only the commit at the tip is + verified. Also the phrasing used for signature and key validity is + adjusted to align with that used by OpenPGP. + (merge 05a5869 kf/gpg-sig-verification-doc later to maint). + + * A couple of bugs around core.autocrlf have been fixed. + (merge caa47ad tb/core-eol-fix later to maint). + + * Many commands normalize command line arguments from NFD to NFC + variant of UTF-8 on OSX, but commands in the "diff" family did + not, causing "git diff $path" to complain that no such path is + known to Git. They have been taught to do the normalization. + (merge 90a78b8 ar/diff-args-osx-precompose later to maint). + + * "git difftool" learned to handle unmerged paths correctly in + dir-diff mode. + (merge 366f9ce da/difftool later to maint). * Other minor clean-ups and documentation updates - (merge aed7480 mm/lockfile-error-message later to maint). - (merge bfee614 jc/index-pack later to maint). - (merge f870899 ss/exc-flag-is-a-collection-of-bits later to maint). - (merge dde7891 pb/t7502-drop-dup later to maint). - (merge 3bd1b51 cc/doc-recommend-performance-trace-to-file later to maint). - (merge 7d5e9c9 jk/credential-cache-comment-exit later to maint). - (merge 16a86d4 nd/apply-doc later to maint). - (merge c3f6b85 pb/opt-cmdmode-doc later to maint). - (merge 30211fb oa/doc-diff-check later to maint). - (merge 01d98e8 ak/use-hashmap-iter-first-in-submodule-config later to maint). - (merge 8b5a3e9 kn/for-each-tag-branch later to maint). - (merge 9c60d9f sb/misc-cleanups later to maint). - (merge 7a6a44c cc/apply later to maint). - (merge 8e9b208 js/mingw-tests-2.8 later to maint). - (merge d55de70 jc/makefile-redirection-stderr later to maint). - (merge 4232b21 ep/trace-doc-sample-fix later to maint). - (merge ef8c95e ew/send-email-drop-data-dumper later to maint). - (merge 24041d6 jc/xstrfmt-null-with-prec-0 later to maint). - (merge 7bec7f5 jk/use-write-script-more later to maint). + (merge 832c0e5 lp/typofixes later to maint). + (merge f5ee54a sb/z-is-gnutar-ism later to maint). + (merge 2e3926b va/i18n-misc-updates later to maint). + (merge f212dcc bn/config-doc-tt-varnames later to maint). + (merge f54bea4 nd/remote-plural-ours-plus-theirs later to maint). + (merge 2bb0518 ak/t4151-ls-files-could-be-empty later to maint). + (merge 4df4313 jc/test-seq later to maint). + (merge a75a308 tb/t5601-sed-fix later to maint). + (merge 6c1fbe1 va/i18n-remote-comment-to-align later to maint). + (merge dee2303 va/mailinfo-doc-typofix later to maint). diff --git a/Documentation/SubmittingPatches b/Documentation/SubmittingPatches index 98fc4cc1d0..e8ad978824 100644 --- a/Documentation/SubmittingPatches +++ b/Documentation/SubmittingPatches @@ -61,23 +61,28 @@ Make sure that you have tests for the bug you are fixing. See t/README for guidance. When adding a new feature, make sure that you have new tests to show -the feature triggers the new behaviour when it should, and to show the -feature does not trigger when it shouldn't. Also make sure that the -test suite passes after your commit. Do not forget to update the -documentation to describe the updated behaviour. - -Speaking of the documentation, it is currently a liberal mixture of US -and UK English norms for spelling and grammar, which is somewhat -unfortunate. A huge patch that touches the files all over the place -only to correct the inconsistency is not welcome, though. Potential -clashes with other changes that can result from such a patch are not -worth it. We prefer to gradually reconcile the inconsistencies in -favor of US English, with small and easily digestible patches, as a -side effect of doing some other real work in the vicinity (e.g. -rewriting a paragraph for clarity, while turning en_UK spelling to -en_US). Obvious typographical fixes are much more welcomed ("teh -> -"the"), preferably submitted as independent patches separate from -other documentation changes. +the feature triggers the new behavior when it should, and to show the +feature does not trigger when it shouldn't. After any code change, make +sure that the entire test suite passes. + +If you have an account at GitHub (and you can get one for free to work +on open source projects), you can use their Travis CI integration to +test your changes on Linux, Mac (and hopefully soon Windows). See +GitHub-Travis CI hints section for details. + +Do not forget to update the documentation to describe the updated +behavior and make sure that the resulting documentation set formats +well. It is currently a liberal mixture of US and UK English norms for +spelling and grammar, which is somewhat unfortunate. A huge patch that +touches the files all over the place only to correct the inconsistency +is not welcome, though. Potential clashes with other changes that can +result from such a patch are not worth it. We prefer to gradually +reconcile the inconsistencies in favor of US English, with small and +easily digestible patches, as a side effect of doing some other real +work in the vicinity (e.g. rewriting a paragraph for clarity, while +turning en_UK spelling to en_US). Obvious typographical fixes are much +more welcomed ("teh -> "the"), preferably submitted as independent +patches separate from other documentation changes. Oh, another thing. We are picky about whitespaces. Make sure your changes do not trigger errors with the sample pre-commit hook shipped @@ -370,6 +375,47 @@ Know the status of your patch after submission entitled "What's cooking in git.git" and "What's in git.git" giving the status of various proposed changes. +-------------------------------------------------- +GitHub-Travis CI hints + +With an account at GitHub (you can get one for free to work on open +source projects), you can use Travis CI to test your changes on Linux, +Mac (and hopefully soon Windows). You can find a successful example +test build here: https://travis-ci.org/git/git/builds/120473209 + +Follow these steps for the initial setup: + + (1) Fork https://github.com/git/git to your GitHub account. + You can find detailed instructions how to fork here: + https://help.github.com/articles/fork-a-repo/ + + (2) Open the Travis CI website: https://travis-ci.org + + (3) Press the "Sign in with GitHub" button. + + (4) Grant Travis CI permissions to access your GitHub account. + You can find more information about the required permissions here: + https://docs.travis-ci.com/user/github-oauth-scopes + + (5) Open your Travis CI profile page: https://travis-ci.org/profile + + (6) Enable Travis CI builds for your Git fork. + +After the initial setup, Travis CI will run whenever you push new changes +to your fork of Git on GitHub. You can monitor the test state of all your +branches here: https://travis-ci.org/<Your GitHub handle>/git/branches + +If a branch did not pass all test cases then it is marked with a red +cross. In that case you can click on the failing Travis CI job and +scroll all the way down in the log. Find the line "<-- Click here to see +detailed test output!" and click on the triangle next to the log line +number to expand the detailed test output. Here is such a failing +example: https://travis-ci.org/git/git/jobs/122676187 + +Fix the problem and push your fix to your Git fork. This will trigger +a new Travis CI build to ensure all tests pass. + + ------------------------------------------------ MUA specific hints diff --git a/Documentation/config.txt b/Documentation/config.txt index 42d2b50477..53f00dbc26 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -81,13 +81,16 @@ Includes You can include one config file from another by setting the special `include.path` variable to the name of the file to be included. The +variable takes a pathname as its value, and is subject to tilde +expansion. + +The included file is expanded immediately, as if its contents had been found at the location of the include directive. If the value of the `include.path` variable is a relative path, the path is considered to be relative to the configuration file in which the include directive was -found. The value of `include.path` is subject to tilde expansion: `~/` -is expanded to the value of `$HOME`, and `~user/` to the specified -user's home directory. See below for examples. +found. See below for examples. + Example ~~~~~~~ @@ -114,7 +117,7 @@ Example [include] path = /path/to/foo.inc ; include by absolute path path = foo ; expand "foo" relative to the current file - path = ~/foo ; expand "foo" in your $HOME directory + path = ~/foo ; expand "foo" in your `$HOME` directory Values @@ -169,6 +172,13 @@ thing on the same output line (e.g. opening parenthesis before the list of branch names in `log --decorate` output) is set to be painted with `bold` or some other attribute. +pathname:: + A variable that takes a pathname value can be given a + string that begins with "`~/`" or "`~user/`", and the usual + tilde expansion happens to such a string: `~/` + is expanded to the value of `$HOME`, and `~user/` to the + specified user's home directory. + Variables ~~~~~~~~~ @@ -269,6 +279,12 @@ See linkgit:git-update-index[1]. + The default is true (when core.filemode is not specified in the config file). +core.hideDotFiles:: + (Windows-only) If true, mark newly-created directories and files whose + name starts with a dot as hidden. If 'dotGitOnly', only the `.git/` + directory is hidden, but no other files starting with a dot. The + default mode is 'dotGitOnly'. + core.ignoreCase:: If true, this option enables various workarounds to enable Git to work better on filesystems that are not case sensitive, @@ -337,9 +353,9 @@ core.quotePath:: core.eol:: Sets the line ending type to use in the working directory for - files that have the `text` property set. Alternatives are - 'lf', 'crlf' and 'native', which uses the platform's native - line ending. The default value is `native`. See + files that have the `text` property set when core.autocrlf is false. + Alternatives are 'lf', 'crlf' and 'native', which uses the platform's + native line ending. The default value is `native`. See linkgit:gitattributes[5] for more information on end-of-line conversion. @@ -486,10 +502,10 @@ repository's usual working tree). core.logAllRefUpdates:: Enable the reflog. Updates to a ref <ref> is logged to the file - "$GIT_DIR/logs/<ref>", by appending the new and old + "`$GIT_DIR/logs/<ref>`", by appending the new and old SHA-1, the date/time and the reason of the update, but only when the file exists. If this configuration - variable is set to true, missing "$GIT_DIR/logs/<ref>" + variable is set to true, missing "`$GIT_DIR/logs/<ref>`" file is automatically created for branch heads (i.e. under refs/heads/), remote refs (i.e. under refs/remotes/), note refs (i.e. under refs/notes/), and the symbolic ref HEAD. @@ -593,12 +609,11 @@ be delta compressed, but larger binary media files won't be. Common unit suffixes of 'k', 'm', or 'g' are supported. core.excludesFile:: - In addition to '.gitignore' (per-directory) and - '.git/info/exclude', Git looks into this file for patterns - of files which are not meant to be tracked. "`~/`" is expanded - to the value of `$HOME` and "`~user/`" to the specified user's - home directory. Its default value is $XDG_CONFIG_HOME/git/ignore. - If $XDG_CONFIG_HOME is either not set or empty, $HOME/.config/git/ignore + Specifies the pathname to the file that contains patterns to + describe paths that are not meant to be tracked, in addition + to '.gitignore' (per-directory) and '.git/info/exclude'. + Defaults to `$XDG_CONFIG_HOME/git/ignore`. + If `$XDG_CONFIG_HOME` is either not set or empty, `$HOME/.config/git/ignore` is used instead. See linkgit:gitignore[5]. core.askPass:: @@ -615,8 +630,25 @@ core.attributesFile:: '.git/info/attributes', Git looks into this file for attributes (see linkgit:gitattributes[5]). Path expansions are made the same way as for `core.excludesFile`. Its default value is - $XDG_CONFIG_HOME/git/attributes. If $XDG_CONFIG_HOME is either not - set or empty, $HOME/.config/git/attributes is used instead. + `$XDG_CONFIG_HOME/git/attributes`. If `$XDG_CONFIG_HOME` is either not + set or empty, `$HOME/.config/git/attributes` is used instead. + +core.hooksPath:: + By default Git will look for your hooks in the + '$GIT_DIR/hooks' directory. Set this to different path, + e.g. '/etc/git/hooks', and Git will try to find your hooks in + that directory, e.g. '/etc/git/hooks/pre-receive' instead of + in '$GIT_DIR/hooks/pre-receive'. ++ +The path can be either absolute or relative. A relative path is +taken as relative to the directory where the hooks are run (see +the "DESCRIPTION" section of linkgit:githooks[5]). ++ +This configuration variable is useful in cases where you'd like to +centrally configure your Git hooks instead of configuring them on a +per-repository basis, or as a more flexible and centralized +alternative to having an `init.templateDir` where you've changed +default hooks. core.editor:: Commands such as `commit` and `tag` that lets you edit @@ -1106,9 +1138,12 @@ commit.status:: message. Defaults to true. commit.template:: - Specify a file to use as the template for new commit messages. - "`~/`" is expanded to the value of `$HOME` and "`~user/`" to the - specified user's home directory. + Specify the pathname of a file to use as the template for + new commit messages. + +commit.verbose:: + A boolean or int to specify the level of verbose with `git commit`. + See linkgit:git-commit[1]. credential.helper:: Specify an external helper to be called when a username or @@ -1259,6 +1294,10 @@ format.outputDirectory:: Set a custom directory to store the resulting files instead of the current working directory. +format.useAutoBase:: + A boolean value which lets you enable the `--base=auto` option of + format-patch by default. + filter.<driver>.clean:: The command which is used to convert the content of a worktree file to a blob upon checkin. See linkgit:gitattributes[5] for @@ -1335,7 +1374,7 @@ gc.worktreePruneExpire:: 'git worktree prune --expire 3.months.ago'. This config variable can be used to set a different grace period. The value "now" may be used to disable the grace - period and prune $GIT_DIR/worktrees immediately, or "never" + period and prune `$GIT_DIR/worktrees` immediately, or "never" may be used to suppress pruning. gc.reflogExpire:: @@ -1475,13 +1514,13 @@ grep.fallbackToNoIndex:: is executed outside of a git repository. Defaults to false. gpg.program:: - Use this custom program instead of "gpg" found on $PATH when + Use this custom program instead of "`gpg`" found on `$PATH` when making or verifying a PGP signature. The program must support the same command-line interface as GPG, namely, to verify a detached - signature, "gpg --verify $file - <$signature" is run, and the + signature, "`gpg --verify $file - <$signature`" is run, and the program is expected to signal a good signature by exiting with code 0, and to generate an ASCII-armored detached signature, the - standard input of "gpg -bsau $key" is fed with the contents to be + standard input of "`gpg -bsau $key`" is fed with the contents to be signed, and the program is expected to send the result to its standard output. @@ -1494,7 +1533,7 @@ gui.diffContext:: made by the linkgit:git-gui[1]. The default is "5". gui.displayUntracked:: - Determines if linkgit::git-gui[1] shows untracked files + Determines if linkgit:git-gui[1] shows untracked files in the file list. The default is "true". gui.encoding:: @@ -1655,12 +1694,19 @@ http.emptyAuth:: a username in the URL, as libcurl normally requires a username for authentication. +http.extraHeader:: + Pass an additional HTTP header when communicating with a server. If + more than one such entry exists, all of them are added as extra + headers. To allow overriding the settings inherited from the system + config, an empty value will reset the extra headers to the empty list. + http.cookieFile:: - File containing previously stored cookie lines which should be used + The pathname of a file containing previously stored cookie lines, + which should be used in the Git http session, if they match the server. The file format of the file to read cookies from should be plain HTTP headers or - the Netscape/Mozilla cookie file format (see linkgit:curl[1]). - NOTE that the file specified with http.cookieFile is only used as + the Netscape/Mozilla cookie file format (see `curl(1)`). + NOTE that the file specified with http.cookieFile is used only as input unless http.saveCookies is set. http.saveCookies:: @@ -2156,8 +2202,11 @@ pack.packSizeLimit:: The maximum size of a pack. This setting only affects packing to a file when repacking, i.e. the git:// protocol is unaffected. It can be overridden by the `--max-pack-size` - option of linkgit:git-repack[1]. The minimum size allowed is - limited to 1 MiB. The default is unlimited. + option of linkgit:git-repack[1]. Reaching this limit results + in the creation of multiple packfiles; which in turn prevents + bitmaps from being created. + The minimum size allowed is limited to 1 MiB. + The default is unlimited. Common unit suffixes of 'k', 'm', or 'g' are supported. @@ -2557,8 +2606,9 @@ repack.writeBitmaps:: objects to disk (e.g., when `git repack -a` is run). This index can speed up the "counting objects" phase of subsequent packs created for clones and fetches, at the cost of some disk - space and extra time spent on the initial repack. Defaults to - false. + space and extra time spent on the initial repack. This has + no effect if multiple packfiles are created. + Defaults to false. rerere.autoUpdate:: When set to true, `git-rerere` updates the index with the diff --git a/Documentation/diff-options.txt b/Documentation/diff-options.txt index 4b0318e2ac..3cb301556e 100644 --- a/Documentation/diff-options.txt +++ b/Documentation/diff-options.txt @@ -271,7 +271,7 @@ For example, `--word-diff-regex=.` will treat each character as a word and, correspondingly, show differences character by character. + The regex can also be set via a diff driver or configuration option, see -linkgit:gitattributes[1] or linkgit:git-config[1]. Giving it explicitly +linkgit:gitattributes[5] or linkgit:git-config[1]. Giving it explicitly overrides any diff driver or configuration setting. Diff drivers override configuration settings. diff --git a/Documentation/everyday.txto b/Documentation/everyday.txto index c5047d8f9b..ae555bd47e 100644 --- a/Documentation/everyday.txto +++ b/Documentation/everyday.txto @@ -1,7 +1,7 @@ Everyday Git With 20 Commands Or So =================================== -This document has been moved to linkgit:giteveryday[1]. +This document has been moved to linkgit:giteveryday[7]. Please let the owners of the referring site know so that they can update the link you clicked to get here. diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.txt index e94367a5ed..611754f10b 100644 --- a/Documentation/git-check-ignore.txt +++ b/Documentation/git-check-ignore.txt @@ -112,7 +112,7 @@ EXIT STATUS SEE ALSO -------- linkgit:gitignore[5] -linkgit:gitconfig[5] +linkgit:git-config[1] linkgit:git-ls-files[1] GIT diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 45d74be297..1b15cd7b16 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,8 +14,8 @@ SYNOPSIS [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--dissociate] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] - [--recursive | --recurse-submodules] [--jobs <n>] [--] <repository> - [<directory>] + [--recursive | --recurse-submodules] [--[no-]shallow-submodules] + [--jobs <n>] [--] <repository> [<directory>] DESCRIPTION ----------- @@ -191,7 +191,9 @@ objects from the source repository into a pack in the cloned repository. Create a 'shallow' clone with a history truncated to the specified number of commits. Implies `--single-branch` unless `--no-single-branch` is given to fetch the histories near the - tips of all branches. + tips of all branches. This implies `--shallow-submodules`. If + you want to have a shallow superproject clone, but full submodules, + also pass `--no-shallow-submodules`. --[no-]single-branch:: Clone only the history leading to the tip of a single branch, @@ -212,6 +214,9 @@ objects from the source repository into a pack in the cloned repository. repository does not have a worktree/checkout (i.e. if any of `--no-checkout`/`-n`, `--bare`, or `--mirror` is given) +--[no-]shallow-submodules:: + All submodules which are cloned will be shallow with a depth of 1. + --separate-git-dir=<git dir>:: Instead of placing the cloned repository where it is supposed to be, place the cloned repository at the specified directory, diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 48c33d7ed7..cb69faab68 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -61,8 +61,8 @@ OPTIONS stuck to the option without a space. --no-gpg-sign:: - Countermand `commit.gpgSign` configuration variable that is - set to force each and every commit to be signed. + Do not GPG-sign commit, to countermand a `--gpg-sign` option + given earlier on the command line. Commit Information diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 9ec6b3cc17..d474226eb7 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -290,7 +290,8 @@ configuration variable documented in linkgit:git-config[1]. what changes the commit has. Note that this diff output doesn't have its lines prefixed with '#'. This diff will not be a part - of the commit message. + of the commit message. See the `commit.verbose` configuration + variable in linkgit:git-config[1]. + If specified twice, show in addition the unified diff between what would be committed and the worktree files, i.e. the unstaged diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 6fc08e3d89..6843114fc0 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -58,10 +58,10 @@ that location (you can say '--local' but that is the default). This command will fail with non-zero status upon error. Some exit codes are: -- The config file is invalid (ret=3), -- can not write to the config file (ret=4), +- The section or key is invalid (ret=1), - no section or name was provided (ret=2), -- the section or key is invalid (ret=1), +- the config file is invalid (ret=3), +- the config file cannot be written (ret=4), - you try to unset an option which does not exist (ret=5), - you try to unset/set an option for which multiple lines match (ret=5), or - you try to use an invalid regexp (ret=6). diff --git a/Documentation/git-filter-branch.txt b/Documentation/git-filter-branch.txt index 73fd9e8230..003731f6a9 100644 --- a/Documentation/git-filter-branch.txt +++ b/Documentation/git-filter-branch.txt @@ -205,7 +205,7 @@ to other tags will be rewritten to point to the underlying commit. Remap to ancestor ~~~~~~~~~~~~~~~~~ -By using linkgit:rev-list[1] arguments, e.g., path limiters, you can limit the +By using linkgit:git-rev-list[1] arguments, e.g., path limiters, you can limit the set of revisions which get rewritten. However, positive refs on the command line are distinguished: we don't let them be excluded by such limiters. For this purpose, they are instead rewritten to point at the nearest ancestor that diff --git a/Documentation/git-for-each-ref.txt b/Documentation/git-for-each-ref.txt index c52578bb87..d9d406dcfb 100644 --- a/Documentation/git-for-each-ref.txt +++ b/Documentation/git-for-each-ref.txt @@ -179,7 +179,7 @@ returns an empty string instead. As a special case for the date-type fields, you may specify a format for the date by adding `:` followed by date format name (see the -values the `--date` option to linkgit::git-rev-list[1] takes). +values the `--date` option to linkgit:git-rev-list[1] takes). EXAMPLES diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 6821441d7d..bdeecd59e0 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -265,6 +265,11 @@ you can use `--suffix=-patch` to get `0001-description-of-my-change-patch`. Output an all-zero hash in each patch's From header instead of the hash of the commit. +--base=<commit>:: + Record the base tree information to identify the state the + patch series applies to. See the BASE TREE INFORMATION section + below for details. + --root:: Treat the revision argument as a <revision range>, even if it is just a single commit (that would normally be treated as a @@ -520,6 +525,61 @@ This should help you to submit patches inline using KMail. 5. Back in the compose window: add whatever other text you wish to the message, complete the addressing and subject fields, and press send. +BASE TREE INFORMATION +--------------------- + +The base tree information block is used for maintainers or third party +testers to know the exact state the patch series applies to. It consists +of the 'base commit', which is a well-known commit that is part of the +stable part of the project history everybody else works off of, and zero +or more 'prerequisite patches', which are well-known patches in flight +that is not yet part of the 'base commit' that need to be applied on top +of 'base commit' in topological order before the patches can be applied. + +The 'base commit' is shown as "base-commit: " followed by the 40-hex of +the commit object name. A 'prerequisite patch' is shown as +"prerequisite-patch-id: " followed by the 40-hex 'patch id', which can +be obtained by passing the patch through the `git patch-id --stable` +command. + +Imagine that on top of the public commit P, you applied well-known +patches X, Y and Z from somebody else, and then built your three-patch +series A, B, C, the history would be like: + +................................................ +---P---X---Y---Z---A---B---C +................................................ + +With `git format-patch --base=P -3 C` (or variants thereof, e.g. with +`--cover-letter` of using `Z..C` instead of `-3 C` to specify the +range), the base tree information block is shown at the end of the +first message the command outputs (either the first patch, or the +cover letter), like this: + +------------ +base-commit: P +prerequisite-patch-id: X +prerequisite-patch-id: Y +prerequisite-patch-id: Z +------------ + +For non-linear topology, such as + +................................................ +---P---X---A---M---C + \ / + Y---Z---B +................................................ + +You can also use `git format-patch --base=P -3 C` to generate patches +for A, B and C, and the identifiers for P, X, Y, Z are appended at the +end of the first message. + +If set `--base=auto` in cmdline, it will track base commit automatically, +the base commit will be the merge base of tip commit of the remote-tracking +branch and revision-range specified in cmdline. +For a local branch, you need to track a remote branch by `git branch +--set-upstream-to` before using this option. EXAMPLES -------- diff --git a/Documentation/git-init.txt b/Documentation/git-init.txt index 8174d27efd..6364e5dc45 100644 --- a/Documentation/git-init.txt +++ b/Documentation/git-init.txt @@ -130,7 +130,12 @@ The template directory will be one of the following (in order): - the default template directory: `/usr/share/git-core/templates`. The default template directory includes some directory structure, suggested -"exclude patterns" (see linkgit:gitignore[5]), and sample hook files (see linkgit:githooks[5]). +"exclude patterns" (see linkgit:gitignore[5]), and sample hook files. + +The sample hooks are all disabled by default, To enable one of the +sample hooks rename it by removing its `.sample` suffix. + +See linkgit:githooks[5] for more general info on hook execution. EXAMPLES -------- diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 0947084140..3bbc731f67 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -85,7 +85,7 @@ with comments and suggestions on the message you are responding to, and to conclude it with a patch submission, separating the discussion and the beginning of the proposed commit log message with a scissors line. + -This can enabled by default with the configuration option mailinfo.scissors. +This can be enabled by default with the configuration option mailinfo.scissors. --no-scissors:: Ignore scissors lines. Useful for overriding mailinfo.scissors settings. diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 689aa4c57c..b758d5556c 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -11,6 +11,7 @@ SYNOPSIS [verse] 'git merge' [-n] [--stat] [--no-commit] [--squash] [--[no-]edit] [-s <strategy>] [-X <strategy-option>] [-S[<keyid>]] + [--[no-]allow-unrelated-histories] [--[no-]rerere-autoupdate] [-m <msg>] [<commit>...] 'git merge' <msg> HEAD <commit>... 'git merge' --abort @@ -98,19 +99,6 @@ commit or stash your changes before running 'git merge'. 'git merge --abort' is equivalent to 'git reset --merge' when `MERGE_HEAD` is present. ---allow-unrelated-histories:: - By default, `git merge` command refuses to merge histories - that do not share a common ancestor. This option can be - used to override this safety when merging histories of two - projects that started their lives independently. As that is - a very rare occasion, no configuration variable to enable - this by default exists and will not be added, and the list - of options at the top of this documentation does not mention - this option. Also `git pull` does not pass this option down - to `git merge` (instead, you `git fetch` first, examine what - you will be merging and then `git merge` locally with this - option). - <commit>...:: Commits, usually other branch heads, to merge into our branch. Specifying more than one commit will create a merge with diff --git a/Documentation/git-notes.txt b/Documentation/git-notes.txt index 8de349968a..9c4fd6812c 100644 --- a/Documentation/git-notes.txt +++ b/Documentation/git-notes.txt @@ -402,4 +402,4 @@ on the `notes.rewrite.<command>` and `notes.rewriteRef` settings. GIT --- -Part of the linkgit:git[7] suite +Part of the linkgit:git[1] suite diff --git a/Documentation/git-pack-objects.txt b/Documentation/git-pack-objects.txt index bbea5294ca..19cdcd0341 100644 --- a/Documentation/git-pack-objects.txt +++ b/Documentation/git-pack-objects.txt @@ -110,7 +110,8 @@ base-name:: --max-pack-size=<n>:: Maximum size of each output pack file. The size can be suffixed with "k", "m", or "g". The minimum size allowed is limited to 1 MiB. - If specified, multiple packfiles may be created. + If specified, multiple packfiles may be created, which also + prevents the creation of a bitmap index. The default is unlimited, unless the config variable `pack.packSizeLimit` is set. diff --git a/Documentation/git-repack.txt b/Documentation/git-repack.txt index af230d0647..b9c02ce481 100644 --- a/Documentation/git-repack.txt +++ b/Documentation/git-repack.txt @@ -106,7 +106,8 @@ other objects in that pack they already have locally. --max-pack-size=<n>:: Maximum size of each output pack file. The size can be suffixed with "k", "m", or "g". The minimum size allowed is limited to 1 MiB. - If specified, multiple packfiles may be created. + If specified, multiple packfiles may be created, which also + prevents the creation of a bitmap index. The default is unlimited, unless the config variable `pack.packSizeLimit` is set. @@ -115,7 +116,8 @@ other objects in that pack they already have locally. Write a reachability bitmap index as part of the repack. This only makes sense when used with `-a` or `-A`, as the bitmaps must be able to refer to all reachable objects. This option - overrides the setting of `pack.writeBitmaps`. + overrides the setting of `repack.writeBitmaps`. This option + has no effect if multiple packfiles are created. --pack-kept-objects:: Include objects in `.keep` files when repacking. Note that we @@ -123,7 +125,7 @@ other objects in that pack they already have locally. This means that we may duplicate objects, but this makes the option safe to use when there are concurrent pushes or fetches. This option is generally only useful if you are writing bitmaps - with `-b` or `pack.writeBitmaps`, as it ensures that the + with `-b` or `repack.writeBitmaps`, as it ensures that the bitmapped packfile has the necessary objects. Configuration diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index 13adebf7b7..9226c4380c 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -13,7 +13,7 @@ SYNOPSIS [--reference <repository>] [--depth <depth>] [--] <repository> [<path>] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] -'git submodule' [--quiet] deinit [-f|--force] [--] <path>... +'git submodule' [--quiet] deinit [-f|--force] (--all|[--] <path>...) 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase|--merge] [--reference <repository>] [--depth <depth>] [--recursive] [--jobs <n>] [--] [<path>...] @@ -140,12 +140,15 @@ deinit:: tree. Further calls to `git submodule update`, `git submodule foreach` and `git submodule sync` will skip any unregistered submodules until they are initialized again, so use this command if you don't want to - have a local checkout of the submodule in your work tree anymore. If + have a local checkout of the submodule in your working tree anymore. If you really want to remove a submodule from the repository and commit that use linkgit:git-rm[1] instead. + -If `--force` is specified, the submodule's work tree will be removed even if -it contains local modifications. +When the command is run without pathspec, it errors out, +instead of deinit-ing everything, to prevent mistakes. ++ +If `--force` is specified, the submodule's working tree will +be removed even if it contains local modifications. update:: + @@ -247,6 +250,10 @@ OPTIONS --quiet:: Only print error messages. +--all:: + This option is only valid for the deinit command. Unregister all + submodules in the working tree. + -b:: --branch:: Branch of repository to add as submodule. @@ -257,8 +264,8 @@ OPTIONS --force:: This option is only valid for add, deinit and update commands. When running add, allow adding an otherwise ignored submodule path. - When running deinit the submodule work trees will be removed even if - they contain local changes. + When running deinit the submodule working trees will be removed even + if they contain local changes. When running update (only effective with the checkout procedure), throw away local changes in submodules when switching to a different commit; and always run a checkout operation in the diff --git a/Documentation/git.txt b/Documentation/git.txt index 8afe349781..dd6dbf7dd9 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,10 +43,12 @@ unreleased) version of Git, that is available from the 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v2.8.1/git.html[documentation for release 2.8.1] +* link:v2.8.3/git.html[documentation for release 2.8.3] * release notes for - link:RelNotes/2.8.1.txt[2.8.1]. + link:RelNotes/2.8.3.txt[2.8.3], + link:RelNotes/2.8.2.txt[2.8.2], + link:RelNotes/2.8.1.txt[2.8.1], link:RelNotes/2.8.0.txt[2.8]. * link:v2.7.3/git.html[documentation for release 2.7.3] diff --git a/Documentation/githooks.txt b/Documentation/githooks.txt index a2f59b194c..d82e912e55 100644 --- a/Documentation/githooks.txt +++ b/Documentation/githooks.txt @@ -7,24 +7,35 @@ githooks - Hooks used by Git SYNOPSIS -------- -$GIT_DIR/hooks/* +$GIT_DIR/hooks/* (or \`git config core.hooksPath`/*) DESCRIPTION ----------- -Hooks are little scripts you can place in `$GIT_DIR/hooks` -directory to trigger action at certain points. When -'git init' is run, a handful of example hooks are copied into the -`hooks` directory of the new repository, but by default they are -all disabled. To enable a hook, rename it by removing its `.sample` -suffix. +Hooks are programs you can place in a hooks directory to trigger +actions at certain points in git's execution. Hooks that don't have +the executable bit set are ignored. -NOTE: It is also a requirement for a given hook to be executable. -However - in a freshly initialized repository - the `.sample` files are -executable by default. +By default the hooks directory is `$GIT_DIR/hooks`, but that can be +changed via the `core.hooksPath` configuration variable (see +linkgit:git-config[1]). -This document describes the currently defined hooks. +Before Git invokes a hook, it changes its working directory to either +the root of the working tree in a non-bare repository, or to the +$GIT_DIR in a bare repository. + +Hooks can get their arguments via the environment, command-line +arguments, and stdin. See the documentation for each hook below for +details. + +'git init' may copy hooks to the new repository, depending on its +configuration. See the "TEMPLATE DIRECTORY" section in +linkgit:git-init[1] for details. When the rest of this document refers +to "default hooks" it's talking about the default template shipped +with Git. + +The currently supported hooks are described below. HOOKS ----- @@ -32,15 +43,15 @@ HOOKS applypatch-msg ~~~~~~~~~~~~~~ -This hook is invoked by 'git am' script. It takes a single +This hook is invoked by 'git am'. It takes a single parameter, the name of the file that holds the proposed commit -log message. Exiting with non-zero status causes -'git am' to abort before applying the patch. +log message. Exiting with a non-zero status causes 'git am' to abort +before applying the patch. The hook is allowed to edit the message file in place, and can be used to normalize the message into some project standard -format (if the project has one). It can also be used to refuse -the commit after inspecting the message file. +format. It can also be used to refuse the commit after inspecting +the message file. The default 'applypatch-msg' hook, when enabled, runs the 'commit-msg' hook, if the latter is enabled. @@ -73,10 +84,10 @@ pre-commit ~~~~~~~~~~ This hook is invoked by 'git commit', and can be bypassed -with `--no-verify` option. It takes no parameter, and is +with the `--no-verify` option. It takes no parameters, and is invoked before obtaining the proposed commit log message and -making a commit. Exiting with non-zero status from this script -causes the 'git commit' to abort. +making a commit. Exiting with a non-zero status from this script +causes the 'git commit' command to abort before creating a commit. The default 'pre-commit' hook, when enabled, catches introduction of lines with trailing whitespaces and aborts the commit when @@ -115,15 +126,15 @@ commit-msg ~~~~~~~~~~ This hook is invoked by 'git commit', and can be bypassed -with `--no-verify` option. It takes a single parameter, the +with the `--no-verify` option. It takes a single parameter, the name of the file that holds the proposed commit log message. -Exiting with non-zero status causes the 'git commit' to +Exiting with a non-zero status causes the 'git commit' to abort. -The hook is allowed to edit the message file in place, and can -be used to normalize the message into some project standard -format (if the project has one). It can also be used to refuse -the commit after inspecting the message file. +The hook is allowed to edit the message file in place, and can be used +to normalize the message into some project standard format. It +can also be used to refuse the commit after inspecting the message +file. The default 'commit-msg' hook, when enabled, detects duplicate "Signed-off-by" lines, and aborts the commit if one is found. @@ -131,8 +142,8 @@ The default 'commit-msg' hook, when enabled, detects duplicate post-commit ~~~~~~~~~~~ -This hook is invoked by 'git commit'. It takes no -parameter, and is invoked after a commit is made. +This hook is invoked by 'git commit'. It takes no parameters, and is +invoked after a commit is made. This hook is meant primarily for notification, and cannot affect the outcome of 'git commit'. @@ -267,9 +278,11 @@ does not know the entire set of branches, so it would end up firing one e-mail per ref when used naively, though. The <<post-receive,'post-receive'>> hook is more suited to that. -Another use suggested on the mailing list is to use this hook to -implement access control which is finer grained than the one -based on filesystem group. +In an environment that restricts the users' access only to git +commands over the wire, this hook can be used to implement access +control without relying on filesystem ownership and group +membership. See linkgit:git-shell[1] for how you might use the login +shell to restrict the user's access to only git commands. Both standard output and standard error output are forwarded to 'git send-pack' on the other end, so you can simply `echo` messages diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index cafc284359..8ad29e61a9 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -145,7 +145,7 @@ current branch integrates with) obviously do not work, as there is no A fast-forward is a special type of <<def_merge,merge>> where you have a <<def_revision,revision>> and you are "merging" another <<def_branch,branch>>'s changes that happen to be a descendant of what - you have. In such these cases, you do not make a new <<def_merge,merge>> + you have. In such a case, you do not make a new <<def_merge,merge>> <<def_commit,commit>> but instead just update to his revision. This will happen frequently on a <<def_remote_tracking_branch,remote-tracking branch>> of a remote diff --git a/Documentation/lint-gitlink.perl b/Documentation/lint-gitlink.perl new file mode 100755 index 0000000000..476cc30b83 --- /dev/null +++ b/Documentation/lint-gitlink.perl @@ -0,0 +1,71 @@ +#!/usr/bin/perl + +use File::Find; +use Getopt::Long; + +my $basedir = "."; +GetOptions("basedir=s" => \$basedir) + or die("Cannot parse command line arguments\n"); + +my $found_errors = 0; + +sub report { + my ($where, $what, $error) = @_; + print "$where: $error: $what\n"; + $found_errors = 1; +} + +sub grab_section { + my ($page) = @_; + open my $fh, "<", "$basedir/$page.txt"; + my $firstline = <$fh>; + chomp $firstline; + close $fh; + my ($section) = ($firstline =~ /.*\((\d)\)$/); + return $section; +} + +sub lint { + my ($file) = @_; + open my $fh, "<", $file + or return; + while (<$fh>) { + my $where = "$file:$."; + while (s/linkgit:((.*?)\[(\d)\])//) { + my ($target, $page, $section) = ($1, $2, $3); + + # De-AsciiDoc + $page =~ s/{litdd}/--/g; + + if ($page !~ /^git/) { + report($where, $target, "nongit link"); + next; + } + if (! -f "$basedir/$page.txt") { + report($where, $target, "no such source"); + next; + } + $real_section = grab_section($page); + if ($real_section != $section) { + report($where, $target, + "wrong section (should be $real_section)"); + next; + } + } + } + close $fh; +} + +sub lint_it { + lint($File::Find::name) if -f && /\.txt$/; +} + +if (!@ARGV) { + find({ wanted => \&lint_it, no_chdir => 1 }, $basedir); +} else { + for (@ARGV) { + lint($_); + } +} + +exit $found_errors; diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index f08e9b80c5..5b4a62e936 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -89,8 +89,11 @@ option can be used to override --squash. --verify-signatures:: --no-verify-signatures:: - Verify that the commits being merged have good and trusted GPG signatures - and abort the merge in case they do not. + Verify that the tip commit of the side branch being merged is + signed with a valid key, i.e. a key that has a valid uid: in the + default trust model, this means the signing key has been signed by + a trusted key. If the tip commit of the side branch is not signed + with a valid key, the merge is aborted. --summary:: --no-summary:: @@ -114,3 +117,11 @@ ifndef::git-pull[] reporting. endif::git-pull[] + +--allow-unrelated-histories:: + By default, `git merge` command refuses to merge histories + that do not share a common ancestor. This option can be + used to override this safety when merging histories of two + projects that started their lives independently. As that is + a very rare occasion, no configuration variable to enable + this by default exists and will not be added. diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 671cebd95c..29b19b992f 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -143,8 +143,8 @@ ifndef::git-rev-list[] - '%N': commit notes endif::git-rev-list[] - '%GG': raw verification message from GPG for a signed commit -- '%G?': show "G" for a Good signature, "B" for a Bad signature, "U" for a good, - untrusted signature and "N" for no signature +- '%G?': show "G" for a good (valid) signature, "B" for a bad signature, + "U" for a good signature with unknown validity 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 - '%gD': reflog selector, e.g., `refs/stash@{1}` diff --git a/Documentation/technical/api-credentials.txt b/Documentation/technical/api-credentials.txt index e44426dd04..75368f26ca 100644 --- a/Documentation/technical/api-credentials.txt +++ b/Documentation/technical/api-credentials.txt @@ -243,7 +243,7 @@ appended to its command line, which is one of: The details of the credential will be provided on the helper's stdin stream. The exact format is the same as the input/output format of the `git credential` plumbing command (see the section `INPUT/OUTPUT -FORMAT` in linkgit:git-credential[7] for a detailed specification). +FORMAT` in linkgit:git-credential[1] for a detailed specification). For a `get` operation, the helper should produce a list of attributes on stdout in the same format. A helper is free to produce a subset, or @@ -268,4 +268,4 @@ See also linkgit:gitcredentials[7] -linkgit:git-config[5] (See configuration variables `credential.*`) +linkgit:git-config[1] (See configuration variables `credential.*`) diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index 695bd4bf43..27bd701c0d 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -144,8 +144,12 @@ There are some macros to easily define options: `OPT_COUNTUP(short, long, &int_var, description)`:: Introduce a count-up option. - `int_var` is incremented on each use of `--option`, and - reset to zero with `--no-option`. + Each use of `--option` increments `int_var`, starting from zero + (even if initially negative), and `--no-option` resets it to + zero. To determine if `--option` or `--no-option` was encountered at + all, initialize `int_var` to a negative value, and if it is still + negative after parse_options(), then neither `--option` nor + `--no-option` was seen. `OPT_BIT(short, long, &int_var, description, mask)`:: Introduce a boolean option. diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index c6977bbc5a..8b36343802 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -526,7 +526,7 @@ Push Certificate A push certificate begins with a set of header lines. After the header and an empty line, the protocol commands follow, one per -line. Note that the the trailing LF in push-cert PKT-LINEs is _not_ +line. Note that the trailing LF in push-cert PKT-LINEs is _not_ optional; it must be present. Currently, the following header fields are defined: diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 655b49011f..e3d0bed2a9 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v2.8.0.GIT +DEF_VER=v2.9.0-rc0 LF=' ' @@ -440,7 +440,6 @@ DIFF = diff TAR = tar FIND = find INSTALL = install -RPMBUILD = rpmbuild TCL_PATH = tclsh TCLTK_PATH = wish XGETTEXT = xgettext @@ -621,7 +620,7 @@ TEST_PROGRAMS_NEED_X += test-svn-fe TEST_PROGRAMS_NEED_X += test-urlmatch-normalization TEST_PROGRAMS_NEED_X += test-wildmatch -TEST_PROGRAMS = $(patsubst %,%$X,$(TEST_PROGRAMS_NEED_X)) +TEST_PROGRAMS = $(patsubst %,t/helper/%$X,$(TEST_PROGRAMS_NEED_X)) # List built-in command $C whose implementation cmd_$C() is not in # builtin/$C.o but is linked in as part of some other command. @@ -1898,7 +1897,7 @@ VCSSVN_OBJS += vcs-svn/fast_export.o VCSSVN_OBJS += vcs-svn/svndiff.o VCSSVN_OBJS += vcs-svn/svndump.o -TEST_OBJS := $(patsubst test-%$X,test-%.o,$(TEST_PROGRAMS)) +TEST_OBJS := $(patsubst %$X,%.o,$(TEST_PROGRAMS)) OBJECTS := $(LIB_OBJS) $(BUILTIN_OBJS) $(PROGRAM_OBJS) $(TEST_OBJS) \ $(XDIFF_OBJS) \ $(VCSSVN_OBJS) \ @@ -2063,7 +2062,7 @@ XGETTEXT_FLAGS_SH = $(XGETTEXT_FLAGS) --language=Shell \ --keyword=gettextln --keyword=eval_gettextln XGETTEXT_FLAGS_PERL = $(XGETTEXT_FLAGS) --keyword=__ --language=Perl LOCALIZED_C = $(C_OBJ:o=c) $(LIB_H) $(GENERATED_H) -LOCALIZED_SH = $(SCRIPT_SH) +LOCALIZED_SH = $(SCRIPT_SH) git-parse-remote.sh LOCALIZED_PERL = $(SCRIPT_PERL) ifdef XGETTEXT_INCLUDE_TESTS @@ -2205,7 +2204,7 @@ bin-wrappers/%: wrap-for-bin.sh @mkdir -p bin-wrappers $(QUIET_GEN)sed -e '1s|#!.*/sh|#!$(SHELL_PATH_SQ)|' \ -e 's|@@BUILD_DIR@@|$(shell pwd)|' \ - -e 's|@@PROG@@|$(@F)|' < $< > $@ && \ + -e 's|@@PROG@@|$(patsubst test-%,t/helper/test-%,$(@F))|' < $< > $@ && \ chmod +x $@ # GNU make supports exporting all variables by "export" without parameters. @@ -2225,25 +2224,25 @@ perf: all .PHONY: test perf -test-ctype$X: ctype.o +t/helper/test-ctype$X: ctype.o -test-date$X: date.o ctype.o +t/helper/test-date$X: date.o ctype.o -test-delta$X: diff-delta.o patch-delta.o +t/helper/test-delta$X: diff-delta.o patch-delta.o -test-line-buffer$X: vcs-svn/lib.a +t/helper/test-line-buffer$X: vcs-svn/lib.a -test-parse-options$X: parse-options.o parse-options-cb.o +t/helper/test-parse-options$X: parse-options.o parse-options-cb.o -test-svn-fe$X: vcs-svn/lib.a +t/helper/test-svn-fe$X: vcs-svn/lib.a .PRECIOUS: $(TEST_OBJS) -test-%$X: test-%.o GIT-LDFLAGS $(GITLIBS) +t/helper/test-%$X: t/helper/test-%.o GIT-LDFLAGS $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ $(ALL_LDFLAGS) $(filter %.o,$^) $(filter %.a,$^) $(LIBS) -check-sha1:: test-sha1$X - ./test-sha1.sh +check-sha1:: t/helper/test-sha1$X + t/helper/test-sha1.sh SP_OBJ = $(patsubst %.o,%.sp,$(C_OBJ)) @@ -2390,31 +2389,25 @@ quick-install-html: ### Maintainer's dist rules -git.spec: git.spec.in GIT-VERSION-FILE - sed -e 's/@@VERSION@@/$(GIT_VERSION)/g' < $< > $@+ - mv $@+ $@ - GIT_TARNAME = git-$(GIT_VERSION) -dist: git.spec git-archive$(X) configure +dist: git-archive$(X) configure ./git-archive --format=tar \ --prefix=$(GIT_TARNAME)/ HEAD^{tree} > $(GIT_TARNAME).tar @mkdir -p $(GIT_TARNAME) - @cp git.spec configure $(GIT_TARNAME) + @cp configure $(GIT_TARNAME) @echo $(GIT_VERSION) > $(GIT_TARNAME)/version @$(MAKE) -C git-gui TARDIR=../$(GIT_TARNAME)/git-gui dist-version $(TAR) rf $(GIT_TARNAME).tar \ - $(GIT_TARNAME)/git.spec \ $(GIT_TARNAME)/configure \ $(GIT_TARNAME)/version \ $(GIT_TARNAME)/git-gui/version @$(RM) -r $(GIT_TARNAME) gzip -f -9 $(GIT_TARNAME).tar -rpm: dist - $(RPMBUILD) \ - --define "_source_filedigest_algorithm md5" \ - --define "_binary_filedigest_algorithm md5" \ - -ta $(GIT_TARNAME).tar.gz +rpm:: + @echo >&2 "Use distro packaged sources to run rpmbuild" + @false +.PHONY: rpm htmldocs = git-htmldocs-$(GIT_VERSION) manpages = git-manpages-$(GIT_VERSION) @@ -2450,8 +2443,8 @@ profile-clean: $(RM) $(addsuffix *.gcno,$(addprefix $(PROFILE_DIR)/, $(object_dirs))) clean: profile-clean coverage-clean - $(RM) *.o *.res refs/*.o block-sha1/*.o ppc/*.o compat/*.o compat/*/*.o - $(RM) xdiff/*.o vcs-svn/*.o ewah/*.o builtin/*.o + $(RM) *.res + $(RM) $(OBJECTS) $(RM) $(LIB_FILE) $(XDIFF_LIB) $(VCSSVN_LIB) $(RM) $(ALL_PROGRAMS) $(SCRIPT_LIB) $(BUILT_INS) git$X $(RM) $(TEST_PROGRAMS) $(NO_INSTALL) @@ -2490,6 +2483,7 @@ ALL_COMMANDS += git-gui git-citool .PHONY: check-docs check-docs:: + $(MAKE) -C Documentation lint-docs @(for v in $(ALL_COMMANDS); \ do \ case "$$v" in \ @@ -860,8 +860,8 @@ static void check_good_are_ancestors_of_bad(const char *prefix, int no_checkout) /* Create file BISECT_ANCESTORS_OK. */ fd = open(filename, O_CREAT | O_TRUNC | O_WRONLY, 0600); if (fd < 0) - warning("could not create file '%s': %s", - filename, strerror(errno)); + warning_errno("could not create file '%s'", + filename); else close(fd); done: @@ -910,8 +910,7 @@ void read_bisect_terms(const char **read_bad, const char **read_good) *read_good = "good"; return; } else { - die("could not read file '%s': %s", filename, - strerror(errno)); + die_errno("could not read file '%s'", filename); } } else { strbuf_getline_lf(&str, fp); @@ -334,15 +334,16 @@ void remove_branch_state(void) unlink(git_path_squash_msg()); } -void die_if_checked_out(const char *branch) +void die_if_checked_out(const char *branch, int ignore_current_worktree) { - char *existing; + const struct worktree *wt; - existing = find_shared_symref("HEAD", branch); - if (existing) { - skip_prefix(branch, "refs/heads/", &branch); - die(_("'%s' is already checked out at '%s'"), branch, existing); - } + wt = find_shared_symref("HEAD", branch); + if (!wt || (ignore_current_worktree && wt->is_current)) + return; + skip_prefix(branch, "refs/heads/", &branch); + die(_("'%s' is already checked out at '%s'"), + branch, wt->path); } int replace_each_worktree_head_symref(const char *oldref, const char *newref) @@ -357,7 +358,8 @@ int replace_each_worktree_head_symref(const char *oldref, const char *newref) if (strcmp(oldref, worktrees[i]->head_ref)) continue; - if (set_worktree_head_symref(worktrees[i]->git_dir, newref)) { + if (set_worktree_head_symref(get_worktree_git_dir(worktrees[i]), + newref)) { ret = -1; error(_("HEAD of working tree %s is not updated"), worktrees[i]->path); @@ -58,7 +58,7 @@ extern int read_branch_desc(struct strbuf *, const char *branch_name); * worktree and die (with a message describing its checkout location) if * it is. */ -extern void die_if_checked_out(const char *branch); +extern void die_if_checked_out(const char *branch, int ignore_current_worktree); /* * Update all per-worktree HEADs pointing at the old ref to point the new ref. diff --git a/builtin/am.c b/builtin/am.c index d003939bc5..3dfe70b7a0 100644 --- a/builtin/am.c +++ b/builtin/am.c @@ -769,15 +769,15 @@ static int split_mail_conv(mail_conv_fn fn, struct am_state *state, in = fopen(*paths, "r"); if (!in) - return error(_("could not open '%s' for reading: %s"), - *paths, strerror(errno)); + return error_errno(_("could not open '%s' for reading"), + *paths); mail = mkpath("%s/%0*d", state->dir, state->prec, i + 1); out = fopen(mail, "w"); if (!out) - return error(_("could not open '%s' for writing: %s"), - mail, strerror(errno)); + return error_errno(_("could not open '%s' for writing"), + mail); ret = fn(out, in, keep_cr); @@ -857,8 +857,7 @@ static int split_mail_stgit_series(struct am_state *state, const char **paths, fp = fopen(*paths, "r"); if (!fp) - return error(_("could not open '%s' for reading: %s"), *paths, - strerror(errno)); + return error_errno(_("could not open '%s' for reading"), *paths); while (!strbuf_getline_lf(&sb, fp)) { if (*sb.buf == '#') diff --git a/builtin/branch.c b/builtin/branch.c index 0adba629d2..2ecde53bf8 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -220,12 +220,12 @@ static int delete_branches(int argc, const char **argv, int force, int kinds, name = mkpathdup(fmt, bname.buf); if (kinds == FILTER_REFS_BRANCHES) { - char *worktree = find_shared_symref("HEAD", name); - if (worktree) { + const struct worktree *wt = + find_shared_symref("HEAD", name); + if (wt) { error(_("Cannot delete branch '%s' " "checked out at '%s'"), - bname.buf, worktree); - free(worktree); + bname.buf, wt->path); ret = 1; continue; } @@ -375,12 +375,14 @@ static char *get_head_description(void) strbuf_addf(&desc, _("(no branch, bisect started on %s)"), state.branch); else if (state.detached_from) { - /* TRANSLATORS: make sure these match _("HEAD detached at ") - and _("HEAD detached from ") in wt-status.c */ if (state.detached_at) + /* TRANSLATORS: make sure this matches + "HEAD detached at " in wt-status.c */ strbuf_addf(&desc, _("(HEAD detached at %s)"), state.detached_from); else + /* TRANSLATORS: make sure this matches + "HEAD detached from " in wt-status.c */ strbuf_addf(&desc, _("(HEAD detached from %s)"), state.detached_from); } @@ -524,6 +526,29 @@ static void print_ref_list(struct ref_filter *filter, struct ref_sorting *sortin ref_array_clear(&array); } +static void reject_rebase_or_bisect_branch(const char *target) +{ + struct worktree **worktrees = get_worktrees(); + int i; + + for (i = 0; worktrees[i]; i++) { + struct worktree *wt = worktrees[i]; + + if (!wt->is_detached) + continue; + + if (is_worktree_being_rebased(wt, target)) + die(_("Branch %s is being rebased at %s"), + target, wt->path); + + if (is_worktree_being_bisected(wt, target)) + die(_("Branch %s is being bisected at %s"), + target, wt->path); + } + + free_worktrees(worktrees); +} + static void rename_branch(const char *oldname, const char *newname, int force) { struct strbuf oldref = STRBUF_INIT, newref = STRBUF_INIT, logmsg = STRBUF_INIT; @@ -553,6 +578,8 @@ static void rename_branch(const char *oldname, const char *newname, int force) validate_new_branchname(newname, &newref, force, clobber_head_ok); + reject_rebase_or_bisect_branch(oldref.buf); + strbuf_addf(&logmsg, "Branch: renamed %s to %s", oldref.buf, newref.buf); @@ -593,8 +620,7 @@ static int edit_branch_description(const char *branch_name) branch_name, comment_line_char); if (write_file_gently(git_path(edit_description), "%s", buf.buf)) { strbuf_release(&buf); - return error(_("could not write branch description template: %s"), - strerror(errno)); + return error_errno(_("could not write branch description template")); } strbuf_reset(&buf); if (launch_editor(git_path(edit_description), &buf, NULL)) { @@ -630,7 +656,7 @@ int cmd_branch(int argc, const char **argv, const char *prefix) BRANCH_TRACK_EXPLICIT), OPT_SET_INT( 0, "set-upstream", &track, N_("change upstream info"), BRANCH_TRACK_OVERRIDE), - OPT_STRING('u', "set-upstream-to", &new_upstream, "upstream", "change the upstream info"), + OPT_STRING('u', "set-upstream-to", &new_upstream, N_("upstream"), N_("change the upstream info")), OPT_BOOL(0, "unset-upstream", &unset_upstream, "Unset the upstream info"), OPT__COLOR(&branch_use_color, N_("use colored output")), OPT_SET_INT('r', "remotes", &filter.kind, N_("act on remote-tracking branches"), @@ -838,8 +864,8 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (argc == 1 && track == BRANCH_TRACK_OVERRIDE && !branch_existed && remote_tracking) { fprintf(stderr, _("\nIf you wanted to make '%s' track '%s', do this:\n\n"), head, branch->name); - fprintf(stderr, _(" git branch -d %s\n"), branch->name); - fprintf(stderr, _(" git branch --set-upstream-to %s\n"), branch->name); + fprintf(stderr, " git branch -d %s\n", branch->name); + fprintf(stderr, " git branch --set-upstream-to %s\n", branch->name); } } else diff --git a/builtin/checkout.c b/builtin/checkout.c index efcbd8f6b5..3398c61e9a 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -242,7 +242,6 @@ static int checkout_paths(const struct checkout_opts *opts, struct checkout state; static char *ps_matched; unsigned char rev[20]; - int flag; struct commit *head; int errs = 0; struct lock_file *lock_file; @@ -375,7 +374,7 @@ static int checkout_paths(const struct checkout_opts *opts, if (write_locked_index(&the_index, lock_file, COMMIT_LOCK)) die(_("unable to write new index file")); - read_ref_full("HEAD", 0, rev, &flag); + read_ref_full("HEAD", 0, rev, NULL); head = lookup_commit_reference_gently(rev, 1); errs |= post_checkout_hook(head, head, 0); @@ -1111,7 +1110,7 @@ static int checkout_branch(struct checkout_opts *opts, char *head_ref = resolve_refdup("HEAD", 0, sha1, &flag); if (head_ref && (!(flag & REF_ISSYMREF) || strcmp(head_ref, new->path))) - die_if_checked_out(new->path); + die_if_checked_out(new->path, 1); free(head_ref); } diff --git a/builtin/clone.c b/builtin/clone.c index 6576ecf343..5f867e67d8 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -40,6 +40,7 @@ static const char * const builtin_clone_usage[] = { static int option_no_checkout, option_bare, option_mirror, option_single_branch = -1; static int option_local = -1, option_no_hardlinks, option_shared, option_recursive; +static int option_shallow_submodules = -1; static char *option_template, *option_depth; static char *option_origin = NULL; static char *option_branch = NULL; @@ -92,6 +93,8 @@ static struct option builtin_clone_options[] = { N_("create a shallow clone of that depth")), OPT_BOOL(0, "single-branch", &option_single_branch, N_("clone only one branch, HEAD or --branch")), + OPT_BOOL(0, "shallow-submodules", &option_shallow_submodules, + N_("any cloned submodules will be shallow")), OPT_STRING(0, "separate-git-dir", &real_git_dir, N_("gitdir"), N_("separate git dir from working tree")), OPT_STRING_LIST('c', "config", &option_config, N_("key=value"), @@ -735,6 +738,10 @@ static int checkout(void) struct argv_array args = ARGV_ARRAY_INIT; argv_array_pushl(&args, "submodule", "update", "--init", "--recursive", NULL); + if (option_shallow_submodules == 1 + || (option_shallow_submodules == -1 && option_depth)) + argv_array_push(&args, "--depth=1"); + if (max_jobs != -1) argv_array_pushf(&args, "--jobs=%d", max_jobs); diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index 3feeffeab1..8a674bc9e7 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -33,10 +33,6 @@ static int commit_tree_config(const char *var, const char *value, void *cb) int status = git_gpg_config(var, value, NULL); if (status) return status; - if (!strcmp(var, "commit.gpgsign")) { - sign_commit = git_config_bool(var, value) ? "" : NULL; - return 0; - } return git_default_config(var, value, cb); } diff --git a/builtin/commit.c b/builtin/commit.c index 391126e58d..443ff9196d 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -114,6 +114,7 @@ static char *fixup_message, *squash_message; static int all, also, interactive, patch_interactive, only, amend, signoff; static int edit_flag = -1; /* unspecified */ static int quiet, verbose, no_verify, allow_empty, dry_run, renew_authorship; +static int config_commit_verbose = -1; /* unspecified */ static int no_post_rewrite, allow_empty_message; static char *untracked_files_arg, *force_date, *ignore_submodule_arg; static char *sign_commit; @@ -1515,6 +1516,11 @@ static int git_commit_config(const char *k, const char *v, void *cb) sign_commit = git_config_bool(k, v) ? "" : NULL; return 0; } + if (!strcmp(k, "commit.verbose")) { + int is_bool; + config_commit_verbose = git_config_bool_or_int(k, v, &is_bool); + return 0; + } status = git_gpg_config(k, v, NULL); if (status) @@ -1661,9 +1667,13 @@ int cmd_commit(int argc, const char **argv, const char *prefix) if (parse_commit(current_head)) die(_("could not parse HEAD commit")); } + verbose = -1; /* unspecified */ argc = parse_and_validate_options(argc, argv, builtin_commit_options, builtin_commit_usage, prefix, current_head, &s); + if (verbose == -1) + verbose = (config_commit_verbose < 0) ? 0 : config_commit_verbose; + if (dry_run) return dry_run_commit(argc, argv, prefix, current_head, &s); index_file = prepare_index(argc, argv, prefix, current_head, 0); diff --git a/builtin/diff-files.c b/builtin/diff-files.c index 8ed2eb8813..15c61fd8d1 100644 --- a/builtin/diff-files.c +++ b/builtin/diff-files.c @@ -24,6 +24,7 @@ int cmd_diff_files(int argc, const char **argv, const char *prefix) gitmodules_config(); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ rev.abbrev = 0; + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, &rev, NULL); while (1 < argc && argv[1][0] == '-') { diff --git a/builtin/diff-index.c b/builtin/diff-index.c index d979824f93..1af373d002 100644 --- a/builtin/diff-index.c +++ b/builtin/diff-index.c @@ -21,6 +21,7 @@ int cmd_diff_index(int argc, const char **argv, const char *prefix) gitmodules_config(); git_config(git_diff_basic_config, NULL); /* no "diff" UI options */ rev.abbrev = 0; + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, &rev, NULL); for (i = 1; i < argc; i++) { diff --git a/builtin/diff-tree.c b/builtin/diff-tree.c index 2a12b81e06..806dd7a885 100644 --- a/builtin/diff-tree.c +++ b/builtin/diff-tree.c @@ -114,6 +114,8 @@ int cmd_diff_tree(int argc, const char **argv, const char *prefix) opt->disable_stdin = 1; memset(&s_r_opt, 0, sizeof(s_r_opt)); s_r_opt.tweak = diff_tree_tweak_rev; + + precompose_argv(argc, argv); argc = setup_revisions(argc, argv, opt, &s_r_opt); while (--argc > 0) { diff --git a/builtin/diff.c b/builtin/diff.c index 343c6b8f25..b7a9405d9f 100644 --- a/builtin/diff.c +++ b/builtin/diff.c @@ -320,6 +320,7 @@ int cmd_diff(int argc, const char **argv, const char *prefix) gitmodules_config(); init_diff_ui_defaults(); git_config(git_diff_ui_config, NULL); + precompose_argv(argc, argv); init_revisions(&rev, prefix); diff --git a/builtin/fetch.c b/builtin/fetch.c index f8455bde7a..1582ca7184 100644 --- a/builtin/fetch.c +++ b/builtin/fetch.c @@ -607,7 +607,7 @@ static int store_updated_refs(const char *raw_url, const char *remote_name, fp = fopen(filename, "a"); if (!fp) - return error(_("cannot open %s: %s\n"), filename, strerror(errno)); + return error_errno(_("cannot open %s"), filename); if (raw_url) url = transport_anonymize_url(raw_url); @@ -848,7 +848,7 @@ static int truncate_fetch_head(void) FILE *fp = fopen_for_writing(filename); if (!fp) - return error(_("cannot open %s: %s\n"), filename, strerror(errno)); + return error_errno(_("cannot open %s"), filename); fclose(fp); return 0; } diff --git a/builtin/fsck.c b/builtin/fsck.c index 55eac756f7..3f27456883 100644 --- a/builtin/fsck.c +++ b/builtin/fsck.c @@ -493,13 +493,12 @@ static void fsck_object_dir(const char *path) static int fsck_head_link(void) { - int flag; int null_is_error = 0; if (verbose) fprintf(stderr, "Checking HEAD link\n"); - head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, &flag); + head_points_at = resolve_ref_unsafe("HEAD", 0, head_oid.hash, NULL); if (!head_points_at) { errors_found |= ERROR_REFS; return error("Invalid HEAD"); diff --git a/builtin/grep.c b/builtin/grep.c index 111b6f6cf1..462e607901 100644 --- a/builtin/grep.c +++ b/builtin/grep.c @@ -438,7 +438,7 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, strbuf_add(base, entry.path, te_len); if (S_ISREG(entry.mode)) { - hit |= grep_sha1(opt, entry.sha1, base->buf, tn_len, + hit |= grep_sha1(opt, entry.oid->hash, base->buf, tn_len, check_attr ? base->buf + tn_len : NULL); } else if (S_ISDIR(entry.mode)) { @@ -447,10 +447,10 @@ static int grep_tree(struct grep_opt *opt, const struct pathspec *pathspec, void *data; unsigned long size; - data = lock_and_read_sha1_file(entry.sha1, &type, &size); + data = lock_and_read_sha1_file(entry.oid->hash, &type, &size); if (!data) die(_("unable to read tree (%s)"), - sha1_to_hex(entry.sha1)); + oid_to_hex(entry.oid)); strbuf_addch(base, '/'); init_tree_desc(&sub, data, size); diff --git a/builtin/help.c b/builtin/help.c index 3c55ce4563..88480131cf 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -127,7 +127,7 @@ static void exec_woman_emacs(const char *path, const char *page) path = "emacsclient"; strbuf_addf(&man_page, "(woman \"%s\")", page); execlp(path, "emacsclient", "-e", man_page.buf, (char *)NULL); - warning(_("failed to exec '%s': %s"), path, strerror(errno)); + warning_errno(_("failed to exec '%s'"), path); } } @@ -148,7 +148,7 @@ static void exec_man_konqueror(const char *path, const char *page) path = "kfmclient"; strbuf_addf(&man_page, "man:%s(1)", page); execlp(path, filename, "newTab", man_page.buf, (char *)NULL); - warning(_("failed to exec '%s': %s"), path, strerror(errno)); + warning_errno(_("failed to exec '%s'"), path); } } @@ -157,7 +157,7 @@ static void exec_man_man(const char *path, const char *page) if (!path) path = "man"; execlp(path, "man", page, (char *)NULL); - warning(_("failed to exec '%s': %s"), path, strerror(errno)); + warning_errno(_("failed to exec '%s'"), path); } static void exec_man_cmd(const char *cmd, const char *page) @@ -165,7 +165,7 @@ static void exec_man_cmd(const char *cmd, const char *page) struct strbuf shell_cmd = STRBUF_INIT; strbuf_addf(&shell_cmd, "%s %s", cmd, page); execl(SHELL_PATH, SHELL_PATH, "-c", shell_cmd.buf, (char *)NULL); - warning(_("failed to exec '%s': %s"), cmd, strerror(errno)); + warning(_("failed to exec '%s'"), cmd); } static void add_man_viewer(const char *name) diff --git a/builtin/index-pack.c b/builtin/index-pack.c index 2d1eb8bb8a..e8c71fc1d2 100644 --- a/builtin/index-pack.c +++ b/builtin/index-pack.c @@ -1250,7 +1250,9 @@ static void conclude_pack(int fix_thin_pack, const char *curr_pack, unsigned cha nr_unresolved * sizeof(*objects)); f = sha1fd(output_fd, curr_pack); fix_unresolved_deltas(f); - strbuf_addf(&msg, _("completed with %d local objects"), + strbuf_addf(&msg, Q_("completed with %d local object", + "completed with %d local objects", + nr_objects - nr_objects_initial), nr_objects - nr_objects_initial); stop_progress_msg(&progress, msg.buf); strbuf_release(&msg); diff --git a/builtin/log.c b/builtin/log.c index dff3fbbb43..099f4f7be9 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -702,6 +702,7 @@ static void add_header(const char *value) #define THREAD_DEEP 2 static int thread; static int do_signoff; +static int base_auto; static const char *signature = git_version_string; static const char *signature_file; static int config_cover_letter; @@ -786,6 +787,10 @@ static int git_format_config(const char *var, const char *value, void *cb) } if (!strcmp(var, "format.outputdirectory")) return git_config_string(&config_output_directory, var, value); + if (!strcmp(var, "format.useautobase")) { + base_auto = git_config_bool(var, value); + return 0; + } return git_log_config(var, value, cb); } @@ -1191,6 +1196,155 @@ static int from_callback(const struct option *opt, const char *arg, int unset) return 0; } +struct base_tree_info { + struct object_id base_commit; + int nr_patch_id, alloc_patch_id; + struct object_id *patch_id; +}; + +static struct commit *get_base_commit(const char *base_commit, + struct commit **list, + int total) +{ + struct commit *base = NULL; + struct commit **rev; + int i = 0, rev_nr = 0; + + if (base_commit && strcmp(base_commit, "auto")) { + base = lookup_commit_reference_by_name(base_commit); + if (!base) + die(_("Unknown commit %s"), base_commit); + } else if ((base_commit && !strcmp(base_commit, "auto")) || base_auto) { + struct branch *curr_branch = branch_get(NULL); + const char *upstream = branch_get_upstream(curr_branch, NULL); + if (upstream) { + struct commit_list *base_list; + struct commit *commit; + unsigned char sha1[20]; + + if (get_sha1(upstream, sha1)) + die(_("Failed to resolve '%s' as a valid ref."), upstream); + commit = lookup_commit_or_die(sha1, "upstream base"); + base_list = get_merge_bases_many(commit, total, list); + /* There should be one and only one merge base. */ + if (!base_list || base_list->next) + die(_("Could not find exact merge base.")); + base = base_list->item; + free_commit_list(base_list); + } else { + die(_("Failed to get upstream, if you want to record base commit automatically,\n" + "please use git branch --set-upstream-to to track a remote branch.\n" + "Or you could specify base commit by --base=<base-commit-id> manually.")); + } + } + + ALLOC_ARRAY(rev, total); + for (i = 0; i < total; i++) + rev[i] = list[i]; + + rev_nr = total; + /* + * Get merge base through pair-wise computations + * and store it in rev[0]. + */ + while (rev_nr > 1) { + for (i = 0; i < rev_nr / 2; i++) { + struct commit_list *merge_base; + merge_base = get_merge_bases(rev[2 * i], rev[2 * i + 1]); + if (!merge_base || merge_base->next) + die(_("Failed to find exact merge base")); + + rev[i] = merge_base->item; + } + + if (rev_nr % 2) + rev[i] = rev[2 * i]; + rev_nr = (rev_nr + 1) / 2; + } + + if (!in_merge_bases(base, rev[0])) + die(_("base commit should be the ancestor of revision list")); + + for (i = 0; i < total; i++) { + if (base == list[i]) + die(_("base commit shouldn't be in revision list")); + } + + free(rev); + return base; +} + +static void prepare_bases(struct base_tree_info *bases, + struct commit *base, + struct commit **list, + int total) +{ + struct commit *commit; + struct rev_info revs; + struct diff_options diffopt; + int i; + + if (!base) + return; + + diff_setup(&diffopt); + DIFF_OPT_SET(&diffopt, RECURSIVE); + diff_setup_done(&diffopt); + + oidcpy(&bases->base_commit, &base->object.oid); + + init_revisions(&revs, NULL); + revs.max_parents = 1; + revs.topo_order = 1; + for (i = 0; i < total; i++) { + list[i]->object.flags &= ~UNINTERESTING; + add_pending_object(&revs, &list[i]->object, "rev_list"); + list[i]->util = (void *)1; + } + base->object.flags |= UNINTERESTING; + add_pending_object(&revs, &base->object, "base"); + + if (prepare_revision_walk(&revs)) + die(_("revision walk setup failed")); + /* + * Traverse the commits list, get prerequisite patch ids + * and stuff them in bases structure. + */ + while ((commit = get_revision(&revs)) != NULL) { + unsigned char sha1[20]; + struct object_id *patch_id; + if (commit->util) + continue; + if (commit_patch_id(commit, &diffopt, sha1)) + die(_("cannot get patch id")); + ALLOC_GROW(bases->patch_id, bases->nr_patch_id + 1, bases->alloc_patch_id); + patch_id = bases->patch_id + bases->nr_patch_id; + hashcpy(patch_id->hash, sha1); + bases->nr_patch_id++; + } +} + +static void print_bases(struct base_tree_info *bases) +{ + int i; + + /* Only do this once, either for the cover or for the first one */ + if (is_null_oid(&bases->base_commit)) + return; + + /* Show the base commit */ + printf("base-commit: %s\n", oid_to_hex(&bases->base_commit)); + + /* Show the prerequisite patches */ + for (i = bases->nr_patch_id - 1; i >= 0; i--) + printf("prerequisite-patch-id: %s\n", oid_to_hex(&bases->patch_id[i])); + + free(bases->patch_id); + bases->nr_patch_id = 0; + bases->alloc_patch_id = 0; + oidclr(&bases->base_commit); +} + int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; @@ -1215,6 +1369,9 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) int reroll_count = -1; char *branch_name = NULL; char *from = NULL; + char *base_commit = NULL; + struct base_tree_info bases; + const struct option builtin_format_patch_options[] = { { OPTION_CALLBACK, 'n', "numbered", &numbered, NULL, N_("use [PATCH n/m] even with a single patch"), @@ -1277,6 +1434,8 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) PARSE_OPT_OPTARG, thread_callback }, OPT_STRING(0, "signature", &signature, N_("signature"), N_("add a signature")), + OPT_STRING(0, "base", &base_commit, N_("base-commit"), + N_("add prerequisite tree info to the patch series")), OPT_FILENAME(0, "signature-file", &signature_file, N_("add a signature from a file")), OPT__QUIET(&quiet, N_("don't print the patch filenames")), @@ -1514,6 +1673,13 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) signature = strbuf_detach(&buf, NULL); } + memset(&bases, 0, sizeof(bases)); + if (base_commit || base_auto) { + struct commit *base = get_base_commit(base_commit, list, nr); + reset_revision_walk(); + prepare_bases(&bases, base, list, nr); + } + if (in_reply_to || thread || cover_letter) rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); if (in_reply_to) { @@ -1527,6 +1693,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, origin, nr, list, branch_name, quiet); + print_bases(&bases); total++; start_number--; } @@ -1592,6 +1759,7 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.mime_boundary); else print_signature(); + print_bases(&bases); } if (!use_stdout) fclose(stdout); diff --git a/builtin/mailsplit.c b/builtin/mailsplit.c index 104277acc4..4859ede38a 100644 --- a/builtin/mailsplit.c +++ b/builtin/mailsplit.c @@ -109,7 +109,7 @@ static int populate_maildir_list(struct string_list *list, const char *path) if ((dir = opendir(name)) == NULL) { if (errno == ENOENT) continue; - error("cannot opendir %s (%s)", name, strerror(errno)); + error_errno("cannot opendir %s", name); goto out; } @@ -174,12 +174,12 @@ static int split_maildir(const char *maildir, const char *dir, f = fopen(file, "r"); if (!f) { - error("cannot open mail %s (%s)", file, strerror(errno)); + error_errno("cannot open mail %s", file); goto out; } if (strbuf_getwholeline(&buf, f, '\n')) { - error("cannot read mail %s (%s)", file, strerror(errno)); + error_errno("cannot read mail %s", file); goto out; } @@ -210,7 +210,7 @@ static int split_mbox(const char *file, const char *dir, int allow_bare, int file_done = 0; if (!f) { - error("cannot open mbox %s", file); + error_errno("cannot open mbox %s", file); goto out; } @@ -318,7 +318,7 @@ int cmd_mailsplit(int argc, const char **argv, const char *prefix) } if (stat(arg, &argstat) == -1) { - error("cannot stat %s (%s)", arg, strerror(errno)); + error_errno("cannot stat %s", arg); return 1; } diff --git a/builtin/merge-file.c b/builtin/merge-file.c index 55447053f2..13e22a2f0b 100644 --- a/builtin/merge-file.c +++ b/builtin/merge-file.c @@ -62,8 +62,7 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) usage_with_options(merge_file_usage, options); if (quiet) { if (!freopen("/dev/null", "w", stderr)) - return error("failed to redirect stderr to /dev/null: " - "%s", strerror(errno)); + return error_errno("failed to redirect stderr to /dev/null"); } if (prefix) @@ -95,12 +94,13 @@ int cmd_merge_file(int argc, const char **argv, const char *prefix) FILE *f = to_stdout ? stdout : fopen(fpath, "wb"); if (!f) - ret = error("Could not open %s for writing", filename); + ret = error_errno("Could not open %s for writing", + filename); else if (result.size && fwrite(result.ptr, result.size, 1, f) != 1) - ret = error("Could not write to %s", filename); + ret = error_errno("Could not write to %s", filename); else if (fclose(f)) - ret = error("Could not close %s", filename); + ret = error_errno("Could not close %s", filename); free(result.ptr); } diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index ca570041df..5b7ab9b967 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -150,15 +150,15 @@ static void show_result(void) /* An empty entry never compares same, not even to another empty entry */ static int same_entry(struct name_entry *a, struct name_entry *b) { - return a->sha1 && - b->sha1 && - !hashcmp(a->sha1, b->sha1) && + return a->oid && + b->oid && + !oidcmp(a->oid, b->oid) && a->mode == b->mode; } static int both_empty(struct name_entry *a, struct name_entry *b) { - return !(a->sha1 || b->sha1); + return !(a->oid || b->oid); } static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsigned char *sha1, const char *path) @@ -188,8 +188,8 @@ static void resolve(const struct traverse_info *info, struct name_entry *ours, s return; path = traverse_path(info, result); - orig = create_entry(2, ours->mode, ours->sha1, path); - final = create_entry(0, result->mode, result->sha1, path); + orig = create_entry(2, ours->mode, ours->oid->hash, path); + final = create_entry(0, result->mode, result->oid->hash, path); final->link = orig; @@ -213,7 +213,7 @@ static void unresolved_directory(const struct traverse_info *info, newbase = traverse_path(info, p); -#define ENTRY_SHA1(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->sha1 : NULL) +#define ENTRY_SHA1(e) (((e)->mode && S_ISDIR((e)->mode)) ? (e)->oid->hash : NULL) buf0 = fill_tree_descriptor(t+0, ENTRY_SHA1(n + 0)); buf1 = fill_tree_descriptor(t+1, ENTRY_SHA1(n + 1)); buf2 = fill_tree_descriptor(t+2, ENTRY_SHA1(n + 2)); @@ -239,7 +239,7 @@ static struct merge_list *link_entry(unsigned stage, const struct traverse_info path = entry->path; else path = traverse_path(info, n); - link = create_entry(stage, n->mode, n->sha1, path); + link = create_entry(stage, n->mode, n->oid->hash, path); link->link = entry; return link; } @@ -314,7 +314,7 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s } if (same_entry(entry+0, entry+1)) { - if (entry[2].sha1 && !S_ISDIR(entry[2].mode)) { + if (entry[2].oid && !S_ISDIR(entry[2].mode)) { /* We did not touch, they modified -- take theirs */ resolve(info, entry+1, entry+2); return mask; diff --git a/builtin/merge.c b/builtin/merge.c index 41467e4277..b555a1bf9c 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -822,6 +822,14 @@ static int merge_trivial(struct commit *head, struct commit_list *remoteheads) { unsigned char result_tree[20], result_commit[20]; struct commit_list *parents, **pptr = &parents; + static struct lock_file lock; + + hold_locked_index(&lock, 1); + refresh_cache(REFRESH_QUIET); + if (active_cache_changed && + write_locked_index(&the_index, &lock, COMMIT_LOCK)) + return error(_("Unable to write index.")); + rollback_lock_file(&lock); write_tree_trivial(result_tree); printf(_("Wonderful.\n")); @@ -1168,7 +1176,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) struct commit *head_commit; struct strbuf buf = STRBUF_INIT; const char *head_arg; - int flag, i, ret = 0, head_subsumed; + int i, ret = 0, head_subsumed; int best_cnt = -1, merge_was_ok = 0, automerge_was_ok = 0; struct commit_list *common = NULL; const char *best_strategy = NULL, *wt_strategy = NULL; @@ -1182,7 +1190,7 @@ int cmd_merge(int argc, const char **argv, const char *prefix) * Check if we are _not_ on a detached HEAD, i.e. if there is a * current branch. */ - branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, &flag); + branch = branch_to_free = resolve_refdup("HEAD", 0, head_sha1, NULL); if (branch && starts_with(branch, "refs/heads/")) branch += 11; if (!branch || is_null_sha1(head_sha1)) diff --git a/builtin/mv.c b/builtin/mv.c index aeae855e2b..a2014266b6 100644 --- a/builtin/mv.c +++ b/builtin/mv.c @@ -252,15 +252,18 @@ int cmd_mv(int argc, const char **argv, const char *prefix) int pos; if (show_only || verbose) printf(_("Renaming %s to %s\n"), src, dst); - if (!show_only && mode != INDEX) { - if (rename(src, dst) < 0 && !ignore_errors) - die_errno(_("renaming '%s' failed"), src); - if (submodule_gitfile[i]) { - if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR) - connect_work_tree_and_git_dir(dst, submodule_gitfile[i]); - if (!update_path_in_gitmodules(src, dst)) - gitmodules_modified = 1; - } + if (show_only) + continue; + if (mode != INDEX && rename(src, dst) < 0) { + if (ignore_errors) + continue; + die_errno(_("renaming '%s' failed"), src); + } + if (submodule_gitfile[i]) { + if (submodule_gitfile[i] != SUBMODULE_WITH_GITDIR) + connect_work_tree_and_git_dir(dst, submodule_gitfile[i]); + if (!update_path_in_gitmodules(src, dst)) + gitmodules_modified = 1; } if (mode == WORKING_DIRECTORY) diff --git a/builtin/name-rev.c b/builtin/name-rev.c index 092e03c3cc..57be35faf5 100644 --- a/builtin/name-rev.c +++ b/builtin/name-rev.c @@ -10,6 +10,7 @@ typedef struct rev_name { const char *tip_name; + unsigned long taggerdate; int generation; int distance; } rev_name; @@ -20,7 +21,8 @@ static long cutoff = LONG_MAX; #define MERGE_TRAVERSAL_WEIGHT 65535 static void name_rev(struct commit *commit, - const char *tip_name, int generation, int distance, + const char *tip_name, unsigned long taggerdate, + int generation, int distance, int deref) { struct rev_name *name = (struct rev_name *)commit->util; @@ -43,9 +45,12 @@ static void name_rev(struct commit *commit, name = xmalloc(sizeof(rev_name)); commit->util = name; goto copy_data; - } else if (name->distance > distance) { + } else if (name->taggerdate > taggerdate || + (name->taggerdate == taggerdate && + name->distance > distance)) { copy_data: name->tip_name = tip_name; + name->taggerdate = taggerdate; name->generation = generation; name->distance = distance; } else @@ -66,11 +71,11 @@ copy_data: new_name = xstrfmt("%.*s^%d", (int)len, tip_name, parent_number); - name_rev(parents->item, new_name, 0, + name_rev(parents->item, new_name, taggerdate, 0, distance + MERGE_TRAVERSAL_WEIGHT, 0); } else { - name_rev(parents->item, tip_name, generation + 1, - distance + 1, 0); + name_rev(parents->item, tip_name, taggerdate, + generation + 1, distance + 1, 0); } } } @@ -140,6 +145,7 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo struct name_ref_data *data = cb_data; int can_abbreviate_output = data->tags_only && data->name_only; int deref = 0; + unsigned long taggerdate = ULONG_MAX; if (data->tags_only && !starts_with(path, "refs/tags/")) return 0; @@ -164,12 +170,13 @@ static int name_ref(const char *path, const struct object_id *oid, int flags, vo break; /* broken repository */ o = parse_object(t->tagged->oid.hash); deref = 1; + taggerdate = t->date; } if (o && o->type == OBJ_COMMIT) { struct commit *commit = (struct commit *)o; path = name_ref_abbrev(path, can_abbreviate_output); - name_rev(commit, xstrdup(path), 0, 0, deref); + name_rev(commit, xstrdup(path), taggerdate, 0, 0, deref); } return 0; } diff --git a/builtin/notes.c b/builtin/notes.c index 6fd058de92..c65b59ad9a 100644 --- a/builtin/notes.c +++ b/builtin/notes.c @@ -847,15 +847,15 @@ static int merge(int argc, const char **argv, const char *prefix) update_ref(msg.buf, default_notes_ref(), result_sha1, NULL, 0, UPDATE_REFS_DIE_ON_ERR); else { /* Merge has unresolved conflicts */ - char *existing; + const struct worktree *wt; /* Update .git/NOTES_MERGE_PARTIAL with partial merge result */ update_ref(msg.buf, "NOTES_MERGE_PARTIAL", result_sha1, NULL, 0, UPDATE_REFS_DIE_ON_ERR); /* Store ref-to-be-updated into .git/NOTES_MERGE_REF */ - existing = find_shared_symref("NOTES_MERGE_REF", default_notes_ref()); - if (existing) + wt = find_shared_symref("NOTES_MERGE_REF", default_notes_ref()); + if (wt) die(_("A notes merge into %s is already in-progress at %s"), - default_notes_ref(), existing); + default_notes_ref(), wt->path); if (create_symref("NOTES_MERGE_REF", default_notes_ref(), NULL)) die("Failed to store link to current notes ref (%s)", default_notes_ref()); diff --git a/builtin/pack-objects.c b/builtin/pack-objects.c index a27de5b323..8f5e358e22 100644 --- a/builtin/pack-objects.c +++ b/builtin/pack-objects.c @@ -759,6 +759,10 @@ static off_t write_reused_pack(struct sha1file *f) return reuse_packfile_offset - sizeof(struct pack_header); } +static const char no_split_warning[] = N_( +"disabling bitmap writing, packs are split due to pack.packSizeLimit" +); + static void write_pack_file(void) { uint32_t i = 0, j; @@ -813,7 +817,10 @@ static void write_pack_file(void) fixup_pack_header_footer(fd, sha1, pack_tmp_name, nr_written, sha1, offset); close(fd); - write_bitmap_index = 0; + if (write_bitmap_index) { + warning(_(no_split_warning)); + write_bitmap_index = 0; + } } if (!pack_to_stdout) { @@ -828,8 +835,7 @@ static void write_pack_file(void) * to preserve this property. */ if (stat(pack_tmp_name, &st) < 0) { - warning("failed to stat %s: %s", - pack_tmp_name, strerror(errno)); + warning_errno("failed to stat %s", pack_tmp_name); } else if (!last_mtime) { last_mtime = st.st_mtime; } else { @@ -837,8 +843,7 @@ static void write_pack_file(void) utb.actime = st.st_atime; utb.modtime = --last_mtime; if (utime(pack_tmp_name, &utb) < 0) - warning("failed utime() on %s: %s", - pack_tmp_name, strerror(errno)); + warning_errno("failed utime() on %s", pack_tmp_name); } strbuf_addf(&tmpname, "%s-", base_name); @@ -1186,7 +1191,7 @@ static void add_pbase_object(struct tree_desc *tree, if (cmp < 0) return; if (name[cmplen] != '/') { - add_object_entry(entry.sha1, + add_object_entry(entry.oid->hash, object_type(entry.mode), fullname, 1); return; @@ -1197,7 +1202,7 @@ static void add_pbase_object(struct tree_desc *tree, const char *down = name+cmplen+1; int downlen = name_cmp_len(down); - tree = pbase_tree_get(entry.sha1); + tree = pbase_tree_get(entry.oid->hash); if (!tree) return; init_tree_desc(&sub, tree->tree_data, tree->tree_size); diff --git a/builtin/pull.c b/builtin/pull.c index d98f481d31..1d7333c8a1 100644 --- a/builtin/pull.c +++ b/builtin/pull.c @@ -91,6 +91,7 @@ static int config_autostash; static struct argv_array opt_strategies = ARGV_ARRAY_INIT; static struct argv_array opt_strategy_opts = ARGV_ARRAY_INIT; static char *opt_gpg_sign; +static int opt_allow_unrelated_histories; /* Options passed to git-fetch */ static char *opt_all; @@ -163,6 +164,9 @@ static struct option pull_options[] = { OPT_PASSTHRU('S', "gpg-sign", &opt_gpg_sign, N_("key-id"), N_("GPG sign commit"), PARSE_OPT_OPTARG), + OPT_SET_INT(0, "allow-unrelated-histories", + &opt_allow_unrelated_histories, + N_("allow merging unrelated histories"), 1), /* Options passed to git-fetch */ OPT_GROUP(N_("Options related to fetching")), @@ -474,13 +478,13 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); - fprintf_ln(stderr, " git pull <remote> <branch>"); + fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>")); fprintf(stderr, "\n"); } else if (!curr_branch->merge_nr) { const char *remote_name = NULL; if (for_each_remote(get_only_remote, &remote_name) || !remote_name) - remote_name = "<remote>"; + remote_name = _("<remote>"); fprintf_ln(stderr, _("There is no tracking information for the current branch.")); if (opt_rebase) @@ -489,12 +493,12 @@ static void NORETURN die_no_merge_candidates(const char *repo, const char **refs fprintf_ln(stderr, _("Please specify which branch you want to merge with.")); fprintf_ln(stderr, _("See git-pull(1) for details.")); fprintf(stderr, "\n"); - fprintf_ln(stderr, " git pull <remote> <branch>"); + fprintf_ln(stderr, " git pull %s %s", _("<remote>"), _("<branch>")); fprintf(stderr, "\n"); - fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:\n" - "\n" - " git branch --set-upstream-to=%s/<branch> %s\n"), - remote_name, curr_branch->name); + fprintf_ln(stderr, _("If you wish to set tracking information for this branch you can do so with:")); + fprintf(stderr, "\n"); + fprintf_ln(stderr, " git branch --set-upstream-to=%s/%s %s\n", + remote_name, _("<branch>"), curr_branch->name); } else fprintf_ln(stderr, _("Your configuration specifies to merge with the ref '%s'\n" "from the remote, but no such ref was fetched."), @@ -628,6 +632,8 @@ static int run_merge(void) argv_array_pushv(&args, opt_strategy_opts.argv); if (opt_gpg_sign) argv_array_push(&args, opt_gpg_sign); + if (opt_allow_unrelated_histories > 0) + argv_array_push(&args, "--allow-unrelated-histories"); argv_array_push(&args, "FETCH_HEAD"); ret = run_command_v_opt(args.argv, RUN_GIT_CMD); diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 220a899b96..a744437b58 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -1084,13 +1084,13 @@ static void check_aliased_update(struct command *cmd, struct string_list *list) if (!(flag & REF_ISSYMREF)) return; - dst_name = strip_namespace(dst_name); if (!dst_name) { rp_error("refusing update to broken symref '%s'", cmd->ref_name); cmd->skip_update = 1; cmd->error_string = "broken symref"; return; } + dst_name = strip_namespace(dst_name); if ((item = string_list_lookup(list, dst_name)) == NULL) return; diff --git a/builtin/reflog.c b/builtin/reflog.c index 2d46b6482a..7a7136e53e 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -84,8 +84,8 @@ static int tree_is_complete(const unsigned char *sha1) init_tree_desc(&desc, tree->buffer, tree->size); complete = 1; while (tree_entry(&desc, &entry)) { - if (!has_sha1_file(entry.sha1) || - (S_ISDIR(entry.mode) && !tree_is_complete(entry.sha1))) { + if (!has_sha1_file(entry.oid->hash) || + (S_ISDIR(entry.mode) && !tree_is_complete(entry.oid->hash))) { tree->object.flags |= INCOMPLETE; complete = 0; } diff --git a/builtin/remote-ext.c b/builtin/remote-ext.c index 7457c743e8..88eb8f9013 100644 --- a/builtin/remote-ext.c +++ b/builtin/remote-ext.c @@ -168,7 +168,7 @@ static int command_loop(const char *child) size_t i; if (!fgets(buffer, MAXCOMMAND - 1, stdin)) { if (ferror(stdin)) - die("Comammand input error"); + die("Command input error"); exit(0); } /* Strip end of line characters. */ diff --git a/builtin/remote.c b/builtin/remote.c index fda5c2e53d..d33766be39 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -1154,6 +1154,8 @@ static int show(int argc, const char **argv) url_nr = states.remote->url_nr; } for (i = 0; i < url_nr; i++) + /* TRANSLATORS: the colon ':' should align with + the one in " Fetch URL: %s" translation */ printf_ln(_(" Push URL: %s"), url[i]); if (!i) printf_ln(_(" Push URL: %s"), "(no URL)"); diff --git a/builtin/replace.c b/builtin/replace.c index 748c6ca954..b58c714cb8 100644 --- a/builtin/replace.c +++ b/builtin/replace.c @@ -440,6 +440,7 @@ int cmd_replace(int argc, const char **argv, const char *prefix) }; check_replace_refs = 0; + git_config(git_default_config, NULL); argc = parse_options(argc, argv, prefix, options, git_replace_usage, 0); diff --git a/builtin/rm.c b/builtin/rm.c index 8829b09d0b..8abb0207fa 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -152,7 +152,7 @@ static int check_local_mod(unsigned char *head, int index_only) if (lstat(ce->name, &st) < 0) { if (errno != ENOENT && errno != ENOTDIR) - warning("'%s': %s", ce->name, strerror(errno)); + warning_errno(_("failed to stat '%s'"), ce->name); /* It already vanished from the working tree */ continue; } @@ -314,7 +314,7 @@ int cmd_rm(int argc, const char **argv, const char *prefix) list.entry[list.nr].is_submodule = S_ISGITLINK(ce->ce_mode); if (list.entry[list.nr++].is_submodule && !is_staging_gitmodules_ok()) - die (_("Please, stage your changes to .gitmodules or stash them to proceed")); + die (_("Please stage your changes to .gitmodules or stash them to proceed")); } if (pathspec.nr) { diff --git a/builtin/submodule--helper.c b/builtin/submodule--helper.c index 3bd6883eff..8da263f0b0 100644 --- a/builtin/submodule--helper.c +++ b/builtin/submodule--helper.c @@ -9,6 +9,211 @@ #include "submodule-config.h" #include "string-list.h" #include "run-command.h" +#include "remote.h" +#include "refs.h" +#include "connect.h" + +static char *get_default_remote(void) +{ + char *dest = NULL, *ret; + unsigned char sha1[20]; + struct strbuf sb = STRBUF_INIT; + const char *refname = resolve_ref_unsafe("HEAD", 0, sha1, NULL); + + if (!refname) + die(_("No such ref: %s"), "HEAD"); + + /* detached HEAD */ + if (!strcmp(refname, "HEAD")) + return xstrdup("origin"); + + if (!skip_prefix(refname, "refs/heads/", &refname)) + die(_("Expecting a full ref name, got %s"), refname); + + strbuf_addf(&sb, "branch.%s.remote", refname); + if (git_config_get_string(sb.buf, &dest)) + ret = xstrdup("origin"); + else + ret = dest; + + strbuf_release(&sb); + return ret; +} + +static int starts_with_dot_slash(const char *str) +{ + return str[0] == '.' && is_dir_sep(str[1]); +} + +static int starts_with_dot_dot_slash(const char *str) +{ + return str[0] == '.' && str[1] == '.' && is_dir_sep(str[2]); +} + +/* + * Returns 1 if it was the last chop before ':'. + */ +static int chop_last_dir(char **remoteurl, int is_relative) +{ + char *rfind = find_last_dir_sep(*remoteurl); + if (rfind) { + *rfind = '\0'; + return 0; + } + + rfind = strrchr(*remoteurl, ':'); + if (rfind) { + *rfind = '\0'; + return 1; + } + + if (is_relative || !strcmp(".", *remoteurl)) + die(_("cannot strip one component off url '%s'"), + *remoteurl); + + free(*remoteurl); + *remoteurl = xstrdup("."); + return 0; +} + +/* + * The `url` argument is the URL that navigates to the submodule origin + * repo. When relative, this URL is relative to the superproject origin + * URL repo. The `up_path` argument, if specified, is the relative + * path that navigates from the submodule working tree to the superproject + * working tree. Returns the origin URL of the submodule. + * + * Return either an absolute URL or filesystem path (if the superproject + * origin URL is an absolute URL or filesystem path, respectively) or a + * relative file system path (if the superproject origin URL is a relative + * file system path). + * + * When the output is a relative file system path, the path is either + * relative to the submodule working tree, if up_path is specified, or to + * the superproject working tree otherwise. + * + * NEEDSWORK: This works incorrectly on the domain and protocol part. + * remote_url url outcome expectation + * http://a.com/b ../c http://a.com/c as is + * http://a.com/b ../../c http://c error out + * http://a.com/b ../../../c http:/c error out + * http://a.com/b ../../../../c http:c error out + * http://a.com/b ../../../../../c .:c error out + * NEEDSWORK: Given how chop_last_dir() works, this function is broken + * when a local part has a colon in its path component, too. + */ +static char *relative_url(const char *remote_url, + const char *url, + const char *up_path) +{ + int is_relative = 0; + int colonsep = 0; + char *out; + char *remoteurl = xstrdup(remote_url); + struct strbuf sb = STRBUF_INIT; + size_t len = strlen(remoteurl); + + if (is_dir_sep(remoteurl[len])) + remoteurl[len] = '\0'; + + if (!url_is_local_not_ssh(remoteurl) || is_absolute_path(remoteurl)) + is_relative = 0; + else { + is_relative = 1; + /* + * Prepend a './' to ensure all relative + * remoteurls start with './' or '../' + */ + if (!starts_with_dot_slash(remoteurl) && + !starts_with_dot_dot_slash(remoteurl)) { + strbuf_reset(&sb); + strbuf_addf(&sb, "./%s", remoteurl); + free(remoteurl); + remoteurl = strbuf_detach(&sb, NULL); + } + } + /* + * When the url starts with '../', remove that and the + * last directory in remoteurl. + */ + while (url) { + if (starts_with_dot_dot_slash(url)) { + url += 3; + colonsep |= chop_last_dir(&remoteurl, is_relative); + } else if (starts_with_dot_slash(url)) + url += 2; + else + break; + } + strbuf_reset(&sb); + strbuf_addf(&sb, "%s%s%s", remoteurl, colonsep ? ":" : "/", url); + free(remoteurl); + + if (starts_with_dot_slash(sb.buf)) + out = xstrdup(sb.buf + 2); + else + out = xstrdup(sb.buf); + strbuf_reset(&sb); + + if (!up_path || !is_relative) + return out; + + strbuf_addf(&sb, "%s%s", up_path, out); + free(out); + return strbuf_detach(&sb, NULL); +} + +static int resolve_relative_url(int argc, const char **argv, const char *prefix) +{ + char *remoteurl = NULL; + char *remote = get_default_remote(); + const char *up_path = NULL; + char *res; + const char *url; + struct strbuf sb = STRBUF_INIT; + + if (argc != 2 && argc != 3) + die("resolve-relative-url only accepts one or two arguments"); + + url = argv[1]; + strbuf_addf(&sb, "remote.%s.url", remote); + free(remote); + + if (git_config_get_string(sb.buf, &remoteurl)) + /* the repository is its own authoritative upstream */ + remoteurl = xgetcwd(); + + if (argc == 3) + up_path = argv[2]; + + res = relative_url(remoteurl, url, up_path); + puts(res); + free(res); + free(remoteurl); + return 0; +} + +static int resolve_relative_url_test(int argc, const char **argv, const char *prefix) +{ + char *remoteurl, *res; + const char *up_path, *url; + + if (argc != 4) + die("resolve-relative-url-test only accepts three arguments: <up_path> <remoteurl> <url>"); + + up_path = argv[1]; + remoteurl = xstrdup(argv[2]); + url = argv[3]; + + if (!strcmp(up_path, "(null)")) + up_path = NULL; + + res = relative_url(remoteurl, url, up_path); + puts(res); + free(res); + free(remoteurl); + return 0; +} struct module_list { const struct cache_entry **entries; @@ -100,71 +305,142 @@ static int module_list(int argc, const char **argv, const char *prefix) return 0; } -static int module_name(int argc, const char **argv, const char *prefix) +static void init_submodule(const char *path, const char *prefix, int quiet) { const struct submodule *sub; + struct strbuf sb = STRBUF_INIT; + char *upd = NULL, *url = NULL, *displaypath; - if (argc != 2) - usage(_("git submodule--helper name <path>")); - + /* Only loads from .gitmodules, no overlay with .git/config */ gitmodules_config(); - sub = submodule_from_path(null_sha1, argv[1]); + + if (prefix) { + strbuf_addf(&sb, "%s%s", prefix, path); + displaypath = strbuf_detach(&sb, NULL); + } else + displaypath = xstrdup(path); + + sub = submodule_from_path(null_sha1, path); if (!sub) - die(_("no submodule mapping found in .gitmodules for path '%s'"), - argv[1]); + die(_("No url found for submodule path '%s' in .gitmodules"), + displaypath); - printf("%s\n", sub->name); + /* + * Copy url setting when it is not set yet. + * To look up the url in .git/config, we must not fall back to + * .gitmodules, so look it up directly. + */ + strbuf_reset(&sb); + strbuf_addf(&sb, "submodule.%s.url", sub->name); + if (git_config_get_string(sb.buf, &url)) { + url = xstrdup(sub->url); - return 0; + if (!url) + die(_("No url found for submodule path '%s' in .gitmodules"), + displaypath); + + /* Possibly a url relative to parent */ + if (starts_with_dot_dot_slash(url) || + starts_with_dot_slash(url)) { + char *remoteurl, *relurl; + char *remote = get_default_remote(); + struct strbuf remotesb = STRBUF_INIT; + strbuf_addf(&remotesb, "remote.%s.url", remote); + free(remote); + + if (git_config_get_string(remotesb.buf, &remoteurl)) + /* + * The repository is its own + * authoritative upstream + */ + remoteurl = xgetcwd(); + relurl = relative_url(remoteurl, url, NULL); + strbuf_release(&remotesb); + free(remoteurl); + free(url); + url = relurl; + } + + if (git_config_set_gently(sb.buf, url)) + die(_("Failed to register url for submodule path '%s'"), + displaypath); + if (!quiet) + fprintf(stderr, + _("Submodule '%s' (%s) registered for path '%s'\n"), + sub->name, url, displaypath); + } + + /* Copy "update" setting when it is not set yet */ + strbuf_reset(&sb); + strbuf_addf(&sb, "submodule.%s.update", sub->name); + if (git_config_get_string(sb.buf, &upd) && + sub->update_strategy.type != SM_UPDATE_UNSPECIFIED) { + if (sub->update_strategy.type == SM_UPDATE_COMMAND) { + fprintf(stderr, _("warning: command update mode suggested for submodule '%s'\n"), + sub->name); + upd = xstrdup("none"); + } else + upd = xstrdup(submodule_strategy_to_string(&sub->update_strategy)); + + if (git_config_set_gently(sb.buf, upd)) + die(_("Failed to register update mode for submodule path '%s'"), displaypath); + } + strbuf_release(&sb); + free(displaypath); + free(url); + free(upd); } -/* - * Rules to sanitize configuration variables that are Ok to be passed into - * submodule operations from the parent project using "-c". Should only - * include keys which are both (a) safe and (b) necessary for proper - * operation. - */ -static int submodule_config_ok(const char *var) +static int module_init(int argc, const char **argv, const char *prefix) { - if (starts_with(var, "credential.")) + struct pathspec pathspec; + struct module_list list = MODULE_LIST_INIT; + int quiet = 0; + int i; + + struct option module_init_options[] = { + OPT_STRING(0, "prefix", &prefix, + N_("path"), + N_("alternative anchor for relative paths")), + OPT__QUIET(&quiet, N_("Suppress output for initializing a submodule")), + OPT_END() + }; + + const char *const git_submodule_helper_usage[] = { + N_("git submodule--helper init [<path>]"), + NULL + }; + + argc = parse_options(argc, argv, prefix, module_init_options, + git_submodule_helper_usage, 0); + + if (module_list_compute(argc, argv, prefix, &pathspec, &list) < 0) return 1; + + for (i = 0; i < list.nr; i++) + init_submodule(list.entries[i]->name, prefix, quiet); + return 0; } -static int sanitize_submodule_config(const char *var, const char *value, void *data) +static int module_name(int argc, const char **argv, const char *prefix) { - struct strbuf *out = data; + const struct submodule *sub; - if (submodule_config_ok(var)) { - if (out->len) - strbuf_addch(out, ' '); + if (argc != 2) + usage(_("git submodule--helper name <path>")); - if (value) - sq_quotef(out, "%s=%s", var, value); - else - sq_quote_buf(out, var); - } + gitmodules_config(); + sub = submodule_from_path(null_sha1, argv[1]); - return 0; -} + if (!sub) + die(_("no submodule mapping found in .gitmodules for path '%s'"), + argv[1]); -static void prepare_submodule_repo_env(struct argv_array *out) -{ - const char * const *var; - - for (var = local_repo_env; *var; var++) { - if (!strcmp(*var, CONFIG_DATA_ENVIRONMENT)) { - struct strbuf sanitized_config = STRBUF_INIT; - git_config_from_parameters(sanitize_submodule_config, - &sanitized_config); - argv_array_pushf(out, "%s=%s", *var, sanitized_config.buf); - strbuf_release(&sanitized_config); - } else { - argv_array_push(out, *var); - } - } + printf("%s\n", sub->name); + return 0; } static int clone_submodule(const char *path, const char *gitdir, const char *url, @@ -294,22 +570,6 @@ static int module_clone(int argc, const char **argv, const char *prefix) return 0; } -static int module_sanitize_config(int argc, const char **argv, const char *prefix) -{ - struct strbuf sanitized_config = STRBUF_INIT; - - if (argc > 1) - usage(_("git submodule--helper sanitize-config")); - - git_config_from_parameters(sanitize_submodule_config, &sanitized_config); - if (sanitized_config.len) - printf("%s\n", sanitized_config.buf); - - strbuf_release(&sanitized_config); - - return 0; -} - struct submodule_update_clone { /* index into 'list', the list of submodules to look into for cloning */ int current; @@ -336,6 +596,25 @@ struct submodule_update_clone { SUBMODULE_UPDATE_STRATEGY_INIT, 0, NULL, NULL, NULL, NULL, \ STRING_LIST_INIT_DUP, 0} + +static void next_submodule_warn_missing(struct submodule_update_clone *suc, + struct strbuf *out, const char *displaypath) +{ + /* + * Only mention uninitialized submodules when their + * paths have been specified. + */ + if (suc->warn_if_uninitialized) { + strbuf_addf(out, + _("Submodule path '%s' not initialized"), + displaypath); + strbuf_addch(out, '\n'); + strbuf_addstr(out, + _("Maybe you want to use 'update --init'?")); + strbuf_addch(out, '\n'); + } +} + /** * Determine whether 'ce' needs to be cloned. If so, prepare the 'child' to * run the clone. Returns 1 if 'ce' needs to be cloned, 0 otherwise. @@ -370,6 +649,11 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, else displaypath = ce->name; + if (!sub) { + next_submodule_warn_missing(suc, out, displaypath); + goto cleanup; + } + if (suc->update.type == SM_UPDATE_NONE || (suc->update.type == SM_UPDATE_UNSPECIFIED && sub->update_strategy.type == SM_UPDATE_NONE)) { @@ -387,19 +671,7 @@ static int prepare_to_clone_next_submodule(const struct cache_entry *ce, strbuf_addf(&sb, "submodule.%s.url", sub->name); git_config_get_string(sb.buf, &url); if (!url) { - /* - * Only mention uninitialized submodules when their - * path have been specified - */ - if (suc->warn_if_uninitialized) { - strbuf_addf(out, - _("Submodule path '%s' not initialized"), - displaypath); - strbuf_addch(out, '\n'); - strbuf_addstr(out, - _("Maybe you want to use 'update --init'?")); - strbuf_addch(out, '\n'); - } + next_submodule_warn_missing(suc, out, displaypath); goto cleanup; } @@ -570,8 +842,10 @@ static struct cmd_struct commands[] = { {"list", module_list}, {"name", module_name}, {"clone", module_clone}, - {"sanitize-config", module_sanitize_config}, - {"update-clone", update_clone} + {"update-clone", update_clone}, + {"resolve-relative-url", resolve_relative_url}, + {"resolve-relative-url-test", resolve_relative_url_test}, + {"init", module_init} }; int cmd_submodule__helper(int argc, const char **argv, const char *prefix) diff --git a/builtin/tag.c b/builtin/tag.c index 528a1bab69..50e4ae5678 100644 --- a/builtin/tag.c +++ b/builtin/tag.c @@ -105,13 +105,7 @@ static int delete_tag(const char *name, const char *ref, static int verify_tag(const char *name, const char *ref, const unsigned char *sha1) { - const char *argv_verify_tag[] = {"verify-tag", - "-v", "SHA1_HEX", NULL}; - argv_verify_tag[2] = sha1_to_hex(sha1); - - if (run_command_v_opt(argv_verify_tag, RUN_GIT_CMD)) - return error(_("could not verify the tag '%s'"), name); - return 0; + return gpg_verify_tag(sha1, name, GPG_VERIFY_VERBOSE); } static int do_sign(struct strbuf *buffer) diff --git a/builtin/update-index.c b/builtin/update-index.c index 1c94ca59bf..b8b8522249 100644 --- a/builtin/update-index.c +++ b/builtin/update-index.c @@ -255,7 +255,7 @@ static int process_lstat_error(const char *path, int err) { if (err == ENOENT || err == ENOTDIR) return remove_one_path(path); - return error("lstat(\"%s\"): %s", path, strerror(errno)); + return error("lstat(\"%s\"): %s", path, strerror(err)); } static int add_one_path(const struct cache_entry *old, const char *path, int len, struct stat *st) diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index dbfe14f3fe..2caedf1849 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -104,8 +104,7 @@ int cmd_upload_archive(int argc, const char **argv, const char *prefix) pfd[1].events = POLLIN; if (poll(pfd, 2, -1) < 0) { if (errno != EINTR) { - error("poll failed resuming: %s", - strerror(errno)); + error_errno("poll failed resuming"); sleep(1); } continue; diff --git a/builtin/verify-tag.c b/builtin/verify-tag.c index 00663f6a30..99f8148cf7 100644 --- a/builtin/verify-tag.c +++ b/builtin/verify-tag.c @@ -18,55 +18,6 @@ static const char * const verify_tag_usage[] = { NULL }; -static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags) -{ - struct signature_check sigc; - int len; - int ret; - - memset(&sigc, 0, sizeof(sigc)); - - len = parse_signature(buf, size); - - if (size == len) { - if (flags & GPG_VERIFY_VERBOSE) - write_in_full(1, buf, len); - return error("no signature found"); - } - - ret = check_signature(buf, len, buf + len, size - len, &sigc); - print_signature_buffer(&sigc, flags); - - signature_check_clear(&sigc); - return ret; -} - -static int verify_tag(const char *name, unsigned flags) -{ - enum object_type type; - unsigned char sha1[20]; - char *buf; - unsigned long size; - int ret; - - if (get_sha1(name, sha1)) - return error("tag '%s' not found.", name); - - type = sha1_object_info(sha1, NULL); - if (type != OBJ_TAG) - return error("%s: cannot verify a non-tag object of type %s.", - name, typename(type)); - - buf = read_sha1_file(sha1, &type, &size); - if (!buf) - return error("%s: unable to read file.", name); - - ret = run_gpg_verify(buf, size, flags); - - free(buf); - return ret; -} - static int git_verify_tag_config(const char *var, const char *value, void *cb) { int status = git_gpg_config(var, value, cb); @@ -95,11 +46,13 @@ int cmd_verify_tag(int argc, const char **argv, const char *prefix) if (verbose) flags |= GPG_VERIFY_VERBOSE; - /* sometimes the program was terminated because this signal - * was received in the process of writing the gpg input: */ - signal(SIGPIPE, SIG_IGN); - while (i < argc) - if (verify_tag(argv[i++], flags)) + while (i < argc) { + unsigned char sha1[20]; + const char *name = argv[i++]; + if (get_sha1(name, sha1)) + had_error = !!error("tag '%s' not found.", name); + else if (gpg_verify_tag(sha1, name, flags)) had_error = 1; + } return had_error; } diff --git a/builtin/worktree.c b/builtin/worktree.c index d8e3795dc4..96a2834a18 100644 --- a/builtin/worktree.c +++ b/builtin/worktree.c @@ -110,7 +110,7 @@ static void prune_worktrees(void) if (ret < 0 && errno == ENOTDIR) ret = unlink(path.buf); if (ret) - error(_("failed to remove: %s"), strerror(errno)); + error_errno(_("failed to remove '%s'"), path.buf); } closedir(dir); if (!show_only) @@ -205,7 +205,7 @@ static int add_worktree(const char *path, const char *refname, if (!opts->detach && !strbuf_check_branch_ref(&symref, refname) && ref_exists(symref.buf)) { /* it's a branch */ if (!opts->force) - die_if_checked_out(symref.buf); + die_if_checked_out(symref.buf, 0); } else { /* must be a commit */ commit = lookup_commit_reference_by_name(refname); if (!commit) @@ -349,7 +349,7 @@ static int add(int ac, const char **av, const char *prefix) if (!opts.force && !strbuf_check_branch_ref(&symref, opts.new_branch) && ref_exists(symref.buf)) - die_if_checked_out(symref.buf); + die_if_checked_out(symref.buf, 0); strbuf_release(&symref); } diff --git a/cache-tree.c b/cache-tree.c index 3ebf9c3aa4..ddf0cc9f9a 100644 --- a/cache-tree.c +++ b/cache-tree.c @@ -663,7 +663,7 @@ static void prime_cache_tree_rec(struct cache_tree *it, struct tree *tree) cnt++; else { struct cache_tree_sub *sub; - struct tree *subtree = lookup_tree(entry.sha1); + struct tree *subtree = lookup_tree(entry.oid->hash); if (!subtree->object.parsed) parse_tree(subtree); sub = cache_tree_sub(it, entry.path); @@ -710,7 +710,7 @@ int cache_tree_matches_traversal(struct cache_tree *root, it = find_cache_tree_from_traversal(root, info); it = cache_tree_find(it, ent->path); - if (it && it->entry_count > 0 && !hashcmp(ent->sha1, it->sha1)) + if (it && it->entry_count > 0 && !hashcmp(ent->oid->hash, it->sha1)) return it->entry_count; return 0; } @@ -654,6 +654,7 @@ extern int warn_on_object_refname_ambiguity; extern const char *apply_default_whitespace; extern const char *apply_default_ignorewhitespace; extern const char *git_attributes_file; +extern const char *git_hooks_path; extern int zlib_compression_level; extern int core_compression_level; extern int core_compression_seen; @@ -700,6 +701,14 @@ extern int ref_paranoia; extern char comment_line_char; extern int auto_comment_line_char; +/* Windows only */ +enum hide_dotfiles_type { + HIDE_DOTFILES_FALSE = 0, + HIDE_DOTFILES_TRUE, + HIDE_DOTFILES_DOTGITONLY +}; +extern enum hide_dotfiles_type hide_dotfiles; + enum branch_track { BRANCH_TRACK_UNSPECIFIED = -1, BRANCH_TRACK_NEVER = 0, @@ -799,11 +808,14 @@ extern void check_repository_format(void); */ extern const char *mkpath(const char *fmt, ...) __attribute__((format (printf, 1, 2))); extern const char *git_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); +extern const char *git_common_path(const char *fmt, ...) __attribute__((format (printf, 1, 2))); extern char *mksnpath(char *buf, size_t n, const char *fmt, ...) __attribute__((format (printf, 3, 4))); extern void strbuf_git_path(struct strbuf *sb, const char *fmt, ...) __attribute__((format (printf, 2, 3))); +extern void strbuf_git_common_path(struct strbuf *sb, const char *fmt, ...) + __attribute__((format (printf, 2, 3))); extern char *git_path_buf(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); extern void strbuf_git_path_submodule(struct strbuf *sb, const char *path, @@ -958,8 +970,6 @@ static inline int is_empty_blob_sha1(const unsigned char *sha1) int git_mkstemp(char *path, size_t n, const char *template); -int git_mkstemps(char *path, size_t n, const char *template, int suffix_len); - /* set default permissions by passing mode arguments to open(2) */ int git_mkstemps_mode(char *pattern, int suffix_len, int mode); int git_mkstemp_mode(char *pattern, int mode); @@ -1156,6 +1166,8 @@ extern int get_sha1_blob(const char *str, unsigned char *sha1); extern void maybe_die_on_misspelt_object_name(const char *name, const char *prefix); extern int get_sha1_with_context(const char *str, unsigned flags, unsigned char *sha1, struct object_context *orc); +extern int get_oid(const char *str, struct object_id *oid); + typedef int each_abbrev_fn(const unsigned char *sha1, void *); extern int for_each_abbrev(const char *prefix, each_abbrev_fn, void *); @@ -1766,8 +1778,8 @@ int add_files_to_cache(const char *prefix, const struct pathspec *pathspec, int extern int diff_auto_refresh_index; /* match-trees.c */ -void shift_tree(const unsigned char *, const unsigned char *, unsigned char *, int); -void shift_tree_by(const unsigned char *, const unsigned char *, unsigned char *, const char *); +void shift_tree(const struct object_id *, const struct object_id *, struct object_id *, int); +void shift_tree_by(const struct object_id *, const struct object_id *, struct object_id *, const char *); /* * whitespace rules. diff --git a/check-racy.c b/check-racy.c index 00d92a1663..24b6542352 100644 --- a/check-racy.c +++ b/check-racy.c @@ -12,7 +12,7 @@ int main(int ac, char **av) struct stat st; if (lstat(ce->name, &st)) { - error("lstat(%s): %s", ce->name, strerror(errno)); + error_errno("lstat(%s)", ce->name); continue; } diff --git a/ci/test-documentation.sh b/ci/test-documentation.sh new file mode 100755 index 0000000000..579d540d32 --- /dev/null +++ b/ci/test-documentation.sh @@ -0,0 +1,14 @@ +#!/bin/sh +# +# Perform sanity checks on documentation and build it. +# + +set -e + +make check-builtins +make check-docs +make doc + +test -s Documentation/git.html +test -s Documentation/git.xml +test -s Documentation/git.1 diff --git a/combine-diff.c b/combine-diff.c index 0e1d4b0893..8f2313d502 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -1005,8 +1005,7 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, struct strbuf buf = STRBUF_INIT; if (strbuf_readlink(&buf, elem->path, st.st_size) < 0) { - error("readlink(%s): %s", elem->path, - strerror(errno)); + error_errno("readlink(%s)", elem->path); return; } result_size = buf.len; diff --git a/compat/mingw.c b/compat/mingw.c index 0413d5c3cd..a8218e6f0f 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -286,6 +286,49 @@ int mingw_rmdir(const char *pathname) return ret; } +static inline int needs_hiding(const char *path) +{ + const char *basename; + + if (hide_dotfiles == HIDE_DOTFILES_FALSE) + return 0; + + /* We cannot use basename(), as it would remove trailing slashes */ + mingw_skip_dos_drive_prefix((char **)&path); + if (!*path) + return 0; + + for (basename = path; *path; path++) + if (is_dir_sep(*path)) { + do { + path++; + } while (is_dir_sep(*path)); + /* ignore trailing slashes */ + if (*path) + basename = path; + } + + if (hide_dotfiles == HIDE_DOTFILES_TRUE) + return *basename == '.'; + + assert(hide_dotfiles == HIDE_DOTFILES_DOTGITONLY); + return !strncasecmp(".git", basename, 4) && + (!basename[4] || is_dir_sep(basename[4])); +} + +static int set_hidden_flag(const wchar_t *path, int set) +{ + DWORD original = GetFileAttributesW(path), modified; + if (set) + modified = original | FILE_ATTRIBUTE_HIDDEN; + else + modified = original & ~FILE_ATTRIBUTE_HIDDEN; + if (original == modified || SetFileAttributesW(path, modified)) + return 0; + errno = err_win_to_posix(GetLastError()); + return -1; +} + int mingw_mkdir(const char *path, int mode) { int ret; @@ -293,6 +336,8 @@ int mingw_mkdir(const char *path, int mode) if (xutftowcs_path(wpath, path) < 0) return -1; ret = _wmkdir(wpath); + if (!ret && needs_hiding(path)) + return set_hidden_flag(wpath, 1); return ret; } @@ -319,6 +364,21 @@ int mingw_open (const char *filename, int oflags, ...) if (attrs != INVALID_FILE_ATTRIBUTES && (attrs & FILE_ATTRIBUTE_DIRECTORY)) errno = EISDIR; } + if ((oflags & O_CREAT) && needs_hiding(filename)) { + /* + * Internally, _wopen() uses the CreateFile() API which errors + * out with an ERROR_ACCESS_DENIED if CREATE_ALWAYS was + * specified and an already existing file's attributes do not + * match *exactly*. As there is no mode or flag we can set that + * would correspond to FILE_ATTRIBUTE_HIDDEN, let's just try + * again *without* the O_CREAT flag (that corresponds to the + * CREATE_ALWAYS flag of CreateFile()). + */ + if (fd < 0 && errno == EACCES) + fd = _wopen(wfilename, oflags & ~O_CREAT, mode); + if (fd >= 0 && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); + } return fd; } @@ -350,6 +410,7 @@ int mingw_fgetc(FILE *stream) #undef fopen FILE *mingw_fopen (const char *filename, const char *otype) { + int hide = needs_hiding(filename); FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) @@ -357,12 +418,19 @@ FILE *mingw_fopen (const char *filename, const char *otype) if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; + if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { + error("could not unhide %s", filename); + return NULL; + } file = _wfopen(wfilename, wotype); + if (file && hide && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); return file; } FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) { + int hide = needs_hiding(filename); FILE *file; wchar_t wfilename[MAX_PATH], wotype[4]; if (filename && !strcmp(filename, "/dev/null")) @@ -370,7 +438,13 @@ FILE *mingw_freopen (const char *filename, const char *otype, FILE *stream) if (xutftowcs_path(wfilename, filename) < 0 || xutftowcs(wotype, otype, ARRAY_SIZE(wotype)) < 0) return NULL; + if (hide && !access(filename, F_OK) && set_hidden_flag(wfilename, 0)) { + error("could not unhide %s", filename); + return NULL; + } file = _wfreopen(wfilename, wotype, stream); + if (file && hide && set_hidden_flag(wfilename, 1)) + warning("could not mark '%s' as hidden.", filename); return file; } diff --git a/compat/mingw.h b/compat/mingw.h index 1de70ffd62..69bb43dc35 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -142,6 +142,7 @@ static inline int fcntl(int fd, int cmd, ...) #define sigemptyset(x) (void)0 static inline int sigaddset(sigset_t *set, int signum) { return 0; } +#define SIG_BLOCK 0 #define SIG_UNBLOCK 0 static inline int sigprocmask(int how, const sigset_t *set, sigset_t *oldset) { return 0; } @@ -416,9 +417,6 @@ int mingw_offset_1st_component(const char *path); void mingw_open_html(const char *path); #define open_html mingw_open_html -void mingw_mark_as_git_dir(const char *dir); -#define mark_as_git_dir mingw_mark_as_git_dir - /** * Converts UTF-8 encoded string to UTF-16LE. * diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index dfbe6d8408..4293b53b17 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -147,7 +147,7 @@ struct dirent_prec_psx *precompose_utf8_readdir(PREC_DIR *prec_dir) if (errno || inleft) { /* * iconv() failed and errno could be E2BIG, EILSEQ, EINVAL, EBADF - * MacOS X avoids illegal byte sequemces. + * MacOS X avoids illegal byte sequences. * If they occur on a mounted drive (e.g. NFS) it is not worth to * die() for that, but rather let the user see the original name */ diff --git a/compat/win32/pthread.h b/compat/win32/pthread.h index b6ed9e7462..1c164088fb 100644 --- a/compat/win32/pthread.h +++ b/compat/win32/pthread.h @@ -104,4 +104,11 @@ static inline void *pthread_getspecific(pthread_key_t key) return TlsGetValue(key); } +#ifndef __MINGW64_VERSION_MAJOR +static inline int pthread_sigmask(int how, const sigset_t *set, sigset_t *oset) +{ + return 0; +} +#endif + #endif /* PTHREAD_H */ diff --git a/compat/win32/syslog.c b/compat/win32/syslog.c index b905aea31b..6c7c9b6053 100644 --- a/compat/win32/syslog.c +++ b/compat/win32/syslog.c @@ -28,13 +28,13 @@ void syslog(int priority, const char *fmt, ...) va_end(ap); if (str_len < 0) { - warning("vsnprintf failed: '%s'", strerror(errno)); + warning_errno("vsnprintf failed"); return; } str = malloc(st_add(str_len, 1)); if (!str) { - warning("malloc failed: '%s'", strerror(errno)); + warning_errno("malloc failed"); return; } @@ -45,7 +45,7 @@ void syslog(int priority, const char *fmt, ...) while ((pos = strstr(str, "%1")) != NULL) { str = realloc(str, st_add(++str_len, 1)); if (!str) { - warning("realloc failed: '%s'", strerror(errno)); + warning_errno("realloc failed"); return; } memmove(pos + 2, pos + 1, strlen(pos)); diff --git a/compat/win32mmap.c b/compat/win32mmap.c index 80a8c9af4f..519d51f2b6 100644 --- a/compat/win32mmap.c +++ b/compat/win32mmap.c @@ -2,37 +2,42 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t offset) { - HANDLE hmap; + HANDLE osfhandle, hmap; void *temp; - off_t len; - struct stat st; + LARGE_INTEGER len; uint64_t o = offset; uint32_t l = o & 0xFFFFFFFF; uint32_t h = (o >> 32) & 0xFFFFFFFF; - if (!fstat(fd, &st)) - len = st.st_size; - else + osfhandle = (HANDLE)_get_osfhandle(fd); + if (!GetFileSizeEx(osfhandle, &len)) die("mmap: could not determine filesize"); - if ((length + offset) > len) - length = xsize_t(len - offset); + if ((length + offset) > len.QuadPart) + length = xsize_t(len.QuadPart - offset); if (!(flags & MAP_PRIVATE)) die("Invalid usage of mmap when built with USE_WIN32_MMAP"); - hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, - PAGE_WRITECOPY, 0, 0, NULL); + hmap = CreateFileMapping(osfhandle, NULL, + prot == PROT_READ ? PAGE_READONLY : PAGE_WRITECOPY, 0, 0, NULL); - if (!hmap) + if (!hmap) { + errno = EINVAL; return MAP_FAILED; + } - temp = MapViewOfFileEx(hmap, FILE_MAP_COPY, h, l, length, start); + temp = MapViewOfFileEx(hmap, prot == PROT_READ ? + FILE_MAP_READ : FILE_MAP_COPY, h, l, length, start); if (!CloseHandle(hmap)) warning("unable to close file mapping handle"); - return temp ? temp : MAP_FAILED; + if (temp) + return temp; + + errno = GetLastError() == ERROR_COMMITMENT_LIMIT ? EFBIG : EINVAL; + return MAP_FAILED; } int git_munmap(void *start, size_t length) @@ -717,6 +717,9 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.attributesfile")) return git_config_pathname(&git_attributes_file, var, value); + if (!strcmp(var, "core.hookspath")) + return git_config_pathname(&git_hooks_path, var, value); + if (!strcmp(var, "core.bare")) { is_bare_repository_cfg = git_config_bool(var, value); return 0; @@ -803,8 +806,6 @@ static int git_default_core_config(const char *var, const char *value) if (!strcmp(var, "core.autocrlf")) { if (value && !strcasecmp(value, "input")) { - if (core_eol == EOL_CRLF) - return error("core.autocrlf=input conflicts with core.eol=crlf"); auto_crlf = AUTO_CRLF_INPUT; return 0; } @@ -830,8 +831,6 @@ static int git_default_core_config(const char *var, const char *value) core_eol = EOL_NATIVE; else core_eol = EOL_UNSET; - if (core_eol == EOL_CRLF && auto_crlf == AUTO_CRLF_INPUT) - return error("core.autocrlf=input conflicts with core.eol=crlf"); return 0; } @@ -912,6 +911,14 @@ static int git_default_core_config(const char *var, const char *value) return 0; } + if (!strcmp(var, "core.hidedotfiles")) { + if (value && !strcasecmp(value, "dotgitonly")) + hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; + else + hide_dotfiles = git_config_bool(var, value); + return 0; + } + /* Add other config variables here and to Documentation/config.txt. */ return 0; } @@ -1309,14 +1316,11 @@ static struct config_set_element *configset_find_element(struct config_set *cs, struct config_set_element k; struct config_set_element *found_entry; char *normalized_key; - int ret; /* * `key` may come from the user, so normalize it before using it * for querying entries from the hashmap. */ - ret = git_config_parse_key(key, &normalized_key, NULL); - - if (ret) + if (git_config_parse_key(key, &normalized_key, NULL)) return NULL; hashmap_entry_init(&k, strhash(normalized_key)); @@ -2012,7 +2016,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, lock = xcalloc(1, sizeof(struct lock_file)); fd = hold_lock_file_for_update(lock, config_filename, 0); if (fd < 0) { - error("could not lock config file %s: %s", config_filename, strerror(errno)); + error_errno("could not lock config file %s", config_filename); free(store.key); ret = CONFIG_NO_LOCK; goto out_free; @@ -2026,8 +2030,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, free(store.key); if ( ENOENT != errno ) { - error("opening %s: %s", config_filename, - strerror(errno)); + error_errno("opening %s", config_filename); ret = CONFIG_INVALID_FILE; /* same as "invalid config file" */ goto out_free; } @@ -2111,8 +2114,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, if (contents == MAP_FAILED) { if (errno == ENODEV && S_ISDIR(st.st_mode)) errno = EISDIR; - error("unable to mmap '%s': %s", - config_filename, strerror(errno)); + error_errno("unable to mmap '%s'", config_filename); ret = CONFIG_INVALID_FILE; contents = NULL; goto out_free; @@ -2121,8 +2123,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, in_fd = -1; if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) { - error("chmod on %s failed: %s", - get_lock_file_path(lock), strerror(errno)); + error_errno("chmod on %s failed", get_lock_file_path(lock)); ret = CONFIG_NO_WRITE; goto out_free; } @@ -2178,8 +2179,7 @@ int git_config_set_multivar_in_file_gently(const char *config_filename, } if (commit_lock_file(lock) < 0) { - error("could not write config file %s: %s", config_filename, - strerror(errno)); + error_errno("could not write config file %s", config_filename); ret = CONFIG_NO_WRITE; lock = NULL; goto out_free; @@ -2330,8 +2330,8 @@ int git_config_rename_section_in_file(const char *config_filename, fstat(fileno(config_file), &st); if (chmod(get_lock_file_path(lock), st.st_mode & 07777) < 0) { - ret = error("chmod on %s failed: %s", - get_lock_file_path(lock), strerror(errno)); + ret = error_errno("chmod on %s failed", + get_lock_file_path(lock)); goto out; } @@ -2385,8 +2385,8 @@ int git_config_rename_section_in_file(const char *config_filename, fclose(config_file); unlock_and_out: if (commit_lock_file(lock) < 0) - ret = error("could not write config file %s: %s", - config_filename, strerror(errno)); + ret = error_errno("could not write config file %s", + config_filename); out: free(filename_buf); return ret; diff --git a/connected.c b/connected.c index 299c56090b..bf1b12e7ec 100644 --- a/connected.c +++ b/connected.c @@ -86,17 +86,14 @@ static int check_everything_connected_real(sha1_iterate_fn fn, memcpy(commit, sha1_to_hex(sha1), 40); if (write_in_full(rev_list.in, commit, 41) < 0) { if (errno != EPIPE && errno != EINVAL) - error(_("failed write to rev-list: %s"), - strerror(errno)); + error_errno(_("failed write to rev-list")); err = -1; break; } } while (!fn(cb_data, sha1)); - if (close(rev_list.in)) { - error(_("failed to close rev-list's stdin: %s"), strerror(errno)); - err = -1; - } + if (close(rev_list.in)) + err = error_errno(_("failed to close rev-list's stdin")); sigchain_pop(SIGPIPE); return finish_command(&rev_list) || err; diff --git a/contrib/hooks/multimail/CHANGES b/contrib/hooks/multimail/CHANGES index bc77e66b85..100cc7a6d3 100644 --- a/contrib/hooks/multimail/CHANGES +++ b/contrib/hooks/multimail/CHANGES @@ -1,3 +1,46 @@ +Release 1.3.1 (bugfix-only release) +=================================== + +* Generate links to commits in combined emails (it was done only for + commit emails in 1.3.0). + +* Fix broken links on PyPi. + +Release 1.3.0 +============= + +* New options multimailhook.htmlInIntro and multimailhook.htmlInFooter + now allow using HTML in the introduction and footer of emails (e.g. + for a more pleasant formatting or to insert a link to the commit on + a web interface). + +* A new option multimailhook.commitBrowseURL gives a simpler (and less + flexible) way to add a link to a web interface for commit emails + than multimailhook.htmlInIntro and multimailhook.htmlInFooter. + +* A new public function config.add_config_parameters was added to + allow custom hooks to set specific Git configuration variables + without modifying the configuration files. See an example in + post-receive.example. + +* Error handling for SMTP has been improved (we used to print Python + backtraces for legitimate errors). + +* The SMTP mailer can now check TLS certificates when the newly added + configuration variable multimailhook.smtpCACerts. + +* Python 3 portability has been improved. + +* The documentation's formatting has been improved. + +* The testsuite has been improved (we now use pyflakes to check for + errors in the code). + +This version has been tested with Python 2.4 and 2.6 to 3.5, and Git +v1.7.10-406-gdc801e7, 2.1.4 and 2.8.1.339.g3ad15fd. + +No change since 1.3 RC1. + Release 1.2.0 ============= diff --git a/contrib/hooks/multimail/CONTRIBUTING.rst b/contrib/hooks/multimail/CONTRIBUTING.rst index 09efdb059c..530ecbfcf1 100644 --- a/contrib/hooks/multimail/CONTRIBUTING.rst +++ b/contrib/hooks/multimail/CONTRIBUTING.rst @@ -1,3 +1,6 @@ +Contributing +============ + git-multimail is an open-source project, built by volunteers. We would welcome your help! @@ -6,9 +9,7 @@ and Matthieu Moy <matthieu.moy@grenoble-inp.fr>. Please note that although a copy of git-multimail is distributed in the "contrib" section of the main Git project, development takes place -in a separate git-multimail repository on GitHub: - - https://github.com/git-multimail/git-multimail +in a separate `git-multimail repository on GitHub`_. Whenever enough changes to git-multimail have accumulated, a new code-drop of git-multimail will be submitted for inclusion in the Git @@ -21,10 +22,12 @@ to the maintainers). Please sign off your patches as per the `Git project practice <https://github.com/git/git/blob/master/Documentation/SubmittingPatches#L234>`__. -General discussion of git-multimail can take place on the main Git -mailing list, - - git@vger.kernel.org +General discussion of git-multimail can take place on the main `Git +mailing list`_. Please CC emails regarding git-multimail to the maintainers so that we don't overlook them. + + +.. _`git-multimail repository on GitHub`: https://github.com/git-multimail/git-multimail +.. _`Git mailing list`: git@vger.kernel.org diff --git a/contrib/hooks/multimail/README b/contrib/hooks/multimail/README index 55120685f0..0c91d19a57 100644 --- a/contrib/hooks/multimail/README +++ b/contrib/hooks/multimail/README @@ -1,5 +1,5 @@ -git-multimail (version 1.2.0) -============================= +git-multimail 1.3.1 +=================== .. image:: https://travis-ci.org/git-multimail/git-multimail.svg?branch=master :target: https://travis-ci.org/git-multimail/git-multimail @@ -127,6 +127,13 @@ changes of this type, please consider sharing them with the community.) +Troubleshooting/FAQ +------------------- + +Please read `<doc/troubleshooting.rst>`__ for frequently asked +questions and common issues with git-multimail. + + Configuration ------------- @@ -134,19 +141,16 @@ By default, git-multimail mostly takes its configuration from the following ``git config`` settings: multimailhook.environment - This describes the general environment of the repository. In most cases, you do not need to specify a value for this variable: `git-multimail` will autodetect which environment to use. Currently supported values: - * generic - + generic the username of the pusher is read from $USER or $USERNAME and the repository name is derived from the repository's path. - * gitolite - + gitolite the username of the pusher is read from $GL_USER, the repository name is read from $GL_REPO, and the From: header value is optionally read from gitolite.conf (see multimailhook.from). @@ -154,8 +158,7 @@ multimailhook.environment For more information about gitolite and git-multimail, read `<doc/gitolite.rst>`__ - * stash - + stash Environment to use when ``git-multimail`` is ran as an Atlassian BitBucket Server (formerly known as Atlassian Stash) hook. @@ -169,8 +172,7 @@ multimailhook.environment and repo come from these two command line flags, which must be specified. - * gerrit - + gerrit Environment to use when ``git-multimail`` is ran as a ``ref-updated`` Gerrit hook. @@ -205,14 +207,12 @@ multimailhook.environment * If none of the above apply, then ``generic`` is used. multimailhook.repoName - A short name of this Git repository, to be used in various places in the notification email text. The default is to use $GL_REPO for gitolite repositories, or otherwise to derive this value from the repository path name. multimailhook.mailingList - The list of email addresses to which notification emails should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. Leave it unset or set it @@ -221,7 +221,6 @@ multimailhook.mailingList specific types of notification email. multimailhook.refchangeList - The list of email addresses to which summary emails about reference changes should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be @@ -231,7 +230,6 @@ multimailhook.refchangeList multimailhook.mailingList is set. multimailhook.announceList - The list of email addresses to which emails about new annotated tags should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The @@ -241,7 +239,6 @@ multimailhook.announceList even if one of the other values is set. multimailhook.commitList - The list of email addresses to which emails about individual new commits should be sent, as RFC 2822 email addresses separated by commas. This configuration option can be multivalued. The @@ -251,7 +248,6 @@ multimailhook.commitList multimailhook.mailingList is set. multimailhook.announceShortlog - If this option is set to true, then emails about changes to annotated tags include a shortlog of changes since the previous tag. This can be useful if the annotated tags represent releases; @@ -261,7 +257,6 @@ multimailhook.announceShortlog rather than useful. Default is false. multimailhook.commitEmailFormat - The format of email messages for the individual commits, can be "text" or "html". In the latter case, the emails will include diffs using colorized HTML instead of plain text used by default. Note that this currently the @@ -274,8 +269,43 @@ multimailhook.commitEmailFormat the message starting with ``+++`` or ``---`` colored in red or green). -multimailhook.refchangeShowGraph + By default, all the message is HTML-escaped. See + ``multimailhook.htmlInIntro`` to change this behavior. + +multimailhook.commitBrowseURL + Used to generate a link to an online repository browser in commit + emails. This variable must be a string. Format directives like + ``%(<variable>)s`` will be expanded the same way as template + strings. In particular, ``%(id)s`` will be replaced by the full + Git commit identifier (40-chars hexadecimal). + + If the string does not contain any format directive, then + ``%(id)s`` will be automatically added to the string. If you don't + want ``%(id)s`` to be automatically added, use the empty format + directive ``%()s`` anywhere in the string. + + For example, a suitable value for the git-multimail project itself + would be + ``https://github.com/git-multimail/git-multimail/commit/%(id)s``. + +multimailhook.htmlInIntro, multimailhook.htmlInFooter + When generating an HTML message, git-multimail escapes any HTML + sequence by default. This means that if a template contains HTML + like ``<a href="foo">link</a>``, the reader will see the HTML + source code and not a proper link. + + Set ``multimailhook.htmlInIntro`` to true to allow writting HTML + formatting in introduction templates. Similarly, set + ``multimailhook.htmlInFooter`` for HTML in the footer. + Variables expanded in the template are still escaped. For example, + if a repository's path contains a ``<``, it will be rendered as + such in the message. + + Read `<doc/customizing-emails.rst>`__ for more details and + examples. + +multimailhook.refchangeShowGraph If this option is set to true, then summary emails about reference changes will additionally include: @@ -287,7 +317,6 @@ multimailhook.refchangeShowGraph specified in graphOpts. The default is false. multimailhook.refchangeShowLog - If this option is set to true, then summary emails about reference changes will include a detailed log of the added commits in addition to the one line summary. The log is generated by running @@ -295,71 +324,80 @@ multimailhook.refchangeShowLog Default is false. multimailhook.mailer - This option changes the way emails are sent. Accepted values are: - - sendmail (the default): use the command ``/usr/sbin/sendmail`` or + * **sendmail (the default)**: use the command ``/usr/sbin/sendmail`` or ``/usr/lib/sendmail`` (or sendmailCommand, if configured). This mode can be further customized via the following options: - * multimailhook.sendmailCommand - - The command used by mailer ``sendmail`` to send emails. Shell - quoting is allowed in the value of this setting, but remember that - Git requires double-quotes to be escaped; e.g.:: + multimailhook.sendmailCommand + The command used by mailer ``sendmail`` to send emails. Shell + quoting is allowed in the value of this setting, but remember that + Git requires double-quotes to be escaped; e.g.:: - git config multimailhook.sendmailcommand '/usr/sbin/sendmail -oi -t -F \"Git Repo\"' + git config multimailhook.sendmailcommand '/usr/sbin/sendmail -oi -t -F \"Git Repo\"' - Default is '/usr/sbin/sendmail -oi -t' or - '/usr/lib/sendmail -oi -t' (depending on which file is - present and executable). + Default is '/usr/sbin/sendmail -oi -t' or + '/usr/lib/sendmail -oi -t' (depending on which file is + present and executable). - * multimailhook.envelopeSender + multimailhook.envelopeSender + If set then pass this value to sendmail via the -f option to set + the envelope sender address. - If set then pass this value to sendmail via the -f option to set - the envelope sender address. - - - smtp: use Python's smtplib. This is useful when the sendmail + * **smtp**: use Python's smtplib. This is useful when the sendmail command is not available on the system. This mode can be further customized via the following options: - * multimailhook.smtpServer - - The name of the SMTP server to connect to. The value can - also include a colon and a port number; e.g., - ``mail.example.com:25``. Default is 'localhost' using port 25. - - * multimailhook.smtpUser - * multimailhook.smtpPass - - Server username and password. Required if smtpEncryption is 'ssl'. - Note that the username and password currently need to be - set cleartext in the configuration file, which is not - recommended. If you need to use this option, be sure your - configuration file is read-only. + multimailhook.smtpServer + The name of the SMTP server to connect to. The value can + also include a colon and a port number; e.g., + ``mail.example.com:25``. Default is 'localhost' using port 25. - * multimailhook.envelopeSender + multimailhook.smtpUser, multimailhook.smtpPass + Server username and password. Required if smtpEncryption is 'ssl'. + Note that the username and password currently need to be + set cleartext in the configuration file, which is not + recommended. If you need to use this option, be sure your + configuration file is read-only. + multimailhook.envelopeSender The sender address to be passed to the SMTP server. If unset, then the value of multimailhook.from is used. - * multimailhook.smtpServerTimeout - + multimailhook.smtpServerTimeout Timeout in seconds. - * multimailhook.smtpEncryption - - Set the security type. Allowed values: none, ssl, tls. - Default=none. - - * multimailhook.smtpServerDebugLevel - + multimailhook.smtpEncryption + Set the security type. Allowed values: ``none``, ``ssl``, ``tls`` (starttls). + Default is ``none``. + + multimailhook.smtpCACerts + Set the path to a list of trusted CA certificate to verify the + server certificate, only supported when ``smtpEncryption`` is + ``tls``. If unset or empty, the server certificate is not + verified. If it targets a file containing a list of trusted CA + certificates (PEM format) these CAs will be used to verify the + server certificate. For debian, you can set + ``/etc/ssl/certs/ca-certificates.crt`` for using the system + trusted CAs. For self-signed server, you can add your server + certificate to the system store:: + + cd /usr/local/share/ca-certificates/ + openssl s_client -starttls smtp \ + -connect mail.example.net:587 -showcerts \ + </dev/null 2>/dev/null \ + | openssl x509 -outform PEM >mail.example.net.crt + update-ca-certificates + + and used the updated ``/etc/ssl/certs/ca-certificates.crt``. Or + directly use your ``/path/to/mail.example.net.crt``. Default is + unset. + + multimailhook.smtpServerDebugLevel Integer number. Set to greater than 0 to activate debugging. -multimailhook.from -multimailhook.fromCommit -multimailhook.fromRefchange - +multimailhook.from, multimailhook.fromCommit, multimailhook.fromRefchange If set, use this value in the From: field of generated emails. ``fromCommit`` is used for commit emails, ``fromRefchange`` is used for refchange emails, and ``from`` is used as fall-back in @@ -372,7 +410,7 @@ multimailhook.fromRefchange - The value ``pusher``, in which case the pusher's address (if available) will be used. - - The value ``author`` (meaningful only for replyToCommit), in which + - The value ``author`` (meaningful only for ``fromCommit``), in which case the commit author's address will be used. If config values are unset, the value of the From: header is @@ -396,14 +434,12 @@ multimailhook.fromRefchange 3. Use the value of multimailhook.envelopeSender. multimailhook.administrator - The name and/or email address of the administrator of the Git repository; used in FOOTER_TEMPLATE. Default is multimailhook.envelopesender if it is set; otherwise a generic string is used. multimailhook.emailPrefix - All emails have this string prepended to their subjects, to aid email filtering (though filtering based on the X-Git-* email headers is probably more robust). Default is the short name of @@ -411,16 +447,14 @@ multimailhook.emailPrefix value to the empty string to suppress the email prefix. multimailhook.emailMaxLines - The maximum number of lines that should be included in the body of a generated email. If not specified, there is no limit. Lines beyond the limit are suppressed and counted, and a final line is added indicating the number of suppressed lines. multimailhook.emailMaxLineLength - The maximum length of a line in the email body. Lines longer than - this limit are truncated to this length with a trailing `` [...]`` + this limit are truncated to this length with a trailing ``[...]`` added to indicate the missing text. The default is 500, because (a) diffs with longer lines are probably from binary files, for which a diff is useless, and (b) even if a text file has such long @@ -428,7 +462,6 @@ multimailhook.emailMaxLineLength truncation, set this option to 0. multimailhook.maxCommitEmails - The maximum number of commit emails to send for a given change. When the number of patches is larger that this value, only the summary refchange email is sent. This can avoid accidental @@ -436,14 +469,12 @@ multimailhook.maxCommitEmails emails limit, set this option to 0. The default is 500. multimailhook.emailStrictUTF8 - If this boolean option is set to `true`, then the main part of the email body is forced to be valid UTF-8. Any characters that are not valid UTF-8 are converted to the Unicode replacement character, U+FFFD. The default is `true`. multimailhook.diffOpts - Options passed to ``git diff-tree`` when generating the summary information for ReferenceChange emails. Default is ``--stat --summary --find-copies-harder``. Add -p to those options to @@ -452,7 +483,6 @@ multimailhook.diffOpts details. multimailhook.graphOpts - Options passed to ``git log --graph`` when generating graphs for the reference change summary emails (used only if refchangeShowGraph is true). The default is '--oneline --decorate'. @@ -460,7 +490,6 @@ multimailhook.graphOpts Shell quoting is allowed; see logOpts for details. multimailhook.logOpts - Options passed to ``git log`` to generate additional info for reference change emails (used only if refchangeShowLog is set). For example, adding -p will show each commit's complete diff. The @@ -479,7 +508,6 @@ multimailhook.logOpts logopts = --pretty=format:\"%h %aN <%aE>%n%s%n%n%b%n\" multimailhook.commitLogOpts - Options passed to ``git log`` to generate additional info for revision change emails. For example, adding --ignore-all-spaces will suppress whitespace changes. The default options are ``-C @@ -487,26 +515,21 @@ multimailhook.commitLogOpts multimailhook.logOpts for details. multimailhook.dateSubstitute - String to use as a substitute for ``Date:`` in the output of ``git log`` while formatting commit messages. This is usefull to avoid emitting a line that can be interpreted by mailers as the start of a cited message (Zimbra webmail in particular). Defaults to - ``CommitDate: ``. Set to an empty string or ``none`` to deactivate + ``CommitDate:``. Set to an empty string or ``none`` to deactivate the behavior. multimailhook.emailDomain - Domain name appended to the username of the person doing the push to convert it into an email address (via ``"%s@%s" % (username, emaildomain)``). More complicated schemes can be implemented by overriding Environment and overriding its get_pusher_email() method. -multimailhook.replyTo -multimailhook.replyToCommit -multimailhook.replyToRefchange - +multimailhook.replyTo, multimailhook.replyToCommit, multimailhook.replyToRefchange Addresses to use in the Reply-To: field for commit emails (replyToCommit) and refchange emails (replyToRefchange). multimailhook.replyTo is used as default when replyToCommit or @@ -519,32 +542,24 @@ multimailhook.replyToRefchange commit emails. multimailhook.quiet - Do not output the list of email recipients from the hook multimailhook.stdout - For debugging, send emails to stdout rather than to the mailer. Equivalent to the --stdout command line option multimailhook.scanCommitForCc - If this option is set to true, than recipients from lines in commit body that starts with ``CC:`` will be added to CC list. Default: false multimailhook.combineWhenSingleCommit - If this option is set to true and a single new commit is pushed to a branch, combine the summary and commit email messages into a single email. Default: true -multimailhook.refFilterInclusionRegex -multimailhook.refFilterExclusionRegex -multimailhook.refFilterDoSendRegex -multimailhook.refFilterDontSendRegex - +multimailhook.refFilterInclusionRegex, multimailhook.refFilterExclusionRegex, multimailhook.refFilterDoSendRegex, multimailhook.refFilterDontSendRegex **Warning:** these options are experimental. They should work, but the user-interface is not stable yet (in particular, the option names may change). If you want to participate in stabilizing the @@ -626,14 +641,16 @@ git-multimail is mostly customized via an "environment" that describes the local environment in which Git is running. Two types of environment are built in: -* GenericEnvironment: a stand-alone Git repository. +GenericEnvironment + a stand-alone Git repository. -* GitoliteEnvironment: a Git repository that is managed by gitolite - [3]_. For such repositories, the identity of the pusher is read from - environment variable $GL_USER, the name of the repository is read - from $GL_REPO (if it is not overridden by multimailhook.reponame), - and the From: header value is optionally read from gitolite.conf - (see multimailhook.from). +GitoliteEnvironment + a Git repository that is managed by gitolite + [3]_. For such repositories, the identity of the pusher is read from + environment variable $GL_USER, the name of the repository is read + from $GL_REPO (if it is not overridden by multimailhook.reponame), + and the From: header value is optionally read from gitolite.conf + (see multimailhook.from). By default, git-multimail assumes GitoliteEnvironment if $GL_USER and $GL_REPO are set, and otherwise assumes GenericEnvironment. diff --git a/contrib/hooks/multimail/README.Git b/contrib/hooks/multimail/README.Git index 300a2a4d2d..1210bde045 100644 --- a/contrib/hooks/multimail/README.Git +++ b/contrib/hooks/multimail/README.Git @@ -6,10 +6,10 @@ website: https://github.com/git-multimail/git-multimail The version in this directory was obtained from the upstream project -on October 11 2015 and consists of the "git-multimail" subdirectory from +on May 13 2016 and consists of the "git-multimail" subdirectory from revision - c0791b9ef5821a746fc3475c25765e640452eaae refs/tags/1.2.0 + 3ce5470d4abf7251604cbf64e73a962e1b617f5e refs/tags/1.3.1 Please see the README file in this directory for information about how to report bugs or contribute to git-multimail. diff --git a/contrib/hooks/multimail/doc/customizing-emails.rst b/contrib/hooks/multimail/doc/customizing-emails.rst new file mode 100644 index 0000000000..3f5b67f768 --- /dev/null +++ b/contrib/hooks/multimail/doc/customizing-emails.rst @@ -0,0 +1,56 @@ +Customizing the content and formatting of emails +================================================ + +Overloading template strings +---------------------------- + +The content of emails is generated based on template strings defined +in ``git_multimail.py``. You can customize these template strings +without changing the script itself, by defining a Python wrapper +around it. The python wrapper should ``import git_multimail`` and then +override the ``git_multimail.*`` strings like this:: + + import sys # needed for sys.argv + + # Import and customize git_multimail: + import git_multimail + git_multimail.REVISION_INTRO_TEMPLATE = """...""" + git_multimail.COMBINED_INTRO_TEMPLATE = git_multimail.REVISION_INTRO_TEMPLATE + + # start git_multimail itself: + git_multimail.main(sys.argv[1:]) + +The template strings can use any value already used in the existing +templates (read the source code). + +Using HTML in template strings +------------------------------ + +If ``multimailhook.commitEmailFormat`` is set to HTML, then +git-multimail will generate HTML emails for commit notifications. The +log and diff will be formatted automatically by git-multimail. By +default, any HTML special character in the templates will be escaped. + +To use HTML formatting in the introduction of the email, set +``multimailhook.htmlInIntro`` to ``true``. Then, the template can +contain any HTML tags, that will be sent as-is in the email. For +example, to add some formatting and a link to the online commit, use +a format like:: + + git_multimail.REVISION_INTRO_TEMPLATE = """\ + <span style="color:#808080">This is an automated email from the git hooks/post-receive script.</span><br /><br /> + + <strong>%(pusher)s</strong> pushed a commit to %(refname_type)s %(short_refname)s + in repository %(repo_shortname)s.<br /> + + <a href="https://github.com/git-multimail/git-multimail/commit/%(newrev)s">View on GitHub</a>. + """ + +Note that the values expanded from ``%(variable)s`` in the format +strings will still be escaped. + +For a less flexible but easier to set up way to add a link to commit +emails, see ``multimailhook.commitBrowseURL``. + +Similarly, one can set ``multimailhook.htmlInFooter`` and override any +of the ``*_FOOTER*`` template strings. diff --git a/contrib/hooks/multimail/doc/troubleshooting.rst b/contrib/hooks/multimail/doc/troubleshooting.rst new file mode 100644 index 0000000000..d3f346f076 --- /dev/null +++ b/contrib/hooks/multimail/doc/troubleshooting.rst @@ -0,0 +1,44 @@ +Troubleshooting issues with git-multimail: a FAQ +================================================ + +Git is not using the right address in the From/To/Reply-To field +---------------------------------------------------------------- + +First, make sure that git-multimail actually uses what you think it is +using. A lot happens to your email (especially when posting to a +mailing-list) between the time `git_multimail.py` sends it and the +time it reaches your inbox. + +A simple test (to do on a test repository, do not use in production as +it would disable email sending): change your post-receive hook to call +`git_multimail.py` with the `--stdout` option, and try to push to the +repository. You should see something like:: + + Counting objects: 3, done. + Writing objects: 100% (3/3), 263 bytes | 0 bytes/s, done. + Total 3 (delta 0), reused 0 (delta 0) + remote: Sending notification emails to: foo.bar@example.com + remote: =========================================================================== + remote: Date: Mon, 25 Apr 2016 18:39:59 +0200 + remote: To: foo.bar@example.com + remote: Subject: [git] branch master updated: foo + remote: MIME-Version: 1.0 + remote: Content-Type: text/plain; charset=utf-8 + remote: Content-Transfer-Encoding: 8bit + remote: Message-ID: <20160425163959.2311.20498@anie> + remote: From: Auth Or <Foo.Bar@example.com> + remote: Reply-To: Auth Or <Foo.Bar@example.com> + remote: X-Git-Host: example + ... + remote: -- + remote: To stop receiving notification emails like this one, please contact + remote: the administrator of this repository. + remote: =========================================================================== + To /path/to/repo + 6278f04..e173f20 master -> master + +Note: this does not include the sender (Return-Path: header), as it is +not part of the message content but passed to the mailer. Some mailer +show the ``Sender:`` field instead of the ``From:`` field (for +example, Zimbra Webmail shows ``From: <sender-field> on behalf of +<from-field>``). diff --git a/contrib/hooks/multimail/git_multimail.py b/contrib/hooks/multimail/git_multimail.py index 0180dba431..54ab4a4942 100755 --- a/contrib/hooks/multimail/git_multimail.py +++ b/contrib/hooks/multimail/git_multimail.py @@ -1,6 +1,6 @@ #! /usr/bin/env python -__version__ = '1.2.0' +__version__ = '1.3.1' # Copyright (c) 2015 Matthieu Moy and others # Copyright (c) 2012-2014 Michael Haggerty and others @@ -57,6 +57,11 @@ import subprocess import shlex import optparse import smtplib +try: + import ssl +except ImportError: + # Python < 2.6 do not have ssl, but that's OK if we don't use it. + pass import time import cgi @@ -75,6 +80,9 @@ def is_ascii(s): if PYTHON3: + def is_string(s): + return isinstance(s, str) + def str_to_bytes(s): return s.encode(ENCODING) @@ -91,6 +99,12 @@ if PYTHON3: except UnicodeEncodeError: f.buffer.write(msg.encode(ENCODING)) else: + def is_string(s): + try: + return isinstance(s, basestring) + except NameError: # Silence Pyflakes warning + raise + def str_to_bytes(s): return s @@ -313,6 +327,16 @@ in repository %(repo_shortname)s. """ +LINK_TEXT_TEMPLATE = """\ +View the commit online: +%(browse_url)s + +""" + +LINK_HTML_TEMPLATE = """\ +<p><a href="%(browse_url)s">View the commit online</a>.</p> +""" + REVISION_FOOTER_TEMPLATE = FOOTER_TEMPLATE @@ -532,6 +556,28 @@ class Config(object): assert words[-1] == '' return words[:-1] + @staticmethod + def add_config_parameters(c): + """Add configuration parameters to Git. + + c is either an str or a list of str, each element being of the + form 'var=val' or 'var', with the same syntax and meaning as + the argument of 'git -c var=val'. + """ + if isinstance(c, str): + c = (c,) + parameters = os.environ.get('GIT_CONFIG_PARAMETERS', '') + if parameters: + parameters += ' ' + # git expects GIT_CONFIG_PARAMETERS to be of the form + # "'name1=value1' 'name2=value2' 'name3=value3'" + # including everything inside the double quotes (but not the double + # quotes themselves). Spacing is critical. Also, if a value contains + # a literal single quote that quote must be represented using the + # four character sequence: '\'' + parameters += ' '.join("'" + x.replace("'", "'\\''") + "'" for x in c) + os.environ['GIT_CONFIG_PARAMETERS'] = parameters + def get(self, name, default=None): try: values = self._split(read_git_output( @@ -745,6 +791,12 @@ class Change(object): values['multimail_version'] = get_version() return values + # Aliases usable in template strings. Tuple of pairs (destination, + # source). + VALUES_ALIAS = ( + ("id", "newrev"), + ) + def get_values(self, **extra_values): """Return a dictionary {keyword: expansion} for this Change. @@ -760,6 +812,9 @@ class Change(object): values = self._values.copy() if extra_values: values.update(extra_values) + + for alias, val in self.VALUES_ALIAS: + values[alias] = values[val] return values def expand(self, template, **extra_values): @@ -772,10 +827,14 @@ class Change(object): return template % self.get_values(**extra_values) - def expand_lines(self, template, **extra_values): + def expand_lines(self, template, html_escape_val=False, **extra_values): """Break template into lines and expand each line.""" values = self.get_values(**extra_values) + if html_escape_val: + for k in values: + if is_string(values[k]): + values[k] = cgi.escape(values[k], True) for line in template.splitlines(True): yield line % values @@ -787,9 +846,10 @@ class Change(object): values = self.get_values(**extra_values) if self._contains_html_diff: - values['contenttype'] = 'html' + self._content_type = 'html' else: - values['contenttype'] = 'plain' + self._content_type = 'plain' + values['contenttype'] = self._content_type for line in template.splitlines(): (name, value) = line.split(': ', 1) @@ -819,7 +879,11 @@ class Change(object): raise NotImplementedError() - def generate_email_intro(self): + def generate_browse_link(self, base_url): + """Generate a link to an online repository browser.""" + return iter(()) + + def generate_email_intro(self, html_escape_val=False): """Generate the email intro for this Change, a line at a time. The output will be used as the standard boilerplate at the top @@ -835,7 +899,7 @@ class Change(object): raise NotImplementedError() - def generate_email_footer(self): + def generate_email_footer(self, html_escape_val): """Generate the footer of the email, a line at a time. The footer is always included, irrespective of @@ -876,9 +940,18 @@ class Change(object): for line in self.generate_email_header(**extra_header_values): yield line yield '\n' - for line in self._wrap_for_html(self.generate_email_intro()): + html_escape_val = (self.environment.html_in_intro and + self._contains_html_diff) + intro = self.generate_email_intro(html_escape_val) + if not self.environment.html_in_intro: + intro = self._wrap_for_html(intro) + for line in intro: yield line + if self.environment.commitBrowseURL: + for line in self.generate_browse_link(self.environment.commitBrowseURL): + yield line + body = self.generate_email_body(push) if body_filter is not None: body = body_filter(body) @@ -939,8 +1012,12 @@ class Change(object): yield line if self._contains_html_diff: yield '</pre>' - - for line in self._wrap_for_html(self.generate_email_footer()): + html_escape_val = (self.environment.html_in_footer and + self._contains_html_diff) + footer = self.generate_email_footer(html_escape_val) + if not self.environment.html_in_footer: + footer = self._wrap_for_html(footer) + for line in footer: yield line def get_alt_fromaddr(self): @@ -992,6 +1069,7 @@ class Revision(Change): values['rev_short'] = self.rev.short values['change_type'] = self.change_type values['refname'] = self.refname + values['newrev'] = self.rev.sha1 values['short_refname'] = self.reference_change.short_refname values['refname_type'] = self.reference_change.refname_type values['reply_to_msgid'] = self.reference_change.msgid @@ -1015,8 +1093,26 @@ class Revision(Change): ): yield line - def generate_email_intro(self): - for line in self.expand_lines(REVISION_INTRO_TEMPLATE): + def generate_browse_link(self, base_url): + if '%(' not in base_url: + base_url += '%(id)s' + url = "".join(self.expand_lines(base_url)) + if self._content_type == 'html': + for line in self.expand_lines(LINK_HTML_TEMPLATE, + html_escape_val=True, + browse_url=url): + yield line + elif self._content_type == 'plain': + for line in self.expand_lines(LINK_TEXT_TEMPLATE, + html_escape_val=False, + browse_url=url): + yield line + else: + raise NotImplementedError("Content-type %s unsupported. Please report it as a bug.") + + def generate_email_intro(self, html_escape_val=False): + for line in self.expand_lines(REVISION_INTRO_TEMPLATE, + html_escape_val=html_escape_val): yield line def generate_email_body(self, push): @@ -1031,8 +1127,9 @@ class Revision(Change): else: yield line - def generate_email_footer(self): - return self.expand_lines(REVISION_FOOTER_TEMPLATE) + def generate_email_footer(self, html_escape_val): + return self.expand_lines(REVISION_FOOTER_TEMPLATE, + html_escape_val=html_escape_val) def generate_email(self, push, body_filter=None, extra_header_values={}): self._contains_diff() @@ -1217,8 +1314,9 @@ class ReferenceChange(Change): ): yield line - def generate_email_intro(self): - for line in self.expand_lines(self.intro_template): + def generate_email_intro(self, html_escape_val=False): + for line in self.expand_lines(self.intro_template, + html_escape_val=html_escape_val): yield line def generate_email_body(self, push): @@ -1238,8 +1336,9 @@ class ReferenceChange(Change): for line in self.generate_revision_change_summary(push): yield line - def generate_email_footer(self): - return self.expand_lines(self.footer_template) + def generate_email_footer(self, html_escape_val): + return self.expand_lines(self.footer_template, + html_escape_val=html_escape_val) def generate_revision_change_graph(self, push): if self.showgraph: @@ -1605,6 +1704,14 @@ class BranchChange(ReferenceChange): self.header_template = COMBINED_HEADER_TEMPLATE self.intro_template = COMBINED_INTRO_TEMPLATE self.footer_template = COMBINED_FOOTER_TEMPLATE + + def revision_gen_link(base_url): + # revision is used only to generate the body, and + # _content_type is set while generating headers. Get it + # from the BranchChange object. + revision._content_type = self._content_type + return revision.generate_browse_link(base_url) + self.generate_browse_link = revision_gen_link for line in self.generate_email(push, body_filter, values): yield line @@ -1896,6 +2003,7 @@ class SMTPMailer(Mailer): smtpservertimeout=10.0, smtpserverdebuglevel=0, smtpencryption='none', smtpuser='', smtppass='', + smtpcacerts='' ): if not envelopesender: sys.stderr.write( @@ -1915,6 +2023,7 @@ class SMTPMailer(Mailer): self.security = smtpencryption self.username = smtpuser self.password = smtppass + self.smtpcacerts = smtpcacerts try: def call(klass, server, timeout): try: @@ -1925,13 +2034,56 @@ class SMTPMailer(Mailer): if self.security == 'none': self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout) elif self.security == 'ssl': + if self.smtpcacerts: + raise smtplib.SMTPException( + "Checking certificate is not supported for ssl, prefer starttls" + ) self.smtp = call(smtplib.SMTP_SSL, self.smtpserver, timeout=self.smtpservertimeout) elif self.security == 'tls': + if 'ssl' not in sys.modules: + sys.stderr.write( + '*** Your Python version does not have the ssl library installed\n' + '*** smtpEncryption=tls is not available.\n' + '*** Either upgrade Python to 2.6 or later\n' + ' or use git_multimail.py version 1.2.\n') if ':' not in self.smtpserver: self.smtpserver += ':587' # default port for TLS self.smtp = call(smtplib.SMTP, self.smtpserver, timeout=self.smtpservertimeout) + # start: ehlo + starttls + # equivalent to + # self.smtp.ehlo() + # self.smtp.starttls() + # with acces to the ssl layer self.smtp.ehlo() - self.smtp.starttls() + if not self.smtp.has_extn("starttls"): + raise smtplib.SMTPException("STARTTLS extension not supported by server") + resp, reply = self.smtp.docmd("STARTTLS") + if resp != 220: + raise smtplib.SMTPException("Wrong answer to the STARTTLS command") + if self.smtpcacerts: + self.smtp.sock = ssl.wrap_socket( + self.smtp.sock, + ca_certs=self.smtpcacerts, + cert_reqs=ssl.CERT_REQUIRED + ) + else: + self.smtp.sock = ssl.wrap_socket( + self.smtp.sock, + cert_reqs=ssl.CERT_NONE + ) + sys.stderr.write( + '*** Warning, the server certificat is not verified (smtp) ***\n' + '*** set the option smtpCACerts ***\n' + ) + if not hasattr(self.smtp.sock, "read"): + # using httplib.FakeSocket with Python 2.5.x or earlier + self.smtp.sock.read = self.smtp.sock.recv + self.smtp.file = smtplib.SSLFakeFile(self.smtp.sock) + self.smtp.helo_resp = None + self.smtp.ehlo_resp = None + self.smtp.esmtp_features = {} + self.smtp.does_esmtp = 0 + # end: ehlo + starttls self.smtp.ehlo() else: sys.stdout.write('*** Error: Control reached an invalid option. ***') @@ -1951,6 +2103,7 @@ class SMTPMailer(Mailer): def __del__(self): if hasattr(self, 'smtp'): self.smtp.quit() + del self.smtp def send(self, lines, to_addrs): try: @@ -1958,13 +2111,24 @@ class SMTPMailer(Mailer): self.smtp.login(self.username, self.password) msg = ''.join(lines) # turn comma-separated list into Python list if needed. - if isinstance(to_addrs, basestring): + if is_string(to_addrs): to_addrs = [email for (name, email) in getaddresses([to_addrs])] self.smtp.sendmail(self.envelopesender, to_addrs, msg) - except Exception: + except smtplib.SMTPResponseException: sys.stderr.write('*** Error sending email ***\n') - sys.stderr.write('*** %s\n' % sys.exc_info()[1]) - self.smtp.quit() + err = sys.exc_info()[1] + sys.stderr.write('*** Error %d: %s\n' % (err.smtp_code, + bytes_to_str(err.smtp_error))) + try: + smtp = self.smtp + # delete the field before quit() so that in case of + # error, self.smtp is deleted anyway. + del self.smtp + smtp.quit() + except: + sys.stderr.write('*** Error closing the SMTP connection ***\n') + sys.stderr.write('*** Exiting anyway ... ***\n') + sys.stderr.write('*** %s\n' % sys.exc_info()[1]) sys.exit(1) @@ -2097,6 +2261,14 @@ class Environment(object): If "html", generate commit emails in HTML instead of plain text used by default. + html_in_intro (bool) + html_in_footer (bool) + + When generating HTML emails, the introduction (respectively, + the footer) will be HTML-escaped iff html_in_intro (respectively, + the footer) is true. When false, only the values used to expand + the template are escaped. + refchange_showgraph (bool) True iff refchanges emails should include a detailed graph. @@ -2160,6 +2332,9 @@ class Environment(object): self.osenv = osenv or os.environ self.announce_show_shortlog = False self.commit_email_format = "text" + self.html_in_intro = False + self.html_in_footer = False + self.commitBrowseURL = None self.maxcommitemails = 500 self.diffopts = ['--stat', '--summary', '--find-copies-harder'] self.graphopts = ['--oneline', '--decorate'] @@ -2236,7 +2411,7 @@ class Environment(object): The return value is always a new dictionary.""" if self._values is None: - values = {} + values = {'': ''} # %()s expands to the empty string. for key in self.COMPUTED_KEYS: value = getattr(self, 'get_%s' % (key,))() @@ -2375,6 +2550,16 @@ class ConfigOptionsEnvironmentMixin(ConfigEnvironmentMixin): else: self.commit_email_format = commit_email_format + html_in_intro = config.get_bool('htmlInIntro') + if html_in_intro is not None: + self.html_in_intro = html_in_intro + + html_in_footer = config.get_bool('htmlInFooter') + if html_in_footer is not None: + self.html_in_footer = html_in_footer + + self.commitBrowseURL = config.get('commitBrowseURL') + maxcommitemails = config.get('maxcommitemails') if maxcommitemails is not None: try: @@ -2415,7 +2600,6 @@ class ConfigOptionsEnvironmentMixin(ConfigEnvironmentMixin): ['author']) self.__reply_to_commit = config.get('replyToCommit', default=reply_to) - from_addr = self.config.get('from') self.from_refchange = config.get('fromRefchange') self.forbid_field_values('fromRefchange', self.from_refchange, @@ -3390,6 +3574,8 @@ def run_as_post_receive_hook(environment, mailer): if changes: push = Push(environment, changes) push.send_emails(mailer, body_filter=environment.filter_body) + if hasattr(mailer, '__del__'): + mailer.__del__() def run_as_update_hook(environment, mailer, refname, oldrev, newrev, force_send=False): @@ -3406,6 +3592,8 @@ def run_as_update_hook(environment, mailer, refname, oldrev, newrev, force_send= ] push = Push(environment, changes, force_send) push.send_emails(mailer, body_filter=environment.filter_body) + if hasattr(mailer, '__del__'): + mailer.__del__() def choose_mailer(config, environment): @@ -3418,6 +3606,7 @@ def choose_mailer(config, environment): smtpencryption = config.get('smtpencryption', default='none') smtpuser = config.get('smtpuser', default='') smtppass = config.get('smtppass', default='') + smtpcacerts = config.get('smtpcacerts', default='') mailer = SMTPMailer( envelopesender=(environment.get_sender() or environment.get_fromaddr()), smtpserver=smtpserver, smtpservertimeout=smtpservertimeout, @@ -3425,6 +3614,7 @@ def choose_mailer(config, environment): smtpencryption=smtpencryption, smtpuser=smtpuser, smtppass=smtppass, + smtpcacerts=smtpcacerts ) elif mailer == 'sendmail': command = config.get('sendmailcommand') @@ -3691,17 +3881,7 @@ def main(args): return if options.c: - parameters = os.environ.get('GIT_CONFIG_PARAMETERS', '') - if parameters: - parameters += ' ' - # git expects GIT_CONFIG_PARAMETERS to be of the form - # "'name1=value1' 'name2=value2' 'name3=value3'" - # including everything inside the double quotes (but not the double - # quotes themselves). Spacing is critical. Also, if a value contains - # a literal single quote that quote must be represented using the - # four character sequence: '\'' - parameters += ' '.join("'" + x.replace("'", "'\\''") + "'" for x in options.c) - os.environ['GIT_CONFIG_PARAMETERS'] = parameters + Config.add_config_parameters(options.c) config = Config('multimailhook') diff --git a/contrib/hooks/multimail/post-receive.example b/contrib/hooks/multimail/post-receive.example index 9975df7107..1ea113d274 100755 --- a/contrib/hooks/multimail/post-receive.example +++ b/contrib/hooks/multimail/post-receive.example @@ -55,6 +55,12 @@ import git_multimail # git-multimail: config = git_multimail.Config('multimailhook') +# Set some Git configuration variables. Equivalent to passing var=val +# to "git -c var=val" each time git is called, or to adding the +# configuration in .git/config (must come before instanciating the +# environment) : +#git_multimail.Config.add_config_parameters('multimailhook.commitEmailFormat=html') +#git_multimail.Config.add_config_parameters(('user.name=foo', 'user.email=foo@example.com')) # Select the type of environment: try: @@ -1380,27 +1380,22 @@ static struct stream_filter *ident_filter(const unsigned char *sha1) struct stream_filter *get_stream_filter(const char *path, const unsigned char *sha1) { struct conv_attrs ca; - enum crlf_action crlf_action; struct stream_filter *filter = NULL; convert_attrs(&ca, path); - if (ca.drv && (ca.drv->smudge || ca.drv->clean)) - return filter; + return NULL; + + if (ca.crlf_action == CRLF_AUTO || ca.crlf_action == CRLF_AUTO_CRLF) + return NULL; if (ca.ident) filter = ident_filter(sha1); - crlf_action = ca.crlf_action; - - if ((crlf_action == CRLF_BINARY) || - crlf_action == CRLF_AUTO_INPUT || - (crlf_action == CRLF_TEXT_INPUT)) - filter = cascade_filter(filter, &null_filter_singleton); - - else if (output_eol(crlf_action) == EOL_CRLF && - !(crlf_action == CRLF_AUTO || crlf_action == CRLF_AUTO_CRLF)) + if (output_eol(ca.crlf_action) == EOL_CRLF) filter = cascade_filter(filter, lf_to_crlf_filter()); + else + filter = cascade_filter(filter, &null_filter_singleton); return filter; } @@ -42,15 +42,15 @@ int copy_file(const char *dst, const char *src, int mode) status = copy_fd(fdi, fdo); switch (status) { case COPY_READ_ERROR: - error("copy-fd: read returned %s", strerror(errno)); + error_errno("copy-fd: read returned"); break; case COPY_WRITE_ERROR: - error("copy-fd: write returned %s", strerror(errno)); + error_errno("copy-fd: write returned"); break; } close(fdi); if (close(fdo) != 0) - return error("%s: close error: %s", dst, strerror(errno)); + return error_errno("%s: close error", dst); if (!status && adjust_shared_perm(dst)) return -1; diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c index 291c0fd5e9..1f14d56e98 100644 --- a/credential-cache--daemon.c +++ b/credential-cache--daemon.c @@ -179,12 +179,12 @@ static int serve_cache_loop(int fd) client = accept(fd, NULL, NULL); if (client < 0) { - warning("accept failed: %s", strerror(errno)); + warning_errno("accept failed"); return 1; } client2 = dup(client); if (client2 < 0) { - warning("dup failed: %s", strerror(errno)); + warning_errno("dup failed"); close(client); return 1; } diff --git a/diff-no-index.c b/diff-no-index.c index 03daadb25a..1f8999b9ca 100644 --- a/diff-no-index.c +++ b/diff-no-index.c @@ -65,8 +65,7 @@ static int populate_from_stdin(struct diff_filespec *s) size_t size = 0; if (strbuf_read(&buf, 0, 0) < 0) - return error("error while reading from stdin %s", - strerror(errno)); + return error_errno("error while reading from stdin"); s->should_munmap = 0; s->data = strbuf_detach(&buf, &size); @@ -26,6 +26,7 @@ #endif static int diff_detect_rename_default; +static int diff_compaction_heuristic = 1; static int diff_rename_limit_default = 400; static int diff_suppress_blank_empty; static int diff_use_color_default = -1; @@ -189,6 +190,10 @@ int git_diff_ui_config(const char *var, const char *value, void *cb) diff_detect_rename_default = git_config_rename(var, value); return 0; } + if (!strcmp(var, "diff.compactionheuristic")) { + diff_compaction_heuristic = git_config_bool(var, value); + return 0; + } if (!strcmp(var, "diff.autorefreshindex")) { diff_auto_refresh_index = git_config_bool(var, value); return 0; @@ -3278,6 +3283,8 @@ void diff_setup(struct diff_options *options) options->use_color = diff_use_color_default; options->detect_rename = diff_detect_rename_default; options->xdl_opts |= diff_algorithm; + if (diff_compaction_heuristic) + DIFF_XDL_SET(options, COMPACTION_HEURISTIC); options->orderfile = diff_order_file_cfg; @@ -3798,6 +3805,10 @@ int diff_opt_parse(struct diff_options *options, DIFF_XDL_SET(options, IGNORE_WHITESPACE_AT_EOL); else if (!strcmp(arg, "--ignore-blank-lines")) DIFF_XDL_SET(options, IGNORE_BLANK_LINES); + else if (!strcmp(arg, "--compaction-heuristic")) + DIFF_XDL_SET(options, COMPACTION_HEURISTIC); + else if (!strcmp(arg, "--no-compaction-heuristic")) + DIFF_XDL_CLR(options, COMPACTION_HEURISTIC); else if (!strcmp(arg, "--patience")) options->xdl_opts = DIFF_WITH_ALG(options, PATIENCE_DIFF); else if (!strcmp(arg, "--histogram")) @@ -53,24 +53,16 @@ static enum path_treatment read_directory_recursive(struct dir_struct *dir, int check_only, const struct path_simplify *simplify); static int get_dtype(struct dirent *de, const char *path, int len); -/* helper string functions with support for the ignore_case flag */ -int strcmp_icase(const char *a, const char *b) +int fspathcmp(const char *a, const char *b) { return ignore_case ? strcasecmp(a, b) : strcmp(a, b); } -int strncmp_icase(const char *a, const char *b, size_t count) +int fspathncmp(const char *a, const char *b, size_t count) { return ignore_case ? strncasecmp(a, b, count) : strncmp(a, b, count); } -int fnmatch_icase(const char *pattern, const char *string, int flags) -{ - return wildmatch(pattern, string, - flags | (ignore_case ? WM_CASEFOLD : 0), - NULL); -} - int git_fnmatch(const struct pathspec_item *item, const char *pattern, const char *string, int prefix) @@ -802,12 +794,12 @@ int match_basename(const char *basename, int basenamelen, { if (prefix == patternlen) { if (patternlen == basenamelen && - !strncmp_icase(pattern, basename, basenamelen)) + !fspathncmp(pattern, basename, basenamelen)) return 1; } else if (flags & EXC_FLAG_ENDSWITH) { /* "*literal" matching against "fooliteral" */ if (patternlen - 1 <= basenamelen && - !strncmp_icase(pattern + 1, + !fspathncmp(pattern + 1, basename + basenamelen - (patternlen - 1), patternlen - 1)) return 1; @@ -844,7 +836,7 @@ int match_pathname(const char *pathname, int pathlen, */ if (pathlen < baselen + 1 || (baselen && pathname[baselen] != '/') || - strncmp_icase(pathname, base, baselen)) + fspathncmp(pathname, base, baselen)) return 0; namelen = baselen ? pathlen - baselen - 1 : pathlen; @@ -858,7 +850,7 @@ int match_pathname(const char *pathname, int pathlen, if (prefix > namelen) return 0; - if (strncmp_icase(pattern, name, prefix)) + if (fspathncmp(pattern, name, prefix)) return 0; pattern += prefix; patternlen -= prefix; @@ -270,9 +270,8 @@ extern int remove_dir_recursively(struct strbuf *path, int flag); /* tries to remove the path with empty directories along it, ignores ENOENT */ extern int remove_path(const char *path); -extern int strcmp_icase(const char *a, const char *b); -extern int strncmp_icase(const char *a, const char *b, size_t count); -extern int fnmatch_icase(const char *pattern, const char *string, int flags); +extern int fspathcmp(const char *a, const char *b); +extern int fspathncmp(const char *a, const char *b, size_t count); /* * The prefix part of pattern must not contains wildcards. @@ -63,7 +63,6 @@ int launch_editor(const char *path, struct strbuf *buffer, const char *const *en if (!buffer) return 0; if (strbuf_read_file(buffer, path, 0) < 0) - return error("could not read file '%s': %s", - path, strerror(errno)); + return error_errno("could not read file '%s'", path); return 0; } @@ -168,8 +168,8 @@ static int write_entry(struct cache_entry *ce, ret = symlink(new, path); free(new); if (ret) - return error("unable to create symlink %s (%s)", - path, strerror(errno)); + return error_errno("unable to create symlink %s", + path); break; } @@ -186,8 +186,7 @@ static int write_entry(struct cache_entry *ce, fd = open_output_fd(path, ce, to_tempfile); if (fd < 0) { free(new); - return error("unable to create file %s (%s)", - path, strerror(errno)); + return error_errno("unable to create file %s", path); } wrote = write_in_full(fd, new, size); @@ -284,8 +283,7 @@ int checkout_entry(struct cache_entry *ce, return error("%s is a directory", path.buf); remove_subtree(&path); } else if (unlink(path.buf)) - return error("unable to unlink old '%s' (%s)", - path.buf, strerror(errno)); + return error_errno("unable to unlink old '%s'", path.buf); } else if (state->not_new) return 0; diff --git a/environment.c b/environment.c index 57acb2fe2a..ca72464a98 100644 --- a/environment.c +++ b/environment.c @@ -31,6 +31,7 @@ const char *git_log_output_encoding; const char *apply_default_whitespace; const char *apply_default_ignorewhitespace; const char *git_attributes_file; +const char *git_hooks_path; int zlib_compression_level = Z_BEST_SPEED; int core_compression_level; int core_compression_seen; @@ -63,6 +64,7 @@ int core_apply_sparse_checkout; int merge_log_config = -1; int precomposed_unicode = -1; /* see probe_utf8_pathname_composition() */ unsigned long pack_size_limit_cfg; +enum hide_dotfiles_type hide_dotfiles = HIDE_DOTFILES_DOTGITONLY; #ifndef PROTECT_HFS_DEFAULT #define PROTECT_HFS_DEFAULT 0 diff --git a/fast-import.c b/fast-import.c index 9fc7093406..83558dcfe3 100644 --- a/fast-import.c +++ b/fast-import.c @@ -414,7 +414,7 @@ static void write_crash_report(const char *err) struct recent_command *rc; if (!rpt) { - error("can't write crash report %s: %s", loc, strerror(errno)); + error_errno("can't write crash report %s", loc); free(loc); return; } @@ -1512,7 +1512,7 @@ static int tree_content_set( t = root->tree; for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; - if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) { + if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, n)) { if (!*slash1) { if (!S_ISDIR(mode) && e->versions[1].mode == mode @@ -1602,7 +1602,7 @@ static int tree_content_remove( t = root->tree; for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; - if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) { + if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, n)) { if (*slash1 && !S_ISDIR(e->versions[1].mode)) /* * If p names a file in some subdirectory, and a @@ -1669,7 +1669,7 @@ static int tree_content_get( t = root->tree; for (i = 0; i < t->entry_count; i++) { e = t->entries[i]; - if (e->name->str_len == n && !strncmp_icase(p, e->name->str_dat, n)) { + if (e->name->str_len == n && !fspathncmp(p, e->name->str_dat, n)) { if (!*slash1) goto found_entry; if (!S_ISDIR(e->versions[1].mode)) @@ -1806,8 +1806,8 @@ static void dump_marks(void) return; if (hold_lock_file_for_update(&mark_lock, export_marks_file, 0) < 0) { - failure |= error("Unable to write marks file %s: %s", - export_marks_file, strerror(errno)); + failure |= error_errno("Unable to write marks file %s", + export_marks_file); return; } @@ -1822,8 +1822,8 @@ static void dump_marks(void) dump_marks_helper(f, 0, marks); if (commit_lock_file(&mark_lock)) { - failure |= error("Unable to write file %s: %s", - export_marks_file, strerror(errno)); + failure |= error_errno("Unable to write file %s", + export_marks_file); return; } } diff --git a/fetch-pack.c b/fetch-pack.c index f96f6dfb35..b501d5c320 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -15,7 +15,6 @@ #include "version.h" #include "prio-queue.h" #include "sha1-array.h" -#include "sigchain.h" static int transfer_unpack_limit = -1; static int fetch_unpack_limit = -1; @@ -674,10 +673,8 @@ static int sideband_demux(int in, int out, void *data) int *xd = data; int ret; - sigchain_push(SIGPIPE, SIG_IGN); ret = recv_sideband("fetch-pack", xd[0], out); close(out); - sigchain_pop(SIGPIPE); return ret; } @@ -701,6 +698,7 @@ static int get_pack(struct fetch_pack_args *args, demux.proc = sideband_demux; demux.data = xd; demux.out = -1; + demux.isolate_sigpipe = 1; if (start_async(&demux)) die("fetch-pack: unable to fork off sideband" " demultiplexer"); @@ -59,6 +59,7 @@ FUNC(HAS_DOTGIT, WARN) \ FUNC(NULL_SHA1, WARN) \ FUNC(ZERO_PADDED_FILEMODE, WARN) \ + FUNC(NUL_IN_COMMIT, WARN) \ /* infos (reported as warnings, but ignored by default) */ \ FUNC(BAD_TAG_NAME, INFO) \ FUNC(MISSING_TAGGER_ENTRY, INFO) @@ -312,9 +313,9 @@ static int fsck_walk_tree(struct tree *tree, void *data, struct fsck_options *op if (S_ISGITLINK(entry.mode)) continue; if (S_ISDIR(entry.mode)) - result = options->walk(&lookup_tree(entry.sha1)->object, OBJ_TREE, data, options); + result = options->walk(&lookup_tree(entry.oid->hash)->object, OBJ_TREE, data, options); else if (S_ISREG(entry.mode) || S_ISLNK(entry.mode)) - result = options->walk(&lookup_blob(entry.sha1)->object, OBJ_BLOB, data, options); + result = options->walk(&lookup_blob(entry.oid->hash)->object, OBJ_BLOB, data, options); else { result = error("in tree %s: entry %s has bad mode %.6o", oid_to_hex(&tree->object.oid), entry.path, entry.mode); @@ -450,11 +451,11 @@ static int fsck_tree(struct tree *item, struct fsck_options *options) while (desc.size) { unsigned mode; const char *name; - const unsigned char *sha1; + const struct object_id *oid; - sha1 = tree_entry_extract(&desc, &name, &mode); + oid = tree_entry_extract(&desc, &name, &mode); - has_null_sha1 |= is_null_sha1(sha1); + has_null_sha1 |= is_null_oid(oid); has_full_path |= !!strchr(name, '/'); has_empty_name |= !*name; has_dot |= !strcmp(name, "."); @@ -610,6 +611,7 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer, struct commit_graft *graft; unsigned parent_count, parent_line_count = 0, author_count; int err; + const char *buffer_begin = buffer; if (verify_headers(buffer, size, &commit->object, options)) return -1; @@ -666,9 +668,17 @@ static int fsck_commit_buffer(struct commit *commit, const char *buffer, err = fsck_ident(&buffer, &commit->object, options); if (err) return err; - if (!commit->tree) - return report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); - + if (!commit->tree) { + err = report(options, &commit->object, FSCK_MSG_BAD_TREE, "could not load commit's tree %s", sha1_to_hex(tree_sha1)); + if (err) + return err; + } + if (memchr(buffer_begin, '\0', size)) { + err = report(options, &commit->object, FSCK_MSG_NUL_IN_COMMIT, + "NUL byte in the commit object body"); + if (err) + return err; + } return 0; } diff --git a/git-compat-util.h b/git-compat-util.h index 1f8b5f3b1f..49d4029b8d 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -409,7 +409,9 @@ extern NORETURN void usagef(const char *err, ...) __attribute__((format (printf, extern NORETURN void die(const char *err, ...) __attribute__((format (printf, 1, 2))); extern NORETURN void die_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); extern int error(const char *err, ...) __attribute__((format (printf, 1, 2))); +extern int error_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); extern void warning(const char *err, ...) __attribute__((format (printf, 1, 2))); +extern void warning_errno(const char *err, ...) __attribute__((format (printf, 1, 2))); #ifndef NO_OPENSSL #ifdef APPLE_COMMON_CRYPTO diff --git a/git-cvsserver.perl b/git-cvsserver.perl index 02c0445be1..d50c85ed7b 100755 --- a/git-cvsserver.perl +++ b/git-cvsserver.perl @@ -1156,7 +1156,7 @@ sub prepDirForOutput # FUTURE: This would more accurately emulate CVS by sending # another copy of sticky after processing the files in that # directory. Or intermediate: perhaps send all sticky's for - # $seendirs after after processing all files. + # $seendirs after processing all files. } # update \n @@ -2824,7 +2824,7 @@ sub statecleanup } # Return working directory CVS revision "1.X" out -# of the the working directory "entries" state, for the given filename. +# of the working directory "entries" state, for the given filename. # This is prefixed with a dash if the file is scheduled for removal # when it is committed. sub revparse @@ -2935,7 +2935,7 @@ sub filecleanup return $filename; } -# Remove prependdir from the path, so that is is relative to the directory +# Remove prependdir from the path, so that it is relative to the directory # the CVS client was started from, rather than the top of the project. # Essentially the inverse of filecleanup(). sub remove_prependdir diff --git a/git-difftool--helper.sh b/git-difftool--helper.sh index 2b11b1d6fe..84d6cc021c 100755 --- a/git-difftool--helper.sh +++ b/git-difftool--helper.sh @@ -44,10 +44,10 @@ launch_merge_tool () { "$GIT_DIFF_PATH_TOTAL" "$MERGED" if use_ext_cmd then - printf "Launch '%s' [Y/n]: " \ + printf "Launch '%s' [Y/n]? " \ "$GIT_DIFFTOOL_EXTCMD" else - printf "Launch '%s' [Y/n]: " "$merge_tool" + printf "Launch '%s' [Y/n]? " "$merge_tool" fi read ans || return if test "$ans" = n diff --git a/git-difftool.perl b/git-difftool.perl index 488d14b153..ebd13baa6e 100755 --- a/git-difftool.perl +++ b/git-difftool.perl @@ -138,6 +138,7 @@ sub setup_dir_diff my %submodule; my %symlink; my @working_tree = (); + my %working_tree_dups = (); my @rawdiff = split('\0', $diffrtn); my $i = 0; @@ -188,6 +189,10 @@ EOF } if ($rmode ne $null_mode) { + # Avoid duplicate working_tree entries + if ($working_tree_dups{$dst_path}++) { + next; + } my ($use, $wt_sha1) = use_wt_file($repo, $workdir, $dst_path, $rsha1); if ($use) { @@ -273,7 +278,7 @@ EOF # temporary file to both the left and right directories to show the # change in the recorded SHA1 for the submodule. for my $path (keys %submodule) { - my $ok; + my $ok = 0; if (defined($submodule{$path}{left})) { $ok = write_to_file("$ldir/$path", "Subproject commit $submodule{$path}{left}"); @@ -289,7 +294,7 @@ EOF # shows only the link itself, not the contents of the link target. # This loop replicates that behavior. for my $path (keys %symlink) { - my $ok; + my $ok = 0; if (defined($symlink{$path}{left})) { $ok = write_to_file("$ldir/$path", $symlink{$path}{left}); diff --git a/git-merge-octopus.sh b/git-merge-octopus.sh index 8643f74cb0..dc2fd1b5a4 100755 --- a/git-merge-octopus.sh +++ b/git-merge-octopus.sh @@ -44,6 +44,12 @@ esac # MRC is the current "merge reference commit" # MRT is the current "merge result tree" +if ! git diff-index --quiet --cached HEAD -- +then + echo "Error: Your local changes to the following files would be overwritten by merge" + git diff-index --cached --name-only HEAD -- | sed -e 's/^/ /' + exit 2 +fi MRC=$(git rev-parse --verify -q $head) MRT=$(git write-tree) NON_FF_MERGE=0 diff --git a/git-mergetool--lib.sh b/git-mergetool--lib.sh index 302c56de5b..9abd00be21 100644 --- a/git-mergetool--lib.sh +++ b/git-mergetool--lib.sh @@ -100,7 +100,7 @@ check_unchanged () { while true do echo "$MERGED seems unchanged." - printf "Was the merge successful? [y/n] " + printf "Was the merge successful [y/n]? " read answer || return 1 case "$answer" in y*|Y*) return 0 ;; diff --git a/git-mergetool.sh b/git-mergetool.sh index f67bab55e8..bf862705d8 100755 --- a/git-mergetool.sh +++ b/git-mergetool.sh @@ -413,7 +413,7 @@ done prompt_after_failed_merge () { while true do - printf "Continue merging other unresolved paths (y/n) ? " + printf "Continue merging other unresolved paths [y/n]? " read ans || return 1 case "$ans" in [yY]*) @@ -1064,8 +1064,15 @@ class GitLFS(LargeFileSystem): if pointerProcess.wait(): os.remove(contentFile) die('git-lfs pointer command failed. Did you install the extension?') - pointerContents = [i+'\n' for i in pointerFile.split('\n')[2:][:-1]] - oid = pointerContents[1].split(' ')[1].split(':')[1][:-1] + + # Git LFS removed the preamble in the output of the 'pointer' command + # starting from version 1.2.0. Check for the preamble here to support + # earlier versions. + # c.f. https://github.com/github/git-lfs/commit/da2935d9a739592bc775c98d8ef4df9c72ea3b43 + if pointerFile.startswith('Git LFS pointer for'): + pointerFile = re.sub(r'Git LFS pointer for.*\n\n', '', pointerFile) + + oid = re.search(r'^oid \w+:(\w+)', pointerFile, re.MULTILINE).group(1) localLargeFile = os.path.join( os.getcwd(), '.git', 'lfs', 'objects', oid[:2], oid[2:4], @@ -1073,7 +1080,7 @@ class GitLFS(LargeFileSystem): ) # LFS Spec states that pointer files should not have the executable bit set. gitMode = '100644' - return (gitMode, pointerContents, localLargeFile) + return (gitMode, pointerFile, localLargeFile) def pushFile(self, localLargeFile): uploadProcess = subprocess.Popen( @@ -2320,6 +2327,15 @@ class P4Sync(Command, P4UserMap): fnum = fnum + 1 return files + def extractJobsFromCommit(self, commit): + jobs = [] + jnum = 0 + while commit.has_key("job%s" % jnum): + job = commit["job%s" % jnum] + jobs.append(job) + jnum = jnum + 1 + return jobs + def stripRepoPath(self, path, prefixes): """When streaming files, this is called to map a p4 depot path to where it should go in git. The prefixes are either @@ -2665,6 +2681,7 @@ class P4Sync(Command, P4UserMap): def commit(self, details, files, branch, parent = ""): epoch = details["time"] author = details["user"] + jobs = self.extractJobsFromCommit(details) if self.verbose: print('commit into {0}'.format(branch)) @@ -2692,6 +2709,8 @@ class P4Sync(Command, P4UserMap): self.gitStream.write("data <<EOT\n") self.gitStream.write(details["desc"]) + if len(jobs) > 0: + self.gitStream.write("\nJobs: %s" % (' '.join(jobs))) self.gitStream.write("\n[git-p4: depot-paths = \"%s\": change = %s" % (','.join(self.branchPrefixes), details["change"])) if len(details['options']) > 0: diff --git a/git-parse-remote.sh b/git-parse-remote.sh index 55fe8d56c9..d3c39980f3 100644 --- a/git-parse-remote.sh +++ b/git-parse-remote.sh @@ -56,11 +56,13 @@ get_remote_merge_branch () { error_on_missing_default_upstream () { cmd="$1" op_type="$2" - op_prep="$3" + op_prep="$3" # FIXME: op_prep is no longer used example="$4" branch_name=$(git symbolic-ref -q HEAD) + display_branch_name="${branch_name#refs/heads/}" # If there's only one remote, use that in the suggestion - remote="<remote>" + remote="$(gettext "<remote>")" + branch="$(gettext "<branch>")" if test $(git remote | wc -l) = 1 then remote=$(git remote) @@ -68,22 +70,32 @@ error_on_missing_default_upstream () { if test -z "$branch_name" then - echo "You are not currently on a branch. Please specify which -branch you want to $op_type $op_prep. See git-${cmd}(1) for details. - - $example -" + gettextln "You are not currently on a branch." else - echo "There is no tracking information for the current branch. -Please specify which branch you want to $op_type $op_prep. -See git-${cmd}(1) for details - - $example - -If you wish to set tracking information for this branch you can do so with: - - git branch --set-upstream-to=$remote/<branch> ${branch_name#refs/heads/} -" + gettextln "There is no tracking information for the current branch." + fi + case "$op_type" in + rebase) + gettextln "Please specify which branch you want to rebase against." + ;; + merge) + gettextln "Please specify which branch you want to merge with." + ;; + *) + echo >&2 "BUG: unknown operation type: $op_type" + exit 1 + ;; + esac + eval_gettextln "See git-\${cmd}(1) for details." + echo + echo " $example" + echo + if test -n "$branch_name" + then + gettextln "If you wish to set tracking information for this branch you can do so with:" + echo + echo " git branch --set-upstream-to=$remote/$branch $display_branch_name" + echo fi exit 1 } diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 9ea30756f1..9d2bfb7a16 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -82,6 +82,7 @@ rewritten_pending="$state_dir"/rewritten-pending cr=$(printf "\015") strategy_args=${strategy:+--strategy=$strategy} +test -n "$strategy_opts" && eval ' for strategy_opt in '"$strategy_opts"' do @@ -866,12 +867,12 @@ add_exec_commands () { # $3: the input filename check_commit_sha () { badsha=0 - if test -z $1 + if test -z "$1" then badsha=1 else sha1_verif="$(git rev-parse --verify --quiet $1^{commit})" - if test -z $sha1_verif + if test -z "$sha1_verif" then badsha=1 fi diff --git a/git-rebase--merge.sh b/git-rebase--merge.sh index 2cc2a6d273..8d43db9069 100644 --- a/git-rebase--merge.sh +++ b/git-rebase--merge.sh @@ -67,7 +67,9 @@ call_merge () { GIT_MERGE_VERBOSITY=1 && export GIT_MERGE_VERBOSITY fi test -z "$strategy" && strategy=recursive - eval 'git-merge-$strategy' $strategy_opts '"$cmt^" -- "$hd" "$cmt"' + # If cmt doesn't have a parent, don't include it as a base + base=$(git rev-parse --verify --quiet $cmt^) + eval 'git-merge-$strategy' $strategy_opts $base ' -- "$hd" "$cmt"' rv=$? case "$rv" in 0) diff --git a/git-rebase.sh b/git-rebase.sh index 0bf41ee72b..44ede367ae 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -87,7 +87,10 @@ preserve_merges= autosquash= keep_empty= test "$(git config --bool rebase.autosquash)" = "true" && autosquash=t -gpg_sign_opt= +case "$(git config --bool commit.gpgsign)" in +true) gpg_sign_opt=-S ;; +*) gpg_sign_opt= ;; +esac read_basic_state () { test -f "$state_dir/head-name" && diff --git a/git-send-email.perl b/git-send-email.perl index 1406f64d78..69587856df 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -827,9 +827,10 @@ if (defined $sender) { # But it's a no-op to run sanitize_address on an already sanitized address. $sender = sanitize_address($sender); +my $to_whom = "To whom should the emails be sent (if anyone)?"; my $prompting = 0; if (!@initial_to && !defined $to_cmd) { - my $to = ask("Who should the emails be sent to (if any)? ", + my $to = ask("$to_whom ", default => "", valid_re => qr/\@.*\./, confirm_only => 1); push @initial_to, parse_address_line($to) if defined $to; # sanitized/validated later @@ -924,7 +925,7 @@ sub validate_address { cleanup_compose_files(); exit(0); } - $address = ask("Who should the email be sent to (if any)? ", + $address = ask("$to_whom ", default => "", valid_re => qr/\@.*\./, confirm_only => 1); } diff --git a/git-stash.sh b/git-stash.sh index c7c65e25f5..c7509e8da4 100755 --- a/git-stash.sh +++ b/git-stash.sh @@ -185,7 +185,7 @@ store_stash () { git update-ref --create-reflog -m "$stash_msg" $ref_stash $w_commit ret=$? - test $ret != 0 && test -z $quiet && + test $ret != 0 && test -z "$quiet" && die "$(eval_gettext "Cannot update \$ref_stash with \$w_commit")" return $ret } @@ -277,7 +277,7 @@ save_stash () { git clean --force --quiet -d $CLEAN_X_OPTION fi - if test "$keep_index" = "t" && test -n $i_tree + if test "$keep_index" = "t" && test -n "$i_tree" then git read-tree --reset -u $i_tree fi diff --git a/git-submodule.sh b/git-submodule.sh index cd749f473c..5a4dec050b 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -8,7 +8,7 @@ dashless=$(basename "$0" | sed -e 's/-/ /') USAGE="[--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] [--] <path>... + or: $dashless [--quiet] deinit [-f|--force] (--all| [--] <path>...) or: $dashless [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--checkout|--merge|--rebase] [--reference <repository>] [--recursive] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] or: $dashless [--quiet] foreach [--recursive] <command> @@ -46,79 +46,6 @@ prefix= custom_name= depth= -# The function takes at most 2 arguments. The first argument is the -# URL that navigates to the submodule origin repo. When relative, this URL -# is relative to the superproject origin URL repo. The second up_path -# argument, if specified, is the relative path that navigates -# from the submodule working tree to the superproject working tree. -# -# The output of the function is the origin URL of the submodule. -# -# The output will either be an absolute URL or filesystem path (if the -# superproject origin URL is an absolute URL or filesystem path, -# respectively) or a relative file system path (if the superproject -# origin URL is a relative file system path). -# -# When the output is a relative file system path, the path is either -# relative to the submodule working tree, if up_path is specified, or to -# the superproject working tree otherwise. -resolve_relative_url () -{ - remote=$(get_default_remote) - remoteurl=$(git config "remote.$remote.url") || - remoteurl=$(pwd) # the repository is its own authoritative upstream - url="$1" - remoteurl=${remoteurl%/} - sep=/ - up_path="$2" - - case "$remoteurl" in - *:*|/*) - is_relative= - ;; - ./*|../*) - is_relative=t - ;; - *) - is_relative=t - remoteurl="./$remoteurl" - ;; - esac - - while test -n "$url" - do - case "$url" in - ../*) - url="${url#../}" - case "$remoteurl" in - */*) - remoteurl="${remoteurl%/*}" - ;; - *:*) - remoteurl="${remoteurl%:*}" - sep=: - ;; - *) - if test -z "$is_relative" || test "." = "$remoteurl" - then - die "$(eval_gettext "cannot strip one component off url '\$remoteurl'")" - else - remoteurl=. - fi - ;; - esac - ;; - ./*) - url="${url#./}" - ;; - *) - break;; - esac - done - remoteurl="$remoteurl$sep${url%/}" - echo "${is_relative:+${up_path}}${remoteurl#./}" -} - # Resolve a path to be relative to another path. This is intended for # converting submodule paths when git-submodule is run in a subdirectory # and only handles paths where the directory separator is '/'. @@ -197,9 +124,10 @@ isnumber() # of the settings from GIT_CONFIG_PARAMETERS. sanitize_submodule_env() { - sanitized_config=$(git submodule--helper sanitize-config) + save_config=$GIT_CONFIG_PARAMETERS clear_local_git_env - GIT_CONFIG_PARAMETERS=$sanitized_config + GIT_CONFIG_PARAMETERS=$save_config + export GIT_CONFIG_PARAMETERS } # @@ -291,7 +219,7 @@ cmd_add() die "$(gettext "Relative path can only be used from the toplevel of the working tree")" # dereference source url relative to parent's url - realrepo=$(resolve_relative_url "$repo") || exit + realrepo=$(git submodule--helper resolve-relative-url "$repo") || exit ;; *:*|/*) # absolute url @@ -423,8 +351,8 @@ cmd_foreach() die_if_unmatched "$mode" if test -e "$sm_path"/.git then - displaypath=$(relative_path "$sm_path") - say "$(eval_gettext "Entering '\$prefix\$displaypath'")" + displaypath=$(relative_path "$prefix$sm_path") + say "$(eval_gettext "Entering '\$displaypath'")" name=$(git submodule--helper name "$sm_path") ( prefix="$prefix$sm_path/" @@ -444,7 +372,7 @@ cmd_foreach() cmd_foreach "--recursive" "$@" fi ) <&3 3<&- || - die "$(eval_gettext "Stopping at '\$prefix\$displaypath'; script returned non-zero status.")" + die "$(eval_gettext "Stopping at '\$displaypath'; script returned non-zero status.")" fi done } @@ -477,50 +405,7 @@ cmd_init() shift done - git submodule--helper list --prefix "$wt_prefix" "$@" | - while read mode sha1 stage sm_path - do - die_if_unmatched "$mode" - name=$(git submodule--helper name "$sm_path") || exit - - displaypath=$(relative_path "$sm_path") - - # Copy url setting when it is not set yet - if test -z "$(git config "submodule.$name.url")" - then - url=$(git config -f .gitmodules submodule."$name".url) - test -z "$url" && - die "$(eval_gettext "No url found for submodule path '\$displaypath' in .gitmodules")" - - # Possibly a url relative to parent - case "$url" in - ./*|../*) - url=$(resolve_relative_url "$url") || exit - ;; - esac - git config submodule."$name".url "$url" || - die "$(eval_gettext "Failed to register url for submodule path '\$displaypath'")" - - say "$(eval_gettext "Submodule '\$name' (\$url) registered for path '\$displaypath'")" - fi - - # Copy "update" setting when it is not set yet - if upd="$(git config -f .gitmodules submodule."$name".update)" && - test -n "$upd" && - test -z "$(git config submodule."$name".update)" - then - case "$upd" in - checkout | rebase | merge | none) - ;; # known modes of updating - *) - echo >&2 "warning: unknown update mode '$upd' suggested for submodule '$name'" - upd=none - ;; - esac - git config submodule."$name".update "$upd" || - die "$(eval_gettext "Failed to register update mode for submodule path '\$displaypath'")" - fi - done + git ${wt_prefix:+-C "$wt_prefix"} submodule--helper init ${GIT_QUIET:+--quiet} ${prefix:+--prefix "$prefix"} "$@" } # @@ -531,6 +416,7 @@ cmd_init() cmd_deinit() { # parse $args after "submodule ... deinit". + deinit_all= while test $# -ne 0 do case "$1" in @@ -540,6 +426,9 @@ cmd_deinit() -q|--quiet) GIT_QUIET=1 ;; + --all) + deinit_all=t + ;; --) shift break @@ -554,9 +443,14 @@ cmd_deinit() shift done - if test $# = 0 + if test -n "$deinit_all" && test "$#" -ne 0 + then + echo >&2 "$(eval_gettext "pathspec and --all are incompatible")" + usage + fi + if test $# = 0 && test -z "$deinit_all" then - die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")" + die "$(eval_gettext "Use '--all' if you really want to deinitialize all submodules")" fi git submodule--helper list --prefix "$wt_prefix" "$@" | @@ -800,8 +694,8 @@ cmd_update() ;; !*) command="${update_module#!}" - die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$prefix\$sm_path'")" - say_msg="$(eval_gettext "Submodule path '\$prefix\$sm_path': '\$command \$sha1'")" + die_msg="$(eval_gettext "Execution of '\$command \$sha1' failed in submodule path '\$displaypath'")" + say_msg="$(eval_gettext "Submodule path '\$displaypath': '\$command \$sha1'")" must_die_on_failure=yes ;; *) @@ -823,7 +717,8 @@ cmd_update() if test -n "$recursive" then ( - prefix="$prefix$sm_path/" + prefix=$(relative_path "$prefix$sm_path/") + wt_prefix= sanitize_submodule_env cd "$sm_path" && eval cmd_update @@ -1157,6 +1052,7 @@ cmd_status() ( prefix="$displaypath/" sanitize_submodule_env + wt_prefix= cd "$sm_path" && eval cmd_status ) || @@ -1211,9 +1107,9 @@ cmd_sync() # guarantee a trailing / up_path=${up_path%/}/ && # path from submodule work tree to submodule origin repo - sub_origin_url=$(resolve_relative_url "$url" "$up_path") && + sub_origin_url=$(git submodule--helper resolve-relative-url "$url" "$up_path") && # path from superproject work tree to submodule origin repo - super_config_url=$(resolve_relative_url "$url") || exit + super_config_url=$(git submodule--helper resolve-relative-url "$url") || exit ;; *) sub_origin_url="$url" diff --git a/git.spec.in b/git.spec.in deleted file mode 100644 index bfd1cfb63f..0000000000 --- a/git.spec.in +++ /dev/null @@ -1,330 +0,0 @@ -# Pass --without docs to rpmbuild if you don't want the documentation - -Name: git -Version: @@VERSION@@ -Release: 1%{?dist} -Summary: Core git tools -License: GPL -Group: Development/Tools -URL: http://kernel.org/pub/software/scm/git/ -Source: http://kernel.org/pub/software/scm/git/%{name}-%{version}.tar.gz -BuildRequires: zlib-devel >= 1.2, openssl-devel, curl-devel, expat-devel, gettext %{!?_without_docs:, xmlto, asciidoc > 6.0.3} -BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) - -Requires: perl-Git = %{version}-%{release} -Requires: zlib >= 1.2, rsync, less, openssh-clients, expat -Provides: git-core = %{version}-%{release} -Obsoletes: git-core <= 1.5.4.2 -Obsoletes: git-p4 - -%description -Git is a fast, scalable, distributed revision control system with an -unusually rich command set that provides both high-level operations -and full access to internals. - -The git rpm installs the core tools with minimal dependencies. To -install all git packages, including tools for integrating with other -SCMs, install the git-all meta-package. - -%package all -Summary: Meta-package to pull in all git tools -Group: Development/Tools -Requires: git = %{version}-%{release} -Requires: git-svn = %{version}-%{release} -Requires: git-cvs = %{version}-%{release} -Requires: git-arch = %{version}-%{release} -Requires: git-email = %{version}-%{release} -Requires: gitk = %{version}-%{release} -Requires: gitweb = %{version}-%{release} -Requires: git-gui = %{version}-%{release} -Obsoletes: git <= 1.5.4.2 - -%description all -Git is a fast, scalable, distributed revision control system with an -unusually rich command set that provides both high-level operations -and full access to internals. - -This is a dummy package which brings in all subpackages. - -%package svn -Summary: Git tools for importing Subversion repositories -Group: Development/Tools -Requires: git = %{version}-%{release}, subversion -%description svn -Git tools for importing Subversion repositories. - -%package cvs -Summary: Git tools for importing CVS repositories -Group: Development/Tools -Requires: git = %{version}-%{release}, cvs, cvsps -%description cvs -Git tools for importing CVS repositories. - -%package arch -Summary: Git tools for importing Arch repositories -Group: Development/Tools -Requires: git = %{version}-%{release}, tla -%description arch -Git tools for importing Arch repositories. - -%package email -Summary: Git tools for sending email -Group: Development/Tools -Requires: git = %{version}-%{release} -%description email -Git tools for sending email. - -%package gui -Summary: Git GUI tool -Group: Development/Tools -Requires: git = %{version}-%{release}, tk >= 8.4 -%description gui -Git GUI tool - -%package -n gitk -Summary: Git revision tree visualiser ('gitk') -Group: Development/Tools -Requires: git = %{version}-%{release}, tk >= 8.4 -%description -n gitk -Git revision tree visualiser ('gitk') - -%package -n gitweb -Summary: Git web interface -Group: Development/Tools -Requires: git = %{version}-%{release} -%description -n gitweb -Browsing git repository on the web - -%package -n perl-Git -Summary: Perl interface to Git -Group: Development/Libraries -Requires: git = %{version}-%{release} -Requires: perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version)) -BuildRequires: perl(Error) -BuildRequires: perl(ExtUtils::MakeMaker) - -%description -n perl-Git -Perl interface to Git - -%define path_settings ETC_GITCONFIG=/etc/gitconfig prefix=%{_prefix} mandir=%{_mandir} htmldir=%{_docdir}/%{name}-%{version} -%{!?python_sitelib: %global python_sitelib %(%{__python} -c "from distutils.sysconfig import get_python_lib; print get_python_lib()")} - -%prep -%setup -q - -%build -make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" \ - %{path_settings} \ - all %{!?_without_docs: doc} - -%install -rm -rf $RPM_BUILD_ROOT -make %{_smp_mflags} CFLAGS="$RPM_OPT_FLAGS" DESTDIR=$RPM_BUILD_ROOT \ - %{path_settings} \ - INSTALLDIRS=vendor install %{!?_without_docs: install-doc} -test ! -d $RPM_BUILD_ROOT%{python_sitelib} || rm -fr $RPM_BUILD_ROOT%{python_sitelib} -find $RPM_BUILD_ROOT -type f -name .packlist -exec rm -f {} ';' -find $RPM_BUILD_ROOT -type f -name '*.bs' -empty -exec rm -f {} ';' -find $RPM_BUILD_ROOT -type f -name perllocal.pod -exec rm -f {} ';' - -(find $RPM_BUILD_ROOT%{_bindir} -type f | grep -vE "archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) > bin-man-doc-files -(find $RPM_BUILD_ROOT%{_libexecdir}/git-core -type f | grep -vE "archimport|svn|cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@) >> bin-man-doc-files -(find $RPM_BUILD_ROOT%{perl_vendorlib} -type f | sed -e s@^$RPM_BUILD_ROOT@@) >> perl-files -%if %{!?_without_docs:1}0 -(find $RPM_BUILD_ROOT%{_mandir} $RPM_BUILD_ROOT/Documentation -type f | grep -vE "archimport|svn|git-cvs|email|gitk|git-gui|git-citool" | sed -e s@^$RPM_BUILD_ROOT@@ -e 's/$/*/' ) >> bin-man-doc-files -%else -rm -rf $RPM_BUILD_ROOT%{_mandir} -%endif -rm -rf $RPM_BUILD_ROOT%{_datadir}/locale - -mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d -install -m 644 -T contrib/completion/git-completion.bash $RPM_BUILD_ROOT%{_sysconfdir}/bash_completion.d/git - -%clean -rm -rf $RPM_BUILD_ROOT - -%files -f bin-man-doc-files -%defattr(-,root,root) -%{_datadir}/git-core/ -%doc README.md COPYING Documentation/*.txt -%{!?_without_docs: %doc Documentation/*.html Documentation/howto} -%{!?_without_docs: %doc Documentation/technical} -%{_sysconfdir}/bash_completion.d - -%files svn -%defattr(-,root,root) -%{_libexecdir}/git-core/*svn* -%doc Documentation/*svn*.txt -%{!?_without_docs: %{_mandir}/man1/*svn*.1*} -%{!?_without_docs: %doc Documentation/*svn*.html } - -%files cvs -%defattr(-,root,root) -%doc Documentation/*git-cvs*.txt -%{_bindir}/git-cvsserver -%{_libexecdir}/git-core/*cvs* -%{!?_without_docs: %{_mandir}/man1/*cvs*.1*} -%{!?_without_docs: %doc Documentation/*git-cvs*.html } - -%files arch -%defattr(-,root,root) -%doc Documentation/git-archimport.txt -%{_libexecdir}/git-core/git-archimport -%{!?_without_docs: %{_mandir}/man1/git-archimport.1*} -%{!?_without_docs: %doc Documentation/git-archimport.html } - -%files email -%defattr(-,root,root) -%doc Documentation/*email*.txt -%{_libexecdir}/git-core/*email* -%{!?_without_docs: %{_mandir}/man1/*email*.1*} -%{!?_without_docs: %doc Documentation/*email*.html } - -%files gui -%defattr(-,root,root) -%{_libexecdir}/git-core/git-gui -%{_libexecdir}/git-core/git-citool -%{_libexecdir}/git-core/git-gui--askpass -%{_datadir}/git-gui/ -%{!?_without_docs: %{_mandir}/man1/git-gui.1*} -%{!?_without_docs: %doc Documentation/git-gui.html} -%{!?_without_docs: %{_mandir}/man1/git-citool.1*} -%{!?_without_docs: %doc Documentation/git-citool.html} - -%files -n gitk -%defattr(-,root,root) -%doc Documentation/*gitk*.txt -%{_bindir}/*gitk* -%{_datadir}/gitk/ -%{!?_without_docs: %{_mandir}/man1/*gitk*.1*} -%{!?_without_docs: %doc Documentation/*gitk*.html } - -%files -n gitweb -%defattr(-,root,root) -%doc gitweb/README gitweb/INSTALL Documentation/*gitweb*.txt -%{_datadir}/gitweb -%{!?_without_docs: %{_mandir}/man1/*gitweb*.1*} -%{!?_without_docs: %{_mandir}/man5/*gitweb*.5*} -%{!?_without_docs: %doc Documentation/*gitweb*.html } - -%files -n perl-Git -f perl-files -%defattr(-,root,root) - -%files all -# No files for you! - -%changelog -* Sun Sep 18 2011 Jakub Narebski <jnareb@gmail.com> -- Add gitweb manpages to 'gitweb' subpackage - -* Wed Jun 30 2010 Junio C Hamano <gitster@pobox.com> -- Add 'gitweb' subpackage. - -* Fri Mar 26 2010 Ian Ward Comfort <icomfort@stanford.edu> -- Ship bash completion support from contrib/ in the core package. - -* Sun Jan 31 2010 Junio C Hamano <gitster@pobox.com> -- Do not use %define inside %{!?...} construct. - -* Sat Jan 30 2010 Junio C Hamano <gitster@pobox.com> -- We don't ship Python bits until a real foreign scm interface comes. - -* Mon Feb 04 2009 David J. Mellor <dmellor@whistlingcat.com> -- fixed broken git help -w after renaming the git-core package to git. - -* Fri Sep 12 2008 Quy Tonthat <qtonthat@gmail.com> -- move git-cvsserver to bindir. - -* Sun Jun 15 2008 Junio C Hamano <gitster@pobox.com> -- Remove curl from Requires list. - -* Fri Feb 15 2008 Kristian HΓΈgsberg <krh@redhat.com> -- Rename git-core to just git and rename meta package from git to git-all. - -* Sun Feb 03 2008 James Bowes <jbowes@dangerouslyinc.com> -- Add a BuildRequires for gettext - -* Fri Jan 11 2008 Junio C Hamano <gitster@pobox.com> -- Include gitk message files - -* Sun Jan 06 2008 James Bowes <jbowes@dangerouslyinc.com> -- Make the metapackage require the same version of the subpackages. - -* Wed Dec 12 2007 Junio C Hamano <gitster@pobox.com> -- Adjust htmldir to point at /usr/share/doc/git-core-$version/ - -* Sun Jul 15 2007 Sean Estabrooks <seanlkml@sympatico.ca> -- Removed p4import. - -* Tue Jun 26 2007 Quy Tonthat <qtonthat@gmail.com> -- Fixed problems looking for wrong manpages. - -* Thu Jun 21 2007 Shawn O. Pearce <spearce@spearce.org> -- Added documentation files for git-gui - -* Tue May 13 2007 Quy Tonthat <qtonthat@gmail.com> -- Added lib files for git-gui -- Added Documentation/technical (As needed by Git Users Manual) - -* Tue May 8 2007 Quy Tonthat <qtonthat@gmail.com> -- Added howto files - -* Tue Mar 27 2007 Eygene Ryabinkin <rea-git@codelabs.ru> -- Added the git-p4 package: Perforce import stuff. - -* Mon Feb 13 2007 Nicolas Pitre <nico@fluxnic.net> -- Update core package description (Git isn't as stupid as it used to be) - -* Mon Feb 12 2007 Junio C Hamano <junkio@cox.net> -- Add git-gui and git-citool. - -* Mon Nov 14 2005 H. Peter Anvin <hpa@zytor.com> 0.99.9j-1 -- Change subpackage names to git-<name> instead of git-core-<name> -- Create empty root package which brings in all subpackages -- Rename git-tk -> gitk - -* Thu Nov 10 2005 Chris Wright <chrisw@osdl.org> 0.99.9g-1 -- zlib dependency fix -- Minor cleanups from split -- Move arch import to separate package as well - -* Tue Sep 27 2005 Jim Radford <radford@blackbean.org> -- Move programs with non-standard dependencies (svn, cvs, email) - into separate packages - -* Tue Sep 27 2005 H. Peter Anvin <hpa@zytor.com> -- parallelize build -- COPTS -> CFLAGS - -* Fri Sep 16 2005 Chris Wright <chrisw@osdl.org> 0.99.6-1 -- update to 0.99.6 - -* Fri Sep 16 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl> -- Linus noticed that less is required, added to the dependencies - -* Sun Sep 11 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl> -- Updated dependencies -- Don't assume manpages are gzipped - -* Thu Aug 18 2005 Chris Wright <chrisw@osdl.org> 0.99.4-4 -- drop sh_utils, sh-utils, diffutils, mktemp, and openssl Requires -- use RPM_OPT_FLAGS in spec file, drop patch0 - -* Wed Aug 17 2005 Tom "spot" Callaway <tcallawa@redhat.com> 0.99.4-3 -- use dist tag to differentiate between branches -- use rpm optflags by default (patch0) -- own %{_datadir}/git-core/ - -* Mon Aug 15 2005 Chris Wright <chrisw@osdl.org> -- update spec file to fix Buildroot, Requires, and drop Vendor - -* Sun Aug 07 2005 Horst H. von Brand <vonbrand@inf.utfsm.cl> -- Redid the description -- Cut overlong make line, loosened changelog a bit -- I think Junio (or perhaps OSDL?) should be vendor... - -* Thu Jul 14 2005 Eric Biederman <ebiederm@xmission.com> -- Add the man pages, and the --without docs build option - -* Wed Jul 7 2005 Chris Wright <chris@osdl.org> -- initial git spec file diff --git a/gitweb/gitweb.perl b/gitweb/gitweb.perl index 05d7910b7c..2fddf750fa 100755 --- a/gitweb/gitweb.perl +++ b/gitweb/gitweb.perl @@ -3935,6 +3935,9 @@ sub run_highlighter { close $fd; open $fd, quote_command(git_cmd(), "cat-file", "blob", $hash)." | ". + quote_command($^X, '-CO', '-MEncode=decode,FB_DEFAULT', '-pse', + '$_ = decode($fe, $_, FB_DEFAULT) if !utf8::decode($_);', + '--', "-fe=$fallback_encoding")." | ". quote_command($highlight_bin). " --replace-tabs=8 --fragment --syntax $syntax |" or die_error(500, "Couldn't open file or run syntax highlighter"); diff --git a/gpg-interface.c b/gpg-interface.c index 3dc2fe397e..c4b1e8c78d 100644 --- a/gpg-interface.c +++ b/gpg-interface.c @@ -219,11 +219,9 @@ int verify_signed_buffer(const char *payload, size_t payload_size, args_gpg[0] = gpg_program; fd = git_mkstemp(path, PATH_MAX, ".git_vtag_tmpXXXXXX"); if (fd < 0) - return error(_("could not create temporary file '%s': %s"), - path, strerror(errno)); + return error_errno(_("could not create temporary file '%s'"), path); if (write_in_full(fd, signature, signature_size) < 0) - return error(_("failed writing detached signature to '%s': %s"), - path, strerror(errno)); + return error_errno(_("failed writing detached signature to '%s'"), path); close(fd); gpg.argv = args_gpg; @@ -237,6 +235,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size, return error(_("could not run gpg.")); } + sigchain_push(SIGPIPE, SIG_IGN); write_in_full(gpg.in, payload, payload_size); close(gpg.in); @@ -250,6 +249,7 @@ int verify_signed_buffer(const char *payload, size_t payload_size, close(gpg.out); ret = finish_command(&gpg); + sigchain_pop(SIGPIPE); unlink_or_warn(path); @@ -1732,7 +1732,7 @@ static int grep_source_load_file(struct grep_source *gs) if (lstat(filename, &st) < 0) { err_ret: if (errno != ENOENT) - error(_("'%s': %s"), filename, strerror(errno)); + error_errno(_("failed to stat '%s'"), filename); return -1; } if (!S_ISREG(st.st_mode)) @@ -1743,7 +1743,7 @@ static int grep_source_load_file(struct grep_source *gs) goto err_ret; data = xmallocz(size); if (st.st_size != read_in_full(i, data, size)) { - error(_("'%s': short read %s"), filename, strerror(errno)); + error_errno(_("'%s': short read"), filename); close(i); free(data); return -1; diff --git a/http-backend.c b/http-backend.c index 8870a2681e..214881459d 100644 --- a/http-backend.c +++ b/http-backend.c @@ -484,9 +484,9 @@ static int show_head_ref(const char *refname, const struct object_id *oid, const char *target = resolve_ref_unsafe(refname, RESOLVE_REF_READING, unused.hash, NULL); - const char *target_nons = strip_namespace(target); - strbuf_addf(buf, "ref: %s\n", target_nons); + if (target) + strbuf_addf(buf, "ref: %s\n", strip_namespace(target)); } else { strbuf_addf(buf, "%s\n", oid_to_hex(oid)); } diff --git a/http-push.c b/http-push.c index bd60668707..a092f0288b 100644 --- a/http-push.c +++ b/http-push.c @@ -211,7 +211,7 @@ static void curl_setup_http(CURL *curl, const char *url, static struct curl_slist *get_dav_token_headers(struct remote_lock *lock, enum dav_header_flag options) { struct strbuf buf = STRBUF_INIT; - struct curl_slist *dav_headers = NULL; + struct curl_slist *dav_headers = http_copy_default_headers(); if (options & DAV_HEADER_IF) { strbuf_addf(&buf, "If: (<%s>)", lock->token); @@ -417,7 +417,7 @@ static void start_put(struct transfer_request *request) static void start_move(struct transfer_request *request) { struct active_request_slot *slot; - struct curl_slist *dav_headers = NULL; + struct curl_slist *dav_headers = http_copy_default_headers(); slot = get_active_slot(); slot->callback_func = process_response; @@ -845,7 +845,7 @@ static struct remote_lock *lock_remote(const char *path, long timeout) char *ep; char timeout_header[25]; struct remote_lock *lock = NULL; - struct curl_slist *dav_headers = NULL; + struct curl_slist *dav_headers = http_copy_default_headers(); struct xml_ctx ctx; char *escaped; @@ -1126,7 +1126,7 @@ static void remote_ls(const char *path, int flags, struct slot_results results; struct strbuf in_buffer = STRBUF_INIT; struct buffer out_buffer = { STRBUF_INIT, 0 }; - struct curl_slist *dav_headers = NULL; + struct curl_slist *dav_headers = http_copy_default_headers(); struct xml_ctx ctx; struct remote_ls_ctx ls; @@ -1204,7 +1204,7 @@ static int locking_available(void) struct slot_results results; struct strbuf in_buffer = STRBUF_INIT; struct buffer out_buffer = { STRBUF_INIT, 0 }; - struct curl_slist *dav_headers = NULL; + struct curl_slist *dav_headers = http_copy_default_headers(); struct xml_ctx ctx; int lock_flags = 0; char *escaped; @@ -1312,10 +1312,10 @@ static struct object_list **process_tree(struct tree *tree, while (tree_entry(&desc, &entry)) switch (object_type(entry.mode)) { case OBJ_TREE: - p = process_tree(lookup_tree(entry.sha1), p); + p = process_tree(lookup_tree(entry.oid->hash), p); break; case OBJ_BLOB: - p = process_blob(lookup_blob(entry.sha1), p); + p = process_blob(lookup_blob(entry.oid->hash), p); break; default: /* Subproject commit - not in this repository */ @@ -114,6 +114,7 @@ static unsigned long http_auth_methods = CURLAUTH_ANY; static struct curl_slist *pragma_header; static struct curl_slist *no_pragma_header; +static struct curl_slist *extra_http_headers; static struct active_request_slot *active_queue_head; @@ -293,7 +294,7 @@ static int http_options(const char *var, const char *value, void *cb) return git_config_string(&http_proxy_authmethod, var, value); if (!strcmp("http.cookiefile", var)) - return git_config_string(&curl_cookie_file, var, value); + return git_config_pathname(&curl_cookie_file, var, value); if (!strcmp("http.savecookies", var)) { curl_save_cookies = git_config_bool(var, value); return 0; @@ -323,6 +324,19 @@ static int http_options(const char *var, const char *value, void *cb) #endif } + if (!strcmp("http.extraheader", var)) { + if (!value) { + return config_error_nonbool(var); + } else if (!*value) { + curl_slist_free_all(extra_http_headers); + extra_http_headers = NULL; + } else { + extra_http_headers = + curl_slist_append(extra_http_headers, value); + } + return 0; + } + /* Fall back on the default ones */ return git_default_config(var, value, cb); } @@ -446,8 +460,7 @@ static int sockopt_callback(void *client, curl_socket_t fd, curlsocktype type) rc = setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, (void *)&ka, len); if (rc < 0) - warning("unable to set SO_KEEPALIVE on socket %s", - strerror(errno)); + warning_errno("unable to set SO_KEEPALIVE on socket"); return 0; /* CURL_SOCKOPT_OK only exists since curl 7.21.5 */ } @@ -678,8 +691,10 @@ void http_init(struct remote *remote, const char *url, int proactive_auth) if (remote) var_override(&http_proxy_authmethod, remote->http_proxy_authmethod); - pragma_header = curl_slist_append(pragma_header, "Pragma: no-cache"); - no_pragma_header = curl_slist_append(no_pragma_header, "Pragma:"); + pragma_header = curl_slist_append(http_copy_default_headers(), + "Pragma: no-cache"); + no_pragma_header = curl_slist_append(http_copy_default_headers(), + "Pragma:"); #ifdef USE_CURL_MULTI { @@ -765,6 +780,9 @@ void http_cleanup(void) #endif curl_global_cleanup(); + curl_slist_free_all(extra_http_headers); + extra_http_headers = NULL; + curl_slist_free_all(pragma_header); pragma_header = NULL; @@ -1163,6 +1181,16 @@ int run_one_slot(struct active_request_slot *slot, return handle_curl_result(results); } +struct curl_slist *http_copy_default_headers(void) +{ + struct curl_slist *headers = NULL, *h; + + for (h = extra_http_headers; h; h = h->next) + headers = curl_slist_append(headers, h->data); + + return headers; +} + static CURLcode curlinfo_strbuf(CURL *curl, CURLINFO info, struct strbuf *buf) { char *ptr; @@ -1380,7 +1408,7 @@ static int http_request(const char *url, { struct active_request_slot *slot; struct slot_results results; - struct curl_slist *headers = NULL; + struct curl_slist *headers = http_copy_default_headers(); struct strbuf buf = STRBUF_INIT; const char *accept_language; int ret; @@ -1894,8 +1922,7 @@ struct http_object_request *new_http_object_request(const char *base_url, } if (freq->localfile < 0) { - error("Couldn't create temporary file %s: %s", - freq->tmpfile, strerror(errno)); + error_errno("Couldn't create temporary file %s", freq->tmpfile); goto abort; } @@ -1940,8 +1967,8 @@ struct http_object_request *new_http_object_request(const char *base_url, prev_posn = 0; lseek(freq->localfile, 0, SEEK_SET); if (ftruncate(freq->localfile, 0) < 0) { - error("Couldn't truncate temporary file %s: %s", - freq->tmpfile, strerror(errno)); + error_errno("Couldn't truncate temporary file %s", + freq->tmpfile); goto abort; } } @@ -106,6 +106,7 @@ extern void step_active_slots(void); extern void http_init(struct remote *remote, const char *url, int proactive_auth); extern void http_cleanup(void); +extern struct curl_slist *http_copy_default_headers(void); extern long int git_curl_ipresolve; extern int active_requests; @@ -75,14 +75,12 @@ static int add_mailname_host(struct strbuf *buf) mailname = fopen("/etc/mailname", "r"); if (!mailname) { if (errno != ENOENT) - warning("cannot open /etc/mailname: %s", - strerror(errno)); + warning_errno("cannot open /etc/mailname"); return -1; } if (strbuf_getline(&mailnamebuf, mailname) == EOF) { if (ferror(mailname)) - warning("cannot read /etc/mailname: %s", - strerror(errno)); + warning_errno("cannot read /etc/mailname"); strbuf_release(&mailnamebuf); fclose(mailname); return -1; @@ -125,7 +123,7 @@ static void add_domainname(struct strbuf *out, int *is_bogus) char buf[1024]; if (gethostname(buf, sizeof(buf))) { - warning("cannot get host name: %s", strerror(errno)); + warning_errno("cannot get host name"); strbuf_addstr(out, "(none)"); *is_bogus = 1; return; @@ -351,15 +349,17 @@ const char *fmt_ident(const char *name, const char *email, if (want_name) { int using_default = 0; if (!name) { + if (strict && ident_use_config_only + && !(ident_config_given & IDENT_NAME_GIVEN)) { + fputs(env_hint, stderr); + die("no name was given and auto-detection is disabled"); + } name = ident_default_name(); using_default = 1; if (strict && default_name_is_bogus) { fputs(env_hint, stderr); die("unable to auto-detect name (got '%s')", name); } - if (strict && ident_use_config_only - && !(ident_config_given & IDENT_NAME_GIVEN)) - die("user.useConfigOnly set but no name given"); } if (!*name) { struct passwd *pw; @@ -374,14 +374,16 @@ const char *fmt_ident(const char *name, const char *email, } if (!email) { + if (strict && ident_use_config_only + && !(ident_config_given & IDENT_MAIL_GIVEN)) { + fputs(env_hint, stderr); + die("no email was given and auto-detection is disabled"); + } email = ident_default_email(); if (strict && default_email_is_bogus) { fputs(env_hint, stderr); die("unable to auto-detect email address (got '%s')", email); } - if (strict && ident_use_config_only - && !(ident_config_given & IDENT_MAIL_GIVEN)) - die("user.useConfigOnly set but no mail given"); } strbuf_reset(&ident); diff --git a/list-objects.c b/list-objects.c index 917cc5d7c9..f3ca6aafb7 100644 --- a/list-objects.c +++ b/list-objects.c @@ -110,16 +110,16 @@ static void process_tree(struct rev_info *revs, if (S_ISDIR(entry.mode)) process_tree(revs, - lookup_tree(entry.sha1), + lookup_tree(entry.oid->hash), show, base, entry.path, cb_data); else if (S_ISGITLINK(entry.mode)) - process_gitlink(revs, entry.sha1, + process_gitlink(revs, entry.oid->hash, show, base, entry.path, cb_data); else process_blob(revs, - lookup_blob(entry.sha1), + lookup_blob(entry.oid->hash), show, base, entry.path, cb_data); } diff --git a/ll-merge.c b/ll-merge.c index ff4a43a982..ad8be42f91 100644 --- a/ll-merge.c +++ b/ll-merge.c @@ -47,7 +47,9 @@ static int ll_binary_merge(const struct ll_merge_driver *drv_unused, assert(opts); /* - * The tentative merge result is the or common ancestor for an internal merge. + * The tentative merge result is the common ancestor for an + * internal merge. For the final merge, it is "ours" by + * default but -Xours/-Xtheirs can tweak the choice. */ if (opts->virtual_ancestor) { stolen = orig; @@ -383,8 +385,12 @@ int ll_merge(mmbuffer_t *result_buf, } } driver = find_ll_merge_driver(ll_driver_name); - if (opts->virtual_ancestor && driver->recursive) - driver = find_ll_merge_driver(driver->recursive); + + if (opts->virtual_ancestor) { + if (driver->recursive) + driver = find_ll_merge_driver(driver->recursive); + marker_size += 2; + } return driver->fn(driver, result_buf, path, ancestor, ancestor_label, ours, our_label, theirs, their_label, opts, marker_size); @@ -189,8 +189,7 @@ static int read_mailmap_file(struct string_list *map, const char *filename, if (!f) { if (errno == ENOENT) return 0; - return error("unable to open mailmap at %s: %s", - filename, strerror(errno)); + return error_errno("unable to open mailmap at %s", filename); } while (fgets(buffer, sizeof(buffer), f) != NULL) diff --git a/match-trees.c b/match-trees.c index 1ce0954a3e..396b7338df 100644 --- a/match-trees.c +++ b/match-trees.c @@ -48,17 +48,17 @@ static int score_matches(unsigned mode1, unsigned mode2, const char *path) } static void *fill_tree_desc_strict(struct tree_desc *desc, - const unsigned char *hash) + const struct object_id *hash) { void *buffer; enum object_type type; unsigned long size; - buffer = read_sha1_file(hash, &type, &size); + buffer = read_sha1_file(hash->hash, &type, &size); if (!buffer) - die("unable to read tree (%s)", sha1_to_hex(hash)); + die("unable to read tree (%s)", oid_to_hex(hash)); if (type != OBJ_TREE) - die("%s is not a tree", sha1_to_hex(hash)); + die("%s is not a tree", oid_to_hex(hash)); init_tree_desc(desc, buffer, size); return buffer; } @@ -73,7 +73,7 @@ static int base_name_entries_compare(const struct name_entry *a, /* * Inspect two trees, and give a score that tells how similar they are. */ -static int score_trees(const unsigned char *hash1, const unsigned char *hash2) +static int score_trees(const struct object_id *hash1, const struct object_id *hash2) { struct tree_desc one; struct tree_desc two; @@ -104,7 +104,7 @@ static int score_trees(const unsigned char *hash1, const unsigned char *hash2) else if (cmp > 0) /* path2 does not appear in one */ score += score_missing(e2.mode, e2.path); - else if (hashcmp(e1.sha1, e2.sha1)) + else if (oidcmp(e1.oid, e2.oid)) /* they are different */ score += score_differs(e1.mode, e2.mode, e1.path); else @@ -119,8 +119,8 @@ static int score_trees(const unsigned char *hash1, const unsigned char *hash2) /* * Match one itself and its subtrees with two and pick the best match. */ -static void match_trees(const unsigned char *hash1, - const unsigned char *hash2, +static void match_trees(const struct object_id *hash1, + const struct object_id *hash2, int *best_score, char **best_match, const char *base, @@ -131,7 +131,7 @@ static void match_trees(const unsigned char *hash1, while (one.size) { const char *path; - const unsigned char *elem; + const struct object_id *elem; unsigned mode; int score; @@ -191,15 +191,15 @@ static int splice_tree(const unsigned char *hash1, while (desc.size) { const char *name; unsigned mode; - const unsigned char *sha1; + const struct object_id *oid; - sha1 = tree_entry_extract(&desc, &name, &mode); + oid = tree_entry_extract(&desc, &name, &mode); if (strlen(name) == toplen && !memcmp(name, prefix, toplen)) { if (!S_ISDIR(mode)) die("entry %s in tree %s is not a tree", name, sha1_to_hex(hash1)); - rewrite_here = (unsigned char *) sha1; + rewrite_here = (unsigned char *) oid->hash; break; } update_tree_entry(&desc); @@ -229,9 +229,9 @@ static int splice_tree(const unsigned char *hash1, * other hand, it could cover tree one and we might need to pick a * subtree of it. */ -void shift_tree(const unsigned char *hash1, - const unsigned char *hash2, - unsigned char *shifted, +void shift_tree(const struct object_id *hash1, + const struct object_id *hash2, + struct object_id *shifted, int depth_limit) { char *add_prefix; @@ -262,7 +262,7 @@ void shift_tree(const unsigned char *hash1, match_trees(hash2, hash1, &del_score, &del_prefix, "", depth_limit); /* Assume we do not have to do any shifting */ - hashcpy(shifted, hash2); + oidcpy(shifted, hash2); if (add_score < del_score) { /* We need to pick a subtree of two */ @@ -271,16 +271,16 @@ void shift_tree(const unsigned char *hash1, if (!*del_prefix) return; - if (get_tree_entry(hash2, del_prefix, shifted, &mode)) + if (get_tree_entry(hash2->hash, del_prefix, shifted->hash, &mode)) die("cannot find path %s in tree %s", - del_prefix, sha1_to_hex(hash2)); + del_prefix, oid_to_hex(hash2)); return; } if (!*add_prefix) return; - splice_tree(hash1, add_prefix, hash2, shifted); + splice_tree(hash1->hash, add_prefix, hash2->hash, shifted->hash); } /* @@ -288,22 +288,22 @@ void shift_tree(const unsigned char *hash1, * Unfortunately we cannot fundamentally tell which one to * be prefixed, as recursive merge can work in either direction. */ -void shift_tree_by(const unsigned char *hash1, - const unsigned char *hash2, - unsigned char *shifted, +void shift_tree_by(const struct object_id *hash1, + const struct object_id *hash2, + struct object_id *shifted, const char *shift_prefix) { - unsigned char sub1[20], sub2[20]; + struct object_id sub1, sub2; unsigned mode1, mode2; unsigned candidate = 0; /* Can hash2 be a tree at shift_prefix in tree hash1? */ - if (!get_tree_entry(hash1, shift_prefix, sub1, &mode1) && + if (!get_tree_entry(hash1->hash, shift_prefix, sub1.hash, &mode1) && S_ISDIR(mode1)) candidate |= 1; /* Can hash1 be a tree at shift_prefix in tree hash2? */ - if (!get_tree_entry(hash2, shift_prefix, sub2, &mode2) && + if (!get_tree_entry(hash2->hash, shift_prefix, sub2.hash, &mode2) && S_ISDIR(mode2)) candidate |= 2; @@ -313,19 +313,19 @@ void shift_tree_by(const unsigned char *hash1, int score; candidate = 0; - score = score_trees(sub1, hash2); + score = score_trees(&sub1, hash2); if (score > best_score) { candidate = 1; best_score = score; } - score = score_trees(sub2, hash1); + score = score_trees(&sub2, hash1); if (score > best_score) candidate = 2; } if (!candidate) { /* Neither is plausible -- do not shift */ - hashcpy(shifted, hash2); + oidcpy(shifted, hash2); return; } @@ -334,11 +334,11 @@ void shift_tree_by(const unsigned char *hash1, * shift tree2 down by adding shift_prefix above it * to match tree1. */ - splice_tree(hash1, shift_prefix, hash2, shifted); + splice_tree(hash1->hash, shift_prefix, hash2->hash, shifted->hash); else /* * shift tree2 up by removing shift_prefix from it * to match tree1. */ - hashcpy(shifted, sub2); + oidcpy(shifted, &sub2); } diff --git a/merge-recursive.c b/merge-recursive.c index b880ae50e7..65cb5d6c1f 100644 --- a/merge-recursive.c +++ b/merge-recursive.c @@ -29,9 +29,9 @@ static struct tree *shift_tree_object(struct tree *one, struct tree *two, struct object_id shifted; if (!*subtree_shift) { - shift_tree(one->object.oid.hash, two->object.oid.hash, shifted.hash, 0); + shift_tree(&one->object.oid, &two->object.oid, &shifted, 0); } else { - shift_tree_by(one->object.oid.hash, two->object.oid.hash, shifted.hash, + shift_tree_by(&one->object.oid, &two->object.oid, &shifted, subtree_shift); } if (!oidcmp(&two->object.oid, &shifted)) @@ -622,7 +622,7 @@ static char *unique_path(struct merge_options *o, const char *path, const char * base_len = newpath.len; while (string_list_has_string(&o->current_file_set, newpath.buf) || string_list_has_string(&o->current_directory_set, newpath.buf) || - file_exists(newpath.buf)) { + (!o->call_depth && file_exists(newpath.buf))) { strbuf_setlen(&newpath, base_len); strbuf_addf(&newpath, "_%d", suffix++); } @@ -1234,8 +1234,8 @@ static void conflict_rename_rename_2to1(struct merge_options *o, a->path, c1->path, ci->branch1, b->path, c2->path, ci->branch2); - remove_file(o, 1, a->path, would_lose_untracked(a->path)); - remove_file(o, 1, b->path, would_lose_untracked(b->path)); + remove_file(o, 1, a->path, o->call_depth || would_lose_untracked(a->path)); + remove_file(o, 1, b->path, o->call_depth || would_lose_untracked(b->path)); mfi_c1 = merge_file_special_markers(o, a, c1, &ci->ren1_other, o->branch1, c1->path, @@ -1773,8 +1773,6 @@ static int process_entry(struct merge_options *o, output(o, 1, _("CONFLICT (%s): There is a directory with name %s in %s. " "Adding %s as %s"), conf, path, other_branch, path, new_path); - if (o->call_depth) - remove_file_from_cache(path); update_file(o, 0, sha, mode, new_path); if (o->call_depth) remove_file_from_cache(path); @@ -446,7 +446,7 @@ static void load_subtree(struct notes_tree *t, struct leaf_node *subtree, l = (struct leaf_node *) xcalloc(1, sizeof(struct leaf_node)); hashcpy(l->key_sha1, object_sha1); - hashcpy(l->val_sha1, entry.sha1); + hashcpy(l->val_sha1, entry.oid->hash); if (len < 20) { if (!S_ISDIR(entry.mode) || path_len != 2) goto handle_non_note; /* not subtree */ @@ -493,7 +493,7 @@ handle_non_note: } strbuf_addstr(&non_note_path, entry.path); add_non_note(t, strbuf_detach(&non_note_path, NULL), - entry.mode, entry.sha1); + entry.mode, entry.oid->hash); } } free(buf); diff --git a/parse-options.c b/parse-options.c index 47a9192060..312a85dbde 100644 --- a/parse-options.c +++ b/parse-options.c @@ -110,6 +110,8 @@ static int get_value(struct parse_opt_ctx_t *p, return 0; case OPTION_COUNTUP: + if (*(int *)opt->value < 0) + *(int *)opt->value = 0; *(int *)opt->value = unset ? 0 : *(int *)opt->value + 1; return 0; diff --git a/patch-ids.c b/patch-ids.c index b7b3e5a1a7..a4d0016664 100644 --- a/patch-ids.c +++ b/patch-ids.c @@ -4,7 +4,7 @@ #include "sha1-lookup.h" #include "patch-ids.h" -static int commit_patch_id(struct commit *commit, struct diff_options *options, +int commit_patch_id(struct commit *commit, struct diff_options *options, unsigned char *sha1) { if (commit->parents) diff --git a/patch-ids.h b/patch-ids.h index c8c7ca110a..eeb56b307f 100644 --- a/patch-ids.h +++ b/patch-ids.h @@ -13,6 +13,8 @@ struct patch_ids { struct patch_id_bucket *patches; }; +int commit_patch_id(struct commit *commit, struct diff_options *options, + unsigned char *sha1); int init_patch_ids(struct patch_ids *); int free_patch_ids(struct patch_ids *); struct patch_id *add_commit_patch_id(struct commit *, struct patch_ids *); @@ -5,6 +5,7 @@ #include "strbuf.h" #include "string-list.h" #include "dir.h" +#include "worktree.h" static int get_st_mode_bits(const char *path, int *mode) { @@ -134,7 +135,7 @@ static struct common_dir common_list[] = { * definite * definition * - * The trie would look look like: + * The trie would look like: * root: len = 0, children a and d non-NULL, value = NULL. * a: len = 2, contents = bc, value = (data for "abc") * d: len = 2, contents = ef, children i non-NULL, value = (data for "def") @@ -383,10 +384,11 @@ static void adjust_git_path(struct strbuf *buf, int git_dir_len) update_common_dir(buf, git_dir_len, NULL); } -static void do_git_path(struct strbuf *buf, const char *fmt, va_list args) +static void do_git_path(const struct worktree *wt, struct strbuf *buf, + const char *fmt, va_list args) { int gitdir_len; - strbuf_addstr(buf, get_git_dir()); + strbuf_addstr(buf, get_worktree_git_dir(wt)); if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) strbuf_addch(buf, '/'); gitdir_len = buf->len; @@ -400,7 +402,7 @@ char *git_path_buf(struct strbuf *buf, const char *fmt, ...) va_list args; strbuf_reset(buf); va_start(args, fmt); - do_git_path(buf, fmt, args); + do_git_path(NULL, buf, fmt, args); va_end(args); return buf->buf; } @@ -409,7 +411,7 @@ void strbuf_git_path(struct strbuf *sb, const char *fmt, ...) { va_list args; va_start(args, fmt); - do_git_path(sb, fmt, args); + do_git_path(NULL, sb, fmt, args); va_end(args); } @@ -418,7 +420,7 @@ const char *git_path(const char *fmt, ...) struct strbuf *pathname = get_pathname(); va_list args; va_start(args, fmt); - do_git_path(pathname, fmt, args); + do_git_path(NULL, pathname, fmt, args); va_end(args); return pathname->buf; } @@ -428,7 +430,7 @@ char *git_pathdup(const char *fmt, ...) struct strbuf path = STRBUF_INIT; va_list args; va_start(args, fmt); - do_git_path(&path, fmt, args); + do_git_path(NULL, &path, fmt, args); va_end(args); return strbuf_detach(&path, NULL); } @@ -454,6 +456,16 @@ const char *mkpath(const char *fmt, ...) return cleanup_path(pathname->buf); } +const char *worktree_git_path(const struct worktree *wt, const char *fmt, ...) +{ + struct strbuf *pathname = get_pathname(); + va_list args; + va_start(args, fmt); + do_git_path(wt, pathname, fmt, args); + va_end(args); + return pathname->buf; +} + static void do_submodule_path(struct strbuf *buf, const char *path, const char *fmt, va_list args) { @@ -503,6 +515,35 @@ void strbuf_git_path_submodule(struct strbuf *buf, const char *path, va_end(args); } +static void do_git_common_path(struct strbuf *buf, + const char *fmt, + va_list args) +{ + strbuf_addstr(buf, get_git_common_dir()); + if (buf->len && !is_dir_sep(buf->buf[buf->len - 1])) + strbuf_addch(buf, '/'); + strbuf_vaddf(buf, fmt, args); + strbuf_cleanup_path(buf); +} + +const char *git_common_path(const char *fmt, ...) +{ + struct strbuf *pathname = get_pathname(); + va_list args; + va_start(args, fmt); + do_git_common_path(pathname, fmt, args); + va_end(args); + return pathname->buf; +} + +void strbuf_git_common_path(struct strbuf *sb, const char *fmt, ...) +{ + va_list args; + va_start(args, fmt); + do_git_common_path(sb, fmt, args); + va_end(args); +} + int validate_headref(const char *path) { struct stat st; diff --git a/perl/Git.pm b/perl/Git.pm index 49eb88af8d..ce7e4e8da3 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -393,7 +393,7 @@ sub command_close_pipe { Execute the given C<COMMAND> in the same way as command_output_pipe() does but return both an input pipe filehandle and an output pipe filehandle. -The function will return return C<($pid, $pipe_in, $pipe_out, $ctx)>. +The function will return C<($pid, $pipe_in, $pipe_out, $ctx)>. See C<command_close_bidi_pipe()> for details. =cut diff --git a/perl/Git/SVN.pm b/perl/Git/SVN.pm index b2c14e2ff5..d94d01cfdc 100644 --- a/perl/Git/SVN.pm +++ b/perl/Git/SVN.pm @@ -97,7 +97,8 @@ sub resolve_local_globs { "existing: $existing\n", " globbed: $refname\n"; } - my $u = (::cmt_metadata("$refname"))[0]; + my $u = (::cmt_metadata("$refname"))[0] or die + "$refname: no associated commit metadata\n"; $u =~ s!^\Q$url\E(/|$)!! or die "$refname: '$url' not found in '$u'\n"; if ($pathname ne $u) { @@ -2945,7 +2945,7 @@ msgstr "utiliser l'horodatage actuel pour la date d'auteur" #: builtin/am.c:2321 builtin/commit.c:1593 builtin/merge.c:225 #: builtin/pull.c:159 builtin/revert.c:92 builtin/tag.c:355 msgid "key-id" -msgstr "id de clΓ©" +msgstr "id-clΓ©" #: builtin/am.c:2322 msgid "GPG-sign commits" @@ -4545,7 +4545,7 @@ msgstr "style" #: builtin/checkout.c:1154 msgid "conflict style (merge or diff3)" -msgstr "style de conflit (fusion ou diff3)" +msgstr "style de conflit (merge (fusion) ou diff3)" #: builtin/checkout.c:1157 msgid "do not limit pathspecs to sparse entries only" @@ -6197,7 +6197,7 @@ msgstr "convertir en un dΓ©pΓ΄t complet" #: builtin/fetch.c:122 builtin/log.c:1236 msgid "dir" -msgstr "dir" +msgstr "rΓ©pertoire" #: builtin/fetch.c:123 msgid "prepend this to submodule path output" @@ -10809,11 +10809,11 @@ msgstr "git show-ref --exclude-existing[=<motif>]" #: builtin/show-ref.c:165 msgid "only show tags (can be combined with heads)" -msgstr "afficher seulement les Γ©tiquettes (peut Γͺtre combinΓ© avec des tΓͺtes)" +msgstr "afficher seulement les Γ©tiquettes (peut Γͺtre combinΓ© avec heads)" #: builtin/show-ref.c:166 msgid "only show heads (can be combined with tags)" -msgstr "afficher seulement les tΓͺtes (peut Γͺtre combinΓ© avec des Γ©tiquettes)" +msgstr "afficher seulement les tΓͺtes (peut Γͺtre combinΓ© avec tags)" #: builtin/show-ref.c:167 msgid "stricter reference checking, requires exact ref path" diff --git a/po/git.pot b/po/git.pot index 72ef798cde..c9be5dfebe 100644 --- a/po/git.pot +++ b/po/git.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2016-03-16 00:16+0800\n" +"POT-Creation-Date: 2016-05-24 23:42+0800\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" "Language-Team: LANGUAGE <LL@li.org>\n" @@ -29,7 +29,7 @@ msgid "" "as appropriate to mark resolution and make a commit." msgstr "" -#: advice.c:101 builtin/merge.c:1226 +#: advice.c:101 builtin/merge.c:1238 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "" @@ -71,7 +71,7 @@ msgstr "" msgid "archive format" msgstr "" -#: archive.c:430 builtin/log.c:1232 +#: archive.c:430 builtin/log.c:1395 msgid "prefix" msgstr "" @@ -79,9 +79,9 @@ msgstr "" msgid "prepend prefix to each pathname in the archive" msgstr "" -#: archive.c:432 builtin/archive.c:88 builtin/blame.c:2547 -#: builtin/blame.c:2548 builtin/config.c:60 builtin/fast-export.c:987 -#: builtin/fast-export.c:989 builtin/grep.c:720 builtin/hash-object.c:100 +#: archive.c:432 builtin/archive.c:88 builtin/blame.c:2548 +#: builtin/blame.c:2549 builtin/config.c:60 builtin/fast-export.c:987 +#: builtin/fast-export.c:989 builtin/grep.c:722 builtin/hash-object.c:100 #: builtin/ls-files.c:459 builtin/ls-files.c:462 builtin/notes.c:398 #: builtin/notes.c:561 builtin/read-tree.c:109 parse-options.h:153 msgid "file" @@ -115,7 +115,8 @@ msgstr "" msgid "list supported archive formats" msgstr "" -#: archive.c:451 builtin/archive.c:90 builtin/clone.c:78 +#: archive.c:451 builtin/archive.c:90 builtin/clone.c:82 +#: builtin/submodule--helper.c:776 msgid "repo" msgstr "" @@ -251,11 +252,16 @@ msgstr "" msgid "Not a valid branch point: '%s'." msgstr "" -#: branch.c:344 +#: branch.c:345 #, c-format msgid "'%s' is already checked out at '%s'" msgstr "" +#: branch.c:364 +#, c-format +msgid "HEAD of working tree %s is not updated" +msgstr "" + #: bundle.c:34 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -266,7 +272,7 @@ msgstr "" msgid "unrecognized header: %s%s (%d)" msgstr "" -#: bundle.c:87 builtin/commit.c:766 +#: bundle.c:87 builtin/commit.c:777 #, c-format msgid "could not open '%s'" msgstr "" @@ -275,10 +281,10 @@ msgstr "" msgid "Repository lacks these prerequisite commits:" msgstr "" -#: bundle.c:163 ref-filter.c:1462 sequencer.c:627 sequencer.c:1074 -#: builtin/blame.c:2754 builtin/commit.c:1045 builtin/log.c:334 -#: builtin/log.c:852 builtin/log.c:1467 builtin/log.c:1700 builtin/merge.c:358 -#: builtin/shortlog.c:170 +#: bundle.c:163 ref-filter.c:1462 sequencer.c:627 sequencer.c:1073 +#: builtin/blame.c:2755 builtin/commit.c:1056 builtin/log.c:340 +#: builtin/log.c:863 builtin/log.c:1308 builtin/log.c:1633 builtin/log.c:1875 +#: builtin/merge.c:361 builtin/shortlog.c:170 msgid "revision walk setup failed" msgstr "" @@ -317,21 +323,21 @@ msgstr "" msgid "ref '%s' is excluded by the rev-list options" msgstr "" -#: bundle.c:443 builtin/log.c:157 builtin/log.c:1372 builtin/shortlog.c:273 +#: bundle.c:443 builtin/log.c:163 builtin/log.c:1538 builtin/shortlog.c:273 #, c-format msgid "unrecognized argument: %s" msgstr "" -#: bundle.c:449 +#: bundle.c:451 msgid "Refusing to create empty bundle." msgstr "" -#: bundle.c:459 +#: bundle.c:463 #, c-format msgid "cannot create '%s'" msgstr "" -#: bundle.c:480 +#: bundle.c:491 msgid "index-pack died" msgstr "" @@ -340,8 +346,8 @@ msgstr "" msgid "invalid color value: %.*s" msgstr "" -#: commit.c:40 builtin/am.c:437 builtin/am.c:473 builtin/am.c:1505 -#: builtin/am.c:2135 +#: commit.c:40 builtin/am.c:437 builtin/am.c:473 builtin/am.c:1504 +#: builtin/am.c:2134 #, c-format msgid "could not parse %s" msgstr "" @@ -375,21 +381,21 @@ msgstr "" msgid "failed to expand user dir in: '%s'" msgstr "" -#: config.c:758 config.c:769 +#: config.c:761 config.c:772 #, c-format msgid "bad zlib compression level %d" msgstr "" -#: config.c:891 +#: config.c:890 #, c-format msgid "invalid mode for object creation: %s" msgstr "" -#: config.c:1220 +#: config.c:1228 msgid "unable to parse command-line config" msgstr "" -#: config.c:1281 +#: config.c:1284 msgid "unknown error occured while reading the configuration files" msgstr "" @@ -408,9 +414,14 @@ msgstr "" msgid "%s has multiple values" msgstr "" +#: config.c:2224 +#, c-format +msgid "could not set '%s' to '%s'" +msgstr "" + #: config.c:2226 #, c-format -msgid "Could not set '%s' to '%s'" +msgid "could not unset '%s'" msgstr "" #: connected.c:69 @@ -418,13 +429,11 @@ msgid "Could not run 'git rev-list'" msgstr "" #: connected.c:89 -#, c-format -msgid "failed write to rev-list: %s" +msgid "failed write to rev-list" msgstr "" -#: connected.c:97 -#, c-format -msgid "failed to close rev-list's stdin: %s" +#: connected.c:96 +msgid "failed to close rev-list's stdin" msgstr "" #: date.c:95 @@ -500,62 +509,62 @@ msgstr[1] "" msgid "failed to read orderfile '%s'" msgstr "" -#: diffcore-rename.c:536 +#: diffcore-rename.c:538 msgid "Performing inexact rename detection" msgstr "" -#: diff.c:115 +#: diff.c:116 #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr "" -#: diff.c:120 +#: diff.c:121 #, c-format msgid " Unknown dirstat parameter '%s'\n" msgstr "" -#: diff.c:215 +#: diff.c:225 #, c-format msgid "Unknown value for 'diff.submodule' config variable: '%s'" msgstr "" -#: diff.c:267 +#: diff.c:277 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" "%s" msgstr "" -#: diff.c:2997 +#: diff.c:3007 #, c-format msgid "external diff died, stopping at %s" msgstr "" -#: diff.c:3393 +#: diff.c:3405 msgid "--follow requires exactly one pathspec" msgstr "" -#: diff.c:3556 +#: diff.c:3568 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" "%s" msgstr "" -#: diff.c:3570 +#: diff.c:3582 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "" -#: dir.c:2004 +#: dir.c:1823 msgid "failed to get kernel name and information" msgstr "" -#: dir.c:2123 +#: dir.c:1942 msgid "Untracked cache is disabled on this system or location." msgstr "" -#: gpg-interface.c:166 gpg-interface.c:237 +#: gpg-interface.c:166 gpg-interface.c:235 msgid "could not run gpg." msgstr "" @@ -569,12 +578,12 @@ msgstr "" #: gpg-interface.c:222 #, c-format -msgid "could not create temporary file '%s': %s" +msgid "could not create temporary file '%s'" msgstr "" -#: gpg-interface.c:225 +#: gpg-interface.c:224 #, c-format -msgid "failed writing detached signature to '%s': %s" +msgid "failed writing detached signature to '%s'" msgstr "" #: grep.c:1718 @@ -582,14 +591,14 @@ msgstr "" msgid "'%s': unable to read %s" msgstr "" -#: grep.c:1735 +#: grep.c:1735 builtin/clone.c:382 builtin/diff.c:84 builtin/rm.c:155 #, c-format -msgid "'%s': %s" +msgid "failed to stat '%s'" msgstr "" #: grep.c:1746 #, c-format -msgid "'%s': short read %s" +msgid "'%s': short read" msgstr "" #: help.c:205 @@ -648,12 +657,29 @@ msgstr[1] "" msgid "%s: %s - %s" msgstr "" +#: lockfile.c:152 +#, c-format +msgid "" +"Unable to create '%s.lock': %s.\n" +"\n" +"Another git process seems to be running in this repository, e.g.\n" +"an editor opened by 'git commit'. Please make sure all processes\n" +"are terminated then try again. If it still fails, a git process\n" +"may have crashed in this repository earlier:\n" +"remove the file manually to continue." +msgstr "" + +#: lockfile.c:160 +#, c-format +msgid "Unable to create '%s.lock': %s" +msgstr "" + #: merge.c:41 msgid "failed to read the cache" msgstr "" -#: merge.c:94 builtin/am.c:2008 builtin/am.c:2043 builtin/checkout.c:376 -#: builtin/checkout.c:587 builtin/clone.c:730 +#: merge.c:94 builtin/am.c:2007 builtin/am.c:2042 builtin/checkout.c:375 +#: builtin/checkout.c:586 builtin/clone.c:732 msgid "unable to write new index file" msgstr "" @@ -700,7 +726,7 @@ msgstr "" msgid "blob expected for %s '%s'" msgstr "" -#: merge-recursive.c:790 builtin/clone.c:374 +#: merge-recursive.c:790 builtin/clone.c:376 #, c-format msgid "failed to open '%s'" msgstr "" @@ -827,7 +853,7 @@ msgstr "" msgid "Auto-merging %s" msgstr "" -#: merge-recursive.c:1650 git-submodule.sh:1048 +#: merge-recursive.c:1650 git-submodule.sh:941 msgid "submodule" msgstr "" @@ -854,50 +880,50 @@ msgstr "" msgid "CONFLICT (%s): There is a directory with name %s in %s. Adding %s as %s" msgstr "" -#: merge-recursive.c:1783 +#: merge-recursive.c:1781 #, c-format msgid "Adding %s" msgstr "" -#: merge-recursive.c:1800 +#: merge-recursive.c:1798 msgid "Fatal merge failure, shouldn't happen." msgstr "" -#: merge-recursive.c:1819 +#: merge-recursive.c:1817 msgid "Already up-to-date!" msgstr "" -#: merge-recursive.c:1828 +#: merge-recursive.c:1826 #, c-format msgid "merging of trees %s and %s failed" msgstr "" -#: merge-recursive.c:1858 +#: merge-recursive.c:1856 #, c-format msgid "Unprocessed path??? %s" msgstr "" -#: merge-recursive.c:1906 +#: merge-recursive.c:1904 msgid "Merging:" msgstr "" -#: merge-recursive.c:1919 +#: merge-recursive.c:1917 #, c-format msgid "found %u common ancestor:" msgid_plural "found %u common ancestors:" msgstr[0] "" msgstr[1] "" -#: merge-recursive.c:1956 +#: merge-recursive.c:1954 msgid "merge returned no commit" msgstr "" -#: merge-recursive.c:2013 +#: merge-recursive.c:2011 #, c-format msgid "Could not parse object '%s'" msgstr "" -#: merge-recursive.c:2024 builtin/merge.c:646 +#: merge-recursive.c:2022 builtin/merge.c:649 builtin/merge.c:831 msgid "Unable to write index." msgstr "" @@ -927,28 +953,28 @@ msgstr "" msgid "unable to parse object: %s" msgstr "" -#: parse-options.c:570 +#: parse-options.c:572 msgid "..." msgstr "" -#: parse-options.c:588 +#: parse-options.c:590 #, c-format msgid "usage: %s" msgstr "" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation -#: parse-options.c:592 +#: parse-options.c:594 #, c-format msgid " or: %s" msgstr "" -#: parse-options.c:595 +#: parse-options.c:597 #, c-format msgid " %s" msgstr "" -#: parse-options.c:629 +#: parse-options.c:631 msgid "-NUM" msgstr "" @@ -957,7 +983,7 @@ msgstr "" msgid "malformed object name '%s'" msgstr "" -#: path.c:752 +#: path.c:796 #, c-format msgid "Could not make %s writable by group" msgstr "" @@ -1022,7 +1048,7 @@ msgid "" "Perhaps you forgot to add either ':/' or '.' ?" msgstr "" -#: pretty.c:969 +#: pretty.c:971 msgid "unable to parse --pretty format" msgstr "" @@ -1044,23 +1070,23 @@ msgid "" "Using version %i" msgstr "" -#: refs.c:543 builtin/merge.c:761 builtin/merge.c:872 builtin/merge.c:974 -#: builtin/merge.c:984 +#: refs.c:543 builtin/merge.c:764 builtin/merge.c:883 builtin/merge.c:985 +#: builtin/merge.c:995 #, c-format msgid "Could not open '%s' for writing" msgstr "" -#: refs/files-backend.c:2374 +#: refs/files-backend.c:2243 #, c-format msgid "could not delete reference %s: %s" msgstr "" -#: refs/files-backend.c:2377 +#: refs/files-backend.c:2246 #, c-format msgid "could not delete references: %s" msgstr "" -#: refs/files-backend.c:2386 +#: refs/files-backend.c:2255 #, c-format msgid "could not remove reference %s" msgstr "" @@ -1199,93 +1225,93 @@ msgstr "" msgid "malformed object name %s" msgstr "" -#: remote.c:745 +#: remote.c:746 #, c-format msgid "Cannot fetch both %s and %s to %s" msgstr "" -#: remote.c:749 +#: remote.c:750 #, c-format msgid "%s usually tracks %s, not %s" msgstr "" -#: remote.c:753 +#: remote.c:754 #, c-format msgid "%s tracks both %s and %s" msgstr "" -#: remote.c:761 +#: remote.c:762 msgid "Internal error" msgstr "" -#: remote.c:1677 remote.c:1720 +#: remote.c:1678 remote.c:1721 msgid "HEAD does not point to a branch" msgstr "" -#: remote.c:1686 +#: remote.c:1687 #, c-format msgid "no such branch: '%s'" msgstr "" -#: remote.c:1689 +#: remote.c:1690 #, c-format msgid "no upstream configured for branch '%s'" msgstr "" -#: remote.c:1695 +#: remote.c:1696 #, c-format msgid "upstream branch '%s' not stored as a remote-tracking branch" msgstr "" -#: remote.c:1710 +#: remote.c:1711 #, c-format msgid "push destination '%s' on remote '%s' has no local tracking branch" msgstr "" -#: remote.c:1725 +#: remote.c:1726 #, c-format msgid "branch '%s' has no remote for pushing" msgstr "" -#: remote.c:1736 +#: remote.c:1737 #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "" -#: remote.c:1749 +#: remote.c:1750 msgid "push has no destination (push.default is 'nothing')" msgstr "" -#: remote.c:1771 +#: remote.c:1772 msgid "cannot resolve 'simple' push to a single destination" msgstr "" -#: remote.c:2073 +#: remote.c:2074 #, c-format msgid "Your branch is based on '%s', but the upstream is gone.\n" msgstr "" -#: remote.c:2077 +#: remote.c:2078 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr "" -#: remote.c:2080 +#: remote.c:2081 #, c-format msgid "Your branch is up-to-date with '%s'.\n" msgstr "" -#: remote.c:2084 +#: remote.c:2085 #, c-format msgid "Your branch is ahead of '%s' by %d commit.\n" msgid_plural "Your branch is ahead of '%s' by %d commits.\n" msgstr[0] "" msgstr[1] "" -#: remote.c:2090 +#: remote.c:2091 msgid " (use \"git push\" to publish your local commits)\n" msgstr "" -#: remote.c:2093 +#: remote.c:2094 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -1293,11 +1319,11 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: remote.c:2101 +#: remote.c:2102 msgid " (use \"git pull\" to update your local branch)\n" msgstr "" -#: remote.c:2104 +#: remote.c:2105 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -1308,20 +1334,20 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: remote.c:2114 +#: remote.c:2115 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" -#: revision.c:2131 +#: revision.c:2142 msgid "your current branch appears to be broken" msgstr "" -#: revision.c:2134 +#: revision.c:2145 #, c-format msgid "your current branch '%s' does not have any commits yet" msgstr "" -#: revision.c:2328 +#: revision.c:2339 msgid "--first-parent is incompatible with --bisect" msgstr "" @@ -1365,7 +1391,7 @@ msgid "" "and commit the result with 'git commit'" msgstr "" -#: sequencer.c:190 sequencer.c:833 sequencer.c:913 +#: sequencer.c:190 sequencer.c:833 sequencer.c:912 #, c-format msgid "Could not write to %s" msgstr "" @@ -1523,12 +1549,12 @@ msgstr "" msgid "Could not create sequencer directory %s" msgstr "" -#: sequencer.c:835 sequencer.c:917 +#: sequencer.c:835 sequencer.c:916 #, c-format msgid "Error wrapping up %s." msgstr "" -#: sequencer.c:854 sequencer.c:987 +#: sequencer.c:854 sequencer.c:986 msgid "no cherry-pick or revert in progress" msgstr "" @@ -1540,63 +1566,72 @@ msgstr "" msgid "cannot abort from a branch yet to be born" msgstr "" -#: sequencer.c:878 builtin/apply.c:4287 +#: sequencer.c:878 builtin/fetch.c:610 builtin/fetch.c:851 #, c-format -msgid "cannot open %s: %s" +msgid "cannot open %s" msgstr "" -#: sequencer.c:881 +#: sequencer.c:880 #, c-format msgid "cannot read %s: %s" msgstr "" -#: sequencer.c:882 +#: sequencer.c:881 msgid "unexpected end of file" msgstr "" -#: sequencer.c:888 +#: sequencer.c:887 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "" -#: sequencer.c:910 +#: sequencer.c:909 #, c-format msgid "Could not format %s." msgstr "" -#: sequencer.c:1055 +#: sequencer.c:1054 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "" -#: sequencer.c:1058 +#: sequencer.c:1057 #, c-format msgid "%s: bad revision" msgstr "" -#: sequencer.c:1092 +#: sequencer.c:1091 msgid "Can't revert as initial commit" msgstr "" -#: sequencer.c:1093 +#: sequencer.c:1092 msgid "Can't cherry-pick into empty head" msgstr "" -#: setup.c:246 +#: setup.c:248 #, c-format msgid "failed to read %s" msgstr "" +#: setup.c:468 +#, c-format +msgid "Expected git repo version <= %d, found %d" +msgstr "" + +#: setup.c:476 +msgid "unknown repository extensions found:" +msgstr "" + #: sha1_file.c:1080 msgid "offset before end of packfile (broken .idx?)" msgstr "" -#: sha1_file.c:2459 +#: sha1_file.c:2458 #, c-format msgid "offset before start of pack index for %s (corrupt index?)" msgstr "" -#: sha1_file.c:2463 +#: sha1_file.c:2462 #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" msgstr "" @@ -1614,29 +1649,38 @@ msgid "" "running \"git config advice.objectNameWarning false\"" msgstr "" -#: submodule.c:62 submodule.c:96 +#: submodule.c:64 submodule.c:98 msgid "Cannot change unmerged .gitmodules, resolve merge conflicts first" msgstr "" -#: submodule.c:66 submodule.c:100 +#: submodule.c:68 submodule.c:102 #, c-format msgid "Could not find section in .gitmodules where path=%s" msgstr "" -#: submodule.c:74 +#: submodule.c:76 #, c-format msgid "Could not update .gitmodules entry %s" msgstr "" -#: submodule.c:107 +#: submodule.c:109 #, c-format msgid "Could not remove .gitmodules entry for %s" msgstr "" -#: submodule.c:118 +#: submodule.c:120 msgid "staging updated .gitmodules failed" msgstr "" +#: submodule.c:177 +msgid "negative values not allowed for submodule.fetchJobs" +msgstr "" + +#: submodule-config.c:355 +#, c-format +msgid "invalid value for %s" +msgstr "" + #: trailer.c:237 #, c-format msgid "running trailer command '%s' failed" @@ -1696,7 +1740,175 @@ msgstr "" msgid "Could not read ref %s" msgstr "" -#: unpack-trees.c:203 +#: unpack-trees.c:64 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by checkout:\n" +"%%sPlease commit your changes or stash them before you can switch branches." +msgstr "" + +#: unpack-trees.c:66 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by checkout:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:69 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by merge:\n" +"%%sPlease commit your changes or stash them before you can merge." +msgstr "" + +#: unpack-trees.c:71 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by merge:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:74 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by %s:\n" +"%%sPlease commit your changes or stash them before you can %s." +msgstr "" + +#: unpack-trees.c:76 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by %s:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:81 +#, c-format +msgid "" +"Updating the following directories would lose untracked files in it:\n" +"%s" +msgstr "" + +#: unpack-trees.c:85 +#, c-format +msgid "" +"The following untracked working tree files would be removed by checkout:\n" +"%%sPlease move or remove them before you can switch branches." +msgstr "" + +#: unpack-trees.c:87 +#, c-format +msgid "" +"The following untracked working tree files would be removed by checkout:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:90 +#, c-format +msgid "" +"The following untracked working tree files would be removed by merge:\n" +"%%sPlease move or remove them before you can merge." +msgstr "" + +#: unpack-trees.c:92 +#, c-format +msgid "" +"The following untracked working tree files would be removed by merge:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:95 +#, c-format +msgid "" +"The following untracked working tree files would be removed by %s:\n" +"%%sPlease move or remove them before you can %s." +msgstr "" + +#: unpack-trees.c:97 +#, c-format +msgid "" +"The following untracked working tree files would be removed by %s:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:102 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by " +"checkout:\n" +"%%sPlease move or remove them before you can switch branches." +msgstr "" + +#: unpack-trees.c:104 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by " +"checkout:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:107 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by merge:\n" +"%%sPlease move or remove them before you can merge." +msgstr "" + +#: unpack-trees.c:109 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by merge:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:112 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by %s:\n" +"%%sPlease move or remove them before you can %s." +msgstr "" + +#: unpack-trees.c:114 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by %s:\n" +"%%s" +msgstr "" + +#: unpack-trees.c:121 +#, c-format +msgid "Entry '%s' overlaps with '%s'. Cannot bind." +msgstr "" + +#: unpack-trees.c:124 +#, c-format +msgid "" +"Cannot update sparse checkout: the following entries are not up-to-date:\n" +"%s" +msgstr "" + +#: unpack-trees.c:126 +#, c-format +msgid "" +"The following Working tree files would be overwritten by sparse checkout " +"update:\n" +"%s" +msgstr "" + +#: unpack-trees.c:128 +#, c-format +msgid "" +"The following Working tree files would be removed by sparse checkout " +"update:\n" +"%s" +msgstr "" + +#: unpack-trees.c:205 +#, c-format +msgid "Aborting\n" +msgstr "" + +#: unpack-trees.c:237 msgid "Checking out files" msgstr "" @@ -1734,230 +1946,226 @@ msgstr "" msgid "could not open '%s' for reading and writing" msgstr "" -#: wrapper.c:224 wrapper.c:383 +#: wrapper.c:224 wrapper.c:383 builtin/am.c:779 #, c-format msgid "could not open '%s' for writing" msgstr "" -#: wrapper.c:226 wrapper.c:385 builtin/am.c:323 builtin/commit.c:1691 -#: builtin/merge.c:1075 builtin/pull.c:387 +#: wrapper.c:226 wrapper.c:385 builtin/am.c:323 builtin/am.c:772 +#: builtin/am.c:860 builtin/commit.c:1711 builtin/merge.c:1086 +#: builtin/pull.c:407 #, c-format msgid "could not open '%s' for reading" msgstr "" -#: wrapper.c:611 -#, c-format -msgid "unable to access '%s': %s" -msgstr "" - -#: wrapper.c:632 +#: wrapper.c:594 wrapper.c:615 #, c-format msgid "unable to access '%s'" msgstr "" -#: wrapper.c:640 +#: wrapper.c:623 msgid "unable to get current working directory" msgstr "" -#: wrapper.c:667 +#: wrapper.c:650 #, c-format msgid "could not open %s for writing" msgstr "" -#: wrapper.c:678 builtin/am.c:410 +#: wrapper.c:661 builtin/am.c:410 #, c-format msgid "could not write to %s" msgstr "" -#: wrapper.c:684 +#: wrapper.c:667 #, c-format msgid "could not close %s" msgstr "" -#: wt-status.c:149 +#: wt-status.c:150 msgid "Unmerged paths:" msgstr "" -#: wt-status.c:176 wt-status.c:203 +#: wt-status.c:177 wt-status.c:204 #, c-format msgid " (use \"git reset %s <file>...\" to unstage)" msgstr "" -#: wt-status.c:178 wt-status.c:205 +#: wt-status.c:179 wt-status.c:206 msgid " (use \"git rm --cached <file>...\" to unstage)" msgstr "" -#: wt-status.c:182 +#: wt-status.c:183 msgid " (use \"git add <file>...\" to mark resolution)" msgstr "" -#: wt-status.c:184 wt-status.c:188 +#: wt-status.c:185 wt-status.c:189 msgid " (use \"git add/rm <file>...\" as appropriate to mark resolution)" msgstr "" -#: wt-status.c:186 +#: wt-status.c:187 msgid " (use \"git rm <file>...\" to mark resolution)" msgstr "" -#: wt-status.c:197 wt-status.c:880 +#: wt-status.c:198 wt-status.c:881 msgid "Changes to be committed:" msgstr "" -#: wt-status.c:215 wt-status.c:889 +#: wt-status.c:216 wt-status.c:890 msgid "Changes not staged for commit:" msgstr "" -#: wt-status.c:219 +#: wt-status.c:220 msgid " (use \"git add <file>...\" to update what will be committed)" msgstr "" -#: wt-status.c:221 +#: wt-status.c:222 msgid " (use \"git add/rm <file>...\" to update what will be committed)" msgstr "" -#: wt-status.c:222 +#: wt-status.c:223 msgid "" " (use \"git checkout -- <file>...\" to discard changes in working directory)" msgstr "" -#: wt-status.c:224 +#: wt-status.c:225 msgid " (commit or discard the untracked or modified content in submodules)" msgstr "" -#: wt-status.c:236 +#: wt-status.c:237 #, c-format msgid " (use \"git %s <file>...\" to include in what will be committed)" msgstr "" -#: wt-status.c:251 +#: wt-status.c:252 msgid "both deleted:" msgstr "" -#: wt-status.c:253 +#: wt-status.c:254 msgid "added by us:" msgstr "" -#: wt-status.c:255 +#: wt-status.c:256 msgid "deleted by them:" msgstr "" -#: wt-status.c:257 +#: wt-status.c:258 msgid "added by them:" msgstr "" -#: wt-status.c:259 +#: wt-status.c:260 msgid "deleted by us:" msgstr "" -#: wt-status.c:261 +#: wt-status.c:262 msgid "both added:" msgstr "" -#: wt-status.c:263 +#: wt-status.c:264 msgid "both modified:" msgstr "" -#: wt-status.c:265 +#: wt-status.c:266 #, c-format msgid "bug: unhandled unmerged status %x" msgstr "" -#: wt-status.c:273 +#: wt-status.c:274 msgid "new file:" msgstr "" -#: wt-status.c:275 +#: wt-status.c:276 msgid "copied:" msgstr "" -#: wt-status.c:277 +#: wt-status.c:278 msgid "deleted:" msgstr "" -#: wt-status.c:279 +#: wt-status.c:280 msgid "modified:" msgstr "" -#: wt-status.c:281 +#: wt-status.c:282 msgid "renamed:" msgstr "" -#: wt-status.c:283 +#: wt-status.c:284 msgid "typechange:" msgstr "" -#: wt-status.c:285 +#: wt-status.c:286 msgid "unknown:" msgstr "" -#: wt-status.c:287 +#: wt-status.c:288 msgid "unmerged:" msgstr "" -#: wt-status.c:369 +#: wt-status.c:370 msgid "new commits, " msgstr "" -#: wt-status.c:371 +#: wt-status.c:372 msgid "modified content, " msgstr "" -#: wt-status.c:373 +#: wt-status.c:374 msgid "untracked content, " msgstr "" -#: wt-status.c:390 +#: wt-status.c:391 #, c-format msgid "bug: unhandled diff status %c" msgstr "" -#: wt-status.c:754 +#: wt-status.c:755 msgid "Submodules changed but not updated:" msgstr "" -#: wt-status.c:756 +#: wt-status.c:757 msgid "Submodule changes to be committed:" msgstr "" -#: wt-status.c:837 +#: wt-status.c:838 msgid "" "Do not touch the line above.\n" "Everything below will be removed." msgstr "" -#: wt-status.c:948 +#: wt-status.c:949 msgid "You have unmerged paths." msgstr "" -#: wt-status.c:951 +#: wt-status.c:952 msgid " (fix conflicts and run \"git commit\")" msgstr "" -#: wt-status.c:954 +#: wt-status.c:956 msgid "All conflicts fixed but you are still merging." msgstr "" -#: wt-status.c:957 +#: wt-status.c:959 msgid " (use \"git commit\" to conclude merge)" msgstr "" -#: wt-status.c:967 +#: wt-status.c:969 msgid "You are in the middle of an am session." msgstr "" -#: wt-status.c:970 +#: wt-status.c:972 msgid "The current patch is empty." msgstr "" -#: wt-status.c:974 +#: wt-status.c:976 msgid " (fix conflicts and then run \"git am --continue\")" msgstr "" -#: wt-status.c:976 +#: wt-status.c:978 msgid " (use \"git am --skip\" to skip this patch)" msgstr "" -#: wt-status.c:978 +#: wt-status.c:980 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" @@ -2096,43 +2304,43 @@ msgstr "" msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" -#: wt-status.c:1438 +#: wt-status.c:1460 msgid "On branch " msgstr "" -#: wt-status.c:1444 +#: wt-status.c:1466 msgid "interactive rebase in progress; onto " msgstr "" -#: wt-status.c:1446 +#: wt-status.c:1468 msgid "rebase in progress; onto " msgstr "" -#: wt-status.c:1451 +#: wt-status.c:1473 msgid "HEAD detached at " msgstr "" -#: wt-status.c:1453 +#: wt-status.c:1475 msgid "HEAD detached from " msgstr "" -#: wt-status.c:1456 +#: wt-status.c:1478 msgid "Not currently on any branch." msgstr "" -#: wt-status.c:1474 +#: wt-status.c:1496 msgid "Initial commit" msgstr "" -#: wt-status.c:1488 +#: wt-status.c:1510 msgid "Untracked files" msgstr "" -#: wt-status.c:1490 +#: wt-status.c:1512 msgid "Ignored files" msgstr "" -#: wt-status.c:1494 +#: wt-status.c:1516 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -2140,82 +2348,82 @@ msgid "" "new files yourself (see 'git help status')." msgstr "" -#: wt-status.c:1500 +#: wt-status.c:1522 #, c-format msgid "Untracked files not listed%s" msgstr "" -#: wt-status.c:1502 +#: wt-status.c:1524 msgid " (use -u option to show untracked files)" msgstr "" -#: wt-status.c:1508 +#: wt-status.c:1530 msgid "No changes" msgstr "" -#: wt-status.c:1513 +#: wt-status.c:1535 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" -#: wt-status.c:1516 +#: wt-status.c:1538 #, c-format msgid "no changes added to commit\n" msgstr "" -#: wt-status.c:1519 +#: wt-status.c:1541 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " "track)\n" msgstr "" -#: wt-status.c:1522 +#: wt-status.c:1544 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "" -#: wt-status.c:1525 +#: wt-status.c:1547 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" -#: wt-status.c:1528 wt-status.c:1533 +#: wt-status.c:1550 wt-status.c:1555 #, c-format msgid "nothing to commit\n" msgstr "" -#: wt-status.c:1531 +#: wt-status.c:1553 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" -#: wt-status.c:1535 +#: wt-status.c:1557 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "" -#: wt-status.c:1642 +#: wt-status.c:1664 msgid "Initial commit on " msgstr "" -#: wt-status.c:1646 +#: wt-status.c:1668 msgid "HEAD (no branch)" msgstr "" -#: wt-status.c:1675 +#: wt-status.c:1697 msgid "gone" msgstr "" -#: wt-status.c:1677 wt-status.c:1685 +#: wt-status.c:1699 wt-status.c:1707 msgid "behind " msgstr "" -#: wt-status.c:1680 wt-status.c:1683 +#: wt-status.c:1702 wt-status.c:1705 msgid "ahead " msgstr "" -#: compat/precompose_utf8.c:57 builtin/clone.c:413 +#: compat/precompose_utf8.c:57 builtin/clone.c:415 #, c-format msgid "failed to unlink '%s'" msgstr "" @@ -2229,7 +2437,7 @@ msgstr "" msgid "unexpected diff status %c" msgstr "" -#: builtin/add.c:70 builtin/commit.c:278 +#: builtin/add.c:70 builtin/commit.c:280 msgid "updating files failed" msgstr "" @@ -2242,7 +2450,7 @@ msgstr "" msgid "Unstaged changes after refreshing the index:" msgstr "" -#: builtin/add.c:194 builtin/rev-parse.c:797 +#: builtin/add.c:194 builtin/rev-parse.c:811 msgid "Could not read the index" msgstr "" @@ -2278,14 +2486,14 @@ msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" #: builtin/add.c:249 builtin/clean.c:870 builtin/fetch.c:112 builtin/mv.c:111 -#: builtin/prune-packed.c:55 builtin/pull.c:189 builtin/push.c:511 -#: builtin/remote.c:1330 builtin/rm.c:268 builtin/send-pack.c:162 +#: builtin/prune-packed.c:55 builtin/pull.c:197 builtin/push.c:511 +#: builtin/remote.c:1332 builtin/rm.c:268 builtin/send-pack.c:162 msgid "dry run" msgstr "" -#: builtin/add.c:250 builtin/apply.c:4561 builtin/check-ignore.c:19 -#: builtin/commit.c:1322 builtin/count-objects.c:85 builtin/fsck.c:558 -#: builtin/log.c:1651 builtin/mv.c:110 builtin/read-tree.c:114 +#: builtin/add.c:250 builtin/apply.c:4563 builtin/check-ignore.c:19 +#: builtin/commit.c:1333 builtin/count-objects.c:85 builtin/fsck.c:557 +#: builtin/log.c:1826 builtin/mv.c:110 builtin/read-tree.c:114 msgid "be verbose" msgstr "" @@ -2293,7 +2501,7 @@ msgstr "" msgid "interactive picking" msgstr "" -#: builtin/add.c:253 builtin/checkout.c:1155 builtin/reset.c:286 +#: builtin/add.c:253 builtin/checkout.c:1154 builtin/reset.c:286 msgid "select hunks interactively" msgstr "" @@ -2361,16 +2569,16 @@ msgid "Maybe you wanted to say 'git add .'?\n" msgstr "" #: builtin/add.c:358 builtin/check-ignore.c:172 builtin/clean.c:914 -#: builtin/commit.c:337 builtin/mv.c:131 builtin/reset.c:235 builtin/rm.c:298 -#: builtin/submodule--helper.c:35 +#: builtin/commit.c:339 builtin/mv.c:131 builtin/reset.c:235 builtin/rm.c:298 +#: builtin/submodule--helper.c:240 msgid "index file corrupt" msgstr "" -#: builtin/add.c:439 builtin/apply.c:4659 builtin/mv.c:280 builtin/rm.c:430 +#: builtin/add.c:439 builtin/apply.c:4661 builtin/mv.c:283 builtin/rm.c:430 msgid "Unable to write new index file" msgstr "" -#: builtin/am.c:256 builtin/commit.c:738 builtin/merge.c:1078 +#: builtin/am.c:256 builtin/commit.c:749 builtin/merge.c:1089 #, c-format msgid "could not read '%s'" msgstr "" @@ -2398,16 +2606,6 @@ msgstr "" msgid "fseek failed" msgstr "" -#: builtin/am.c:772 builtin/am.c:860 -#, c-format -msgid "could not open '%s' for reading: %s" -msgstr "" - -#: builtin/am.c:779 -#, c-format -msgid "could not open '%s' for writing: %s" -msgstr "" - #: builtin/am.c:788 #, c-format msgid "could not parse patch '%s'" @@ -2417,109 +2615,109 @@ msgstr "" msgid "Only one StGIT patch series can be applied at once" msgstr "" -#: builtin/am.c:901 +#: builtin/am.c:900 msgid "invalid timestamp" msgstr "" -#: builtin/am.c:904 builtin/am.c:912 +#: builtin/am.c:903 builtin/am.c:911 msgid "invalid Date line" msgstr "" -#: builtin/am.c:909 +#: builtin/am.c:908 msgid "invalid timezone offset" msgstr "" -#: builtin/am.c:996 +#: builtin/am.c:995 msgid "Patch format detection failed." msgstr "" -#: builtin/am.c:1001 builtin/clone.c:378 +#: builtin/am.c:1000 builtin/clone.c:380 #, c-format msgid "failed to create directory '%s'" msgstr "" -#: builtin/am.c:1005 +#: builtin/am.c:1004 msgid "Failed to split patches." msgstr "" -#: builtin/am.c:1137 builtin/commit.c:363 +#: builtin/am.c:1136 builtin/commit.c:365 msgid "unable to write index file" msgstr "" -#: builtin/am.c:1188 +#: builtin/am.c:1187 #, c-format msgid "When you have resolved this problem, run \"%s --continue\"." msgstr "" -#: builtin/am.c:1189 +#: builtin/am.c:1188 #, c-format msgid "If you prefer to skip this patch, run \"%s --skip\" instead." msgstr "" -#: builtin/am.c:1190 +#: builtin/am.c:1189 #, c-format msgid "To restore the original branch and stop patching, run \"%s --abort\"." msgstr "" -#: builtin/am.c:1328 +#: builtin/am.c:1327 msgid "Patch is empty. Was it split wrong?" msgstr "" -#: builtin/am.c:1402 builtin/log.c:1350 +#: builtin/am.c:1401 builtin/log.c:1516 #, c-format msgid "invalid ident line: %s" msgstr "" -#: builtin/am.c:1429 +#: builtin/am.c:1428 #, c-format msgid "unable to parse commit %s" msgstr "" -#: builtin/am.c:1631 +#: builtin/am.c:1630 msgid "Repository lacks necessary blobs to fall back on 3-way merge." msgstr "" -#: builtin/am.c:1633 +#: builtin/am.c:1632 msgid "Using index info to reconstruct a base tree..." msgstr "" -#: builtin/am.c:1652 +#: builtin/am.c:1651 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." msgstr "" -#: builtin/am.c:1658 +#: builtin/am.c:1657 msgid "Falling back to patching base and 3-way merge..." msgstr "" -#: builtin/am.c:1673 +#: builtin/am.c:1672 msgid "Failed to merge in the changes." msgstr "" -#: builtin/am.c:1697 builtin/merge.c:633 +#: builtin/am.c:1696 builtin/merge.c:636 msgid "git write-tree failed to write a tree" msgstr "" -#: builtin/am.c:1704 +#: builtin/am.c:1703 msgid "applying to an empty history" msgstr "" -#: builtin/am.c:1717 builtin/commit.c:1755 builtin/merge.c:830 -#: builtin/merge.c:855 +#: builtin/am.c:1716 builtin/commit.c:1775 builtin/merge.c:841 +#: builtin/merge.c:866 msgid "failed to write commit object" msgstr "" -#: builtin/am.c:1749 builtin/am.c:1753 +#: builtin/am.c:1748 builtin/am.c:1752 #, c-format msgid "cannot resume: %s does not exist." msgstr "" -#: builtin/am.c:1769 +#: builtin/am.c:1768 msgid "cannot be interactive without stdin connected to a terminal." msgstr "" -#: builtin/am.c:1774 +#: builtin/am.c:1773 msgid "Commit Body is:" msgstr "" @@ -2527,231 +2725,233 @@ msgstr "" #. in your translation. The program will only accept English #. input at this point. #. -#: builtin/am.c:1784 +#: builtin/am.c:1783 msgid "Apply? [y]es/[n]o/[e]dit/[v]iew patch/[a]ccept all: " msgstr "" -#: builtin/am.c:1834 +#: builtin/am.c:1833 #, c-format msgid "Dirty index: cannot apply patches (dirty: %s)" msgstr "" -#: builtin/am.c:1869 builtin/am.c:1941 +#: builtin/am.c:1868 builtin/am.c:1940 #, c-format msgid "Applying: %.*s" msgstr "" -#: builtin/am.c:1885 +#: builtin/am.c:1884 msgid "No changes -- Patch already applied." msgstr "" -#: builtin/am.c:1893 +#: builtin/am.c:1892 #, c-format msgid "Patch failed at %s %.*s" msgstr "" -#: builtin/am.c:1899 +#: builtin/am.c:1898 #, c-format msgid "The copy of the patch that failed is found in: %s" msgstr "" -#: builtin/am.c:1944 +#: builtin/am.c:1943 msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" "already introduced the same changes; you might want to skip this patch." msgstr "" -#: builtin/am.c:1951 +#: builtin/am.c:1950 msgid "" "You still have unmerged paths in your index.\n" "Did you forget to use 'git add'?" msgstr "" -#: builtin/am.c:2059 builtin/am.c:2063 builtin/am.c:2075 builtin/reset.c:308 +#: builtin/am.c:2058 builtin/am.c:2062 builtin/am.c:2074 builtin/reset.c:308 #: builtin/reset.c:316 #, c-format msgid "Could not parse object '%s'." msgstr "" -#: builtin/am.c:2111 +#: builtin/am.c:2110 msgid "failed to clean index" msgstr "" -#: builtin/am.c:2145 +#: builtin/am.c:2144 msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" msgstr "" -#: builtin/am.c:2206 +#: builtin/am.c:2205 #, c-format msgid "Invalid value for --patch-format: %s" msgstr "" -#: builtin/am.c:2239 +#: builtin/am.c:2238 msgid "git am [<options>] [(<mbox>|<Maildir>)...]" msgstr "" -#: builtin/am.c:2240 +#: builtin/am.c:2239 msgid "git am [<options>] (--continue | --skip | --abort)" msgstr "" -#: builtin/am.c:2246 +#: builtin/am.c:2245 msgid "run interactively" msgstr "" -#: builtin/am.c:2248 +#: builtin/am.c:2247 msgid "historical option -- no-op" msgstr "" -#: builtin/am.c:2250 +#: builtin/am.c:2249 msgid "allow fall back on 3way merging if needed" msgstr "" -#: builtin/am.c:2251 builtin/init-db.c:474 builtin/prune-packed.c:57 +#: builtin/am.c:2250 builtin/init-db.c:478 builtin/prune-packed.c:57 #: builtin/repack.c:171 msgid "be quiet" msgstr "" -#: builtin/am.c:2253 +#: builtin/am.c:2252 msgid "add a Signed-off-by line to the commit message" msgstr "" -#: builtin/am.c:2256 +#: builtin/am.c:2255 msgid "recode into utf8 (default)" msgstr "" -#: builtin/am.c:2258 +#: builtin/am.c:2257 msgid "pass -k flag to git-mailinfo" msgstr "" -#: builtin/am.c:2260 +#: builtin/am.c:2259 msgid "pass -b flag to git-mailinfo" msgstr "" -#: builtin/am.c:2262 +#: builtin/am.c:2261 msgid "pass -m flag to git-mailinfo" msgstr "" -#: builtin/am.c:2264 +#: builtin/am.c:2263 msgid "pass --keep-cr flag to git-mailsplit for mbox format" msgstr "" -#: builtin/am.c:2267 +#: builtin/am.c:2266 msgid "do not pass --keep-cr flag to git-mailsplit independent of am.keepcr" msgstr "" -#: builtin/am.c:2270 +#: builtin/am.c:2269 msgid "strip everything before a scissors line" msgstr "" -#: builtin/am.c:2271 builtin/apply.c:4544 +#: builtin/am.c:2270 builtin/apply.c:4546 msgid "action" msgstr "" -#: builtin/am.c:2272 builtin/am.c:2275 builtin/am.c:2278 builtin/am.c:2281 -#: builtin/am.c:2284 builtin/am.c:2287 builtin/am.c:2290 builtin/am.c:2293 -#: builtin/am.c:2299 +#: builtin/am.c:2271 builtin/am.c:2274 builtin/am.c:2277 builtin/am.c:2280 +#: builtin/am.c:2283 builtin/am.c:2286 builtin/am.c:2289 builtin/am.c:2292 +#: builtin/am.c:2298 msgid "pass it through git-apply" msgstr "" -#: builtin/am.c:2280 builtin/apply.c:4568 +#: builtin/am.c:2279 builtin/apply.c:4570 msgid "root" msgstr "" -#: builtin/am.c:2283 builtin/am.c:2286 builtin/apply.c:4506 -#: builtin/apply.c:4509 builtin/clone.c:86 builtin/fetch.c:95 -#: builtin/pull.c:171 builtin/submodule--helper.c:72 -#: builtin/submodule--helper.c:160 builtin/submodule--helper.c:163 +#: builtin/am.c:2282 builtin/am.c:2285 builtin/apply.c:4508 +#: builtin/apply.c:4511 builtin/clone.c:90 builtin/fetch.c:95 +#: builtin/pull.c:179 builtin/submodule--helper.c:277 +#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:485 +#: builtin/submodule--helper.c:488 builtin/submodule--helper.c:767 +#: builtin/submodule--helper.c:770 msgid "path" msgstr "" -#: builtin/am.c:2289 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 -#: builtin/grep.c:704 builtin/merge.c:198 builtin/pull.c:131 -#: builtin/pull.c:185 builtin/repack.c:178 builtin/repack.c:182 +#: builtin/am.c:2288 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 +#: builtin/grep.c:706 builtin/merge.c:199 builtin/pull.c:134 +#: builtin/pull.c:193 builtin/repack.c:178 builtin/repack.c:182 #: builtin/show-branch.c:645 builtin/show-ref.c:175 builtin/tag.c:340 #: parse-options.h:132 parse-options.h:134 parse-options.h:244 msgid "n" msgstr "" -#: builtin/am.c:2292 builtin/apply.c:4512 +#: builtin/am.c:2291 builtin/apply.c:4514 msgid "num" msgstr "" -#: builtin/am.c:2295 builtin/for-each-ref.c:37 builtin/replace.c:438 +#: builtin/am.c:2294 builtin/for-each-ref.c:37 builtin/replace.c:438 #: builtin/tag.c:372 msgid "format" msgstr "" -#: builtin/am.c:2296 +#: builtin/am.c:2295 msgid "format the patch(es) are in" msgstr "" -#: builtin/am.c:2302 +#: builtin/am.c:2301 msgid "override error message when patch failure occurs" msgstr "" -#: builtin/am.c:2304 +#: builtin/am.c:2303 msgid "continue applying patches after resolving a conflict" msgstr "" -#: builtin/am.c:2307 +#: builtin/am.c:2306 msgid "synonyms for --continue" msgstr "" -#: builtin/am.c:2310 +#: builtin/am.c:2309 msgid "skip the current patch" msgstr "" -#: builtin/am.c:2313 +#: builtin/am.c:2312 msgid "restore the original branch and abort the patching operation." msgstr "" -#: builtin/am.c:2317 +#: builtin/am.c:2316 msgid "lie about committer date" msgstr "" -#: builtin/am.c:2319 +#: builtin/am.c:2318 msgid "use current timestamp for author date" msgstr "" -#: builtin/am.c:2321 builtin/commit.c:1593 builtin/merge.c:225 -#: builtin/pull.c:159 builtin/revert.c:92 builtin/tag.c:355 +#: builtin/am.c:2320 builtin/commit.c:1609 builtin/merge.c:228 +#: builtin/pull.c:164 builtin/revert.c:92 builtin/tag.c:355 msgid "key-id" msgstr "" -#: builtin/am.c:2322 +#: builtin/am.c:2321 msgid "GPG-sign commits" msgstr "" -#: builtin/am.c:2325 +#: builtin/am.c:2324 msgid "(internal use for git-rebase)" msgstr "" -#: builtin/am.c:2340 +#: builtin/am.c:2339 msgid "" "The -b/--binary option has been a no-op for long time, and\n" "it will be removed. Please do not use it anymore." msgstr "" -#: builtin/am.c:2347 +#: builtin/am.c:2346 msgid "failed to read the index" msgstr "" -#: builtin/am.c:2362 +#: builtin/am.c:2361 #, c-format msgid "previous rebase directory %s still exists but mbox given." msgstr "" -#: builtin/am.c:2386 +#: builtin/am.c:2385 #, c-format msgid "" "Stray %s directory found.\n" "Use \"git am --abort\" to remove it." msgstr "" -#: builtin/am.c:2392 +#: builtin/am.c:2391 msgid "Resolve operation not in progress, we are not resuming." msgstr "" @@ -2784,37 +2984,37 @@ msgstr "" msgid "unable to find filename in patch at line %d" msgstr "" -#: builtin/apply.c:940 +#: builtin/apply.c:937 #, c-format msgid "git apply: bad git-diff - expected /dev/null, got %s on line %d" msgstr "" -#: builtin/apply.c:944 +#: builtin/apply.c:942 #, c-format msgid "git apply: bad git-diff - inconsistent new filename on line %d" msgstr "" -#: builtin/apply.c:945 +#: builtin/apply.c:943 #, c-format msgid "git apply: bad git-diff - inconsistent old filename on line %d" msgstr "" -#: builtin/apply.c:952 +#: builtin/apply.c:949 #, c-format msgid "git apply: bad git-diff - expected /dev/null on line %d" msgstr "" -#: builtin/apply.c:1415 +#: builtin/apply.c:1406 #, c-format msgid "recount: unexpected line: %.*s" msgstr "" -#: builtin/apply.c:1472 +#: builtin/apply.c:1463 #, c-format msgid "patch fragment without header at line %d: %.*s" msgstr "" -#: builtin/apply.c:1489 +#: builtin/apply.c:1480 #, c-format msgid "" "git diff header lacks filename information when removing %d leading pathname " @@ -2825,396 +3025,406 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:1655 +#: builtin/apply.c:1646 msgid "new file depends on old contents" msgstr "" -#: builtin/apply.c:1657 +#: builtin/apply.c:1648 msgid "deleted file still has contents" msgstr "" -#: builtin/apply.c:1683 +#: builtin/apply.c:1674 #, c-format msgid "corrupt patch at line %d" msgstr "" -#: builtin/apply.c:1719 +#: builtin/apply.c:1710 #, c-format msgid "new file %s depends on old contents" msgstr "" -#: builtin/apply.c:1721 +#: builtin/apply.c:1712 #, c-format msgid "deleted file %s still has contents" msgstr "" -#: builtin/apply.c:1724 +#: builtin/apply.c:1715 #, c-format msgid "** warning: file %s becomes empty but is not deleted" msgstr "" -#: builtin/apply.c:1870 +#: builtin/apply.c:1861 #, c-format msgid "corrupt binary patch at line %d: %.*s" msgstr "" -#: builtin/apply.c:1899 +#: builtin/apply.c:1895 #, c-format msgid "unrecognized binary patch at line %d" msgstr "" -#: builtin/apply.c:2050 +#: builtin/apply.c:2048 #, c-format msgid "patch with only garbage at line %d" msgstr "" -#: builtin/apply.c:2140 +#: builtin/apply.c:2138 #, c-format msgid "unable to read symlink %s" msgstr "" -#: builtin/apply.c:2144 +#: builtin/apply.c:2142 #, c-format msgid "unable to open or read %s" msgstr "" -#: builtin/apply.c:2777 +#: builtin/apply.c:2775 #, c-format msgid "invalid start of line: '%c'" msgstr "" -#: builtin/apply.c:2896 +#: builtin/apply.c:2894 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:2908 +#: builtin/apply.c:2906 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "" -#: builtin/apply.c:2914 +#: builtin/apply.c:2912 #, c-format msgid "" "while searching for:\n" "%.*s" msgstr "" -#: builtin/apply.c:2934 +#: builtin/apply.c:2932 #, c-format msgid "missing binary patch data for '%s'" msgstr "" -#: builtin/apply.c:3035 +#: builtin/apply.c:3033 #, c-format msgid "binary patch does not apply to '%s'" msgstr "" -#: builtin/apply.c:3041 +#: builtin/apply.c:3039 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" -#: builtin/apply.c:3062 +#: builtin/apply.c:3060 #, c-format msgid "patch failed: %s:%ld" msgstr "" -#: builtin/apply.c:3186 +#: builtin/apply.c:3184 #, c-format msgid "cannot checkout %s" msgstr "" -#: builtin/apply.c:3231 builtin/apply.c:3242 builtin/apply.c:3287 +#: builtin/apply.c:3229 builtin/apply.c:3240 builtin/apply.c:3285 #, c-format msgid "read of %s failed" msgstr "" -#: builtin/apply.c:3239 +#: builtin/apply.c:3237 #, c-format msgid "reading from '%s' beyond a symbolic link" msgstr "" -#: builtin/apply.c:3267 builtin/apply.c:3489 +#: builtin/apply.c:3265 builtin/apply.c:3487 #, c-format msgid "path %s has been renamed/deleted" msgstr "" -#: builtin/apply.c:3348 builtin/apply.c:3503 +#: builtin/apply.c:3346 builtin/apply.c:3501 #, c-format msgid "%s: does not exist in index" msgstr "" -#: builtin/apply.c:3352 builtin/apply.c:3495 builtin/apply.c:3517 +#: builtin/apply.c:3350 builtin/apply.c:3493 builtin/apply.c:3515 #, c-format msgid "%s: %s" msgstr "" -#: builtin/apply.c:3357 builtin/apply.c:3511 +#: builtin/apply.c:3355 builtin/apply.c:3509 #, c-format msgid "%s: does not match index" msgstr "" -#: builtin/apply.c:3459 +#: builtin/apply.c:3457 msgid "removal patch leaves file contents" msgstr "" -#: builtin/apply.c:3528 +#: builtin/apply.c:3526 #, c-format msgid "%s: wrong type" msgstr "" -#: builtin/apply.c:3530 +#: builtin/apply.c:3528 #, c-format msgid "%s has type %o, expected %o" msgstr "" -#: builtin/apply.c:3689 builtin/apply.c:3691 +#: builtin/apply.c:3687 builtin/apply.c:3689 #, c-format msgid "invalid path '%s'" msgstr "" -#: builtin/apply.c:3746 +#: builtin/apply.c:3744 #, c-format msgid "%s: already exists in index" msgstr "" -#: builtin/apply.c:3749 +#: builtin/apply.c:3747 #, c-format msgid "%s: already exists in working directory" msgstr "" -#: builtin/apply.c:3769 +#: builtin/apply.c:3767 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "" -#: builtin/apply.c:3774 +#: builtin/apply.c:3772 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "" -#: builtin/apply.c:3794 +#: builtin/apply.c:3792 #, c-format msgid "affected file '%s' is beyond a symbolic link" msgstr "" -#: builtin/apply.c:3798 +#: builtin/apply.c:3796 #, c-format msgid "%s: patch does not apply" msgstr "" -#: builtin/apply.c:3812 +#: builtin/apply.c:3810 #, c-format msgid "Checking patch %s..." msgstr "" -#: builtin/apply.c:3905 builtin/checkout.c:233 builtin/reset.c:135 +#: builtin/apply.c:3903 builtin/checkout.c:233 builtin/reset.c:135 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "" -#: builtin/apply.c:4048 +#: builtin/apply.c:4046 #, c-format msgid "unable to remove %s from index" msgstr "" -#: builtin/apply.c:4077 +#: builtin/apply.c:4075 #, c-format msgid "corrupt patch for submodule %s" msgstr "" -#: builtin/apply.c:4081 +#: builtin/apply.c:4079 #, c-format msgid "unable to stat newly created file '%s'" msgstr "" -#: builtin/apply.c:4086 +#: builtin/apply.c:4084 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "" -#: builtin/apply.c:4089 builtin/apply.c:4197 +#: builtin/apply.c:4087 builtin/apply.c:4195 #, c-format msgid "unable to add cache entry for %s" msgstr "" -#: builtin/apply.c:4122 +#: builtin/apply.c:4120 #, c-format msgid "closing file '%s'" msgstr "" -#: builtin/apply.c:4171 +#: builtin/apply.c:4169 #, c-format msgid "unable to write file '%s' mode %o" msgstr "" -#: builtin/apply.c:4258 +#: builtin/apply.c:4256 #, c-format msgid "Applied patch %s cleanly." msgstr "" -#: builtin/apply.c:4266 +#: builtin/apply.c:4264 msgid "internal error" msgstr "" -#: builtin/apply.c:4269 +#: builtin/apply.c:4267 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:4279 +#: builtin/apply.c:4277 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "" -#: builtin/apply.c:4300 +#: builtin/apply.c:4285 +#, c-format +msgid "cannot open %s: %s" +msgstr "" + +#: builtin/apply.c:4298 #, c-format msgid "Hunk #%d applied cleanly." msgstr "" -#: builtin/apply.c:4303 +#: builtin/apply.c:4301 #, c-format msgid "Rejected hunk #%d." msgstr "" -#: builtin/apply.c:4393 +#: builtin/apply.c:4387 +#, c-format +msgid "Skipped patch '%s'." +msgstr "" + +#: builtin/apply.c:4395 msgid "unrecognized input" msgstr "" -#: builtin/apply.c:4404 +#: builtin/apply.c:4406 msgid "unable to read index file" msgstr "" -#: builtin/apply.c:4507 +#: builtin/apply.c:4509 msgid "don't apply changes matching the given path" msgstr "" -#: builtin/apply.c:4510 +#: builtin/apply.c:4512 msgid "apply changes matching the given path" msgstr "" -#: builtin/apply.c:4513 +#: builtin/apply.c:4515 msgid "remove <num> leading slashes from traditional diff paths" msgstr "" -#: builtin/apply.c:4516 +#: builtin/apply.c:4518 msgid "ignore additions made by the patch" msgstr "" -#: builtin/apply.c:4518 +#: builtin/apply.c:4520 msgid "instead of applying the patch, output diffstat for the input" msgstr "" -#: builtin/apply.c:4522 +#: builtin/apply.c:4524 msgid "show number of added and deleted lines in decimal notation" msgstr "" -#: builtin/apply.c:4524 +#: builtin/apply.c:4526 msgid "instead of applying the patch, output a summary for the input" msgstr "" -#: builtin/apply.c:4526 +#: builtin/apply.c:4528 msgid "instead of applying the patch, see if the patch is applicable" msgstr "" -#: builtin/apply.c:4528 +#: builtin/apply.c:4530 msgid "make sure the patch is applicable to the current index" msgstr "" -#: builtin/apply.c:4530 +#: builtin/apply.c:4532 msgid "apply a patch without touching the working tree" msgstr "" -#: builtin/apply.c:4532 +#: builtin/apply.c:4534 msgid "accept a patch that touches outside the working area" msgstr "" -#: builtin/apply.c:4534 +#: builtin/apply.c:4536 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "" -#: builtin/apply.c:4536 +#: builtin/apply.c:4538 msgid "attempt three-way merge if a patch does not apply" msgstr "" -#: builtin/apply.c:4538 +#: builtin/apply.c:4540 msgid "build a temporary index based on embedded index information" msgstr "" -#: builtin/apply.c:4541 builtin/checkout-index.c:169 builtin/ls-files.c:425 +#: builtin/apply.c:4543 builtin/checkout-index.c:169 builtin/ls-files.c:425 msgid "paths are separated with NUL character" msgstr "" -#: builtin/apply.c:4543 +#: builtin/apply.c:4545 msgid "ensure at least <n> lines of context match" msgstr "" -#: builtin/apply.c:4545 +#: builtin/apply.c:4547 msgid "detect new or modified lines that have whitespace errors" msgstr "" -#: builtin/apply.c:4548 builtin/apply.c:4551 +#: builtin/apply.c:4550 builtin/apply.c:4553 msgid "ignore changes in whitespace when finding context" msgstr "" -#: builtin/apply.c:4554 +#: builtin/apply.c:4556 msgid "apply the patch in reverse" msgstr "" -#: builtin/apply.c:4556 +#: builtin/apply.c:4558 msgid "don't expect at least one line of context" msgstr "" -#: builtin/apply.c:4558 +#: builtin/apply.c:4560 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "" -#: builtin/apply.c:4560 +#: builtin/apply.c:4562 msgid "allow overlapping hunks" msgstr "" -#: builtin/apply.c:4563 +#: builtin/apply.c:4565 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "" -#: builtin/apply.c:4566 +#: builtin/apply.c:4568 msgid "do not trust the line counts in the hunk headers" msgstr "" -#: builtin/apply.c:4569 +#: builtin/apply.c:4571 msgid "prepend <root> to all filenames" msgstr "" -#: builtin/apply.c:4591 +#: builtin/apply.c:4593 msgid "--3way outside a repository" msgstr "" -#: builtin/apply.c:4599 +#: builtin/apply.c:4601 msgid "--index outside a repository" msgstr "" -#: builtin/apply.c:4602 +#: builtin/apply.c:4604 msgid "--cached outside a repository" msgstr "" -#: builtin/apply.c:4621 +#: builtin/apply.c:4623 #, c-format msgid "can't open patch '%s'" msgstr "" -#: builtin/apply.c:4635 +#: builtin/apply.c:4637 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:4641 builtin/apply.c:4651 +#: builtin/apply.c:4643 builtin/apply.c:4653 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -3280,99 +3490,99 @@ msgstr "" msgid "Blaming lines" msgstr "" -#: builtin/blame.c:2530 +#: builtin/blame.c:2531 msgid "Show blame entries as we find them, incrementally" msgstr "" -#: builtin/blame.c:2531 +#: builtin/blame.c:2532 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" -#: builtin/blame.c:2532 +#: builtin/blame.c:2533 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "" -#: builtin/blame.c:2533 +#: builtin/blame.c:2534 msgid "Show work cost statistics" msgstr "" -#: builtin/blame.c:2534 +#: builtin/blame.c:2535 msgid "Force progress reporting" msgstr "" -#: builtin/blame.c:2535 +#: builtin/blame.c:2536 msgid "Show output score for blame entries" msgstr "" -#: builtin/blame.c:2536 +#: builtin/blame.c:2537 msgid "Show original filename (Default: auto)" msgstr "" -#: builtin/blame.c:2537 +#: builtin/blame.c:2538 msgid "Show original linenumber (Default: off)" msgstr "" -#: builtin/blame.c:2538 +#: builtin/blame.c:2539 msgid "Show in a format designed for machine consumption" msgstr "" -#: builtin/blame.c:2539 +#: builtin/blame.c:2540 msgid "Show porcelain format with per-line commit information" msgstr "" -#: builtin/blame.c:2540 +#: builtin/blame.c:2541 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "" -#: builtin/blame.c:2541 +#: builtin/blame.c:2542 msgid "Show raw timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2542 +#: builtin/blame.c:2543 msgid "Show long commit SHA1 (Default: off)" msgstr "" -#: builtin/blame.c:2543 +#: builtin/blame.c:2544 msgid "Suppress author name and timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2544 +#: builtin/blame.c:2545 msgid "Show author email instead of name (Default: off)" msgstr "" -#: builtin/blame.c:2545 +#: builtin/blame.c:2546 msgid "Ignore whitespace differences" msgstr "" -#: builtin/blame.c:2546 +#: builtin/blame.c:2547 msgid "Spend extra cycles to find better match" msgstr "" -#: builtin/blame.c:2547 +#: builtin/blame.c:2548 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "" -#: builtin/blame.c:2548 +#: builtin/blame.c:2549 msgid "Use <file>'s contents as the final image" msgstr "" -#: builtin/blame.c:2549 builtin/blame.c:2550 +#: builtin/blame.c:2550 builtin/blame.c:2551 msgid "score" msgstr "" -#: builtin/blame.c:2549 +#: builtin/blame.c:2550 msgid "Find line copies within and across files" msgstr "" -#: builtin/blame.c:2550 +#: builtin/blame.c:2551 msgid "Find line movements within and across files" msgstr "" -#: builtin/blame.c:2551 +#: builtin/blame.c:2552 msgid "n,m" msgstr "" -#: builtin/blame.c:2551 +#: builtin/blame.c:2552 msgid "Process only line range n,m, counting from 1" msgstr "" @@ -3382,392 +3592,413 @@ msgstr "" #. takes 22 places, is the longest among various forms of #. relative timestamps, but your language may need more or #. fewer display columns. -#: builtin/blame.c:2640 +#: builtin/blame.c:2641 msgid "4 years, 11 months ago" msgstr "" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [<options>] [-r | -a] [--merged | --no-merged]" msgstr "" -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [<options>] [-l] [-f] <branch-name> [<start-point>]" msgstr "" -#: builtin/branch.c:27 +#: builtin/branch.c:28 msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..." msgstr "" -#: builtin/branch.c:28 +#: builtin/branch.c:29 msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>" msgstr "" -#: builtin/branch.c:29 +#: builtin/branch.c:30 msgid "git branch [<options>] [-r | -a] [--points-at]" msgstr "" -#: builtin/branch.c:142 +#: builtin/branch.c:143 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" " '%s', but not yet merged to HEAD." msgstr "" -#: builtin/branch.c:146 +#: builtin/branch.c:147 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" " '%s', even though it is merged to HEAD." msgstr "" -#: builtin/branch.c:160 +#: builtin/branch.c:161 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "" -#: builtin/branch.c:164 +#: builtin/branch.c:165 #, c-format msgid "" "The branch '%s' is not fully merged.\n" "If you are sure you want to delete it, run 'git branch -D %s'." msgstr "" -#: builtin/branch.c:177 +#: builtin/branch.c:178 msgid "Update of config-file failed" msgstr "" -#: builtin/branch.c:205 +#: builtin/branch.c:206 msgid "cannot use -a with -d" msgstr "" -#: builtin/branch.c:211 +#: builtin/branch.c:212 msgid "Couldn't look up commit object for HEAD" msgstr "" -#: builtin/branch.c:219 +#: builtin/branch.c:226 #, c-format -msgid "Cannot delete the branch '%s' which you are currently on." +msgid "Cannot delete branch '%s' checked out at '%s'" msgstr "" -#: builtin/branch.c:235 +#: builtin/branch.c:241 #, c-format msgid "remote-tracking branch '%s' not found." msgstr "" -#: builtin/branch.c:236 +#: builtin/branch.c:242 #, c-format msgid "branch '%s' not found." msgstr "" -#: builtin/branch.c:251 +#: builtin/branch.c:257 #, c-format msgid "Error deleting remote-tracking branch '%s'" msgstr "" -#: builtin/branch.c:252 +#: builtin/branch.c:258 #, c-format msgid "Error deleting branch '%s'" msgstr "" -#: builtin/branch.c:259 +#: builtin/branch.c:265 #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:260 +#: builtin/branch.c:266 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:303 +#: builtin/branch.c:309 #, c-format msgid "[%s: gone]" msgstr "" -#: builtin/branch.c:308 +#: builtin/branch.c:314 #, c-format msgid "[%s]" msgstr "" -#: builtin/branch.c:313 +#: builtin/branch.c:319 #, c-format msgid "[%s: behind %d]" msgstr "" -#: builtin/branch.c:315 +#: builtin/branch.c:321 #, c-format msgid "[behind %d]" msgstr "" -#: builtin/branch.c:319 +#: builtin/branch.c:325 #, c-format msgid "[%s: ahead %d]" msgstr "" -#: builtin/branch.c:321 +#: builtin/branch.c:327 #, c-format msgid "[ahead %d]" msgstr "" -#: builtin/branch.c:324 +#: builtin/branch.c:330 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:327 +#: builtin/branch.c:333 #, c-format msgid "[ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:340 +#: builtin/branch.c:346 msgid " **** invalid ref ****" msgstr "" -#: builtin/branch.c:366 +#: builtin/branch.c:372 #, c-format msgid "(no branch, rebasing %s)" msgstr "" -#: builtin/branch.c:369 +#: builtin/branch.c:375 #, c-format msgid "(no branch, bisect started on %s)" msgstr "" -#: builtin/branch.c:375 +#. TRANSLATORS: make sure this matches +#. "HEAD detached at " in wt-status.c +#: builtin/branch.c:381 #, c-format msgid "(HEAD detached at %s)" msgstr "" -#: builtin/branch.c:378 +#. TRANSLATORS: make sure this matches +#. "HEAD detached from " in wt-status.c +#: builtin/branch.c:386 #, c-format msgid "(HEAD detached from %s)" msgstr "" -#: builtin/branch.c:382 +#: builtin/branch.c:390 msgid "(no branch)" msgstr "" -#: builtin/branch.c:524 +#: builtin/branch.c:541 +#, c-format +msgid "Branch %s is being rebased at %s" +msgstr "" + +#: builtin/branch.c:545 +#, c-format +msgid "Branch %s is being bisected at %s" +msgstr "" + +#: builtin/branch.c:560 msgid "cannot rename the current branch while not on any." msgstr "" -#: builtin/branch.c:534 +#: builtin/branch.c:570 #, c-format msgid "Invalid branch name: '%s'" msgstr "" -#: builtin/branch.c:549 +#: builtin/branch.c:587 msgid "Branch rename failed" msgstr "" -#: builtin/branch.c:553 +#: builtin/branch.c:591 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "" -#: builtin/branch.c:557 +#: builtin/branch.c:594 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "" -#: builtin/branch.c:564 +#: builtin/branch.c:601 msgid "Branch is renamed, but update of config-file failed" msgstr "" -#: builtin/branch.c:586 -#, c-format -msgid "could not write branch description template: %s" +#: builtin/branch.c:623 +msgid "could not write branch description template" msgstr "" -#: builtin/branch.c:615 +#: builtin/branch.c:651 msgid "Generic options" msgstr "" -#: builtin/branch.c:617 +#: builtin/branch.c:653 msgid "show hash and subject, give twice for upstream branch" msgstr "" -#: builtin/branch.c:618 +#: builtin/branch.c:654 msgid "suppress informational messages" msgstr "" -#: builtin/branch.c:619 +#: builtin/branch.c:655 msgid "set up tracking mode (see git-pull(1))" msgstr "" -#: builtin/branch.c:621 +#: builtin/branch.c:657 msgid "change upstream info" msgstr "" -#: builtin/branch.c:625 +#: builtin/branch.c:659 +msgid "upstream" +msgstr "" + +#: builtin/branch.c:659 +msgid "change the upstream info" +msgstr "" + +#: builtin/branch.c:661 msgid "use colored output" msgstr "" -#: builtin/branch.c:626 +#: builtin/branch.c:662 msgid "act on remote-tracking branches" msgstr "" -#: builtin/branch.c:628 builtin/branch.c:629 +#: builtin/branch.c:664 builtin/branch.c:665 msgid "print only branches that contain the commit" msgstr "" -#: builtin/branch.c:632 +#: builtin/branch.c:668 msgid "Specific git-branch actions:" msgstr "" -#: builtin/branch.c:633 +#: builtin/branch.c:669 msgid "list both remote-tracking and local branches" msgstr "" -#: builtin/branch.c:635 +#: builtin/branch.c:671 msgid "delete fully merged branch" msgstr "" -#: builtin/branch.c:636 +#: builtin/branch.c:672 msgid "delete branch (even if not merged)" msgstr "" -#: builtin/branch.c:637 +#: builtin/branch.c:673 msgid "move/rename a branch and its reflog" msgstr "" -#: builtin/branch.c:638 +#: builtin/branch.c:674 msgid "move/rename a branch, even if target exists" msgstr "" -#: builtin/branch.c:639 +#: builtin/branch.c:675 msgid "list branch names" msgstr "" -#: builtin/branch.c:640 +#: builtin/branch.c:676 msgid "create the branch's reflog" msgstr "" -#: builtin/branch.c:642 +#: builtin/branch.c:678 msgid "edit the description for the branch" msgstr "" -#: builtin/branch.c:643 +#: builtin/branch.c:679 msgid "force creation, move/rename, deletion" msgstr "" -#: builtin/branch.c:644 +#: builtin/branch.c:680 msgid "print only branches that are merged" msgstr "" -#: builtin/branch.c:645 +#: builtin/branch.c:681 msgid "print only branches that are not merged" msgstr "" -#: builtin/branch.c:646 +#: builtin/branch.c:682 msgid "list branches in columns" msgstr "" -#: builtin/branch.c:647 builtin/for-each-ref.c:38 builtin/tag.c:366 +#: builtin/branch.c:683 builtin/for-each-ref.c:38 builtin/tag.c:366 msgid "key" msgstr "" -#: builtin/branch.c:648 builtin/for-each-ref.c:39 builtin/tag.c:367 +#: builtin/branch.c:684 builtin/for-each-ref.c:39 builtin/tag.c:367 msgid "field name to sort on" msgstr "" -#: builtin/branch.c:650 builtin/for-each-ref.c:41 builtin/notes.c:401 +#: builtin/branch.c:686 builtin/for-each-ref.c:41 builtin/notes.c:401 #: builtin/notes.c:404 builtin/notes.c:564 builtin/notes.c:567 #: builtin/tag.c:369 msgid "object" msgstr "" -#: builtin/branch.c:651 +#: builtin/branch.c:687 msgid "print only branches of the object" msgstr "" -#: builtin/branch.c:669 +#: builtin/branch.c:705 msgid "Failed to resolve HEAD as a valid ref." msgstr "" -#: builtin/branch.c:673 builtin/clone.c:705 +#: builtin/branch.c:709 builtin/clone.c:707 msgid "HEAD not found below refs/heads!" msgstr "" -#: builtin/branch.c:693 +#: builtin/branch.c:729 msgid "--column and --verbose are incompatible" msgstr "" -#: builtin/branch.c:704 builtin/branch.c:746 +#: builtin/branch.c:740 builtin/branch.c:782 msgid "branch name required" msgstr "" -#: builtin/branch.c:722 +#: builtin/branch.c:758 msgid "Cannot give description to detached HEAD" msgstr "" -#: builtin/branch.c:727 +#: builtin/branch.c:763 msgid "cannot edit description of more than one branch" msgstr "" -#: builtin/branch.c:734 +#: builtin/branch.c:770 #, c-format msgid "No commit on branch '%s' yet." msgstr "" -#: builtin/branch.c:737 +#: builtin/branch.c:773 #, c-format msgid "No branch named '%s'." msgstr "" -#: builtin/branch.c:752 +#: builtin/branch.c:788 msgid "too many branches for a rename operation" msgstr "" -#: builtin/branch.c:757 +#: builtin/branch.c:793 msgid "too many branches to set new upstream" msgstr "" -#: builtin/branch.c:761 +#: builtin/branch.c:797 #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch." msgstr "" -#: builtin/branch.c:764 builtin/branch.c:786 builtin/branch.c:807 +#: builtin/branch.c:800 builtin/branch.c:822 builtin/branch.c:843 #, c-format msgid "no such branch '%s'" msgstr "" -#: builtin/branch.c:768 +#: builtin/branch.c:804 #, c-format msgid "branch '%s' does not exist" msgstr "" -#: builtin/branch.c:780 +#: builtin/branch.c:816 msgid "too many branches to unset upstream" msgstr "" -#: builtin/branch.c:784 +#: builtin/branch.c:820 msgid "could not unset upstream of HEAD when it does not point to any branch." msgstr "" -#: builtin/branch.c:790 +#: builtin/branch.c:826 #, c-format msgid "Branch '%s' has no upstream information" msgstr "" -#: builtin/branch.c:804 +#: builtin/branch.c:840 msgid "it does not make sense to create 'HEAD' manually" msgstr "" -#: builtin/branch.c:810 +#: builtin/branch.c:846 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" -#: builtin/branch.c:813 +#: builtin/branch.c:849 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" "track or --set-upstream-to\n" msgstr "" -#: builtin/branch.c:830 +#: builtin/branch.c:866 #, c-format msgid "" "\n" @@ -3775,16 +4006,6 @@ msgid "" "\n" msgstr "" -#: builtin/branch.c:831 -#, c-format -msgid " git branch -d %s\n" -msgstr "" - -#: builtin/branch.c:832 -#, c-format -msgid " git branch --set-upstream-to %s\n" -msgstr "" - #: builtin/bundle.c:51 #, c-format msgid "%s is okay\n" @@ -3880,7 +4101,7 @@ msgstr "" msgid "terminate input and output records by a NUL character" msgstr "" -#: builtin/check-ignore.c:18 builtin/checkout.c:1136 builtin/gc.c:325 +#: builtin/check-ignore.c:18 builtin/checkout.c:1135 builtin/gc.c:325 msgid "suppress progress reporting" msgstr "" @@ -3970,8 +4191,9 @@ msgid "write the content to temporary files" msgstr "" #: builtin/checkout-index.c:174 builtin/column.c:30 -#: builtin/submodule--helper.c:166 builtin/submodule--helper.c:169 -#: builtin/submodule--helper.c:172 builtin/submodule--helper.c:175 +#: builtin/submodule--helper.c:491 builtin/submodule--helper.c:494 +#: builtin/submodule--helper.c:497 builtin/submodule--helper.c:500 +#: builtin/submodule--helper.c:774 msgid "string" msgstr "" @@ -4021,79 +4243,79 @@ msgstr "" msgid "Unable to add merge result for '%s'" msgstr "" -#: builtin/checkout.c:251 builtin/checkout.c:254 builtin/checkout.c:257 -#: builtin/checkout.c:260 +#: builtin/checkout.c:250 builtin/checkout.c:253 builtin/checkout.c:256 +#: builtin/checkout.c:259 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "" -#: builtin/checkout.c:263 builtin/checkout.c:266 +#: builtin/checkout.c:262 builtin/checkout.c:265 #, c-format msgid "'%s' cannot be used with %s" msgstr "" -#: builtin/checkout.c:269 +#: builtin/checkout.c:268 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "" -#: builtin/checkout.c:280 builtin/checkout.c:474 +#: builtin/checkout.c:279 builtin/checkout.c:473 msgid "corrupt index file" msgstr "" -#: builtin/checkout.c:340 builtin/checkout.c:347 +#: builtin/checkout.c:339 builtin/checkout.c:346 #, c-format msgid "path '%s' is unmerged" msgstr "" -#: builtin/checkout.c:496 +#: builtin/checkout.c:495 msgid "you need to resolve your current index first" msgstr "" -#: builtin/checkout.c:623 +#: builtin/checkout.c:622 #, c-format msgid "Can not do reflog for '%s': %s\n" msgstr "" -#: builtin/checkout.c:661 +#: builtin/checkout.c:660 msgid "HEAD is now at" msgstr "" -#: builtin/checkout.c:665 builtin/clone.c:659 +#: builtin/checkout.c:664 builtin/clone.c:661 msgid "unable to update HEAD" msgstr "" -#: builtin/checkout.c:669 +#: builtin/checkout.c:668 #, c-format msgid "Reset branch '%s'\n" msgstr "" -#: builtin/checkout.c:672 +#: builtin/checkout.c:671 #, c-format msgid "Already on '%s'\n" msgstr "" -#: builtin/checkout.c:676 +#: builtin/checkout.c:675 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "" -#: builtin/checkout.c:678 builtin/checkout.c:1068 +#: builtin/checkout.c:677 builtin/checkout.c:1067 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "" -#: builtin/checkout.c:680 +#: builtin/checkout.c:679 #, c-format msgid "Switched to branch '%s'\n" msgstr "" -#: builtin/checkout.c:732 +#: builtin/checkout.c:731 #, c-format msgid " ... and %d more.\n" msgstr "" -#: builtin/checkout.c:738 +#: builtin/checkout.c:737 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -4108,7 +4330,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: builtin/checkout.c:757 +#: builtin/checkout.c:756 #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -4125,162 +4347,162 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: builtin/checkout.c:793 +#: builtin/checkout.c:792 msgid "internal error in revision walk" msgstr "" -#: builtin/checkout.c:797 +#: builtin/checkout.c:796 msgid "Previous HEAD position was" msgstr "" -#: builtin/checkout.c:824 builtin/checkout.c:1063 +#: builtin/checkout.c:823 builtin/checkout.c:1062 msgid "You are on a branch yet to be born" msgstr "" -#: builtin/checkout.c:969 +#: builtin/checkout.c:968 #, c-format msgid "only one reference expected, %d given." msgstr "" -#: builtin/checkout.c:1009 builtin/worktree.c:211 +#: builtin/checkout.c:1008 builtin/worktree.c:212 #, c-format msgid "invalid reference: %s" msgstr "" -#: builtin/checkout.c:1038 +#: builtin/checkout.c:1037 #, c-format msgid "reference is not a tree: %s" msgstr "" -#: builtin/checkout.c:1077 +#: builtin/checkout.c:1076 msgid "paths cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:1080 builtin/checkout.c:1084 +#: builtin/checkout.c:1079 builtin/checkout.c:1083 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:1088 builtin/checkout.c:1091 builtin/checkout.c:1096 -#: builtin/checkout.c:1099 +#: builtin/checkout.c:1087 builtin/checkout.c:1090 builtin/checkout.c:1095 +#: builtin/checkout.c:1098 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "" -#: builtin/checkout.c:1104 +#: builtin/checkout.c:1103 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "" -#: builtin/checkout.c:1137 builtin/checkout.c:1139 builtin/clone.c:84 -#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:318 -#: builtin/worktree.c:320 +#: builtin/checkout.c:1136 builtin/checkout.c:1138 builtin/clone.c:88 +#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:323 +#: builtin/worktree.c:325 msgid "branch" msgstr "" -#: builtin/checkout.c:1138 +#: builtin/checkout.c:1137 msgid "create and checkout a new branch" msgstr "" -#: builtin/checkout.c:1140 +#: builtin/checkout.c:1139 msgid "create/reset and checkout a branch" msgstr "" -#: builtin/checkout.c:1141 +#: builtin/checkout.c:1140 msgid "create reflog for new branch" msgstr "" -#: builtin/checkout.c:1142 +#: builtin/checkout.c:1141 msgid "detach the HEAD at named commit" msgstr "" -#: builtin/checkout.c:1143 +#: builtin/checkout.c:1142 msgid "set upstream info for new branch" msgstr "" -#: builtin/checkout.c:1145 +#: builtin/checkout.c:1144 msgid "new-branch" msgstr "" -#: builtin/checkout.c:1145 +#: builtin/checkout.c:1144 msgid "new unparented branch" msgstr "" -#: builtin/checkout.c:1146 +#: builtin/checkout.c:1145 msgid "checkout our version for unmerged files" msgstr "" -#: builtin/checkout.c:1148 +#: builtin/checkout.c:1147 msgid "checkout their version for unmerged files" msgstr "" -#: builtin/checkout.c:1150 +#: builtin/checkout.c:1149 msgid "force checkout (throw away local modifications)" msgstr "" -#: builtin/checkout.c:1151 +#: builtin/checkout.c:1150 msgid "perform a 3-way merge with the new branch" msgstr "" -#: builtin/checkout.c:1152 builtin/merge.c:227 +#: builtin/checkout.c:1151 builtin/merge.c:230 msgid "update ignored files (default)" msgstr "" -#: builtin/checkout.c:1153 builtin/log.c:1269 parse-options.h:250 +#: builtin/checkout.c:1152 builtin/log.c:1432 parse-options.h:250 msgid "style" msgstr "" -#: builtin/checkout.c:1154 +#: builtin/checkout.c:1153 msgid "conflict style (merge or diff3)" msgstr "" -#: builtin/checkout.c:1157 +#: builtin/checkout.c:1156 msgid "do not limit pathspecs to sparse entries only" msgstr "" -#: builtin/checkout.c:1159 +#: builtin/checkout.c:1158 msgid "second guess 'git checkout <no-such-branch>'" msgstr "" -#: builtin/checkout.c:1161 +#: builtin/checkout.c:1160 msgid "do not check if another worktree is holding the given ref" msgstr "" -#: builtin/checkout.c:1162 builtin/clone.c:58 builtin/fetch.c:116 -#: builtin/merge.c:224 builtin/pull.c:113 builtin/push.c:526 +#: builtin/checkout.c:1161 builtin/clone.c:60 builtin/fetch.c:116 +#: builtin/merge.c:227 builtin/pull.c:116 builtin/push.c:526 #: builtin/send-pack.c:168 msgid "force progress reporting" msgstr "" -#: builtin/checkout.c:1193 +#: builtin/checkout.c:1192 msgid "-b, -B and --orphan are mutually exclusive" msgstr "" -#: builtin/checkout.c:1210 +#: builtin/checkout.c:1209 msgid "--track needs a branch name" msgstr "" -#: builtin/checkout.c:1215 +#: builtin/checkout.c:1214 msgid "Missing branch name; try -b" msgstr "" -#: builtin/checkout.c:1251 +#: builtin/checkout.c:1250 msgid "invalid path specification" msgstr "" -#: builtin/checkout.c:1258 +#: builtin/checkout.c:1257 #, c-format 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 "" -#: builtin/checkout.c:1263 +#: builtin/checkout.c:1262 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "" -#: builtin/checkout.c:1267 +#: builtin/checkout.c:1266 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -4410,8 +4632,8 @@ msgstr "" msgid "remove whole directories" msgstr "" -#: builtin/clean.c:875 builtin/describe.c:407 builtin/grep.c:722 -#: builtin/ls-files.c:456 builtin/name-rev.c:307 builtin/show-ref.c:182 +#: builtin/clean.c:875 builtin/describe.c:407 builtin/grep.c:724 +#: builtin/ls-files.c:456 builtin/name-rev.c:314 builtin/show-ref.c:182 msgid "pattern" msgstr "" @@ -4447,286 +4669,290 @@ msgstr "" msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "" -#: builtin/clone.c:60 +#: builtin/clone.c:62 msgid "don't create a checkout" msgstr "" -#: builtin/clone.c:61 builtin/clone.c:63 builtin/init-db.c:469 +#: builtin/clone.c:63 builtin/clone.c:65 builtin/init-db.c:473 msgid "create a bare repository" msgstr "" -#: builtin/clone.c:65 +#: builtin/clone.c:67 msgid "create a mirror repository (implies bare)" msgstr "" -#: builtin/clone.c:67 +#: builtin/clone.c:69 msgid "to clone from a local repository" msgstr "" -#: builtin/clone.c:69 +#: builtin/clone.c:71 msgid "don't use local hardlinks, always copy" msgstr "" -#: builtin/clone.c:71 +#: builtin/clone.c:73 msgid "setup as shared repository" msgstr "" -#: builtin/clone.c:73 builtin/clone.c:75 +#: builtin/clone.c:75 builtin/clone.c:77 msgid "initialize submodules in the clone" msgstr "" -#: builtin/clone.c:76 builtin/init-db.c:466 +#: builtin/clone.c:79 +msgid "number of submodules cloned in parallel" +msgstr "" + +#: builtin/clone.c:80 builtin/init-db.c:470 msgid "template-directory" msgstr "" -#: builtin/clone.c:77 builtin/init-db.c:467 +#: builtin/clone.c:81 builtin/init-db.c:471 msgid "directory from which templates will be used" msgstr "" -#: builtin/clone.c:79 builtin/submodule--helper.c:173 +#: builtin/clone.c:83 builtin/submodule--helper.c:498 +#: builtin/submodule--helper.c:777 msgid "reference repository" msgstr "" -#: builtin/clone.c:81 +#: builtin/clone.c:85 msgid "use --reference only while cloning" msgstr "" -#: builtin/clone.c:82 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "" -#: builtin/clone.c:83 +#: builtin/clone.c:87 msgid "use <name> instead of 'origin' to track upstream" msgstr "" -#: builtin/clone.c:85 +#: builtin/clone.c:89 msgid "checkout <branch> instead of the remote's HEAD" msgstr "" -#: builtin/clone.c:87 +#: builtin/clone.c:91 msgid "path to git-upload-pack on the remote" msgstr "" -#: builtin/clone.c:88 builtin/fetch.c:117 builtin/grep.c:665 -#: builtin/pull.c:193 +#: builtin/clone.c:92 builtin/fetch.c:117 builtin/grep.c:667 +#: builtin/pull.c:201 msgid "depth" msgstr "" -#: builtin/clone.c:89 +#: builtin/clone.c:93 msgid "create a shallow clone of that depth" msgstr "" -#: builtin/clone.c:91 +#: builtin/clone.c:95 msgid "clone only one branch, HEAD or --branch" msgstr "" -#: builtin/clone.c:92 builtin/init-db.c:475 +#: builtin/clone.c:97 +msgid "any cloned submodules will be shallow" +msgstr "" + +#: builtin/clone.c:98 builtin/init-db.c:479 msgid "gitdir" msgstr "" -#: builtin/clone.c:93 builtin/init-db.c:476 +#: builtin/clone.c:99 builtin/init-db.c:480 msgid "separate git dir from working tree" msgstr "" -#: builtin/clone.c:94 +#: builtin/clone.c:100 msgid "key=value" msgstr "" -#: builtin/clone.c:95 +#: builtin/clone.c:101 msgid "set config inside the new repository" msgstr "" -#: builtin/clone.c:96 builtin/fetch.c:131 builtin/push.c:536 +#: builtin/clone.c:102 builtin/fetch.c:131 builtin/push.c:536 msgid "use IPv4 addresses only" msgstr "" -#: builtin/clone.c:98 builtin/fetch.c:133 builtin/push.c:538 +#: builtin/clone.c:104 builtin/fetch.c:133 builtin/push.c:538 msgid "use IPv6 addresses only" msgstr "" -#: builtin/clone.c:239 +#: builtin/clone.c:241 msgid "" "No directory name could be guessed.\n" "Please specify a directory on the command line" msgstr "" -#: builtin/clone.c:305 +#: builtin/clone.c:307 #, c-format msgid "reference repository '%s' as a linked checkout is not supported yet." msgstr "" -#: builtin/clone.c:307 +#: builtin/clone.c:309 #, c-format msgid "reference repository '%s' is not a local repository." msgstr "" -#: builtin/clone.c:312 +#: builtin/clone.c:314 #, c-format msgid "reference repository '%s' is shallow" msgstr "" -#: builtin/clone.c:315 +#: builtin/clone.c:317 #, c-format msgid "reference repository '%s' is grafted" msgstr "" -#: builtin/clone.c:380 builtin/diff.c:84 -#, c-format -msgid "failed to stat '%s'" -msgstr "" - -#: builtin/clone.c:382 +#: builtin/clone.c:384 #, c-format msgid "%s exists and is not a directory" msgstr "" -#: builtin/clone.c:396 +#: builtin/clone.c:398 #, c-format msgid "failed to stat %s\n" msgstr "" -#: builtin/clone.c:418 +#: builtin/clone.c:420 #, c-format msgid "failed to create link '%s'" msgstr "" -#: builtin/clone.c:422 +#: builtin/clone.c:424 #, c-format msgid "failed to copy file to '%s'" msgstr "" -#: builtin/clone.c:447 builtin/clone.c:631 +#: builtin/clone.c:449 builtin/clone.c:633 #, c-format msgid "done.\n" msgstr "" -#: builtin/clone.c:459 +#: builtin/clone.c:461 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" "and retry the checkout with 'git checkout -f HEAD'\n" msgstr "" -#: builtin/clone.c:536 +#: builtin/clone.c:538 #, c-format msgid "Could not find remote branch %s to clone." msgstr "" -#: builtin/clone.c:626 +#: builtin/clone.c:628 #, c-format msgid "Checking connectivity... " msgstr "" -#: builtin/clone.c:629 +#: builtin/clone.c:631 msgid "remote did not send all necessary objects" msgstr "" -#: builtin/clone.c:647 +#: builtin/clone.c:649 #, c-format msgid "unable to update %s" msgstr "" -#: builtin/clone.c:696 +#: builtin/clone.c:698 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" -#: builtin/clone.c:727 +#: builtin/clone.c:729 msgid "unable to checkout working tree" msgstr "" -#: builtin/clone.c:753 +#: builtin/clone.c:767 msgid "unable to write parameters to config file" msgstr "" -#: builtin/clone.c:816 +#: builtin/clone.c:830 msgid "cannot repack to clean up" msgstr "" -#: builtin/clone.c:818 +#: builtin/clone.c:832 msgid "cannot unlink temporary alternates file" msgstr "" -#: builtin/clone.c:850 +#: builtin/clone.c:864 builtin/receive-pack.c:1731 msgid "Too many arguments." msgstr "" -#: builtin/clone.c:854 +#: builtin/clone.c:868 msgid "You must specify a repository to clone." msgstr "" -#: builtin/clone.c:865 +#: builtin/clone.c:879 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "" -#: builtin/clone.c:868 +#: builtin/clone.c:882 msgid "--bare and --separate-git-dir are incompatible." msgstr "" -#: builtin/clone.c:881 +#: builtin/clone.c:895 #, c-format msgid "repository '%s' does not exist" msgstr "" -#: builtin/clone.c:887 builtin/fetch.c:1174 +#: builtin/clone.c:901 builtin/fetch.c:1174 #, c-format msgid "depth %s is not a positive number" msgstr "" -#: builtin/clone.c:897 +#: builtin/clone.c:911 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "" -#: builtin/clone.c:907 +#: builtin/clone.c:921 #, c-format msgid "working tree '%s' already exists." msgstr "" -#: builtin/clone.c:922 builtin/clone.c:933 builtin/submodule--helper.c:218 -#: builtin/worktree.c:219 builtin/worktree.c:246 +#: builtin/clone.c:936 builtin/clone.c:947 builtin/submodule--helper.c:547 +#: builtin/worktree.c:220 builtin/worktree.c:247 #, c-format msgid "could not create leading directories of '%s'" msgstr "" -#: builtin/clone.c:925 +#: builtin/clone.c:939 #, c-format msgid "could not create work tree dir '%s'" msgstr "" -#: builtin/clone.c:943 +#: builtin/clone.c:957 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "" -#: builtin/clone.c:945 +#: builtin/clone.c:959 #, c-format msgid "Cloning into '%s'...\n" msgstr "" -#: builtin/clone.c:984 +#: builtin/clone.c:998 msgid "--depth is ignored in local clones; use file:// instead." msgstr "" -#: builtin/clone.c:987 +#: builtin/clone.c:1001 msgid "source repository is shallow, ignoring --local" msgstr "" -#: builtin/clone.c:992 +#: builtin/clone.c:1006 msgid "--local is ignored" msgstr "" -#: builtin/clone.c:996 +#: builtin/clone.c:1010 #, c-format msgid "Don't know how to clone %s" msgstr "" -#: builtin/clone.c:1045 builtin/clone.c:1053 +#: builtin/clone.c:1059 builtin/clone.c:1067 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "" -#: builtin/clone.c:1056 +#: builtin/clone.c:1070 msgid "You appear to have cloned an empty repository." msgstr "" @@ -4829,103 +5055,103 @@ msgid "" "the remaining commits.\n" msgstr "" -#: builtin/commit.c:305 +#: builtin/commit.c:307 msgid "failed to unpack HEAD tree object" msgstr "" -#: builtin/commit.c:346 +#: builtin/commit.c:348 msgid "unable to create temporary index" msgstr "" -#: builtin/commit.c:352 +#: builtin/commit.c:354 msgid "interactive add failed" msgstr "" -#: builtin/commit.c:365 +#: builtin/commit.c:367 msgid "unable to update temporary index" msgstr "" -#: builtin/commit.c:367 +#: builtin/commit.c:369 msgid "Failed to update main cache tree" msgstr "" -#: builtin/commit.c:391 builtin/commit.c:414 builtin/commit.c:463 +#: builtin/commit.c:393 builtin/commit.c:416 builtin/commit.c:465 msgid "unable to write new_index file" msgstr "" -#: builtin/commit.c:445 +#: builtin/commit.c:447 msgid "cannot do a partial commit during a merge." msgstr "" -#: builtin/commit.c:447 +#: builtin/commit.c:449 msgid "cannot do a partial commit during a cherry-pick." msgstr "" -#: builtin/commit.c:456 +#: builtin/commit.c:458 msgid "cannot read the index" msgstr "" -#: builtin/commit.c:475 +#: builtin/commit.c:477 msgid "unable to write temporary index file" msgstr "" -#: builtin/commit.c:580 +#: builtin/commit.c:582 #, c-format msgid "commit '%s' lacks author header" msgstr "" -#: builtin/commit.c:582 +#: builtin/commit.c:584 #, c-format msgid "commit '%s' has malformed author line" msgstr "" -#: builtin/commit.c:601 +#: builtin/commit.c:603 msgid "malformed --author parameter" msgstr "" -#: builtin/commit.c:609 +#: builtin/commit.c:611 #, c-format msgid "invalid date format: %s" msgstr "" -#: builtin/commit.c:653 +#: builtin/commit.c:655 msgid "" "unable to select a comment character that is not used\n" "in the current commit message" msgstr "" -#: builtin/commit.c:690 builtin/commit.c:723 builtin/commit.c:1080 +#: builtin/commit.c:692 builtin/commit.c:725 builtin/commit.c:1091 #, c-format msgid "could not lookup commit %s" msgstr "" -#: builtin/commit.c:702 builtin/shortlog.c:285 +#: builtin/commit.c:704 builtin/shortlog.c:285 #, c-format msgid "(reading log message from standard input)\n" msgstr "" -#: builtin/commit.c:704 +#: builtin/commit.c:706 msgid "could not read log from standard input" msgstr "" -#: builtin/commit.c:708 +#: builtin/commit.c:710 #, c-format msgid "could not read log file '%s'" msgstr "" -#: builtin/commit.c:730 -msgid "could not read MERGE_MSG" +#: builtin/commit.c:737 builtin/commit.c:745 +msgid "could not read SQUASH_MSG" msgstr "" -#: builtin/commit.c:734 -msgid "could not read SQUASH_MSG" +#: builtin/commit.c:742 +msgid "could not read MERGE_MSG" msgstr "" -#: builtin/commit.c:785 +#: builtin/commit.c:796 msgid "could not write commit template" msgstr "" -#: builtin/commit.c:803 +#: builtin/commit.c:814 #, c-format msgid "" "\n" @@ -4935,7 +5161,7 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:808 +#: builtin/commit.c:819 #, c-format msgid "" "\n" @@ -4945,14 +5171,14 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:821 +#: builtin/commit.c:832 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" "with '%c' will be ignored, and an empty message aborts the commit.\n" msgstr "" -#: builtin/commit.c:828 +#: builtin/commit.c:839 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -4960,341 +5186,341 @@ msgid "" "An empty message aborts the commit.\n" msgstr "" -#: builtin/commit.c:848 +#: builtin/commit.c:859 #, c-format msgid "%sAuthor: %.*s <%.*s>" msgstr "" -#: builtin/commit.c:856 +#: builtin/commit.c:867 #, c-format msgid "%sDate: %s" msgstr "" -#: builtin/commit.c:863 +#: builtin/commit.c:874 #, c-format msgid "%sCommitter: %.*s <%.*s>" msgstr "" -#: builtin/commit.c:881 +#: builtin/commit.c:892 msgid "Cannot read index" msgstr "" -#: builtin/commit.c:938 +#: builtin/commit.c:949 msgid "Error building trees" msgstr "" -#: builtin/commit.c:953 builtin/tag.c:266 +#: builtin/commit.c:964 builtin/tag.c:266 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "" -#: builtin/commit.c:1055 +#: builtin/commit.c:1066 #, c-format msgid "--author '%s' is not 'Name <email>' and matches no existing author" msgstr "" -#: builtin/commit.c:1070 builtin/commit.c:1310 +#: builtin/commit.c:1081 builtin/commit.c:1321 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "" -#: builtin/commit.c:1107 +#: builtin/commit.c:1118 msgid "--long and -z are incompatible" msgstr "" -#: builtin/commit.c:1137 +#: builtin/commit.c:1148 msgid "Using both --reset-author and --author does not make sense" msgstr "" -#: builtin/commit.c:1146 +#: builtin/commit.c:1157 msgid "You have nothing to amend." msgstr "" -#: builtin/commit.c:1149 +#: builtin/commit.c:1160 msgid "You are in the middle of a merge -- cannot amend." msgstr "" -#: builtin/commit.c:1151 +#: builtin/commit.c:1162 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "" -#: builtin/commit.c:1154 +#: builtin/commit.c:1165 msgid "Options --squash and --fixup cannot be used together" msgstr "" -#: builtin/commit.c:1164 +#: builtin/commit.c:1175 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "" -#: builtin/commit.c:1166 +#: builtin/commit.c:1177 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "" -#: builtin/commit.c:1174 +#: builtin/commit.c:1185 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" -#: builtin/commit.c:1191 +#: builtin/commit.c:1202 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" -#: builtin/commit.c:1193 +#: builtin/commit.c:1204 msgid "No paths with --include/--only does not make sense." msgstr "" -#: builtin/commit.c:1195 +#: builtin/commit.c:1206 msgid "Clever... amending the last one with dirty index." msgstr "" -#: builtin/commit.c:1197 +#: builtin/commit.c:1208 msgid "Explicit paths specified without -i or -o; assuming --only paths..." msgstr "" -#: builtin/commit.c:1209 builtin/tag.c:475 +#: builtin/commit.c:1220 builtin/tag.c:474 #, c-format msgid "Invalid cleanup mode %s" msgstr "" -#: builtin/commit.c:1214 +#: builtin/commit.c:1225 msgid "Paths with -a does not make sense." msgstr "" -#: builtin/commit.c:1324 builtin/commit.c:1605 +#: builtin/commit.c:1335 builtin/commit.c:1621 msgid "show status concisely" msgstr "" -#: builtin/commit.c:1326 builtin/commit.c:1607 +#: builtin/commit.c:1337 builtin/commit.c:1623 msgid "show branch information" msgstr "" -#: builtin/commit.c:1328 builtin/commit.c:1609 builtin/push.c:512 -#: builtin/worktree.c:430 +#: builtin/commit.c:1339 builtin/commit.c:1625 builtin/push.c:512 +#: builtin/worktree.c:437 msgid "machine-readable output" msgstr "" -#: builtin/commit.c:1331 builtin/commit.c:1611 +#: builtin/commit.c:1342 builtin/commit.c:1627 msgid "show status in long format (default)" msgstr "" -#: builtin/commit.c:1334 builtin/commit.c:1614 +#: builtin/commit.c:1345 builtin/commit.c:1630 msgid "terminate entries with NUL" msgstr "" -#: builtin/commit.c:1336 builtin/commit.c:1617 builtin/fast-export.c:981 +#: builtin/commit.c:1347 builtin/commit.c:1633 builtin/fast-export.c:981 #: builtin/fast-export.c:984 builtin/tag.c:353 msgid "mode" msgstr "" -#: builtin/commit.c:1337 builtin/commit.c:1617 +#: builtin/commit.c:1348 builtin/commit.c:1633 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" -#: builtin/commit.c:1340 +#: builtin/commit.c:1351 msgid "show ignored files" msgstr "" -#: builtin/commit.c:1341 parse-options.h:155 +#: builtin/commit.c:1352 parse-options.h:155 msgid "when" msgstr "" -#: builtin/commit.c:1342 +#: builtin/commit.c:1353 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" msgstr "" -#: builtin/commit.c:1344 +#: builtin/commit.c:1355 msgid "list untracked files in columns" msgstr "" -#: builtin/commit.c:1430 +#: builtin/commit.c:1441 msgid "couldn't look up newly created commit" msgstr "" -#: builtin/commit.c:1432 +#: builtin/commit.c:1443 msgid "could not parse newly created commit" msgstr "" -#: builtin/commit.c:1477 +#: builtin/commit.c:1488 msgid "detached HEAD" msgstr "" -#: builtin/commit.c:1480 +#: builtin/commit.c:1491 msgid " (root-commit)" msgstr "" -#: builtin/commit.c:1575 +#: builtin/commit.c:1591 msgid "suppress summary after successful commit" msgstr "" -#: builtin/commit.c:1576 +#: builtin/commit.c:1592 msgid "show diff in commit message template" msgstr "" -#: builtin/commit.c:1578 +#: builtin/commit.c:1594 msgid "Commit message options" msgstr "" -#: builtin/commit.c:1579 builtin/tag.c:351 +#: builtin/commit.c:1595 builtin/tag.c:351 msgid "read message from file" msgstr "" -#: builtin/commit.c:1580 +#: builtin/commit.c:1596 msgid "author" msgstr "" -#: builtin/commit.c:1580 +#: builtin/commit.c:1596 msgid "override author for commit" msgstr "" -#: builtin/commit.c:1581 builtin/gc.c:326 +#: builtin/commit.c:1597 builtin/gc.c:326 msgid "date" msgstr "" -#: builtin/commit.c:1581 +#: builtin/commit.c:1597 msgid "override date for commit" msgstr "" -#: builtin/commit.c:1582 builtin/merge.c:218 builtin/notes.c:395 +#: builtin/commit.c:1598 builtin/merge.c:219 builtin/notes.c:395 #: builtin/notes.c:558 builtin/tag.c:349 msgid "message" msgstr "" -#: builtin/commit.c:1582 +#: builtin/commit.c:1598 msgid "commit message" msgstr "" -#: builtin/commit.c:1583 builtin/commit.c:1584 builtin/commit.c:1585 -#: builtin/commit.c:1586 parse-options.h:256 ref-filter.h:79 +#: builtin/commit.c:1599 builtin/commit.c:1600 builtin/commit.c:1601 +#: builtin/commit.c:1602 parse-options.h:256 ref-filter.h:79 msgid "commit" msgstr "" -#: builtin/commit.c:1583 +#: builtin/commit.c:1599 msgid "reuse and edit message from specified commit" msgstr "" -#: builtin/commit.c:1584 +#: builtin/commit.c:1600 msgid "reuse message from specified commit" msgstr "" -#: builtin/commit.c:1585 +#: builtin/commit.c:1601 msgid "use autosquash formatted message to fixup specified commit" msgstr "" -#: builtin/commit.c:1586 +#: builtin/commit.c:1602 msgid "use autosquash formatted message to squash specified commit" msgstr "" -#: builtin/commit.c:1587 +#: builtin/commit.c:1603 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "" -#: builtin/commit.c:1588 builtin/log.c:1219 builtin/revert.c:86 +#: builtin/commit.c:1604 builtin/log.c:1382 builtin/revert.c:86 msgid "add Signed-off-by:" msgstr "" -#: builtin/commit.c:1589 +#: builtin/commit.c:1605 msgid "use specified template file" msgstr "" -#: builtin/commit.c:1590 +#: builtin/commit.c:1606 msgid "force edit of commit" msgstr "" -#: builtin/commit.c:1591 +#: builtin/commit.c:1607 msgid "default" msgstr "" -#: builtin/commit.c:1591 builtin/tag.c:354 +#: builtin/commit.c:1607 builtin/tag.c:354 msgid "how to strip spaces and #comments from message" msgstr "" -#: builtin/commit.c:1592 +#: builtin/commit.c:1608 msgid "include status in commit message template" msgstr "" -#: builtin/commit.c:1594 builtin/merge.c:226 builtin/pull.c:160 +#: builtin/commit.c:1610 builtin/merge.c:229 builtin/pull.c:165 #: builtin/revert.c:93 msgid "GPG sign commit" msgstr "" -#: builtin/commit.c:1597 +#: builtin/commit.c:1613 msgid "Commit contents options" msgstr "" -#: builtin/commit.c:1598 +#: builtin/commit.c:1614 msgid "commit all changed files" msgstr "" -#: builtin/commit.c:1599 +#: builtin/commit.c:1615 msgid "add specified files to index for commit" msgstr "" -#: builtin/commit.c:1600 +#: builtin/commit.c:1616 msgid "interactively add files" msgstr "" -#: builtin/commit.c:1601 +#: builtin/commit.c:1617 msgid "interactively add changes" msgstr "" -#: builtin/commit.c:1602 +#: builtin/commit.c:1618 msgid "commit only specified files" msgstr "" -#: builtin/commit.c:1603 +#: builtin/commit.c:1619 msgid "bypass pre-commit hook" msgstr "" -#: builtin/commit.c:1604 +#: builtin/commit.c:1620 msgid "show what would be committed" msgstr "" -#: builtin/commit.c:1615 +#: builtin/commit.c:1631 msgid "amend previous commit" msgstr "" -#: builtin/commit.c:1616 +#: builtin/commit.c:1632 msgid "bypass post-rewrite hook" msgstr "" -#: builtin/commit.c:1621 +#: builtin/commit.c:1637 msgid "ok to record an empty change" msgstr "" -#: builtin/commit.c:1623 +#: builtin/commit.c:1639 msgid "ok to record a change with an empty message" msgstr "" -#: builtin/commit.c:1652 +#: builtin/commit.c:1668 msgid "could not parse HEAD commit" msgstr "" -#: builtin/commit.c:1698 +#: builtin/commit.c:1718 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "" -#: builtin/commit.c:1705 +#: builtin/commit.c:1725 msgid "could not read MERGE_MODE" msgstr "" -#: builtin/commit.c:1724 +#: builtin/commit.c:1744 #, c-format msgid "could not read commit message: %s" msgstr "" -#: builtin/commit.c:1735 +#: builtin/commit.c:1755 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "" -#: builtin/commit.c:1740 +#: builtin/commit.c:1760 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "" -#: builtin/commit.c:1788 +#: builtin/commit.c:1808 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full and quota is\n" @@ -5437,7 +5663,7 @@ msgstr "" msgid "unable to parse default color value" msgstr "" -#: builtin/config.c:469 +#: builtin/config.c:472 #, c-format msgid "" "# This is Git's per-user configuration file.\n" @@ -5447,7 +5673,7 @@ msgid "" "#\temail = %s\n" msgstr "" -#: builtin/config.c:611 +#: builtin/config.c:614 #, c-format msgid "cannot create configuration file %s" msgstr "" @@ -5483,7 +5709,7 @@ msgstr "" msgid "tag '%s' is really '%s' here" msgstr "" -#: builtin/describe.c:250 builtin/log.c:459 +#: builtin/describe.c:250 builtin/log.c:465 #, c-format msgid "Not a valid object name %s" msgstr "" @@ -5570,7 +5796,7 @@ msgstr "" msgid "only consider tags matching <pattern>" msgstr "" -#: builtin/describe.c:410 builtin/name-rev.c:314 +#: builtin/describe.c:410 builtin/name-rev.c:321 msgid "show abbreviated commit object as fallback" msgstr "" @@ -5604,21 +5830,21 @@ msgstr "" msgid "invalid option: %s" msgstr "" -#: builtin/diff.c:358 +#: builtin/diff.c:360 msgid "Not a git repository" msgstr "" -#: builtin/diff.c:401 +#: builtin/diff.c:403 #, c-format msgid "invalid object '%s' given." msgstr "" -#: builtin/diff.c:410 +#: builtin/diff.c:412 #, c-format msgid "more than two blobs given: '%s'" msgstr "" -#: builtin/diff.c:417 +#: builtin/diff.c:419 #, c-format msgid "unhandled object '%s' given." msgstr "" @@ -5691,19 +5917,19 @@ msgstr "" msgid "git fetch --all [<options>]" msgstr "" -#: builtin/fetch.c:92 builtin/pull.c:166 +#: builtin/fetch.c:92 builtin/pull.c:174 msgid "fetch from all remotes" msgstr "" -#: builtin/fetch.c:94 builtin/pull.c:169 +#: builtin/fetch.c:94 builtin/pull.c:177 msgid "append to .git/FETCH_HEAD instead of overwriting" msgstr "" -#: builtin/fetch.c:96 builtin/pull.c:172 +#: builtin/fetch.c:96 builtin/pull.c:180 msgid "path to upload pack on remote end" msgstr "" -#: builtin/fetch.c:97 builtin/pull.c:174 +#: builtin/fetch.c:97 builtin/pull.c:182 msgid "force overwrite of local branch" msgstr "" @@ -5711,7 +5937,7 @@ msgstr "" msgid "fetch from multiple remotes" msgstr "" -#: builtin/fetch.c:101 builtin/pull.c:176 +#: builtin/fetch.c:101 builtin/pull.c:184 msgid "fetch all tags and associated objects" msgstr "" @@ -5723,19 +5949,19 @@ msgstr "" msgid "number of submodules fetched in parallel" msgstr "" -#: builtin/fetch.c:107 builtin/pull.c:179 +#: builtin/fetch.c:107 builtin/pull.c:187 msgid "prune remote-tracking branches no longer on remote" msgstr "" -#: builtin/fetch.c:108 builtin/pull.c:182 +#: builtin/fetch.c:108 builtin/pull.c:190 msgid "on-demand" msgstr "" -#: builtin/fetch.c:109 builtin/pull.c:183 +#: builtin/fetch.c:109 builtin/pull.c:191 msgid "control recursive fetching of submodules" msgstr "" -#: builtin/fetch.c:113 builtin/pull.c:191 +#: builtin/fetch.c:113 builtin/pull.c:199 msgid "keep downloaded pack" msgstr "" @@ -5743,15 +5969,15 @@ msgstr "" msgid "allow updating of HEAD ref" msgstr "" -#: builtin/fetch.c:118 builtin/pull.c:194 +#: builtin/fetch.c:118 builtin/pull.c:202 msgid "deepen history of shallow clone" msgstr "" -#: builtin/fetch.c:120 builtin/pull.c:197 +#: builtin/fetch.c:120 builtin/pull.c:205 msgid "convert to a complete repository" msgstr "" -#: builtin/fetch.c:122 builtin/log.c:1236 +#: builtin/fetch.c:122 builtin/log.c:1399 msgid "dir" msgstr "" @@ -5763,15 +5989,15 @@ msgstr "" msgid "default mode for recursion" msgstr "" -#: builtin/fetch.c:128 builtin/pull.c:200 +#: builtin/fetch.c:128 builtin/pull.c:208 msgid "accept refs that update .git/shallow" msgstr "" -#: builtin/fetch.c:129 builtin/pull.c:202 +#: builtin/fetch.c:129 builtin/pull.c:210 msgid "refmap" msgstr "" -#: builtin/fetch.c:130 builtin/pull.c:203 +#: builtin/fetch.c:130 builtin/pull.c:211 msgid "specify fetch refmap" msgstr "" @@ -5829,11 +6055,6 @@ msgstr "" msgid "(non-fast-forward)" msgstr "" -#: builtin/fetch.c:610 builtin/fetch.c:851 -#, c-format -msgid "cannot open %s: %s\n" -msgstr "" - #: builtin/fetch.c:619 #, c-format msgid "%s did not send all necessary objects\n" @@ -6028,55 +6249,55 @@ msgstr "" msgid "Checking object directories" msgstr "" -#: builtin/fsck.c:553 +#: builtin/fsck.c:552 msgid "git fsck [<options>] [<object>...]" msgstr "" -#: builtin/fsck.c:559 +#: builtin/fsck.c:558 msgid "show unreachable objects" msgstr "" -#: builtin/fsck.c:560 +#: builtin/fsck.c:559 msgid "show dangling objects" msgstr "" -#: builtin/fsck.c:561 +#: builtin/fsck.c:560 msgid "report tags" msgstr "" -#: builtin/fsck.c:562 +#: builtin/fsck.c:561 msgid "report root nodes" msgstr "" -#: builtin/fsck.c:563 +#: builtin/fsck.c:562 msgid "make index objects head nodes" msgstr "" -#: builtin/fsck.c:564 +#: builtin/fsck.c:563 msgid "make reflogs head nodes (default)" msgstr "" -#: builtin/fsck.c:565 +#: builtin/fsck.c:564 msgid "also consider packs and alternate objects" msgstr "" -#: builtin/fsck.c:566 +#: builtin/fsck.c:565 msgid "check only connectivity" msgstr "" -#: builtin/fsck.c:567 +#: builtin/fsck.c:566 msgid "enable more strict checking" msgstr "" -#: builtin/fsck.c:569 +#: builtin/fsck.c:568 msgid "write dangling objects in .git/lost-found" msgstr "" -#: builtin/fsck.c:570 builtin/prune.c:107 +#: builtin/fsck.c:569 builtin/prune.c:107 msgid "show progress" msgstr "" -#: builtin/fsck.c:631 +#: builtin/fsck.c:630 msgid "Checking objects" msgstr "" @@ -6170,214 +6391,214 @@ msgstr "" msgid "unable to grep from object of type %s" msgstr "" -#: builtin/grep.c:558 +#: builtin/grep.c:560 #, c-format msgid "switch `%c' expects a numerical value" msgstr "" -#: builtin/grep.c:575 +#: builtin/grep.c:577 #, c-format msgid "cannot open '%s'" msgstr "" -#: builtin/grep.c:644 +#: builtin/grep.c:646 msgid "search in index instead of in the work tree" msgstr "" -#: builtin/grep.c:646 +#: builtin/grep.c:648 msgid "find in contents not managed by git" msgstr "" -#: builtin/grep.c:648 +#: builtin/grep.c:650 msgid "search in both tracked and untracked files" msgstr "" -#: builtin/grep.c:650 +#: builtin/grep.c:652 msgid "ignore files specified via '.gitignore'" msgstr "" -#: builtin/grep.c:653 +#: builtin/grep.c:655 msgid "show non-matching lines" msgstr "" -#: builtin/grep.c:655 +#: builtin/grep.c:657 msgid "case insensitive matching" msgstr "" -#: builtin/grep.c:657 +#: builtin/grep.c:659 msgid "match patterns only at word boundaries" msgstr "" -#: builtin/grep.c:659 +#: builtin/grep.c:661 msgid "process binary files as text" msgstr "" -#: builtin/grep.c:661 +#: builtin/grep.c:663 msgid "don't match patterns in binary files" msgstr "" -#: builtin/grep.c:664 +#: builtin/grep.c:666 msgid "process binary files with textconv filters" msgstr "" -#: builtin/grep.c:666 +#: builtin/grep.c:668 msgid "descend at most <depth> levels" msgstr "" -#: builtin/grep.c:670 +#: builtin/grep.c:672 msgid "use extended POSIX regular expressions" msgstr "" -#: builtin/grep.c:673 +#: builtin/grep.c:675 msgid "use basic POSIX regular expressions (default)" msgstr "" -#: builtin/grep.c:676 +#: builtin/grep.c:678 msgid "interpret patterns as fixed strings" msgstr "" -#: builtin/grep.c:679 +#: builtin/grep.c:681 msgid "use Perl-compatible regular expressions" msgstr "" -#: builtin/grep.c:682 +#: builtin/grep.c:684 msgid "show line numbers" msgstr "" -#: builtin/grep.c:683 +#: builtin/grep.c:685 msgid "don't show filenames" msgstr "" -#: builtin/grep.c:684 +#: builtin/grep.c:686 msgid "show filenames" msgstr "" -#: builtin/grep.c:686 +#: builtin/grep.c:688 msgid "show filenames relative to top directory" msgstr "" -#: builtin/grep.c:688 +#: builtin/grep.c:690 msgid "show only filenames instead of matching lines" msgstr "" -#: builtin/grep.c:690 +#: builtin/grep.c:692 msgid "synonym for --files-with-matches" msgstr "" -#: builtin/grep.c:693 +#: builtin/grep.c:695 msgid "show only the names of files without match" msgstr "" -#: builtin/grep.c:695 +#: builtin/grep.c:697 msgid "print NUL after filenames" msgstr "" -#: builtin/grep.c:697 +#: builtin/grep.c:699 msgid "show the number of matches instead of matching lines" msgstr "" -#: builtin/grep.c:698 +#: builtin/grep.c:700 msgid "highlight matches" msgstr "" -#: builtin/grep.c:700 +#: builtin/grep.c:702 msgid "print empty line between matches from different files" msgstr "" -#: builtin/grep.c:702 +#: builtin/grep.c:704 msgid "show filename only once above matches from same file" msgstr "" -#: builtin/grep.c:705 +#: builtin/grep.c:707 msgid "show <n> context lines before and after matches" msgstr "" -#: builtin/grep.c:708 +#: builtin/grep.c:710 msgid "show <n> context lines before matches" msgstr "" -#: builtin/grep.c:710 +#: builtin/grep.c:712 msgid "show <n> context lines after matches" msgstr "" -#: builtin/grep.c:712 +#: builtin/grep.c:714 msgid "use <n> worker threads" msgstr "" -#: builtin/grep.c:713 +#: builtin/grep.c:715 msgid "shortcut for -C NUM" msgstr "" -#: builtin/grep.c:716 +#: builtin/grep.c:718 msgid "show a line with the function name before matches" msgstr "" -#: builtin/grep.c:718 +#: builtin/grep.c:720 msgid "show the surrounding function" msgstr "" -#: builtin/grep.c:721 +#: builtin/grep.c:723 msgid "read patterns from file" msgstr "" -#: builtin/grep.c:723 +#: builtin/grep.c:725 msgid "match <pattern>" msgstr "" -#: builtin/grep.c:725 +#: builtin/grep.c:727 msgid "combine patterns specified with -e" msgstr "" -#: builtin/grep.c:737 +#: builtin/grep.c:739 msgid "indicate hit with exit status without output" msgstr "" -#: builtin/grep.c:739 +#: builtin/grep.c:741 msgid "show only matches from files that match all patterns" msgstr "" -#: builtin/grep.c:741 +#: builtin/grep.c:743 msgid "show parse tree for grep expression" msgstr "" -#: builtin/grep.c:745 +#: builtin/grep.c:747 msgid "pager" msgstr "" -#: builtin/grep.c:745 +#: builtin/grep.c:747 msgid "show matching files in the pager" msgstr "" -#: builtin/grep.c:748 +#: builtin/grep.c:750 msgid "allow calling of grep(1) (ignored by this build)" msgstr "" -#: builtin/grep.c:811 +#: builtin/grep.c:813 msgid "no pattern given." msgstr "" -#: builtin/grep.c:843 builtin/index-pack.c:1475 +#: builtin/grep.c:845 builtin/index-pack.c:1477 #, c-format msgid "invalid number of threads specified (%d)" msgstr "" -#: builtin/grep.c:873 +#: builtin/grep.c:875 msgid "--open-files-in-pager only works on the worktree" msgstr "" -#: builtin/grep.c:899 +#: builtin/grep.c:901 msgid "--cached or --untracked cannot be used with --no-index." msgstr "" -#: builtin/grep.c:904 +#: builtin/grep.c:906 msgid "--no-index or --untracked cannot be used with revs." msgstr "" -#: builtin/grep.c:907 +#: builtin/grep.c:909 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" -#: builtin/grep.c:915 +#: builtin/grep.c:917 msgid "both --cached and trees are given." msgstr "" @@ -6464,7 +6685,7 @@ msgstr "" #: builtin/help.c:130 builtin/help.c:151 builtin/help.c:160 builtin/help.c:168 #, c-format -msgid "failed to exec '%s': %s" +msgid "failed to exec '%s'" msgstr "" #: builtin/help.c:205 @@ -6719,107 +6940,109 @@ msgstr "" #: builtin/index-pack.c:1253 #, c-format -msgid "completed with %d local objects" -msgstr "" +msgid "completed with %d local object" +msgid_plural "completed with %d local objects" +msgstr[0] "" +msgstr[1] "" -#: builtin/index-pack.c:1263 +#: builtin/index-pack.c:1265 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "" -#: builtin/index-pack.c:1267 +#: builtin/index-pack.c:1269 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1291 +#: builtin/index-pack.c:1293 #, c-format msgid "unable to deflate appended object (%d)" msgstr "" -#: builtin/index-pack.c:1367 +#: builtin/index-pack.c:1369 #, c-format msgid "local object %s is corrupt" msgstr "" -#: builtin/index-pack.c:1391 +#: builtin/index-pack.c:1393 msgid "error while closing pack file" msgstr "" -#: builtin/index-pack.c:1404 +#: builtin/index-pack.c:1406 #, c-format msgid "cannot write keep file '%s'" msgstr "" -#: builtin/index-pack.c:1412 +#: builtin/index-pack.c:1414 #, c-format msgid "cannot close written keep file '%s'" msgstr "" -#: builtin/index-pack.c:1425 +#: builtin/index-pack.c:1427 msgid "cannot store pack file" msgstr "" -#: builtin/index-pack.c:1436 +#: builtin/index-pack.c:1438 msgid "cannot store index file" msgstr "" -#: builtin/index-pack.c:1469 +#: builtin/index-pack.c:1471 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "" -#: builtin/index-pack.c:1479 builtin/index-pack.c:1664 +#: builtin/index-pack.c:1481 builtin/index-pack.c:1678 #, c-format msgid "no threads support, ignoring %s" msgstr "" -#: builtin/index-pack.c:1538 +#: builtin/index-pack.c:1540 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "" -#: builtin/index-pack.c:1540 +#: builtin/index-pack.c:1542 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "" -#: builtin/index-pack.c:1587 +#: builtin/index-pack.c:1589 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1594 +#: builtin/index-pack.c:1596 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1624 +#: builtin/index-pack.c:1609 +#, c-format +msgid "packfile name '%s' does not end with '.pack'" +msgstr "" + +#: builtin/index-pack.c:1638 msgid "Cannot come back to cwd" msgstr "" -#: builtin/index-pack.c:1676 builtin/index-pack.c:1679 -#: builtin/index-pack.c:1691 builtin/index-pack.c:1695 +#: builtin/index-pack.c:1690 builtin/index-pack.c:1693 +#: builtin/index-pack.c:1705 builtin/index-pack.c:1709 #, c-format msgid "bad %s" msgstr "" -#: builtin/index-pack.c:1709 +#: builtin/index-pack.c:1723 msgid "--fix-thin cannot be used without --stdin" msgstr "" -#: builtin/index-pack.c:1713 builtin/index-pack.c:1722 -#, c-format -msgid "packfile name '%s' does not end with '.pack'" -msgstr "" - -#: builtin/index-pack.c:1730 +#: builtin/index-pack.c:1731 msgid "--verify with no packfile name given" msgstr "" @@ -6858,27 +7081,27 @@ msgstr "" msgid "ignoring template %s" msgstr "" -#: builtin/init-db.c:118 +#: builtin/init-db.c:120 #, c-format msgid "templates not found %s" msgstr "" -#: builtin/init-db.c:131 +#: builtin/init-db.c:135 #, c-format -msgid "not copying templates of a wrong format version %d from '%s'" +msgid "not copying templates from '%s': %s" msgstr "" -#: builtin/init-db.c:309 builtin/init-db.c:312 +#: builtin/init-db.c:312 builtin/init-db.c:315 #, c-format msgid "%s already exists" msgstr "" -#: builtin/init-db.c:340 +#: builtin/init-db.c:344 #, c-format msgid "unable to handle file type %d" msgstr "" -#: builtin/init-db.c:343 +#: builtin/init-db.c:347 #, c-format msgid "unable to move %s to %s" msgstr "" @@ -6886,55 +7109,55 @@ msgstr "" #. TRANSLATORS: The first '%s' is either "Reinitialized #. existing" or "Initialized empty", the second " shared" or #. "", and the last '%s%s' is the verbatim directory name. -#: builtin/init-db.c:399 +#: builtin/init-db.c:403 #, c-format msgid "%s%s Git repository in %s%s\n" msgstr "" -#: builtin/init-db.c:400 +#: builtin/init-db.c:404 msgid "Reinitialized existing" msgstr "" -#: builtin/init-db.c:400 +#: builtin/init-db.c:404 msgid "Initialized empty" msgstr "" -#: builtin/init-db.c:401 +#: builtin/init-db.c:405 msgid " shared" msgstr "" -#: builtin/init-db.c:448 +#: builtin/init-db.c:452 msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--" "shared[=<permissions>]] [<directory>]" msgstr "" -#: builtin/init-db.c:471 +#: builtin/init-db.c:475 msgid "permissions" msgstr "" -#: builtin/init-db.c:472 +#: builtin/init-db.c:476 msgid "specify that the git repository is to be shared amongst several users" msgstr "" -#: builtin/init-db.c:506 builtin/init-db.c:511 +#: builtin/init-db.c:510 builtin/init-db.c:515 #, c-format msgid "cannot mkdir %s" msgstr "" -#: builtin/init-db.c:515 +#: builtin/init-db.c:519 #, c-format msgid "cannot chdir to %s" msgstr "" -#: builtin/init-db.c:536 +#: builtin/init-db.c:540 #, c-format msgid "" "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-" "dir=<directory>)" msgstr "" -#: builtin/init-db.c:564 +#: builtin/init-db.c:568 #, c-format msgid "Cannot access work tree '%s'" msgstr "" @@ -6978,273 +7201,316 @@ msgstr "" msgid "invalid --decorate option: %s" msgstr "" -#: builtin/log.c:131 +#: builtin/log.c:137 msgid "suppress diff output" msgstr "" -#: builtin/log.c:132 +#: builtin/log.c:138 msgid "show source" msgstr "" -#: builtin/log.c:133 +#: builtin/log.c:139 msgid "Use mail map file" msgstr "" -#: builtin/log.c:134 +#: builtin/log.c:140 msgid "decorate options" msgstr "" -#: builtin/log.c:137 +#: builtin/log.c:143 msgid "Process line range n,m in file, counting from 1" msgstr "" -#: builtin/log.c:233 +#: builtin/log.c:239 #, c-format msgid "Final output: %d %s\n" msgstr "" -#: builtin/log.c:465 +#: builtin/log.c:471 #, c-format msgid "git show %s: bad file" msgstr "" -#: builtin/log.c:479 builtin/log.c:572 +#: builtin/log.c:485 builtin/log.c:578 #, c-format msgid "Could not read object %s" msgstr "" -#: builtin/log.c:596 +#: builtin/log.c:602 #, c-format msgid "Unknown type: %d" msgstr "" -#: builtin/log.c:715 +#: builtin/log.c:722 msgid "format.headers without value" msgstr "" -#: builtin/log.c:801 +#: builtin/log.c:812 msgid "name of output directory is too long" msgstr "" -#: builtin/log.c:816 +#: builtin/log.c:827 #, c-format msgid "Cannot open patch file %s" msgstr "" -#: builtin/log.c:830 +#: builtin/log.c:841 msgid "Need exactly one range." msgstr "" -#: builtin/log.c:840 +#: builtin/log.c:851 msgid "Not a range." msgstr "" -#: builtin/log.c:946 +#: builtin/log.c:957 msgid "Cover letter needs email format" msgstr "" -#: builtin/log.c:1025 +#: builtin/log.c:1036 #, c-format msgid "insane in-reply-to: %s" msgstr "" -#: builtin/log.c:1053 +#: builtin/log.c:1064 msgid "git format-patch [<options>] [<since> | <revision-range>]" msgstr "" -#: builtin/log.c:1098 +#: builtin/log.c:1109 msgid "Two output directories?" msgstr "" -#: builtin/log.c:1214 +#: builtin/log.c:1216 builtin/log.c:1857 builtin/log.c:1859 builtin/log.c:1871 +#, c-format +msgid "Unknown commit %s" +msgstr "" + +#: builtin/log.c:1226 builtin/notes.c:253 builtin/notes.c:304 +#: builtin/notes.c:306 builtin/notes.c:369 builtin/notes.c:424 +#: builtin/notes.c:510 builtin/notes.c:515 builtin/notes.c:593 +#: builtin/notes.c:656 builtin/notes.c:881 builtin/tag.c:455 +#, c-format +msgid "Failed to resolve '%s' as a valid ref." +msgstr "" + +#: builtin/log.c:1231 +msgid "Could not find exact merge base." +msgstr "" + +#: builtin/log.c:1235 +msgid "" +"Failed to get upstream, if you want to record base commit automatically,\n" +"please use git branch --set-upstream-to to track a remote branch.\n" +"Or you could specify base commit by --base=<base-commit-id> manually." +msgstr "" + +#: builtin/log.c:1255 +msgid "Failed to find exact merge base" +msgstr "" + +#: builtin/log.c:1266 +msgid "base commit should be the ancestor of revision list" +msgstr "" + +#: builtin/log.c:1270 +msgid "base commit shouldn't be in revision list" +msgstr "" + +#: builtin/log.c:1319 +msgid "cannot get patch id" +msgstr "" + +#: builtin/log.c:1377 msgid "use [PATCH n/m] even with a single patch" msgstr "" -#: builtin/log.c:1217 +#: builtin/log.c:1380 msgid "use [PATCH] even with multiple patches" msgstr "" -#: builtin/log.c:1221 +#: builtin/log.c:1384 msgid "print patches to standard out" msgstr "" -#: builtin/log.c:1223 +#: builtin/log.c:1386 msgid "generate a cover letter" msgstr "" -#: builtin/log.c:1225 +#: builtin/log.c:1388 msgid "use simple number sequence for output file names" msgstr "" -#: builtin/log.c:1226 +#: builtin/log.c:1389 msgid "sfx" msgstr "" -#: builtin/log.c:1227 +#: builtin/log.c:1390 msgid "use <sfx> instead of '.patch'" msgstr "" -#: builtin/log.c:1229 +#: builtin/log.c:1392 msgid "start numbering patches at <n> instead of 1" msgstr "" -#: builtin/log.c:1231 +#: builtin/log.c:1394 msgid "mark the series as Nth re-roll" msgstr "" -#: builtin/log.c:1233 +#: builtin/log.c:1396 msgid "Use [<prefix>] instead of [PATCH]" msgstr "" -#: builtin/log.c:1236 +#: builtin/log.c:1399 msgid "store resulting files in <dir>" msgstr "" -#: builtin/log.c:1239 +#: builtin/log.c:1402 msgid "don't strip/add [PATCH]" msgstr "" -#: builtin/log.c:1242 +#: builtin/log.c:1405 msgid "don't output binary diffs" msgstr "" -#: builtin/log.c:1244 +#: builtin/log.c:1407 msgid "output all-zero hash in From header" msgstr "" -#: builtin/log.c:1246 +#: builtin/log.c:1409 msgid "don't include a patch matching a commit upstream" msgstr "" -#: builtin/log.c:1248 +#: builtin/log.c:1411 msgid "show patch format instead of default (patch + stat)" msgstr "" -#: builtin/log.c:1250 +#: builtin/log.c:1413 msgid "Messaging" msgstr "" -#: builtin/log.c:1251 +#: builtin/log.c:1414 msgid "header" msgstr "" -#: builtin/log.c:1252 +#: builtin/log.c:1415 msgid "add email header" msgstr "" -#: builtin/log.c:1253 builtin/log.c:1255 +#: builtin/log.c:1416 builtin/log.c:1418 msgid "email" msgstr "" -#: builtin/log.c:1253 +#: builtin/log.c:1416 msgid "add To: header" msgstr "" -#: builtin/log.c:1255 +#: builtin/log.c:1418 msgid "add Cc: header" msgstr "" -#: builtin/log.c:1257 +#: builtin/log.c:1420 msgid "ident" msgstr "" -#: builtin/log.c:1258 +#: builtin/log.c:1421 msgid "set From address to <ident> (or committer ident if absent)" msgstr "" -#: builtin/log.c:1260 +#: builtin/log.c:1423 msgid "message-id" msgstr "" -#: builtin/log.c:1261 +#: builtin/log.c:1424 msgid "make first mail a reply to <message-id>" msgstr "" -#: builtin/log.c:1262 builtin/log.c:1265 +#: builtin/log.c:1425 builtin/log.c:1428 msgid "boundary" msgstr "" -#: builtin/log.c:1263 +#: builtin/log.c:1426 msgid "attach the patch" msgstr "" -#: builtin/log.c:1266 +#: builtin/log.c:1429 msgid "inline the patch" msgstr "" -#: builtin/log.c:1270 +#: builtin/log.c:1433 msgid "enable message threading, styles: shallow, deep" msgstr "" -#: builtin/log.c:1272 +#: builtin/log.c:1435 msgid "signature" msgstr "" -#: builtin/log.c:1273 +#: builtin/log.c:1436 msgid "add a signature" msgstr "" -#: builtin/log.c:1275 +#: builtin/log.c:1437 +msgid "base-commit" +msgstr "" + +#: builtin/log.c:1438 +msgid "add prerequisite tree info to the patch series" +msgstr "" + +#: builtin/log.c:1440 msgid "add a signature from a file" msgstr "" -#: builtin/log.c:1276 +#: builtin/log.c:1441 msgid "don't print the patch filenames" msgstr "" -#: builtin/log.c:1365 +#: builtin/log.c:1531 msgid "-n and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1367 +#: builtin/log.c:1533 msgid "--subject-prefix and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1375 +#: builtin/log.c:1541 msgid "--name-only does not make sense" msgstr "" -#: builtin/log.c:1377 +#: builtin/log.c:1543 msgid "--name-status does not make sense" msgstr "" -#: builtin/log.c:1379 +#: builtin/log.c:1545 msgid "--check does not make sense" msgstr "" -#: builtin/log.c:1407 +#: builtin/log.c:1573 msgid "standard output, or directory, which one?" msgstr "" -#: builtin/log.c:1409 +#: builtin/log.c:1575 #, c-format msgid "Could not create directory '%s'" msgstr "" -#: builtin/log.c:1506 +#: builtin/log.c:1672 #, c-format msgid "unable to read signature file '%s'" msgstr "" -#: builtin/log.c:1569 +#: builtin/log.c:1743 msgid "Failed to create output files" msgstr "" -#: builtin/log.c:1617 +#: builtin/log.c:1792 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "" -#: builtin/log.c:1671 +#: builtin/log.c:1846 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" msgstr "" -#: builtin/log.c:1682 builtin/log.c:1684 builtin/log.c:1696 -#, c-format -msgid "Unknown commit %s" -msgstr "" - #: builtin/ls-files.c:378 msgid "git ls-files [<options>] [<file>...]" msgstr "" @@ -7432,170 +7698,174 @@ msgstr "" msgid "git merge --abort" msgstr "" -#: builtin/merge.c:100 +#: builtin/merge.c:101 msgid "switch `m' requires a value" msgstr "" -#: builtin/merge.c:137 +#: builtin/merge.c:138 #, c-format msgid "Could not find merge strategy '%s'.\n" msgstr "" -#: builtin/merge.c:138 +#: builtin/merge.c:139 #, c-format msgid "Available strategies are:" msgstr "" -#: builtin/merge.c:143 +#: builtin/merge.c:144 #, c-format msgid "Available custom strategies are:" msgstr "" -#: builtin/merge.c:193 builtin/pull.c:123 +#: builtin/merge.c:194 builtin/pull.c:126 msgid "do not show a diffstat at the end of the merge" msgstr "" -#: builtin/merge.c:196 builtin/pull.c:126 +#: builtin/merge.c:197 builtin/pull.c:129 msgid "show a diffstat at the end of the merge" msgstr "" -#: builtin/merge.c:197 builtin/pull.c:129 +#: builtin/merge.c:198 builtin/pull.c:132 msgid "(synonym to --stat)" msgstr "" -#: builtin/merge.c:199 builtin/pull.c:132 +#: builtin/merge.c:200 builtin/pull.c:135 msgid "add (at most <n>) entries from shortlog to merge commit message" msgstr "" -#: builtin/merge.c:202 builtin/pull.c:135 +#: builtin/merge.c:203 builtin/pull.c:138 msgid "create a single commit instead of doing a merge" msgstr "" -#: builtin/merge.c:204 builtin/pull.c:138 +#: builtin/merge.c:205 builtin/pull.c:141 msgid "perform a commit if the merge succeeds (default)" msgstr "" -#: builtin/merge.c:206 builtin/pull.c:141 +#: builtin/merge.c:207 builtin/pull.c:144 msgid "edit message before committing" msgstr "" -#: builtin/merge.c:207 +#: builtin/merge.c:208 msgid "allow fast-forward (default)" msgstr "" -#: builtin/merge.c:209 builtin/pull.c:147 +#: builtin/merge.c:210 builtin/pull.c:150 msgid "abort if fast-forward is not possible" msgstr "" -#: builtin/merge.c:213 +#: builtin/merge.c:214 msgid "Verify that the named commit has a valid GPG signature" msgstr "" -#: builtin/merge.c:214 builtin/notes.c:770 builtin/pull.c:152 +#: builtin/merge.c:215 builtin/notes.c:771 builtin/pull.c:157 #: builtin/revert.c:89 msgid "strategy" msgstr "" -#: builtin/merge.c:215 builtin/pull.c:153 +#: builtin/merge.c:216 builtin/pull.c:158 msgid "merge strategy to use" msgstr "" -#: builtin/merge.c:216 builtin/pull.c:156 +#: builtin/merge.c:217 builtin/pull.c:161 msgid "option=value" msgstr "" -#: builtin/merge.c:217 builtin/pull.c:157 +#: builtin/merge.c:218 builtin/pull.c:162 msgid "option for selected merge strategy" msgstr "" -#: builtin/merge.c:219 +#: builtin/merge.c:220 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" -#: builtin/merge.c:223 +#: builtin/merge.c:224 msgid "abort the current in-progress merge" msgstr "" -#: builtin/merge.c:251 +#: builtin/merge.c:226 builtin/pull.c:169 +msgid "allow merging unrelated histories" +msgstr "" + +#: builtin/merge.c:254 msgid "could not run stash." msgstr "" -#: builtin/merge.c:256 +#: builtin/merge.c:259 msgid "stash failed" msgstr "" -#: builtin/merge.c:261 +#: builtin/merge.c:264 #, c-format msgid "not a valid object: %s" msgstr "" -#: builtin/merge.c:280 builtin/merge.c:297 +#: builtin/merge.c:283 builtin/merge.c:300 msgid "read-tree failed" msgstr "" -#: builtin/merge.c:327 +#: builtin/merge.c:330 msgid " (nothing to squash)" msgstr "" -#: builtin/merge.c:340 +#: builtin/merge.c:343 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "" -#: builtin/merge.c:344 builtin/merge.c:764 builtin/merge.c:976 -#: builtin/merge.c:989 +#: builtin/merge.c:347 builtin/merge.c:767 builtin/merge.c:987 +#: builtin/merge.c:1000 #, c-format msgid "Could not write to '%s'" msgstr "" -#: builtin/merge.c:372 +#: builtin/merge.c:375 msgid "Writing SQUASH_MSG" msgstr "" -#: builtin/merge.c:374 +#: builtin/merge.c:377 msgid "Finishing SQUASH_MSG" msgstr "" -#: builtin/merge.c:397 +#: builtin/merge.c:400 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "" -#: builtin/merge.c:448 +#: builtin/merge.c:451 #, c-format msgid "'%s' does not point to a commit" msgstr "" -#: builtin/merge.c:538 +#: builtin/merge.c:541 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "" -#: builtin/merge.c:657 +#: builtin/merge.c:660 msgid "Not handling anything other than two heads merge." msgstr "" -#: builtin/merge.c:671 +#: builtin/merge.c:674 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "" -#: builtin/merge.c:684 +#: builtin/merge.c:687 #, c-format msgid "unable to write %s" msgstr "" -#: builtin/merge.c:773 +#: builtin/merge.c:776 #, c-format msgid "Could not read from '%s'" msgstr "" -#: builtin/merge.c:782 +#: builtin/merge.c:785 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" -#: builtin/merge.c:788 +#: builtin/merge.c:791 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -7605,157 +7875,161 @@ msgid "" "the commit.\n" msgstr "" -#: builtin/merge.c:812 +#: builtin/merge.c:815 msgid "Empty commit message." msgstr "" -#: builtin/merge.c:824 +#: builtin/merge.c:835 #, c-format msgid "Wonderful.\n" msgstr "" -#: builtin/merge.c:879 +#: builtin/merge.c:890 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" -#: builtin/merge.c:895 +#: builtin/merge.c:906 #, c-format msgid "'%s' is not a commit" msgstr "" -#: builtin/merge.c:936 +#: builtin/merge.c:947 msgid "No current branch." msgstr "" -#: builtin/merge.c:938 +#: builtin/merge.c:949 msgid "No remote for the current branch." msgstr "" -#: builtin/merge.c:940 +#: builtin/merge.c:951 msgid "No default upstream defined for the current branch." msgstr "" -#: builtin/merge.c:945 +#: builtin/merge.c:956 #, c-format msgid "No remote-tracking branch for %s from %s" msgstr "" -#: builtin/merge.c:1080 +#: builtin/merge.c:1091 #, c-format msgid "could not close '%s'" msgstr "" -#: builtin/merge.c:1207 +#: builtin/merge.c:1219 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "" -#: builtin/merge.c:1223 +#: builtin/merge.c:1235 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." msgstr "" -#: builtin/merge.c:1230 +#: builtin/merge.c:1242 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." msgstr "" -#: builtin/merge.c:1233 +#: builtin/merge.c:1245 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" -#: builtin/merge.c:1242 +#: builtin/merge.c:1254 msgid "You cannot combine --squash with --no-ff." msgstr "" -#: builtin/merge.c:1250 +#: builtin/merge.c:1262 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" -#: builtin/merge.c:1267 +#: builtin/merge.c:1279 msgid "Squash commit into empty head not supported yet" msgstr "" -#: builtin/merge.c:1269 +#: builtin/merge.c:1281 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" -#: builtin/merge.c:1275 +#: builtin/merge.c:1286 #, c-format msgid "%s - not something we can merge" msgstr "" -#: builtin/merge.c:1277 +#: builtin/merge.c:1288 msgid "Can merge only exactly one commit into empty head" msgstr "" -#: builtin/merge.c:1332 +#: builtin/merge.c:1344 #, c-format msgid "Commit %s has an untrusted GPG signature, allegedly by %s." msgstr "" -#: builtin/merge.c:1335 +#: builtin/merge.c:1347 #, c-format msgid "Commit %s has a bad GPG signature allegedly by %s." msgstr "" -#: builtin/merge.c:1338 +#: builtin/merge.c:1350 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "" -#: builtin/merge.c:1341 +#: builtin/merge.c:1353 #, c-format msgid "Commit %s has a good GPG signature by %s\n" msgstr "" -#: builtin/merge.c:1424 +#: builtin/merge.c:1415 +msgid "refusing to merge unrelated histories" +msgstr "" + +#: builtin/merge.c:1439 #, c-format msgid "Updating %s..%s\n" msgstr "" -#: builtin/merge.c:1461 +#: builtin/merge.c:1476 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "" -#: builtin/merge.c:1468 +#: builtin/merge.c:1483 #, c-format msgid "Nope.\n" msgstr "" -#: builtin/merge.c:1500 +#: builtin/merge.c:1515 msgid "Not possible to fast-forward, aborting." msgstr "" -#: builtin/merge.c:1523 builtin/merge.c:1602 +#: builtin/merge.c:1538 builtin/merge.c:1617 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "" -#: builtin/merge.c:1527 +#: builtin/merge.c:1542 #, c-format msgid "Trying merge strategy %s...\n" msgstr "" -#: builtin/merge.c:1593 +#: builtin/merge.c:1608 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "" -#: builtin/merge.c:1595 +#: builtin/merge.c:1610 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "" -#: builtin/merge.c:1604 +#: builtin/merge.c:1619 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "" -#: builtin/merge.c:1616 +#: builtin/merge.c:1631 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -7863,7 +8137,7 @@ msgstr "" msgid "Directory %s is in index and no submodule?" msgstr "" -#: builtin/mv.c:72 +#: builtin/mv.c:72 builtin/rm.c:317 msgid "Please stage your changes to .gitmodules or stash them to proceed" msgstr "" @@ -7941,48 +8215,48 @@ msgstr "" msgid "Renaming %s to %s\n" msgstr "" -#: builtin/mv.c:257 builtin/remote.c:714 builtin/repack.c:365 +#: builtin/mv.c:260 builtin/remote.c:714 builtin/repack.c:365 #, c-format msgid "renaming '%s' failed" msgstr "" -#: builtin/name-rev.c:251 +#: builtin/name-rev.c:258 msgid "git name-rev [<options>] <commit>..." msgstr "" -#: builtin/name-rev.c:252 +#: builtin/name-rev.c:259 msgid "git name-rev [<options>] --all" msgstr "" -#: builtin/name-rev.c:253 +#: builtin/name-rev.c:260 msgid "git name-rev [<options>] --stdin" msgstr "" -#: builtin/name-rev.c:305 +#: builtin/name-rev.c:312 msgid "print only names (no SHA-1)" msgstr "" -#: builtin/name-rev.c:306 +#: builtin/name-rev.c:313 msgid "only use tags to name the commits" msgstr "" -#: builtin/name-rev.c:308 +#: builtin/name-rev.c:315 msgid "only use refs matching <pattern>" msgstr "" -#: builtin/name-rev.c:310 +#: builtin/name-rev.c:317 msgid "list all commits reachable from all refs" msgstr "" -#: builtin/name-rev.c:311 +#: builtin/name-rev.c:318 msgid "read from stdin" msgstr "" -#: builtin/name-rev.c:312 +#: builtin/name-rev.c:319 msgid "allow to print `undefined` names (default)" msgstr "" -#: builtin/name-rev.c:318 +#: builtin/name-rev.c:325 msgid "dereference tags in the input (internal use)" msgstr "" @@ -8123,24 +8397,16 @@ msgstr "" msgid "The note contents have been left in %s" msgstr "" -#: builtin/notes.c:232 builtin/tag.c:440 +#: builtin/notes.c:232 builtin/tag.c:439 #, c-format msgid "cannot read '%s'" msgstr "" -#: builtin/notes.c:234 builtin/tag.c:443 +#: builtin/notes.c:234 builtin/tag.c:442 #, c-format msgid "could not open or read '%s'" msgstr "" -#: builtin/notes.c:253 builtin/notes.c:304 builtin/notes.c:306 -#: builtin/notes.c:369 builtin/notes.c:424 builtin/notes.c:510 -#: builtin/notes.c:515 builtin/notes.c:593 builtin/notes.c:656 -#: builtin/notes.c:880 builtin/tag.c:456 -#, c-format -msgid "Failed to resolve '%s' as a valid ref." -msgstr "" - #: builtin/notes.c:256 #, c-format msgid "Failed to read object '%s'." @@ -8153,7 +8419,7 @@ msgstr "" #: builtin/notes.c:362 builtin/notes.c:417 builtin/notes.c:493 #: builtin/notes.c:505 builtin/notes.c:581 builtin/notes.c:649 -#: builtin/notes.c:945 +#: builtin/notes.c:946 msgid "too many parameters" msgstr "" @@ -8198,7 +8464,7 @@ msgstr "" msgid "Overwriting existing notes for object %s\n" msgstr "" -#: builtin/notes.c:460 builtin/notes.c:621 builtin/notes.c:885 +#: builtin/notes.c:460 builtin/notes.c:621 builtin/notes.c:886 #, c-format msgid "Removing note for object %s\n" msgstr "" @@ -8234,63 +8500,63 @@ msgid "" "Please use 'git notes add -f -m/-F/-c/-C' instead.\n" msgstr "" -#: builtin/notes.c:767 +#: builtin/notes.c:768 msgid "General options" msgstr "" -#: builtin/notes.c:769 +#: builtin/notes.c:770 msgid "Merge options" msgstr "" -#: builtin/notes.c:771 +#: builtin/notes.c:772 msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" msgstr "" -#: builtin/notes.c:773 +#: builtin/notes.c:774 msgid "Committing unmerged notes" msgstr "" -#: builtin/notes.c:775 +#: builtin/notes.c:776 msgid "finalize notes merge by committing unmerged notes" msgstr "" -#: builtin/notes.c:777 +#: builtin/notes.c:778 msgid "Aborting notes merge resolution" msgstr "" -#: builtin/notes.c:779 +#: builtin/notes.c:780 msgid "abort notes merge" msgstr "" -#: builtin/notes.c:856 +#: builtin/notes.c:857 #, c-format msgid "A notes merge into %s is already in-progress at %s" msgstr "" -#: builtin/notes.c:883 +#: builtin/notes.c:884 #, c-format msgid "Object %s has no note\n" msgstr "" -#: builtin/notes.c:895 +#: builtin/notes.c:896 msgid "attempt to remove non-existent note is not an error" msgstr "" -#: builtin/notes.c:898 +#: builtin/notes.c:899 msgid "read object names from the standard input" msgstr "" -#: builtin/notes.c:979 +#: builtin/notes.c:980 msgid "notes-ref" msgstr "" -#: builtin/notes.c:980 +#: builtin/notes.c:981 msgid "use notes from <notes-ref>" msgstr "" -#: builtin/notes.c:1015 builtin/remote.c:1626 +#: builtin/notes.c:1016 builtin/remote.c:1628 #, c-format msgid "Unknown subcommand: %s" msgstr "" @@ -8310,165 +8576,169 @@ msgstr "" msgid "deflate error (%d)" msgstr "" -#: builtin/pack-objects.c:772 +#: builtin/pack-objects.c:763 +msgid "disabling bitmap writing, packs are split due to pack.packSizeLimit" +msgstr "" + +#: builtin/pack-objects.c:776 msgid "Writing objects" msgstr "" -#: builtin/pack-objects.c:1012 +#: builtin/pack-objects.c:1017 msgid "disabling bitmap writing, as some objects are not being packed" msgstr "" -#: builtin/pack-objects.c:2172 +#: builtin/pack-objects.c:2177 msgid "Compressing objects" msgstr "" -#: builtin/pack-objects.c:2558 +#: builtin/pack-objects.c:2563 #, c-format msgid "unsupported index version %s" msgstr "" -#: builtin/pack-objects.c:2562 +#: builtin/pack-objects.c:2567 #, c-format msgid "bad index version '%s'" msgstr "" -#: builtin/pack-objects.c:2592 +#: builtin/pack-objects.c:2597 msgid "do not show progress meter" msgstr "" -#: builtin/pack-objects.c:2594 +#: builtin/pack-objects.c:2599 msgid "show progress meter" msgstr "" -#: builtin/pack-objects.c:2596 +#: builtin/pack-objects.c:2601 msgid "show progress meter during object writing phase" msgstr "" -#: builtin/pack-objects.c:2599 +#: builtin/pack-objects.c:2604 msgid "similar to --all-progress when progress meter is shown" msgstr "" -#: builtin/pack-objects.c:2600 +#: builtin/pack-objects.c:2605 msgid "version[,offset]" msgstr "" -#: builtin/pack-objects.c:2601 +#: builtin/pack-objects.c:2606 msgid "write the pack index file in the specified idx format version" msgstr "" -#: builtin/pack-objects.c:2604 +#: builtin/pack-objects.c:2609 msgid "maximum size of each output pack file" msgstr "" -#: builtin/pack-objects.c:2606 +#: builtin/pack-objects.c:2611 msgid "ignore borrowed objects from alternate object store" msgstr "" -#: builtin/pack-objects.c:2608 +#: builtin/pack-objects.c:2613 msgid "ignore packed objects" msgstr "" -#: builtin/pack-objects.c:2610 +#: builtin/pack-objects.c:2615 msgid "limit pack window by objects" msgstr "" -#: builtin/pack-objects.c:2612 +#: builtin/pack-objects.c:2617 msgid "limit pack window by memory in addition to object limit" msgstr "" -#: builtin/pack-objects.c:2614 +#: builtin/pack-objects.c:2619 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "" -#: builtin/pack-objects.c:2616 +#: builtin/pack-objects.c:2621 msgid "reuse existing deltas" msgstr "" -#: builtin/pack-objects.c:2618 +#: builtin/pack-objects.c:2623 msgid "reuse existing objects" msgstr "" -#: builtin/pack-objects.c:2620 +#: builtin/pack-objects.c:2625 msgid "use OFS_DELTA objects" msgstr "" -#: builtin/pack-objects.c:2622 +#: builtin/pack-objects.c:2627 msgid "use threads when searching for best delta matches" msgstr "" -#: builtin/pack-objects.c:2624 +#: builtin/pack-objects.c:2629 msgid "do not create an empty pack output" msgstr "" -#: builtin/pack-objects.c:2626 +#: builtin/pack-objects.c:2631 msgid "read revision arguments from standard input" msgstr "" -#: builtin/pack-objects.c:2628 +#: builtin/pack-objects.c:2633 msgid "limit the objects to those that are not yet packed" msgstr "" -#: builtin/pack-objects.c:2631 +#: builtin/pack-objects.c:2636 msgid "include objects reachable from any reference" msgstr "" -#: builtin/pack-objects.c:2634 +#: builtin/pack-objects.c:2639 msgid "include objects referred by reflog entries" msgstr "" -#: builtin/pack-objects.c:2637 +#: builtin/pack-objects.c:2642 msgid "include objects referred to by the index" msgstr "" -#: builtin/pack-objects.c:2640 +#: builtin/pack-objects.c:2645 msgid "output pack to stdout" msgstr "" -#: builtin/pack-objects.c:2642 +#: builtin/pack-objects.c:2647 msgid "include tag objects that refer to objects to be packed" msgstr "" -#: builtin/pack-objects.c:2644 +#: builtin/pack-objects.c:2649 msgid "keep unreachable objects" msgstr "" -#: builtin/pack-objects.c:2645 parse-options.h:142 +#: builtin/pack-objects.c:2650 parse-options.h:142 msgid "time" msgstr "" -#: builtin/pack-objects.c:2646 +#: builtin/pack-objects.c:2651 msgid "unpack unreachable objects newer than <time>" msgstr "" -#: builtin/pack-objects.c:2649 +#: builtin/pack-objects.c:2654 msgid "create thin packs" msgstr "" -#: builtin/pack-objects.c:2651 +#: builtin/pack-objects.c:2656 msgid "create packs suitable for shallow fetches" msgstr "" -#: builtin/pack-objects.c:2653 +#: builtin/pack-objects.c:2658 msgid "ignore packs that have companion .keep file" msgstr "" -#: builtin/pack-objects.c:2655 +#: builtin/pack-objects.c:2660 msgid "pack compression level" msgstr "" -#: builtin/pack-objects.c:2657 +#: builtin/pack-objects.c:2662 msgid "do not hide commits by grafts" msgstr "" -#: builtin/pack-objects.c:2659 +#: builtin/pack-objects.c:2664 msgid "use a bitmap index if available to speed up counting objects" msgstr "" -#: builtin/pack-objects.c:2661 +#: builtin/pack-objects.c:2666 msgid "write a bitmap index together with the pack index" msgstr "" -#: builtin/pack-objects.c:2752 +#: builtin/pack-objects.c:2757 msgid "Counting objects" msgstr "" @@ -8496,15 +8766,15 @@ msgstr "" msgid "git prune [-n] [-v] [--expire <time>] [--] [<head>...]" msgstr "" -#: builtin/prune.c:105 builtin/worktree.c:124 +#: builtin/prune.c:105 builtin/worktree.c:125 msgid "do not remove, show only" msgstr "" -#: builtin/prune.c:106 builtin/worktree.c:125 +#: builtin/prune.c:106 builtin/worktree.c:126 msgid "report pruned objects" msgstr "" -#: builtin/prune.c:109 builtin/worktree.c:127 +#: builtin/prune.c:109 builtin/worktree.c:128 msgid "expire objects older than <time>" msgstr "" @@ -8516,65 +8786,69 @@ msgstr "" msgid "git pull [<options>] [<repository> [<refspec>...]]" msgstr "" -#: builtin/pull.c:117 +#: builtin/pull.c:120 msgid "Options related to merging" msgstr "" -#: builtin/pull.c:120 +#: builtin/pull.c:123 msgid "incorporate changes by rebasing rather than merging" msgstr "" -#: builtin/pull.c:144 builtin/revert.c:105 +#: builtin/pull.c:147 builtin/revert.c:105 msgid "allow fast-forward" msgstr "" -#: builtin/pull.c:150 +#: builtin/pull.c:153 msgid "verify that the named commit has a valid GPG signature" msgstr "" -#: builtin/pull.c:164 +#: builtin/pull.c:156 +msgid "automatically stash/stash pop before and after rebase" +msgstr "" + +#: builtin/pull.c:172 msgid "Options related to fetching" msgstr "" -#: builtin/pull.c:186 +#: builtin/pull.c:194 msgid "number of submodules pulled in parallel" msgstr "" -#: builtin/pull.c:275 +#: builtin/pull.c:283 #, c-format msgid "Invalid value for pull.ff: %s" msgstr "" -#: builtin/pull.c:359 +#: builtin/pull.c:379 msgid "Cannot pull with rebase: You have unstaged changes." msgstr "" -#: builtin/pull.c:365 +#: builtin/pull.c:385 msgid "Additionally, your index contains uncommitted changes." msgstr "" -#: builtin/pull.c:367 +#: builtin/pull.c:387 msgid "Cannot pull with rebase: Your index contains uncommitted changes." msgstr "" -#: builtin/pull.c:443 +#: builtin/pull.c:463 msgid "" "There is no candidate for rebasing against among the refs that you just " "fetched." msgstr "" -#: builtin/pull.c:445 +#: builtin/pull.c:465 msgid "" "There are no candidates for merging among the refs that you just fetched." msgstr "" -#: builtin/pull.c:446 +#: builtin/pull.c:466 msgid "" "Generally this means that you provided a wildcard refspec which had no\n" "matches on the remote end." msgstr "" -#: builtin/pull.c:449 +#: builtin/pull.c:469 #, c-format msgid "" "You asked to pull from the remote '%s', but did not specify\n" @@ -8582,46 +8856,57 @@ msgid "" "for your current branch, you must specify a branch on the command line." msgstr "" -#: builtin/pull.c:454 +#: builtin/pull.c:474 git-parse-remote.sh:73 msgid "You are not currently on a branch." msgstr "" -#: builtin/pull.c:456 builtin/pull.c:471 +#: builtin/pull.c:476 builtin/pull.c:491 git-parse-remote.sh:79 msgid "Please specify which branch you want to rebase against." msgstr "" -#: builtin/pull.c:458 builtin/pull.c:473 +#: builtin/pull.c:478 builtin/pull.c:493 git-parse-remote.sh:82 msgid "Please specify which branch you want to merge with." msgstr "" -#: builtin/pull.c:459 builtin/pull.c:474 +#: builtin/pull.c:479 builtin/pull.c:494 msgid "See git-pull(1) for details." msgstr "" -#: builtin/pull.c:469 +#: builtin/pull.c:481 builtin/pull.c:487 builtin/pull.c:496 +#: git-parse-remote.sh:64 +msgid "<remote>" +msgstr "" + +#: builtin/pull.c:481 builtin/pull.c:496 builtin/pull.c:501 +#: git-parse-remote.sh:65 +msgid "<branch>" +msgstr "" + +#: builtin/pull.c:489 git-parse-remote.sh:75 msgid "There is no tracking information for the current branch." msgstr "" -#: builtin/pull.c:478 -#, c-format +#: builtin/pull.c:498 git-parse-remote.sh:95 msgid "" -"If you wish to set tracking information for this branch you can do so with:\n" -"\n" -" git branch --set-upstream-to=%s/<branch> %s\n" +"If you wish to set tracking information for this branch you can do so with:" msgstr "" -#: builtin/pull.c:483 +#: builtin/pull.c:503 #, c-format msgid "" "Your configuration specifies to merge with the ref '%s'\n" "from the remote, but no such ref was fetched." msgstr "" -#: builtin/pull.c:841 +#: builtin/pull.c:864 +msgid "--[no-]autostash option is only valid with --rebase." +msgstr "" + +#: builtin/pull.c:872 msgid "Updating an unborn branch with changes added to the index." msgstr "" -#: builtin/pull.c:870 +#: builtin/pull.c:900 #, c-format msgid "" "fetch updated the current branch head.\n" @@ -8629,7 +8914,7 @@ msgid "" "commit %s." msgstr "" -#: builtin/pull.c:875 +#: builtin/pull.c:905 #, c-format msgid "" "Cannot fast-forward your working tree.\n" @@ -8640,11 +8925,11 @@ msgid "" "to recover." msgstr "" -#: builtin/pull.c:890 +#: builtin/pull.c:920 msgid "Cannot merge multiple branches into empty head." msgstr "" -#: builtin/pull.c:894 +#: builtin/pull.c:924 msgid "Cannot rebase onto multiple branches." msgstr "" @@ -8950,6 +9235,18 @@ msgstr "" msgid "debug unpack-trees" msgstr "" +#: builtin/receive-pack.c:25 +msgid "git receive-pack <git-dir>" +msgstr "" + +#: builtin/receive-pack.c:1719 +msgid "quiet" +msgstr "" + +#: builtin/receive-pack.c:1733 +msgid "You must specify a directory." +msgstr "" + #: builtin/reflog.c:423 #, c-format msgid "'%s' for '%s' is not a valid timestamp" @@ -9261,176 +9558,178 @@ msgstr "" msgid " Fetch URL: %s" msgstr "" -#: builtin/remote.c:1148 builtin/remote.c:1299 +#: builtin/remote.c:1148 builtin/remote.c:1301 msgid "(no URL)" msgstr "" -#: builtin/remote.c:1157 builtin/remote.c:1159 +#. TRANSLATORS: the colon ':' should align with +#. the one in " Fetch URL: %s" translation +#: builtin/remote.c:1159 builtin/remote.c:1161 #, c-format msgid " Push URL: %s" msgstr "" -#: builtin/remote.c:1161 builtin/remote.c:1163 builtin/remote.c:1165 +#: builtin/remote.c:1163 builtin/remote.c:1165 builtin/remote.c:1167 #, c-format msgid " HEAD branch: %s" msgstr "" -#: builtin/remote.c:1167 +#: builtin/remote.c:1169 #, c-format msgid "" " HEAD branch (remote HEAD is ambiguous, may be one of the following):\n" msgstr "" -#: builtin/remote.c:1179 +#: builtin/remote.c:1181 #, c-format msgid " Remote branch:%s" msgid_plural " Remote branches:%s" msgstr[0] "" msgstr[1] "" -#: builtin/remote.c:1182 builtin/remote.c:1209 +#: builtin/remote.c:1184 builtin/remote.c:1211 msgid " (status not queried)" msgstr "" -#: builtin/remote.c:1191 +#: builtin/remote.c:1193 msgid " Local branch configured for 'git pull':" msgid_plural " Local branches configured for 'git pull':" msgstr[0] "" msgstr[1] "" -#: builtin/remote.c:1199 +#: builtin/remote.c:1201 msgid " Local refs will be mirrored by 'git push'" msgstr "" -#: builtin/remote.c:1206 +#: builtin/remote.c:1208 #, c-format msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] "" msgstr[1] "" -#: builtin/remote.c:1227 +#: builtin/remote.c:1229 msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "" -#: builtin/remote.c:1229 +#: builtin/remote.c:1231 msgid "delete refs/remotes/<name>/HEAD" msgstr "" -#: builtin/remote.c:1244 +#: builtin/remote.c:1246 msgid "Cannot determine remote HEAD" msgstr "" -#: builtin/remote.c:1246 +#: builtin/remote.c:1248 msgid "Multiple remote HEAD branches. Please choose one explicitly with:" msgstr "" -#: builtin/remote.c:1256 +#: builtin/remote.c:1258 #, c-format msgid "Could not delete %s" msgstr "" -#: builtin/remote.c:1264 +#: builtin/remote.c:1266 #, c-format msgid "Not a valid ref: %s" msgstr "" -#: builtin/remote.c:1266 +#: builtin/remote.c:1268 #, c-format msgid "Could not setup %s" msgstr "" -#: builtin/remote.c:1284 +#: builtin/remote.c:1286 #, c-format msgid " %s will become dangling!" msgstr "" -#: builtin/remote.c:1285 +#: builtin/remote.c:1287 #, c-format msgid " %s has become dangling!" msgstr "" -#: builtin/remote.c:1295 +#: builtin/remote.c:1297 #, c-format msgid "Pruning %s" msgstr "" -#: builtin/remote.c:1296 +#: builtin/remote.c:1298 #, c-format msgid "URL: %s" msgstr "" -#: builtin/remote.c:1312 +#: builtin/remote.c:1314 #, c-format msgid " * [would prune] %s" msgstr "" -#: builtin/remote.c:1315 +#: builtin/remote.c:1317 #, c-format msgid " * [pruned] %s" msgstr "" -#: builtin/remote.c:1360 +#: builtin/remote.c:1362 msgid "prune remotes after fetching" msgstr "" -#: builtin/remote.c:1423 builtin/remote.c:1477 builtin/remote.c:1545 +#: builtin/remote.c:1425 builtin/remote.c:1479 builtin/remote.c:1547 #, c-format msgid "No such remote '%s'" msgstr "" -#: builtin/remote.c:1439 +#: builtin/remote.c:1441 msgid "add branch" msgstr "" -#: builtin/remote.c:1446 +#: builtin/remote.c:1448 msgid "no remote specified" msgstr "" -#: builtin/remote.c:1463 +#: builtin/remote.c:1465 msgid "query push URLs rather than fetch URLs" msgstr "" -#: builtin/remote.c:1465 +#: builtin/remote.c:1467 msgid "return all URLs" msgstr "" -#: builtin/remote.c:1493 +#: builtin/remote.c:1495 #, c-format msgid "no URLs configured for remote '%s'" msgstr "" -#: builtin/remote.c:1519 +#: builtin/remote.c:1521 msgid "manipulate push URLs" msgstr "" -#: builtin/remote.c:1521 +#: builtin/remote.c:1523 msgid "add URL" msgstr "" -#: builtin/remote.c:1523 +#: builtin/remote.c:1525 msgid "delete URLs" msgstr "" -#: builtin/remote.c:1530 +#: builtin/remote.c:1532 msgid "--add --delete doesn't make sense" msgstr "" -#: builtin/remote.c:1571 +#: builtin/remote.c:1573 #, c-format msgid "Invalid old URL pattern: %s" msgstr "" -#: builtin/remote.c:1579 +#: builtin/remote.c:1581 #, c-format msgid "No such URL found: %s" msgstr "" -#: builtin/remote.c:1581 +#: builtin/remote.c:1583 msgid "Will not delete all non-push URLs" msgstr "" -#: builtin/remote.c:1595 +#: builtin/remote.c:1597 msgid "be verbose; must be placed before a subcommand" msgstr "" @@ -9916,10 +10215,6 @@ msgstr "" msgid "exit with a zero status even if nothing matched" msgstr "" -#: builtin/rm.c:317 -msgid "Please, stage your changes to .gitmodules or stash them to proceed" -msgstr "" - #: builtin/rm.c:335 #, c-format msgid "not removing '%s' recursively without -r" @@ -10112,78 +10407,177 @@ msgstr "" msgid "prepend comment character and space to each line" msgstr "" -#: builtin/submodule--helper.c:73 builtin/submodule--helper.c:161 +#: builtin/submodule--helper.c:24 +#, c-format +msgid "No such ref: %s" +msgstr "" + +#: builtin/submodule--helper.c:31 +#, c-format +msgid "Expecting a full ref name, got %s" +msgstr "" + +#: builtin/submodule--helper.c:71 +#, c-format +msgid "cannot strip one component off url '%s'" +msgstr "" + +#: builtin/submodule--helper.c:278 builtin/submodule--helper.c:405 +#: builtin/submodule--helper.c:486 msgid "alternative anchor for relative paths" msgstr "" -#: builtin/submodule--helper.c:78 +#: builtin/submodule--helper.c:283 msgid "git submodule--helper list [--prefix=<path>] [<path>...]" msgstr "" -#: builtin/submodule--helper.c:108 +#: builtin/submodule--helper.c:326 builtin/submodule--helper.c:340 +#, c-format +msgid "No url found for submodule path '%s' in .gitmodules" +msgstr "" + +#: builtin/submodule--helper.c:366 +#, c-format +msgid "Failed to register url for submodule path '%s'" +msgstr "" + +#: builtin/submodule--helper.c:370 +#, c-format +msgid "Submodule '%s' (%s) registered for path '%s'\n" +msgstr "" + +#: builtin/submodule--helper.c:380 +#, c-format +msgid "warning: command update mode suggested for submodule '%s'\n" +msgstr "" + +#: builtin/submodule--helper.c:387 +#, c-format +msgid "Failed to register update mode for submodule path '%s'" +msgstr "" + +#: builtin/submodule--helper.c:406 +msgid "Suppress output for initializing a submodule" +msgstr "" + +#: builtin/submodule--helper.c:411 +msgid "git submodule--helper init [<path>]" +msgstr "" + +#: builtin/submodule--helper.c:432 msgid "git submodule--helper name <path>" msgstr "" -#: builtin/submodule--helper.c:114 +#: builtin/submodule--helper.c:438 #, c-format msgid "no submodule mapping found in .gitmodules for path '%s'" msgstr "" -#: builtin/submodule--helper.c:164 +#: builtin/submodule--helper.c:489 msgid "where the new submodule will be cloned to" msgstr "" -#: builtin/submodule--helper.c:167 +#: builtin/submodule--helper.c:492 msgid "name of the new submodule" msgstr "" -#: builtin/submodule--helper.c:170 +#: builtin/submodule--helper.c:495 msgid "url where to clone the submodule from" msgstr "" -#: builtin/submodule--helper.c:176 +#: builtin/submodule--helper.c:501 msgid "depth for shallow clones" msgstr "" -#: builtin/submodule--helper.c:182 +#: builtin/submodule--helper.c:507 msgid "" "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference " -"<repository>] [--name <name>] [--url <url>][--depth <depth>] [--] [<path>...]" +"<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>" msgstr "" -#: builtin/submodule--helper.c:196 builtin/submodule--helper.c:202 -#: builtin/submodule--helper.c:210 +#: builtin/submodule--helper.c:532 builtin/submodule--helper.c:538 #, c-format msgid "could not create directory '%s'" msgstr "" -#: builtin/submodule--helper.c:198 +#: builtin/submodule--helper.c:534 #, c-format msgid "clone of '%s' into submodule path '%s' failed" msgstr "" -#: builtin/submodule--helper.c:221 +#: builtin/submodule--helper.c:550 #, c-format msgid "cannot open file '%s'" msgstr "" -#: builtin/submodule--helper.c:226 +#: builtin/submodule--helper.c:555 #, c-format msgid "could not close file %s" msgstr "" -#: builtin/submodule--helper.c:241 +#: builtin/submodule--helper.c:562 #, c-format msgid "could not get submodule directory for '%s'" msgstr "" -#: builtin/submodule--helper.c:267 -msgid "fatal: submodule--helper subcommand must be called with a subcommand" +#: builtin/submodule--helper.c:609 +#, c-format +msgid "Submodule path '%s' not initialized" +msgstr "" + +#: builtin/submodule--helper.c:613 +msgid "Maybe you want to use 'update --init'?" +msgstr "" + +#: builtin/submodule--helper.c:639 +#, c-format +msgid "Skipping unmerged submodule %s" +msgstr "" + +#: builtin/submodule--helper.c:660 +#, c-format +msgid "Skipping submodule '%s'" +msgstr "" + +#: builtin/submodule--helper.c:768 +msgid "path into the working tree" +msgstr "" + +#: builtin/submodule--helper.c:771 +msgid "path into the working tree, across nested submodule boundaries" +msgstr "" + +#: builtin/submodule--helper.c:775 +msgid "rebase, merge, checkout or none" +msgstr "" + +#: builtin/submodule--helper.c:779 +msgid "Create a shallow clone truncated to the specified number of revisions" +msgstr "" + +#: builtin/submodule--helper.c:782 +msgid "parallel jobs" msgstr "" -#: builtin/submodule--helper.c:274 +#: builtin/submodule--helper.c:783 +msgid "don't print cloning progress" +msgstr "" + +#: builtin/submodule--helper.c:788 +msgid "git submodule--helper update_clone [--prefix=<path>] [<path>...]" +msgstr "" + +#: builtin/submodule--helper.c:798 +msgid "bad value for update parameter" +msgstr "" + +#: builtin/submodule--helper.c:855 +msgid "submodule--helper subcommand must be called with a subcommand" +msgstr "" + +#: builtin/submodule--helper.c:862 #, c-format -msgid "fatal: '%s' is not a valid submodule--helper subcommand" +msgid "'%s' is not a valid submodule--helper subcommand" msgstr "" #: builtin/symbolic-ref.c:7 @@ -10234,27 +10628,22 @@ msgstr "" msgid "git tag -v <tagname>..." msgstr "" -#: builtin/tag.c:80 +#: builtin/tag.c:81 #, c-format msgid "tag name too long: %.*s..." msgstr "" -#: builtin/tag.c:85 +#: builtin/tag.c:86 #, c-format msgid "tag '%s' not found." msgstr "" -#: builtin/tag.c:100 +#: builtin/tag.c:101 #, c-format msgid "Deleted tag '%s' (was %s)\n" msgstr "" -#: builtin/tag.c:112 -#, c-format -msgid "could not verify the tag '%s'" -msgstr "" - -#: builtin/tag.c:122 +#: builtin/tag.c:117 #, c-format msgid "" "\n" @@ -10263,7 +10652,7 @@ msgid "" "Lines starting with '%c' will be ignored.\n" msgstr "" -#: builtin/tag.c:126 +#: builtin/tag.c:121 #, c-format msgid "" "\n" @@ -10390,21 +10779,21 @@ msgstr "" msgid "only one -F or -m option is allowed." msgstr "" -#: builtin/tag.c:453 +#: builtin/tag.c:452 msgid "too many params" msgstr "" -#: builtin/tag.c:459 +#: builtin/tag.c:458 #, c-format msgid "'%s' is not a valid tag name." msgstr "" -#: builtin/tag.c:464 +#: builtin/tag.c:463 #, c-format msgid "tag '%s' already exists" msgstr "" -#: builtin/tag.c:489 +#: builtin/tag.c:491 #, c-format msgid "Updated tag '%s' (was %s)\n" msgstr "" @@ -10652,7 +11041,7 @@ msgstr "" msgid "print commit contents" msgstr "" -#: builtin/verify-commit.c:73 builtin/verify-tag.c:84 +#: builtin/verify-commit.c:73 builtin/verify-tag.c:35 msgid "print raw gpg status output" msgstr "" @@ -10672,7 +11061,7 @@ msgstr "" msgid "git verify-tag [-v | --verbose] <tag>..." msgstr "" -#: builtin/verify-tag.c:83 +#: builtin/verify-tag.c:34 msgid "print tag contents" msgstr "" @@ -10688,68 +11077,72 @@ msgstr "" msgid "git worktree list [<options>]" msgstr "" -#: builtin/worktree.c:39 +#: builtin/worktree.c:40 #, c-format msgid "Removing worktrees/%s: not a valid directory" msgstr "" -#: builtin/worktree.c:45 +#: builtin/worktree.c:46 #, c-format msgid "Removing worktrees/%s: gitdir file does not exist" msgstr "" -#: builtin/worktree.c:50 +#: builtin/worktree.c:51 #, c-format msgid "Removing worktrees/%s: unable to read gitdir file (%s)" msgstr "" -#: builtin/worktree.c:61 +#: builtin/worktree.c:62 #, c-format msgid "Removing worktrees/%s: invalid gitdir file" msgstr "" -#: builtin/worktree.c:77 +#: builtin/worktree.c:78 #, c-format msgid "Removing worktrees/%s: gitdir file points to non-existent location" msgstr "" -#: builtin/worktree.c:112 +#: builtin/worktree.c:113 #, c-format -msgid "failed to remove: %s" +msgid "failed to remove '%s'" msgstr "" -#: builtin/worktree.c:201 +#: builtin/worktree.c:202 #, c-format msgid "'%s' already exists" msgstr "" -#: builtin/worktree.c:233 +#: builtin/worktree.c:234 #, c-format msgid "could not create directory of '%s'" msgstr "" -#: builtin/worktree.c:269 +#: builtin/worktree.c:270 #, c-format msgid "Preparing %s (identifier %s)" msgstr "" -#: builtin/worktree.c:317 +#: builtin/worktree.c:322 msgid "checkout <branch> even if already checked out in other worktree" msgstr "" -#: builtin/worktree.c:319 +#: builtin/worktree.c:324 msgid "create a new branch" msgstr "" -#: builtin/worktree.c:321 +#: builtin/worktree.c:326 msgid "create or reset a branch" msgstr "" -#: builtin/worktree.c:322 +#: builtin/worktree.c:327 msgid "detach HEAD at named commit" msgstr "" -#: builtin/worktree.c:329 +#: builtin/worktree.c:328 +msgid "populate the new working tree" +msgstr "" + +#: builtin/worktree.c:336 msgid "-b, -B, and --detach are mutually exclusive" msgstr "" @@ -10769,7 +11162,7 @@ msgstr "" msgid "only useful for debugging" msgstr "" -#: credential-cache--daemon.c:262 +#: credential-cache--daemon.c:271 msgid "print debugging messages to stderr" msgstr "" @@ -10780,7 +11173,7 @@ msgid "" "to read about a specific subcommand or concept." msgstr "" -#: http.c:321 +#: http.c:322 msgid "Public key pinning not supported with cURL < 7.44.0" msgstr "" @@ -10908,7 +11301,7 @@ msgstr "" msgid "use <n> digits to display SHA-1s" msgstr "" -#: rerere.h:38 +#: rerere.h:40 msgid "update the index with reused conflict resolution if possible" msgstr "" @@ -11101,58 +11494,54 @@ msgid "" "\"." msgstr "" -#: git-rebase.sh:165 +#: git-rebase.sh:168 msgid "Applied autostash." msgstr "" -#: git-rebase.sh:168 +#: git-rebase.sh:171 #, sh-format msgid "Cannot store $stash_sha1" msgstr "" -#: git-rebase.sh:169 +#: git-rebase.sh:172 msgid "" "Applying autostash resulted in conflicts.\n" "Your changes are safe in the stash.\n" "You can run \"git stash pop\" or \"git stash drop\" at any time.\n" msgstr "" -#: git-rebase.sh:208 +#: git-rebase.sh:211 msgid "The pre-rebase hook refused to rebase." msgstr "" -#: git-rebase.sh:213 +#: git-rebase.sh:216 msgid "It looks like git-am is in progress. Cannot rebase." msgstr "" -#: git-rebase.sh:354 -msgid "The --exec option must be used with the --interactive option" -msgstr "" - -#: git-rebase.sh:359 +#: git-rebase.sh:357 msgid "No rebase in progress?" msgstr "" -#: git-rebase.sh:370 +#: git-rebase.sh:368 msgid "The --edit-todo action can only be used during interactive rebase." msgstr "" -#: git-rebase.sh:377 +#: git-rebase.sh:375 msgid "Cannot read HEAD" msgstr "" -#: git-rebase.sh:380 +#: git-rebase.sh:378 msgid "" "You must edit all merge conflicts and then\n" "mark them as resolved using git add" msgstr "" -#: git-rebase.sh:398 +#: git-rebase.sh:396 #, sh-format msgid "Could not move back to $head_name" msgstr "" -#: git-rebase.sh:417 +#: git-rebase.sh:415 #, sh-format msgid "" "It seems that there is already a $state_dir_base directory, and\n" @@ -11165,64 +11554,64 @@ msgid "" "valuable there." msgstr "" -#: git-rebase.sh:468 +#: git-rebase.sh:466 #, sh-format msgid "invalid upstream $upstream_name" msgstr "" -#: git-rebase.sh:492 +#: git-rebase.sh:490 #, sh-format msgid "$onto_name: there are more than one merge bases" msgstr "" -#: git-rebase.sh:495 git-rebase.sh:499 +#: git-rebase.sh:493 git-rebase.sh:497 #, sh-format msgid "$onto_name: there is no merge base" msgstr "" -#: git-rebase.sh:504 +#: git-rebase.sh:502 #, sh-format msgid "Does not point to a valid commit: $onto_name" msgstr "" -#: git-rebase.sh:527 +#: git-rebase.sh:525 #, sh-format msgid "fatal: no such branch: $branch_name" msgstr "" -#: git-rebase.sh:560 +#: git-rebase.sh:558 msgid "Cannot autostash" msgstr "" -#: git-rebase.sh:565 +#: git-rebase.sh:563 #, sh-format msgid "Created autostash: $stash_abbrev" msgstr "" -#: git-rebase.sh:569 +#: git-rebase.sh:567 msgid "Please commit or stash them." msgstr "" -#: git-rebase.sh:589 +#: git-rebase.sh:587 #, sh-format msgid "Current branch $branch_name is up to date." msgstr "" -#: git-rebase.sh:593 +#: git-rebase.sh:591 #, sh-format msgid "Current branch $branch_name is up to date, rebase forced." msgstr "" -#: git-rebase.sh:604 +#: git-rebase.sh:602 #, sh-format msgid "Changes from $mb to $onto:" msgstr "" -#: git-rebase.sh:613 +#: git-rebase.sh:611 msgid "First, rewinding head to replay your work on top of it..." msgstr "" -#: git-rebase.sh:623 +#: git-rebase.sh:621 #, sh-format msgid "Fast-forwarded $branch_name to $onto_name." msgstr "" @@ -11364,26 +11753,21 @@ msgstr "" msgid "(To restore them type \"git stash apply\")" msgstr "" -#: git-submodule.sh:104 -#, sh-format -msgid "cannot strip one component off url '$remoteurl'" -msgstr "" - -#: git-submodule.sh:281 +#: git-submodule.sh:219 msgid "Relative path can only be used from the toplevel of the working tree" msgstr "" -#: git-submodule.sh:291 +#: git-submodule.sh:229 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "" -#: git-submodule.sh:308 +#: git-submodule.sh:246 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "" -#: git-submodule.sh:312 +#: git-submodule.sh:250 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -11391,235 +11775,217 @@ msgid "" "Use -f if you really want to add it." msgstr "" -#: git-submodule.sh:330 +#: git-submodule.sh:268 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "" -#: git-submodule.sh:332 +#: git-submodule.sh:270 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "" -#: git-submodule.sh:340 +#: git-submodule.sh:278 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "" -#: git-submodule.sh:342 +#: git-submodule.sh:280 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" msgstr "" -#: git-submodule.sh:344 +#: git-submodule.sh:282 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" msgstr "" -#: git-submodule.sh:345 +#: git-submodule.sh:283 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " "option." msgstr "" -#: git-submodule.sh:347 +#: git-submodule.sh:285 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "" -#: git-submodule.sh:359 +#: git-submodule.sh:297 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "" -#: git-submodule.sh:364 +#: git-submodule.sh:302 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "" -#: git-submodule.sh:373 +#: git-submodule.sh:311 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "" -#: git-submodule.sh:417 -#, sh-format -msgid "Entering '$prefix$displaypath'" -msgstr "" - -#: git-submodule.sh:437 +#: git-submodule.sh:355 #, sh-format -msgid "Stopping at '$prefix$displaypath'; script returned non-zero status." +msgid "Entering '$displaypath'" msgstr "" -#: git-submodule.sh:483 +#: git-submodule.sh:375 #, sh-format -msgid "No url found for submodule path '$displaypath' in .gitmodules" +msgid "Stopping at '$displaypath'; script returned non-zero status." msgstr "" -#: git-submodule.sh:492 +#: git-submodule.sh:448 #, sh-format -msgid "Failed to register url for submodule path '$displaypath'" +msgid "pathspec and --all are incompatible" msgstr "" -#: git-submodule.sh:494 +#: git-submodule.sh:453 #, sh-format -msgid "Submodule '$name' ($url) registered for path '$displaypath'" +msgid "Use '--all' if you really want to deinitialize all submodules" msgstr "" -#: git-submodule.sh:511 -#, sh-format -msgid "Failed to register update mode for submodule path '$displaypath'" -msgstr "" - -#: git-submodule.sh:549 -#, sh-format -msgid "Use '.' if you really want to deinitialize all submodules" -msgstr "" - -#: git-submodule.sh:566 +#: git-submodule.sh:470 #, sh-format msgid "Submodule work tree '$displaypath' contains a .git directory" msgstr "" -#: git-submodule.sh:567 +#: git-submodule.sh:471 #, sh-format msgid "" "(use 'rm -rf' if you really want to remove it including all of its history)" msgstr "" -#: git-submodule.sh:573 +#: git-submodule.sh:477 #, sh-format msgid "" "Submodule work tree '$displaypath' contains local modifications; use '-f' to " "discard them" msgstr "" -#: git-submodule.sh:576 +#: git-submodule.sh:480 #, sh-format msgid "Cleared directory '$displaypath'" msgstr "" -#: git-submodule.sh:577 +#: git-submodule.sh:481 #, sh-format msgid "Could not remove submodule work tree '$displaypath'" msgstr "" -#: git-submodule.sh:580 +#: git-submodule.sh:484 #, sh-format msgid "Could not create empty submodule directory '$displaypath'" msgstr "" -#: git-submodule.sh:589 +#: git-submodule.sh:493 #, sh-format msgid "Submodule '$name' ($url) unregistered for path '$displaypath'" msgstr "" -#: git-submodule.sh:723 -#, sh-format -msgid "" -"Submodule path '$displaypath' not initialized\n" -"Maybe you want to use 'update --init'?" -msgstr "" - -#: git-submodule.sh:736 +#: git-submodule.sh:635 #, sh-format msgid "Unable to find current revision in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:745 +#: git-submodule.sh:644 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:768 +#: git-submodule.sh:667 #, sh-format msgid "Unable to fetch in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:788 +#: git-submodule.sh:680 #, sh-format msgid "Unable to checkout '$sha1' in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:789 +#: git-submodule.sh:681 #, sh-format msgid "Submodule path '$displaypath': checked out '$sha1'" msgstr "" -#: git-submodule.sh:793 +#: git-submodule.sh:685 #, sh-format msgid "Unable to rebase '$sha1' in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:794 +#: git-submodule.sh:686 #, sh-format msgid "Submodule path '$displaypath': rebased into '$sha1'" msgstr "" -#: git-submodule.sh:799 +#: git-submodule.sh:691 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:800 +#: git-submodule.sh:692 #, sh-format msgid "Submodule path '$displaypath': merged in '$sha1'" msgstr "" -#: git-submodule.sh:805 +#: git-submodule.sh:697 #, sh-format -msgid "" -"Execution of '$command $sha1' failed in submodule path '$prefix$sm_path'" +msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:806 +#: git-submodule.sh:698 #, sh-format -msgid "Submodule path '$prefix$sm_path': '$command $sha1'" +msgid "Submodule path '$displaypath': '$command $sha1'" msgstr "" -#: git-submodule.sh:836 +#: git-submodule.sh:729 #, sh-format msgid "Failed to recurse into submodule path '$displaypath'" msgstr "" -#: git-submodule.sh:944 +#: git-submodule.sh:837 msgid "The --cached option cannot be used with the --files option" msgstr "" -#: git-submodule.sh:996 +#: git-submodule.sh:889 #, sh-format msgid "unexpected mode $mod_dst" msgstr "" -#: git-submodule.sh:1016 +#: git-submodule.sh:909 #, sh-format msgid " Warn: $display_name doesn't contain commit $sha1_src" msgstr "" -#: git-submodule.sh:1019 +#: git-submodule.sh:912 #, sh-format msgid " Warn: $display_name doesn't contain commit $sha1_dst" msgstr "" -#: git-submodule.sh:1022 +#: git-submodule.sh:915 #, sh-format msgid " Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" -#: git-submodule.sh:1047 +#: git-submodule.sh:940 msgid "blob" msgstr "" -#: git-submodule.sh:1165 +#: git-submodule.sh:1059 #, sh-format msgid "Failed to recurse into submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:1229 +#: git-submodule.sh:1123 #, sh-format msgid "Synchronizing submodule url for '$displaypath'" msgstr "" + +#: git-parse-remote.sh:89 +#, sh-format +msgid "See git-${cmd}(1) for details." +msgstr "" @@ -6,12 +6,12 @@ # msgid "" msgstr "" -"Project-Id-Version: git v2.8.0-rc0\n" +"Project-Id-Version: git v2.9.0\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2016-03-16 00:16+0800\n" -"PO-Revision-Date: 2016-03-21 07:14+0700\n" +"POT-Creation-Date: 2016-05-24 23:42+0800\n" +"PO-Revision-Date: 2016-05-25 07:39+0700\n" "Last-Translator: TrαΊ§n Ngα»c QuΓ’n <vnwildman@gmail.com>\n" -"Language-Team: Vietnamese <gnome-vi-list@gnome.org>\n" +"Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n" "Language: vi\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" @@ -36,7 +36,7 @@ msgstr "" "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:101 builtin/merge.c:1226 +#: advice.c:101 builtin/merge.c:1238 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)." @@ -80,7 +80,7 @@ msgstr "Δα»nh_dαΊ‘ng" msgid "archive format" msgstr "Δα»nh dαΊ‘ng lΖ°u trα»―" -#: archive.c:430 builtin/log.c:1232 +#: archive.c:430 builtin/log.c:1395 msgid "prefix" msgstr "tiα»n_tα»" @@ -88,9 +88,9 @@ msgstr "tiα»n_tα»" 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:432 builtin/archive.c:88 builtin/blame.c:2547 builtin/blame.c:2548 +#: archive.c:432 builtin/archive.c:88 builtin/blame.c:2548 builtin/blame.c:2549 #: builtin/config.c:60 builtin/fast-export.c:987 builtin/fast-export.c:989 -#: builtin/grep.c:720 builtin/hash-object.c:100 builtin/ls-files.c:459 +#: builtin/grep.c:722 builtin/hash-object.c:100 builtin/ls-files.c:459 #: builtin/ls-files.c:462 builtin/notes.c:398 builtin/notes.c:561 #: builtin/read-tree.c:109 parse-options.h:153 msgid "file" @@ -124,7 +124,8 @@ msgstr "nΓ©n nhα» hΖ‘n" msgid "list supported archive formats" msgstr "liα»t kΓͺ cΓ‘c kiα»u nΓ©n Δược hα» trợ" -#: archive.c:451 builtin/archive.c:90 builtin/clone.c:78 +#: archive.c:451 builtin/archive.c:90 builtin/clone.c:82 +#: builtin/submodule--helper.c:776 msgid "repo" msgstr "kho" @@ -277,11 +278,16 @@ msgstr "TΓͺn Δα»i tượng chΖ°a rΓ΅ rΓ ng: β%sβ." msgid "Not a valid branch point: '%s'." msgstr "NhΓ‘nh khΓ΄ng hợp lα»: β%sβ." -#: branch.c:344 +#: branch.c:345 #, c-format msgid "'%s' is already checked out at '%s'" msgstr "β%sβ ΔΓ£ sαΊ΅n Δược lαΊ₯y ra tαΊ‘i β%sβ" +#: branch.c:364 +#, 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" + #: bundle.c:34 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -292,7 +298,7 @@ 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:87 builtin/commit.c:766 +#: bundle.c:87 builtin/commit.c:777 #, c-format msgid "could not open '%s'" msgstr "khΓ΄ng thα» mα» β%sβ" @@ -301,10 +307,10 @@ msgstr "khΓ΄ng thα» mα» β%sβ" 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:163 ref-filter.c:1462 sequencer.c:627 sequencer.c:1074 -#: builtin/blame.c:2754 builtin/commit.c:1045 builtin/log.c:334 -#: builtin/log.c:852 builtin/log.c:1467 builtin/log.c:1700 builtin/merge.c:358 -#: builtin/shortlog.c:170 +#: bundle.c:163 ref-filter.c:1462 sequencer.c:627 sequencer.c:1073 +#: builtin/blame.c:2755 builtin/commit.c:1056 builtin/log.c:340 +#: builtin/log.c:863 builtin/log.c:1308 builtin/log.c:1633 builtin/log.c:1875 +#: builtin/merge.c:361 builtin/shortlog.c:170 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" @@ -341,21 +347,21 @@ msgstr "rev-list ΔΓ£ chαΊΏt" 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:443 builtin/log.c:157 builtin/log.c:1372 builtin/shortlog.c:273 +#: bundle.c:443 builtin/log.c:163 builtin/log.c:1538 builtin/shortlog.c:273 #, c-format msgid "unrecognized argument: %s" msgstr "Δα»i sα» khΓ΄ng Δược thα»«a nhαΊn: %s" -#: bundle.c:449 +#: bundle.c:451 msgid "Refusing to create empty bundle." msgstr "Tα»« chα»i tαΊ‘o mα»t bΓ³ dα»― liα»u trα»ng rα»ng." -#: bundle.c:459 +#: bundle.c:463 #, c-format msgid "cannot create '%s'" msgstr "khΓ΄ng thα» tαΊ‘o β%sβ" -#: bundle.c:480 +#: bundle.c:491 msgid "index-pack died" msgstr "mα»₯c lα»₯c gΓ³i ΔΓ£ chαΊΏt" @@ -364,8 +370,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:40 builtin/am.c:437 builtin/am.c:473 builtin/am.c:1505 -#: builtin/am.c:2135 +#: commit.c:40 builtin/am.c:437 builtin/am.c:473 builtin/am.c:1504 +#: builtin/am.c:2134 #, c-format msgid "could not parse %s" msgstr "khΓ΄ng thα» phΓ’n tΓch cΓΊ phΓ‘p %s" @@ -399,21 +405,21 @@ msgstr "sai giΓ‘ trα» bαΊ±ng sα» của cαΊ₯u hΓ¬nh β%sβ cho β%sβ: %s" msgid "failed to expand user dir in: '%s'" msgstr "gαΊ·p lα»i mα» rα»ng thΖ° mα»₯c ngΖ°α»i dΓΉng trong: β%sβ" -#: config.c:758 config.c:769 +#: config.c:761 config.c:772 #, c-format msgid "bad zlib compression level %d" msgstr "mα»©c nΓ©n zlib %d lΓ sai" -#: config.c:891 +#: config.c:890 #, c-format msgid "invalid mode for object creation: %s" msgstr "chαΊΏ Δα» khΓ΄ng hợp lα» Δα»i vα»i viα»c tαΊ‘o Δα»i tượng: %s" -#: config.c:1220 +#: config.c:1228 msgid "unable to parse command-line config" msgstr "khΓ΄ng thα» phΓ’n tΓch cαΊ₯u hΓ¬nh dΓ²ng lα»nh" -#: config.c:1281 +#: config.c:1284 msgid "unknown error occured while reading the configuration files" msgstr "ΔΓ£ cΓ³ lα»i chΖ°a biαΊΏt xαΊ£y ra trong khi Δα»c cΓ‘c tαΊp tin cαΊ₯u hΓ¬nh" @@ -432,24 +438,27 @@ msgstr "sai biαΊΏn cαΊ₯u hΓ¬nh β%sβ trong tαΊp tin β%sβ tαΊ‘i dΓ²ng %d" msgid "%s has multiple values" msgstr "%s cΓ³ Δa giΓ‘ trα»" +#: config.c:2224 +#, c-format +msgid "could not set '%s' to '%s'" +msgstr "khΓ΄ng thα» ΔαΊ·t β%sβ thΓ nh β%sβ" + #: config.c:2226 #, c-format -msgid "Could not set '%s' to '%s'" -msgstr "KhΓ΄ng thα» ΔαΊ·t β%sβ thΓ nh β%sβ" +msgid "could not unset '%s'" +msgstr "khΓ΄ng thα» thΓ΄i ΔαΊ·t β%sβ" #: connected.c:69 msgid "Could not run 'git rev-list'" msgstr "KhΓ΄ng thα» chαΊ‘y βgit rev-listβ" #: connected.c:89 -#, c-format -msgid "failed write to rev-list: %s" -msgstr "gαΊ·p lα»i khi ghi vΓ o rev-list: %s" +msgid "failed write to rev-list" +msgstr "gαΊ·p lα»i khi ghi vΓ o rev-list" -#: connected.c:97 -#, c-format -msgid "failed to close rev-list's stdin: %s" -msgstr "gαΊ·p lα»i khi ΔΓ³ng ΔαΊ§u vΓ o chuαΊ©n stdin của rev-list: %s" +#: connected.c:96 +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" #: date.c:95 msgid "in the future" @@ -515,26 +524,26 @@ msgstr[0] "%lu nΔm trΖ°α»c" msgid "failed to read orderfile '%s'" msgstr "gαΊ·p lα»i khi Δα»c tαΊp-tin-thα»©-tα»± β%sβ" -#: diffcore-rename.c:536 +#: diffcore-rename.c:538 msgid "Performing inexact rename detection" msgstr "Δang thα»±c hiα»n dΓ² tΓ¬m Δα»i tΓͺn khΓ΄ng chΓnh xΓ‘c" -#: diff.c:115 +#: diff.c:116 #, c-format msgid " Failed to parse dirstat cut-off percentage '%s'\n" msgstr " GαΊ·p lα»i khi phΓ’n tΓch dirstat cαΊ―t bα» phαΊ§n trΔm β%sβ\n" -#: diff.c:120 +#: diff.c:121 #, c-format msgid " Unknown dirstat parameter '%s'\n" msgstr " KhΓ΄ng hiα»u Δα»i sα» dirstat β%sβ\n" -#: diff.c:215 +#: diff.c:225 #, 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:267 +#: diff.c:277 #, c-format msgid "" "Found errors in 'diff.dirstat' config variable:\n" @@ -543,16 +552,16 @@ msgstr "" "TΓ¬m thαΊ₯y cΓ‘c lα»i trong biαΊΏn cαΊ₯u hΓ¬nh βdiff.dirstatβ:\n" "%s" -#: diff.c:2997 +#: diff.c:3007 #, 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:3393 +#: diff.c:3405 msgid "--follow requires exactly one pathspec" msgstr "--follow cαΊ§n chΓnh xΓ‘c mα»t ΔαΊ·c tαΊ£ ΔΖ°α»ng dαΊ«n" -#: diff.c:3556 +#: diff.c:3568 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -561,20 +570,20 @@ msgstr "" "GαΊ·p lα»i khi phΓ’n tΓch Δα»i sα» tΓΉy chα»n --dirstat/-X:\n" "%s" -#: diff.c:3570 +#: diff.c:3582 #, 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β" -#: dir.c:2004 +#: dir.c:1823 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:2123 +#: dir.c:1942 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." -#: gpg-interface.c:166 gpg-interface.c:237 +#: gpg-interface.c:166 gpg-interface.c:235 msgid "could not run gpg." msgstr "khΓ΄ng thα» chαΊ‘y gpg." @@ -588,28 +597,28 @@ msgstr "gpg gαΊ·p lα»i khi kΓ½ dα»― liα»u" #: gpg-interface.c:222 #, c-format -msgid "could not create temporary file '%s': %s" -msgstr "khΓ΄ng thα» tαΊ‘o tαΊp tin tαΊ‘m thα»i β%sβ: %s" +msgid "could not create temporary file '%s'" +msgstr "khΓ΄ng thα» tαΊ‘o tαΊp tin tαΊ‘m thα»i β%sβ" -#: gpg-interface.c:225 +#: gpg-interface.c:224 #, c-format -msgid "failed writing detached signature to '%s': %s" -msgstr "gαΊ·p lα»i khi ghi chα»― kΓ½ ΔΓnh kΓ¨m vΓ o β%sβ: %s" +msgid "failed writing detached signature to '%s'" +msgstr "gαΊ·p lα»i khi ghi chα»― kΓ½ ΔΓnh kΓ¨m vΓ o β%sβ" #: grep.c:1718 #, c-format msgid "'%s': unable to read %s" msgstr "β%sβ: khΓ΄ng thα» Δα»c %s" -#: grep.c:1735 +#: grep.c:1735 builtin/clone.c:382 builtin/diff.c:84 builtin/rm.c:155 #, c-format -msgid "'%s': %s" -msgstr "β%sβ: %s" +msgid "failed to stat '%s'" +msgstr "gαΊ·p lα»i khi lαΊ₯y thα»ng kΓͺ vα» β%sβ" #: grep.c:1746 #, c-format -msgid "'%s': short read %s" -msgstr "β%sβ: Δα»c ngαΊ―n %s" +msgid "'%s': short read" +msgstr "β%sβ: Δα»c ngαΊ―n" #: help.c:205 #, c-format @@ -672,12 +681,36 @@ msgstr[0] "" msgid "%s: %s - %s" msgstr "%s: %s - %s" +#: lockfile.c:152 +#, c-format +msgid "" +"Unable to create '%s.lock': %s.\n" +"\n" +"Another git process seems to be running in this repository, e.g.\n" +"an editor opened by 'git commit'. Please make sure all processes\n" +"are terminated then try again. If it still fails, a git process\n" +"may have crashed in this repository earlier:\n" +"remove the file manually to continue." +msgstr "" +"KhΓ΄ng thα» tαΊ‘o β%s.lockβ: %s.\n" +"\n" +"TiαΊΏn trΓ¬nh git khΓ‘c cΓ³ lαΊ½ Δang chαΊ‘y α» kho nΓ y, vΓ dα»₯\n" +"mα»t trΓ¬nh soαΊ‘n thαΊ£o Δược mα» bα»i βgit commitβ. Vui lΓ²ng chαΊ―c chαΊ―n\n" +"rαΊ±ng mα»i tiαΊΏn trΓ¬nh ΔΓ£ chαΊ₯m dα»©t vΓ sau ΔΓ³ thα» lαΊ‘i. NαΊΏu vαΊ«n lα»i,\n" +"mα»t tiαΊΏn trΓ¬nh git cΓ³ lαΊ½ ΔΓ£ Δα» vα»‘ khi thα»±c hiα»n α» kho nΓ y trΖ°α»c ΔΓ³:\n" +"gΓ΅ bα» tαΊp tin mα»t cΓ‘ch thủ cΓ΄ng Δα» tiαΊΏp tα»₯c." + +#: lockfile.c:160 +#, c-format +msgid "Unable to create '%s.lock': %s" +msgstr "KhΓ΄ng thα» tαΊ‘o β%s.lockβ: %s" + #: merge.c:41 msgid "failed to read the cache" msgstr "gαΊ·p lα»i khi Δα»c bα» nhα» Δα»m" -#: merge.c:94 builtin/am.c:2008 builtin/am.c:2043 builtin/checkout.c:376 -#: builtin/checkout.c:587 builtin/clone.c:730 +#: merge.c:94 builtin/am.c:2007 builtin/am.c:2042 builtin/checkout.c:375 +#: builtin/checkout.c:586 builtin/clone.c:732 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" @@ -724,7 +757,7 @@ msgstr "khΓ΄ng thα» Δα»c Δα»i tượng %s β%sβ" msgid "blob expected for %s '%s'" msgstr "Δα»i tượng blob Δược mong Δợi cho %s β%sβ" -#: merge-recursive.c:790 builtin/clone.c:374 +#: merge-recursive.c:790 builtin/clone.c:376 #, c-format msgid "failed to open '%s'" msgstr "gαΊ·p lα»i khi mα» β%sβ" @@ -859,7 +892,7 @@ msgstr "ΔΓ£ bα» qua %s (ΔΓ£ cΓ³ sαΊ΅n lαΊ§n hΓ²a trα»n nΓ y)" msgid "Auto-merging %s" msgstr "Tα»±-Δα»ng-hΓ²a-trα»n %s" -#: merge-recursive.c:1650 git-submodule.sh:1048 +#: merge-recursive.c:1650 git-submodule.sh:941 msgid "submodule" msgstr "mΓ΄-Δun-con" @@ -888,49 +921,49 @@ 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:1783 +#: merge-recursive.c:1781 #, c-format msgid "Adding %s" msgstr "ThΓͺm \"%s\"" -#: merge-recursive.c:1800 +#: merge-recursive.c:1798 msgid "Fatal merge failure, shouldn't happen." msgstr "Viα»c hΓ²a trα»n hα»ng nghiΓͺm trα»ng, khΓ΄ng nΓͺn Δα» xαΊ£y ra." -#: merge-recursive.c:1819 +#: merge-recursive.c:1817 msgid "Already up-to-date!" msgstr "ΔΓ£ cαΊp nhαΊt rα»i!" -#: merge-recursive.c:1828 +#: merge-recursive.c:1826 #, 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:1858 +#: merge-recursive.c:1856 #, c-format msgid "Unprocessed path??? %s" msgstr "ΔΖ°α»ng dαΊ«n chΖ°a Δược xα» lΓ½??? %s" -#: merge-recursive.c:1906 +#: merge-recursive.c:1904 msgid "Merging:" msgstr "Δang trα»n:" -#: merge-recursive.c:1919 +#: merge-recursive.c:1917 #, 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:1956 +#: merge-recursive.c:1954 msgid "merge returned no commit" msgstr "hΓ²a trα»n khΓ΄ng trαΊ£ vα» lαΊ§n chuyα»n giao nΓ o" -#: merge-recursive.c:2013 +#: merge-recursive.c:2011 #, c-format msgid "Could not parse object '%s'" msgstr "KhΓ΄ng thα» phΓ’n tΓch Δα»i tượng β%sβ" -#: merge-recursive.c:2024 builtin/merge.c:646 +#: merge-recursive.c:2022 builtin/merge.c:649 builtin/merge.c:831 msgid "Unable to write index." msgstr "KhΓ΄ng thα» ghi bαΊ£ng mα»₯c lα»₯c" @@ -962,28 +995,28 @@ msgstr "GiΓ‘ trα» %s sai: β%sβ" msgid "unable to parse object: %s" msgstr "khΓ΄ng thα» phΓ’n tΓch Δα»i tượng: β%sβ" -#: parse-options.c:570 +#: parse-options.c:572 msgid "..." msgstr "β¦" -#: parse-options.c:588 +#: parse-options.c:590 #, c-format msgid "usage: %s" msgstr "cΓ‘ch dΓΉng: %s" #. TRANSLATORS: the colon here should align with the #. one in "usage: %s" translation -#: parse-options.c:592 +#: parse-options.c:594 #, c-format msgid " or: %s" msgstr " hoαΊ·c: %s" -#: parse-options.c:595 +#: parse-options.c:597 #, c-format msgid " %s" msgstr " %s" -#: parse-options.c:629 +#: parse-options.c:631 msgid "-NUM" msgstr "-Sα»" @@ -992,7 +1025,7 @@ msgstr "-Sα»" msgid "malformed object name '%s'" msgstr "tΓͺn Δα»i tượng dα» hΓ¬nh β%sβ" -#: path.c:752 +#: path.c:796 #, c-format msgid "Could not make %s writable by group" msgstr "KhΓ΄ng thα» lΓ m %s Δược ghi bα»i nhΓ³m" @@ -1062,7 +1095,7 @@ msgstr "" "α» ΔΓ’y khΓ΄ng cΓ³ gΓ¬ bα» loαΊ‘i trα»« bα»i: cΓ‘c mαΊ«u (loαΊ‘i trα»«).\n" "CΓ³ lαΊ½ bαΊ‘n ΔΓ£ quΓͺn thΓͺm hoαΊ·c lΓ β:/β hoαΊ·c lΓ β.β?" -#: pretty.c:969 +#: pretty.c:971 msgid "unable to parse --pretty format" msgstr "khΓ΄ng thα» phΓ’n tΓch Δα»nh dαΊ‘ng --pretty" @@ -1088,23 +1121,23 @@ 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" -#: refs.c:543 builtin/merge.c:761 builtin/merge.c:872 builtin/merge.c:974 -#: builtin/merge.c:984 +#: refs.c:543 builtin/merge.c:764 builtin/merge.c:883 builtin/merge.c:985 +#: builtin/merge.c:995 #, c-format msgid "Could not open '%s' for writing" msgstr "KhΓ΄ng thα» mα» β%sβ Δα» ghi" -#: refs/files-backend.c:2374 +#: refs/files-backend.c:2243 #, c-format msgid "could not delete reference %s: %s" msgstr "khΓ΄ng thα» xΓ³a bα» tham chiαΊΏu %s: %s" -#: refs/files-backend.c:2377 +#: refs/files-backend.c:2246 #, c-format msgid "could not delete references: %s" msgstr "khΓ΄ng thα» xΓ³a bα» tham chiαΊΏu: %s" -#: refs/files-backend.c:2386 +#: refs/files-backend.c:2255 #, c-format msgid "could not remove reference %s" msgstr "khΓ΄ng thα» gα»‘ bα» tham chiαΊΏu: %s" @@ -1243,94 +1276,94 @@ msgstr "Δα»nh dαΊ‘ng: thiαΊΏu nguyΓͺn tα» %%(end)" msgid "malformed object name %s" msgstr "tΓͺn Δα»i tượng dα» hΓ¬nh %s" -#: remote.c:745 +#: remote.c:746 #, 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:749 +#: remote.c:750 #, c-format msgid "%s usually tracks %s, not %s" msgstr "%s thΖ°α»ng theo dΓ΅i %s, khΓ΄ng phαΊ£i %s" -#: remote.c:753 +#: remote.c:754 #, c-format msgid "%s tracks both %s and %s" msgstr "%s theo dΓ΅i cαΊ£ %s vΓ %s" -#: remote.c:761 +#: remote.c:762 msgid "Internal error" msgstr "Lα»i nα»i bα»" -#: remote.c:1677 remote.c:1720 +#: remote.c:1678 remote.c:1721 msgid "HEAD does not point to a branch" msgstr "HEAD khΓ΄ng chα» ΔαΊΏn mα»t nhΓ‘nh nΓ o cαΊ£" -#: remote.c:1686 +#: remote.c:1687 #, c-format msgid "no such branch: '%s'" msgstr "khΓ΄ng cΓ³ nhΓ‘nh nΓ o nhΖ° thαΊΏ: β%sβ" -#: remote.c:1689 +#: remote.c:1690 #, 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:1695 +#: remote.c:1696 #, 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:1710 +#: remote.c:1711 #, 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:1725 +#: remote.c:1726 #, 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:1736 +#: remote.c:1737 #, c-format msgid "push refspecs for '%s' do not include '%s'" msgstr "ΔαΊ©y refspecs cho β%sβ khΓ΄ng bao gα»m β%sβ" -#: remote.c:1749 +#: remote.c:1750 msgid "push has no destination (push.default is 'nothing')" msgstr "ΔαΊ©y lΓͺn mΓ khΓ΄ng cΓ³ ΔΓch (push.default lΓ βnothingβ)" -#: remote.c:1771 +#: remote.c:1772 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:2073 +#: remote.c:2074 #, 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:2077 +#: remote.c:2078 msgid " (use \"git branch --unset-upstream\" to fixup)\n" msgstr " (dΓΉng \" git branch --unset-upstream\" Δα» sα»a)\n" -#: remote.c:2080 +#: remote.c:2081 #, 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:2084 +#: remote.c:2085 #, 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:2090 +#: remote.c:2091 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:2093 +#: remote.c:2094 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -1339,11 +1372,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:2101 +#: remote.c:2102 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:2104 +#: remote.c:2105 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -1356,22 +1389,22 @@ 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:2114 +#: remote.c:2115 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" -#: revision.c:2131 +#: revision.c:2142 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:2134 +#: revision.c:2145 #, 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:2328 +#: revision.c:2339 msgid "--first-parent is incompatible with --bisect" msgstr "--first-parent xung khαΊ―c vα»i --bisect" @@ -1422,7 +1455,7 @@ 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:190 sequencer.c:833 sequencer.c:913 +#: sequencer.c:190 sequencer.c:833 sequencer.c:912 #, c-format msgid "Could not write to %s" msgstr "KhΓ΄ng thα» ghi vΓ o %s" @@ -1582,12 +1615,12 @@ msgstr "hΓ£y thα» \"git cherry-pick (--continue | --quit | --abort)\"" msgid "Could not create sequencer directory %s" msgstr "KhΓ΄ng thα» tαΊ‘o thΖ° mα»₯c xαΊΏp dΓ£y %s" -#: sequencer.c:835 sequencer.c:917 +#: sequencer.c:835 sequencer.c:916 #, c-format msgid "Error wrapping up %s." msgstr "Lα»i bao bα»c %s." -#: sequencer.c:854 sequencer.c:987 +#: sequencer.c:854 sequencer.c:986 msgid "no cherry-pick or revert in progress" msgstr "khΓ΄ng cherry-pick hay hoΓ n nguyΓͺn trong tiαΊΏn trΓ¬nh" @@ -1599,63 +1632,72 @@ msgstr "khΓ΄ng thα» phΓ’n giαΊ£i HEAD" 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:878 builtin/apply.c:4287 +#: sequencer.c:878 builtin/fetch.c:610 builtin/fetch.c:851 #, c-format -msgid "cannot open %s: %s" -msgstr "khΓ΄ng thα» mα» %s: %s" +msgid "cannot open %s" +msgstr "khΓ΄ng mα» Δược β%sβ" -#: sequencer.c:881 +#: sequencer.c:880 #, c-format msgid "cannot read %s: %s" msgstr "khΓ΄ng thα» Δα»c %s: %s" -#: sequencer.c:882 +#: sequencer.c:881 msgid "unexpected end of file" msgstr "gαΊ·p kαΊΏt thΓΊc tαΊp tin Δα»t xuαΊ₯t" -#: sequencer.c:888 +#: sequencer.c:887 #, 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:910 +#: sequencer.c:909 #, c-format msgid "Could not format %s." msgstr "KhΓ΄ng thα» Δα»nh dαΊ‘ng β%sβ." -#: sequencer.c:1055 +#: sequencer.c:1054 #, c-format msgid "%s: can't cherry-pick a %s" msgstr "%s: khΓ΄ng thα» cherry-pick mα»t %s" -#: sequencer.c:1058 +#: sequencer.c:1057 #, c-format msgid "%s: bad revision" msgstr "%s: Δiα»m xΓ©t duyα»t sai" -#: sequencer.c:1092 +#: sequencer.c:1091 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:1093 +#: sequencer.c:1092 msgid "Can't cherry-pick into empty head" msgstr "KhΓ΄ng thα» cherry-pick vΓ o mα»t ΔαΊ§u (head) trα»ng rα»ng" -#: setup.c:246 +#: setup.c:248 #, c-format msgid "failed to read %s" msgstr "gαΊ·p lα»i khi Δα»c %s" +#: setup.c:468 +#, c-format +msgid "Expected git repo version <= %d, found %d" +msgstr "CαΊ§n phiΓͺn bαΊ£n kho git <= %d, nhΖ°ng lαΊ‘i nhαΊn Δược %d" + +#: setup.c:476 +msgid "unknown repository extensions found:" +msgstr "tΓ¬m thαΊ₯y phαΊ§n mα» rα»ng kho chΖ°a biαΊΏt:" + #: sha1_file.c:1080 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 Γ ?)" -#: sha1_file.c:2459 +#: sha1_file.c:2458 #, 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 Γ ?)" -#: sha1_file.c:2463 +#: sha1_file.c:2462 #, c-format msgid "offset beyond end of pack index for %s (truncated index?)" msgstr "" @@ -1685,31 +1727,40 @@ msgstr "" "nΓ y\n" "bαΊ±ng cΓ‘ch chαΊ‘y lα»nh \"git config advice.objectNameWarning false\"" -#: submodule.c:62 submodule.c:96 +#: submodule.c:64 submodule.c:98 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:66 submodule.c:100 +#: submodule.c:68 submodule.c:102 #, 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:74 +#: submodule.c:76 #, c-format msgid "Could not update .gitmodules entry %s" msgstr "KhΓ΄ng thα» cαΊp nhαΊt mα»₯c .gitmodules %s" -#: submodule.c:107 +#: submodule.c:109 #, 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:118 +#: submodule.c:120 msgid "staging updated .gitmodules failed" msgstr "gαΊ·p lα»i khi tα» chα»©c .gitmodules ΔΓ£ cαΊp nhαΊt" +#: submodule.c:177 +msgid "negative values not allowed for submodule.fetchJobs" +msgstr "khΓ΄ng cho phΓ©p giΓ‘ trα» Γ’m α» submodule.fetchJobs" + +#: submodule-config.c:355 +#, c-format +msgid "invalid value for %s" +msgstr "giΓ‘ trα» cho %s khΓ΄ng hợp lα»" + #: trailer.c:237 #, c-format msgid "running trailer command '%s' failed" @@ -1769,7 +1820,241 @@ msgstr "khΓ΄ng thα» Δα»i tΓͺn tαΊp tin tαΊ‘m thα»i thΓ nh %s" msgid "Could not read ref %s" msgstr "KhΓ΄ng thα» Δα»c tham chiαΊΏu %s" -#: unpack-trees.c:203 +#: unpack-trees.c:64 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by checkout:\n" +"%%sPlease commit your changes or stash them before you can switch branches." +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"checkout:\n" +"%%sVui lΓ²ng chuyα»n giao cΓ‘c thay Δα»i hay tαΊ‘m cαΊ₯t chΓΊng Δi trΖ°α»c khi bαΊ‘n cΓ³ " +"thα» chuyα»n nhΓ‘nh." + +#: unpack-trees.c:66 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by checkout:\n" +"%%s" +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"checkout:\n" +"%%s" + +#: unpack-trees.c:69 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by merge:\n" +"%%sPlease commit your changes or stash them before you can merge." +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"hΓ²a trα»n:\n" +"%%sVui lΓ²ng chuyα»n giao cΓ‘c thay Δα»i hay tαΊ‘m cαΊ₯t chΓΊng Δi trΖ°α»c khi bαΊ‘n cΓ³ " +"thα» hΓ²a trα»n." + +#: unpack-trees.c:71 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by merge:\n" +"%%s" +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"hΓ²a trα»n:\n" +"%%s" + +#: unpack-trees.c:74 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by %s:\n" +"%%sPlease commit your changes or stash them before you can %s." +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"%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 cΓ³ " +"thα» %s." + +#: unpack-trees.c:76 +#, c-format +msgid "" +"Your local changes to the following files would be overwritten by %s:\n" +"%%s" +msgstr "" +"CΓ‘c thay Δα»i nα»i bα» của bαΊ‘n vα»i cΓ‘c tαΊp tin sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"%s:\n" +"%%s" + +#: unpack-trees.c:81 +#, c-format +msgid "" +"Updating the following directories would lose untracked files in it:\n" +"%s" +msgstr "" +"Viα»c cαΊp nhαΊt cΓ‘c thΖ° mα»₯c sau ΔΓ’y cΓ³ thα» lΓ m mαΊ₯t cΓ‘c tαΊp tin theo dΓ΅i trong " +"nΓ³:\n" +"%s" + +#: unpack-trees.c:85 +#, c-format +msgid "" +"The following untracked working tree files would be removed by checkout:\n" +"%%sPlease move or remove them before you can switch branches." +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 lα»nh " +"checkout:\n" +"%%sVui lΓ²ng di chuyα»n hay gα»‘ bα» chΓΊng trΖ°α»c khi bαΊ‘n cΓ³ thα» chuyα»n nhΓ‘nh." + +#: unpack-trees.c:87 +#, c-format +msgid "" +"The following untracked working tree files would be removed by checkout:\n" +"%%s" +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 lα»nh " +"checkout:\n" +"%%s" + +#: unpack-trees.c:90 +#, c-format +msgid "" +"The following untracked working tree files would be removed by merge:\n" +"%%sPlease move or remove them before you can merge." +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 lα»nh hΓ²a " +"trα»n:\n" +"%%sVui lΓ²ng di chuyα»n hay gα»‘ bα» chΓΊng trΖ°α»c khi bαΊ‘n cΓ³ thα» hΓ²a trα»n." + +#: unpack-trees.c:92 +#, c-format +msgid "" +"The following untracked working tree files would be removed by merge:\n" +"%%s" +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 lα»nh hΓ²a " +"trα»n:\n" +"%%s" + +#: unpack-trees.c:95 +#, c-format +msgid "" +"The following untracked working tree files would be removed by %s:\n" +"%%sPlease move or remove them before you can %s." +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 cΓ³ thα» %s." + +#: unpack-trees.c:97 +#, c-format +msgid "" +"The following untracked working tree files would be removed by %s:\n" +"%%s" +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:102 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by " +"checkout:\n" +"%%sPlease move or remove them before you can switch branches." +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"checkout:\n" +"%%sVui lΓ²ng di chuyα»n hay gα»‘ bα» chΓΊng trΖ°α»c khi bαΊ‘n cΓ³ thα» chuyα»n nhΓ‘nh." + +#: unpack-trees.c:104 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by " +"checkout:\n" +"%%s" +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"checkout:\n" +"%%s" + +#: unpack-trees.c:107 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by merge:\n" +"%%sPlease move or remove them before you can merge." +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"hΓ²a trα»n:\n" +"%%sVui lΓ²ng di chuyα»n hay gα»‘ bα» chΓΊng trΖ°α»c khi bαΊ‘n cΓ³ thα» hΓ²a trα»n." + +#: unpack-trees.c:109 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by merge:\n" +"%%s" +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"hΓ²a trα»n:\n" +"%%s" + +#: unpack-trees.c:112 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by %s:\n" +"%%sPlease move or remove them before you can %s." +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"%s:\n" +"%%sVui lΓ²ng di chuyα»n hay gα»‘ bα» chΓΊng trΖ°α»c khi bαΊ‘n cΓ³ thα» %s." + +#: unpack-trees.c:114 +#, c-format +msgid "" +"The following untracked working tree files would be overwritten by %s:\n" +"%%s" +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i lα»nh " +"%s:\n" +"%%s" + +#: unpack-trees.c:121 +#, 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:124 +#, c-format +msgid "" +"Cannot update sparse checkout: the following entries are not up-to-date:\n" +"%s" +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:126 +#, c-format +msgid "" +"The following Working tree files would be overwritten by sparse checkout " +"update:\n" +"%s" +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» ghi ΔΓ¨ bα»i cαΊp " +"nhαΊt checkout rαΊ£i rΓ‘c:\n" +"%s" + +#: unpack-trees.c:128 +#, c-format +msgid "" +"The following Working tree files would be removed by sparse checkout " +"update:\n" +"%s" +msgstr "" +"CΓ‘c tαΊp tin cΓ’y lΓ m viα»c chΖ°a Δược theo dΓ΅i sau ΔΓ’y sαΊ½ bα» xΓ³a bα» bα»i cαΊp " +"nhαΊt checkout rαΊ£i rΓ‘c:\n" +"%s" + +#: unpack-trees.c:205 +#, c-format +msgid "Aborting\n" +msgstr "BΓ£i bα»\n" + +#: unpack-trees.c:237 msgid "Checking out files" msgstr "Δang lαΊ₯y ra cΓ‘c tαΊp tin" @@ -1807,200 +2092,196 @@ msgstr "ΔoαΊ‘n ΔΖ°α»ng dαΊ«n β..β khΓ΄ng hợp lα»" msgid "could not open '%s' for reading and writing" msgstr "khΓ΄ng thα» mα» β%sβ Δα» Δα»c vΓ ghi" -#: wrapper.c:224 wrapper.c:383 +#: wrapper.c:224 wrapper.c:383 builtin/am.c:779 #, c-format msgid "could not open '%s' for writing" msgstr "khΓ΄ng thα» mα» β%sβ Δα» ghi" -#: wrapper.c:226 wrapper.c:385 builtin/am.c:323 builtin/commit.c:1691 -#: builtin/merge.c:1075 builtin/pull.c:387 +#: wrapper.c:226 wrapper.c:385 builtin/am.c:323 builtin/am.c:772 +#: builtin/am.c:860 builtin/commit.c:1711 builtin/merge.c:1086 +#: builtin/pull.c:407 #, c-format msgid "could not open '%s' for reading" msgstr "khΓ΄ng thα» mα» β%sβ Δα» Δα»c" -#: wrapper.c:611 -#, c-format -msgid "unable to access '%s': %s" -msgstr "khΓ΄ng thα» truy cαΊp β%sβ: %s" - -#: wrapper.c:632 +#: wrapper.c:594 wrapper.c:615 #, c-format msgid "unable to access '%s'" msgstr "khΓ΄ng thα» truy cαΊp β%sβ" -#: wrapper.c:640 +#: wrapper.c:623 msgid "unable to get current working directory" msgstr "KhΓ΄ng thα» lαΊ₯y thΖ° mα»₯c lΓ m viα»c hiα»n hΓ nh" -#: wrapper.c:667 +#: wrapper.c:650 #, c-format msgid "could not open %s for writing" msgstr "khΓ΄ng thα» mα» %s Δα» ghi" -#: wrapper.c:678 builtin/am.c:410 +#: wrapper.c:661 builtin/am.c:410 #, c-format msgid "could not write to %s" msgstr "khΓ΄ng thα» ghi vΓ o %s" -#: wrapper.c:684 +#: wrapper.c:667 #, c-format msgid "could not close %s" msgstr "khΓ΄ng thα» ΔΓ³ng %s" -#: wt-status.c:149 +#: wt-status.c:150 msgid "Unmerged paths:" msgstr "Nhα»―ng ΔΖ°α»ng dαΊ«n chΖ°a Δược hΓ²a trα»n:" -#: wt-status.c:176 wt-status.c:203 +#: wt-status.c:177 wt-status.c:204 #, 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:178 wt-status.c:205 +#: wt-status.c:179 wt-status.c:206 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:182 +#: wt-status.c:183 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:184 wt-status.c:188 +#: wt-status.c:185 wt-status.c:189 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:186 +#: wt-status.c:187 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:197 wt-status.c:880 +#: wt-status.c:198 wt-status.c:881 msgid "Changes to be committed:" msgstr "Nhα»―ng thay Δα»i sαΊ½ Δược chuyα»n giao:" -#: wt-status.c:215 wt-status.c:889 +#: wt-status.c:216 wt-status.c:890 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:219 +#: wt-status.c:220 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:221 +#: wt-status.c:222 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:222 +#: wt-status.c:223 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:224 +#: wt-status.c:225 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:236 +#: wt-status.c:237 #, 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:251 +#: wt-status.c:252 msgid "both deleted:" msgstr "bα» xΓ³a bα»i cαΊ£ hai:" -#: wt-status.c:253 +#: wt-status.c:254 msgid "added by us:" msgstr "Δược thΓͺm vΓ o bα»i chΓΊng ta:" -#: wt-status.c:255 +#: wt-status.c:256 msgid "deleted by them:" msgstr "bα» xΓ³a Δi bα»i hα»:" -#: wt-status.c:257 +#: wt-status.c:258 msgid "added by them:" msgstr "Δược thΓͺm vΓ o bα»i hα»:" -#: wt-status.c:259 +#: wt-status.c:260 msgid "deleted by us:" msgstr "bα» xΓ³a bα»i chΓΊng ta:" -#: wt-status.c:261 +#: wt-status.c:262 msgid "both added:" msgstr "Δược thΓͺm vΓ o bα»i cαΊ£ hai:" -#: wt-status.c:263 +#: wt-status.c:264 msgid "both modified:" msgstr "bα» sα»a bα»i cαΊ£ hai:" -#: wt-status.c:265 +#: wt-status.c:266 #, c-format msgid "bug: unhandled unmerged status %x" msgstr "lα»i: khΓ΄ng thα» tiαΊΏp nhαΊn trαΊ‘ng thΓ‘i chΖ°a hΓ²a trα»n %x" -#: wt-status.c:273 +#: wt-status.c:274 msgid "new file:" msgstr "tαΊp tin mα»i:" -#: wt-status.c:275 +#: wt-status.c:276 msgid "copied:" msgstr "ΔΓ£ chΓ©p:" -#: wt-status.c:277 +#: wt-status.c:278 msgid "deleted:" msgstr "ΔΓ£ xΓ³a:" -#: wt-status.c:279 +#: wt-status.c:280 msgid "modified:" msgstr "ΔΓ£ sα»a:" -#: wt-status.c:281 +#: wt-status.c:282 msgid "renamed:" msgstr "ΔΓ£ Δα»i tΓͺn:" -#: wt-status.c:283 +#: wt-status.c:284 msgid "typechange:" msgstr "Δα»i-kiα»u:" -#: wt-status.c:285 +#: wt-status.c:286 msgid "unknown:" msgstr "khΓ΄ng hiα»u:" -#: wt-status.c:287 +#: wt-status.c:288 msgid "unmerged:" msgstr "chΖ°a hΓ²a trα»n:" -#: wt-status.c:369 +#: wt-status.c:370 msgid "new commits, " msgstr "lαΊ§n chuyα»n giao mα»i, " -#: wt-status.c:371 +#: wt-status.c:372 msgid "modified content, " msgstr "nα»i dung bα» sα»a Δα»i, " -#: wt-status.c:373 +#: wt-status.c:374 msgid "untracked content, " msgstr "nα»i dung chΖ°a Δược theo dΓ΅i, " -#: wt-status.c:390 +#: wt-status.c:391 #, c-format msgid "bug: unhandled diff status %c" msgstr "lα»i: khΓ΄ng thα» tiαΊΏp nhαΊn trαΊ‘ng thΓ‘i lα»nh diff %c" -#: wt-status.c:754 +#: wt-status.c:755 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:756 +#: wt-status.c:757 msgid "Submodule changes to be committed:" msgstr "Nhα»―ng mΓ΄-Δun-con thay Δα»i ΔΓ£ Δược chuyα»n giao:" -#: wt-status.c:837 +#: wt-status.c:838 msgid "" "Do not touch the line above.\n" "Everything below will be removed." @@ -2008,39 +2289,39 @@ msgstr "" "KhΓ΄ng Δα»ng ΔαΊΏn ΔΖ°α»ng α» trΓͺn.\n" "Mα»i thα»© phΓa dΖ°α»i sαΊ½ Δược xΓ³a bα»." -#: wt-status.c:948 +#: wt-status.c:949 msgid "You have unmerged paths." msgstr "BαΊ‘n cΓ³ nhα»―ng ΔΖ°α»ng dαΊ«n chΖ°a Δược hΓ²a trα»n." -#: wt-status.c:951 +#: wt-status.c:952 msgid " (fix conflicts and run \"git commit\")" msgstr " (sα»a cΓ‘c xung Δα»t rα»i chαΊ‘y \"git commit\")" -#: wt-status.c:954 +#: wt-status.c:956 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:957 +#: wt-status.c:959 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:967 +#: wt-status.c:969 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:970 +#: wt-status.c:972 msgid "The current patch is empty." msgstr "MiαΊΏng vΓ‘ hiα»n tαΊ‘i bα» trα»ng rα»ng." -#: wt-status.c:974 +#: wt-status.c:976 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:976 +#: wt-status.c:978 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:978 +#: wt-status.c:980 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)" @@ -2197,43 +2478,43 @@ msgstr "BαΊ‘n hiα»n tαΊ‘i Δang thα»±c hiα»n viα»c bisect (di chuyα»n nα»a 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:1438 +#: wt-status.c:1460 msgid "On branch " msgstr "TrΓͺn nhΓ‘nh " -#: wt-status.c:1444 +#: wt-status.c:1466 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:1446 +#: wt-status.c:1468 msgid "rebase in progress; onto " msgstr "rebase Δang Δược thα»±c hiα»n: lΓͺn trΓͺn " -#: wt-status.c:1451 +#: wt-status.c:1473 msgid "HEAD detached at " msgstr "HEAD Δược tΓ‘ch rα»i tαΊ‘i " -#: wt-status.c:1453 +#: wt-status.c:1475 msgid "HEAD detached from " msgstr "HEAD Δược tΓ‘ch rα»i tα»« " -#: wt-status.c:1456 +#: wt-status.c:1478 msgid "Not currently on any branch." msgstr "Hiα»n tαΊ‘i chαΊ³ng α» nhΓ‘nh nΓ o cαΊ£." -#: wt-status.c:1474 +#: wt-status.c:1496 msgid "Initial commit" msgstr "LαΊ§n chuyα»n giao khα»i tαΊ‘o" -#: wt-status.c:1488 +#: wt-status.c:1510 msgid "Untracked files" msgstr "Nhα»―ng tαΊp tin chΖ°a Δược theo dΓ΅i" -#: wt-status.c:1490 +#: wt-status.c:1512 msgid "Ignored files" msgstr "Nhα»―ng tαΊp tin bα» lα» Δi" -#: wt-status.c:1494 +#: wt-status.c:1516 #, c-format msgid "" "It took %.2f seconds to enumerate untracked files. 'status -uno'\n" @@ -2245,32 +2526,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:1500 +#: wt-status.c:1522 #, 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:1502 +#: wt-status.c:1524 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:1508 +#: wt-status.c:1530 msgid "No changes" msgstr "KhΓ΄ng cΓ³ thay Δα»i nΓ o" -#: wt-status.c:1513 +#: wt-status.c:1535 #, 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:1516 +#: wt-status.c:1538 #, 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:1519 +#: wt-status.c:1541 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -2279,57 +2560,57 @@ 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:1522 +#: wt-status.c:1544 #, 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:1525 +#: wt-status.c:1547 #, 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:1528 wt-status.c:1533 +#: wt-status.c:1550 wt-status.c:1555 #, c-format msgid "nothing to commit\n" msgstr "khΓ΄ng cΓ³ gΓ¬ Δα» chuyα»n giao\n" -#: wt-status.c:1531 +#: wt-status.c:1553 #, 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:1535 +#: wt-status.c:1557 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "khΓ΄ng cΓ³ gΓ¬ Δα» chuyα»n giao, thΖ° mα»₯c lΓ m viα»c sαΊ‘ch sαΊ½\n" -#: wt-status.c:1642 +#: wt-status.c:1664 msgid "Initial commit on " msgstr "LαΊ§n chuyα»n giao khα»i tαΊ‘o trΓͺn " -#: wt-status.c:1646 +#: wt-status.c:1668 msgid "HEAD (no branch)" msgstr "HEAD (khΓ΄ng nhΓ‘nh)" -#: wt-status.c:1675 +#: wt-status.c:1697 msgid "gone" msgstr "ΔΓ£ ra Δi" -#: wt-status.c:1677 wt-status.c:1685 +#: wt-status.c:1699 wt-status.c:1707 msgid "behind " msgstr "ΔαΊ±ng sau " -#: wt-status.c:1680 wt-status.c:1683 +#: wt-status.c:1702 wt-status.c:1705 msgid "ahead " msgstr "phΓa trΖ°α»c " -#: compat/precompose_utf8.c:57 builtin/clone.c:413 +#: compat/precompose_utf8.c:57 builtin/clone.c:415 #, c-format msgid "failed to unlink '%s'" msgstr "gαΊ·p lα»i khi bα» liΓͺn kαΊΏt (unlink) β%sβ" @@ -2343,7 +2624,7 @@ msgstr "git add [<cΓ‘c-tΓΉy-chα»n>] [--] <pathspec>β¦" msgid "unexpected diff status %c" msgstr "trαΊ‘ng thΓ‘i lα»nh diff khΓ΄ng nhΖ° mong Δợi %c" -#: builtin/add.c:70 builtin/commit.c:278 +#: builtin/add.c:70 builtin/commit.c:280 msgid "updating files failed" msgstr "CαΊp nhαΊt tαΊp tin gαΊ·p lα»i" @@ -2357,7 +2638,7 @@ 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:194 builtin/rev-parse.c:797 +#: builtin/add.c:194 builtin/rev-parse.c:811 msgid "Could not read the index" msgstr "KhΓ΄ng thα» Δα»c bαΊ£ng mα»₯c lα»₯c" @@ -2395,14 +2676,14 @@ msgstr "" "của bαΊ‘n:\n" #: builtin/add.c:249 builtin/clean.c:870 builtin/fetch.c:112 builtin/mv.c:111 -#: builtin/prune-packed.c:55 builtin/pull.c:189 builtin/push.c:511 -#: builtin/remote.c:1330 builtin/rm.c:268 builtin/send-pack.c:162 +#: builtin/prune-packed.c:55 builtin/pull.c:197 builtin/push.c:511 +#: builtin/remote.c:1332 builtin/rm.c:268 builtin/send-pack.c:162 msgid "dry run" msgstr "chαΊ‘y thα»" -#: builtin/add.c:250 builtin/apply.c:4561 builtin/check-ignore.c:19 -#: builtin/commit.c:1322 builtin/count-objects.c:85 builtin/fsck.c:558 -#: builtin/log.c:1651 builtin/mv.c:110 builtin/read-tree.c:114 +#: builtin/add.c:250 builtin/apply.c:4563 builtin/check-ignore.c:19 +#: builtin/commit.c:1333 builtin/count-objects.c:85 builtin/fsck.c:557 +#: builtin/log.c:1826 builtin/mv.c:110 builtin/read-tree.c:114 msgid "be verbose" msgstr "chi tiαΊΏt" @@ -2410,7 +2691,7 @@ msgstr "chi tiαΊΏt" msgid "interactive picking" msgstr "sα»a bαΊ±ng cΓ‘ch tΖ°Ζ‘ng tΓ‘c" -#: builtin/add.c:253 builtin/checkout.c:1155 builtin/reset.c:286 +#: builtin/add.c:253 builtin/checkout.c:1154 builtin/reset.c:286 msgid "select hunks interactively" msgstr "chα»n βhunksβ theo kiα»u tΖ°Ζ‘ng tΓ‘c" @@ -2482,16 +2763,16 @@ msgid "Maybe you wanted to say 'git add .'?\n" msgstr "CΓ³ lαΊ½ Γ½ bαΊ‘n lΓ βgit add .β phαΊ£i khΓ΄ng?\n" #: builtin/add.c:358 builtin/check-ignore.c:172 builtin/clean.c:914 -#: builtin/commit.c:337 builtin/mv.c:131 builtin/reset.c:235 builtin/rm.c:298 -#: builtin/submodule--helper.c:35 +#: builtin/commit.c:339 builtin/mv.c:131 builtin/reset.c:235 builtin/rm.c:298 +#: builtin/submodule--helper.c:240 msgid "index file corrupt" msgstr "tαΊp tin ghi bαΊ£ng mα»₯c lα»₯c bα» hα»ng" -#: builtin/add.c:439 builtin/apply.c:4659 builtin/mv.c:280 builtin/rm.c:430 +#: builtin/add.c:439 builtin/apply.c:4661 builtin/mv.c:283 builtin/rm.c:430 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" -#: builtin/am.c:256 builtin/commit.c:738 builtin/merge.c:1078 +#: builtin/am.c:256 builtin/commit.c:749 builtin/merge.c:1089 #, c-format msgid "could not read '%s'" msgstr "KhΓ΄ng thα» Δα»c β%sβ." @@ -2519,16 +2800,6 @@ msgstr "GαΊ·p lα»i khi sao chΓ©p ghi chΓΊ (note) tα»« β%sβ tα»i β%sβ" msgid "fseek failed" msgstr "fseek gαΊ·p lα»i" -#: builtin/am.c:772 builtin/am.c:860 -#, c-format -msgid "could not open '%s' for reading: %s" -msgstr "khΓ΄ng thα» mα» β%sβ Δα» Δα»c: %s" - -#: builtin/am.c:779 -#, c-format -msgid "could not open '%s' for writing: %s" -msgstr "KhΓ΄ng thα» mα» β%sβ Δα» ghi: %s" - #: builtin/am.c:788 #, c-format msgid "could not parse patch '%s'" @@ -2538,75 +2809,75 @@ msgstr "khΓ΄ng thα» phΓ’n tΓch cΓΊ phΓ‘p β%sβ" 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:901 +#: builtin/am.c:900 msgid "invalid timestamp" msgstr "dαΊ₯u thα»i gian khΓ΄ng hợp lα»" -#: builtin/am.c:904 builtin/am.c:912 +#: builtin/am.c:903 builtin/am.c:911 msgid "invalid Date line" msgstr "dΓ²ng NgΓ y thΓ‘ng khΓ΄ng hợp lα»" -#: builtin/am.c:909 +#: builtin/am.c:908 msgid "invalid timezone offset" msgstr "Δα» lα»ch mΓΊi giα» khΓ΄ng hợp lα»" -#: builtin/am.c:996 +#: builtin/am.c:995 msgid "Patch format detection failed." msgstr "DΓ² tΓ¬m Δα»nh dαΊ‘ng miαΊΏng vΓ‘ gαΊ·p lα»i." -#: builtin/am.c:1001 builtin/clone.c:378 +#: builtin/am.c:1000 builtin/clone.c:380 #, c-format msgid "failed to create directory '%s'" msgstr "tαΊ‘o thΖ° mα»₯c \"%s\" gαΊ·p lα»i" -#: builtin/am.c:1005 +#: builtin/am.c:1004 msgid "Failed to split patches." msgstr "GαΊ·p lα»i khi chia nhα» cΓ‘c miαΊΏng vΓ‘." -#: builtin/am.c:1137 builtin/commit.c:363 +#: builtin/am.c:1136 builtin/commit.c:365 msgid "unable to write index file" msgstr "khΓ΄ng thα» ghi tαΊp tin lΖ°u mα»₯c lα»₯c" -#: builtin/am.c:1188 +#: builtin/am.c:1187 #, 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:1189 +#: builtin/am.c:1188 #, 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:1190 +#: builtin/am.c:1189 #, 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:1328 +#: builtin/am.c:1327 msgid "Patch is empty. Was it split wrong?" msgstr "MiαΊΏng vΓ‘ trα»ng rα»ng. QuΓ‘ trΓ¬nh chia nhα» miαΊΏng vΓ‘ cΓ³ lα»i?" -#: builtin/am.c:1402 builtin/log.c:1350 +#: builtin/am.c:1401 builtin/log.c:1516 #, c-format msgid "invalid ident line: %s" msgstr "dΓ²ng thα»₯t lα» khΓ΄ng hợp lα»: %s" -#: builtin/am.c:1429 +#: builtin/am.c:1428 #, 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:1631 +#: builtin/am.c:1630 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:1633 +#: builtin/am.c:1632 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:1652 +#: builtin/am.c:1651 msgid "" "Did you hand edit your patch?\n" "It does not apply to blobs recorded in its index." @@ -2614,38 +2885,38 @@ 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:1658 +#: builtin/am.c:1657 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:1673 +#: builtin/am.c:1672 msgid "Failed to merge in the changes." msgstr "GαΊ·p lα»i khi trα»n vΓ o cΓ‘c thay Δα»i." -#: builtin/am.c:1697 builtin/merge.c:633 +#: builtin/am.c:1696 builtin/merge.c:636 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" -#: builtin/am.c:1704 +#: builtin/am.c:1703 msgid "applying to an empty history" msgstr "Γ‘p dα»₯ng vΓ o mα»t lα»ch sα» trα»ng rα»ng" -#: builtin/am.c:1717 builtin/commit.c:1755 builtin/merge.c:830 -#: builtin/merge.c:855 +#: builtin/am.c:1716 builtin/commit.c:1775 builtin/merge.c:841 +#: builtin/merge.c:866 msgid "failed to write commit object" msgstr "gαΊ·p lα»i khi ghi Δα»i tượng chuyα»n giao" -#: builtin/am.c:1749 builtin/am.c:1753 +#: builtin/am.c:1748 builtin/am.c:1752 #, 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:1769 +#: builtin/am.c:1768 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" -#: builtin/am.c:1774 +#: builtin/am.c:1773 msgid "Commit Body is:" msgstr "ThΓ’n của lαΊ§n chuyα»n giao lΓ :" @@ -2653,37 +2924,37 @@ 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:1784 +#: builtin/am.c:1783 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:1834 +#: builtin/am.c:1833 #, 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:1869 builtin/am.c:1941 +#: builtin/am.c:1868 builtin/am.c:1940 #, c-format msgid "Applying: %.*s" msgstr "Γp dα»₯ng: %.*s" -#: builtin/am.c:1885 +#: builtin/am.c:1884 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:1893 +#: builtin/am.c:1892 #, c-format msgid "Patch failed at %s %.*s" msgstr "GαΊ·p lα»i khi vΓ‘ tαΊ‘i %s %.*s" -#: builtin/am.c:1899 +#: builtin/am.c:1898 #, c-format msgid "The copy of the patch that failed is found in: %s" msgstr "BαΊ£n sao chΓ©p của miαΊΏng vΓ‘ mΓ nΓ³ gαΊ·p lα»i thΓ¬ Δược tΓ¬m thαΊ₯y trong: %s" -#: builtin/am.c:1944 +#: builtin/am.c:1943 msgid "" "No changes - did you forget to use 'git add'?\n" "If there is nothing left to stage, chances are that something else\n" @@ -2694,7 +2965,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:1951 +#: builtin/am.c:1950 msgid "" "You still have unmerged paths in your index.\n" "Did you forget to use 'git add'?" @@ -2702,17 +2973,17 @@ msgstr "" "BαΊ‘n vαΊ«n cΓ³ nhα»―ng ΔΖ°α»ng dαΊ«n chΖ°a Δược hΓ²a trα»n trong bαΊ£ng mα»₯c lα»₯c của mΓ¬nh.\n" "BαΊ‘n ΔΓ£ quΓͺn sα» dα»₯ng lα»nh βgit addβ Γ ?" -#: builtin/am.c:2059 builtin/am.c:2063 builtin/am.c:2075 builtin/reset.c:308 +#: builtin/am.c:2058 builtin/am.c:2062 builtin/am.c:2074 builtin/reset.c:308 #: builtin/reset.c:316 #, c-format msgid "Could not parse object '%s'." msgstr "khΓ΄ng thα» phΓ’n tΓch Δα»i tượng β%sβ." -#: builtin/am.c:2111 +#: builtin/am.c:2110 msgid "failed to clean index" msgstr "gαΊ·p lα»i khi dα»n bαΊ£ng mα»₯c lα»₯c" -#: builtin/am.c:2145 +#: builtin/am.c:2144 msgid "" "You seem to have moved HEAD since the last 'am' failure.\n" "Not rewinding to ORIG_HEAD" @@ -2720,153 +2991,155 @@ 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:2206 +#: builtin/am.c:2205 #, c-format msgid "Invalid value for --patch-format: %s" msgstr "GiΓ‘ trα» khΓ΄ng hợp lα» cho --patch-format: %s" -#: builtin/am.c:2239 +#: builtin/am.c:2238 msgid "git am [<options>] [(<mbox>|<Maildir>)...]" msgstr "git am [<cΓ‘c-tΓΉy-chα»n>] [(<mbox>|<Maildir>)β¦]" -#: builtin/am.c:2240 +#: builtin/am.c:2239 msgid "git am [<options>] (--continue | --skip | --abort)" msgstr "git am [<cΓ‘c-tΓΉy-chα»n>] (--continue | --skip | --abort)" -#: builtin/am.c:2246 +#: builtin/am.c:2245 msgid "run interactively" msgstr "chαΊ‘y kiα»u tΖ°Ζ‘ng tΓ‘c" -#: builtin/am.c:2248 +#: builtin/am.c:2247 msgid "historical option -- no-op" msgstr "tΓΉy chα»n lα»ch sα» -- khΓ΄ng-toΓ‘n-tα»" -#: builtin/am.c:2250 +#: builtin/am.c:2249 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:2251 builtin/init-db.c:474 builtin/prune-packed.c:57 +#: builtin/am.c:2250 builtin/init-db.c:478 builtin/prune-packed.c:57 #: builtin/repack.c:171 msgid "be quiet" msgstr "im lαΊ·ng" -#: builtin/am.c:2253 +#: builtin/am.c:2252 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" -#: builtin/am.c:2256 +#: builtin/am.c:2255 msgid "recode into utf8 (default)" msgstr "chuyα»n mΓ£ thΓ nh utf8 (mαΊ·c Δα»nh)" -#: builtin/am.c:2258 +#: builtin/am.c:2257 msgid "pass -k flag to git-mailinfo" msgstr "chuyα»n cα» -k cho git-mailinfo" -#: builtin/am.c:2260 +#: builtin/am.c:2259 msgid "pass -b flag to git-mailinfo" msgstr "chuyα»n cα» -b cho git-mailinfo" -#: builtin/am.c:2262 +#: builtin/am.c:2261 msgid "pass -m flag to git-mailinfo" msgstr "chuyα»n cα» -m cho git-mailinfo" -#: builtin/am.c:2264 +#: builtin/am.c:2263 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:2267 +#: builtin/am.c:2266 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:2270 +#: builtin/am.c:2269 msgid "strip everything before a scissors line" msgstr "cαΊ―t mα»i thα»© trΖ°α»c dΓ²ng scissors" -#: builtin/am.c:2271 builtin/apply.c:4544 +#: builtin/am.c:2270 builtin/apply.c:4546 msgid "action" msgstr "hΓ nh Δα»ng" -#: builtin/am.c:2272 builtin/am.c:2275 builtin/am.c:2278 builtin/am.c:2281 -#: builtin/am.c:2284 builtin/am.c:2287 builtin/am.c:2290 builtin/am.c:2293 -#: builtin/am.c:2299 +#: builtin/am.c:2271 builtin/am.c:2274 builtin/am.c:2277 builtin/am.c:2280 +#: builtin/am.c:2283 builtin/am.c:2286 builtin/am.c:2289 builtin/am.c:2292 +#: builtin/am.c:2298 msgid "pass it through git-apply" msgstr "chuyα»n nΓ³ qua git-apply" -#: builtin/am.c:2280 builtin/apply.c:4568 +#: builtin/am.c:2279 builtin/apply.c:4570 msgid "root" msgstr "gα»c" -#: builtin/am.c:2283 builtin/am.c:2286 builtin/apply.c:4506 -#: builtin/apply.c:4509 builtin/clone.c:86 builtin/fetch.c:95 -#: builtin/pull.c:171 builtin/submodule--helper.c:72 -#: builtin/submodule--helper.c:160 builtin/submodule--helper.c:163 +#: builtin/am.c:2282 builtin/am.c:2285 builtin/apply.c:4508 +#: builtin/apply.c:4511 builtin/clone.c:90 builtin/fetch.c:95 +#: builtin/pull.c:179 builtin/submodule--helper.c:277 +#: builtin/submodule--helper.c:404 builtin/submodule--helper.c:485 +#: builtin/submodule--helper.c:488 builtin/submodule--helper.c:767 +#: builtin/submodule--helper.c:770 msgid "path" msgstr "ΔΖ°α»ng-dαΊ«n" -#: builtin/am.c:2289 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 -#: builtin/grep.c:704 builtin/merge.c:198 builtin/pull.c:131 builtin/pull.c:185 +#: builtin/am.c:2288 builtin/fmt-merge-msg.c:666 builtin/fmt-merge-msg.c:669 +#: builtin/grep.c:706 builtin/merge.c:199 builtin/pull.c:134 builtin/pull.c:193 #: builtin/repack.c:178 builtin/repack.c:182 builtin/show-branch.c:645 #: builtin/show-ref.c:175 builtin/tag.c:340 parse-options.h:132 #: parse-options.h:134 parse-options.h:244 msgid "n" msgstr "n" -#: builtin/am.c:2292 builtin/apply.c:4512 +#: builtin/am.c:2291 builtin/apply.c:4514 msgid "num" msgstr "sα»" -#: builtin/am.c:2295 builtin/for-each-ref.c:37 builtin/replace.c:438 +#: builtin/am.c:2294 builtin/for-each-ref.c:37 builtin/replace.c:438 #: builtin/tag.c:372 msgid "format" msgstr "Δα»nh dαΊ‘ng" -#: builtin/am.c:2296 +#: builtin/am.c:2295 msgid "format the patch(es) are in" msgstr "Δα»nh dαΊ‘ng (cΓ‘c) miαΊΏng vΓ‘ theo" -#: builtin/am.c:2302 +#: builtin/am.c:2301 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:2304 +#: builtin/am.c:2303 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:2307 +#: builtin/am.c:2306 msgid "synonyms for --continue" msgstr "Δα»ng nghΔ©a vα»i --continue" -#: builtin/am.c:2310 +#: builtin/am.c:2309 msgid "skip the current patch" msgstr "bα» qua miαΊΏng vΓ‘ hiα»n hΓ nh" -#: builtin/am.c:2313 +#: builtin/am.c:2312 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:2317 +#: builtin/am.c:2316 msgid "lie about committer date" msgstr "nΓ³i dα»i vα» ngΓ y chuyα»n giao" -#: builtin/am.c:2319 +#: builtin/am.c:2318 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:2321 builtin/commit.c:1593 builtin/merge.c:225 -#: builtin/pull.c:159 builtin/revert.c:92 builtin/tag.c:355 +#: builtin/am.c:2320 builtin/commit.c:1609 builtin/merge.c:228 +#: builtin/pull.c:164 builtin/revert.c:92 builtin/tag.c:355 msgid "key-id" msgstr "mΓ£-sα»-khΓ³a" -#: builtin/am.c:2322 +#: builtin/am.c:2321 msgid "GPG-sign commits" msgstr "lαΊ§n chuyα»n giao kΓ½-GPG" -#: builtin/am.c:2325 +#: builtin/am.c:2324 msgid "(internal use for git-rebase)" msgstr "(dΓΉng nα»i bα» cho git-rebase)" -#: builtin/am.c:2340 +#: builtin/am.c:2339 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." @@ -2874,16 +3147,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:2347 +#: builtin/am.c:2346 msgid "failed to read the index" msgstr "gαΊ·p lα»i Δα»c bαΊ£ng mα»₯c lα»₯c" -#: builtin/am.c:2362 +#: builtin/am.c:2361 #, 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:2386 +#: builtin/am.c:2385 #, c-format msgid "" "Stray %s directory found.\n" @@ -2892,7 +3165,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:2392 +#: builtin/am.c:2391 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." @@ -2927,38 +3200,38 @@ msgstr "thi hΓ nh biα»u thα»©c chΓnh quy trαΊ£ vα» %d cho ΔαΊ§u vΓ o: %s" 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" -#: builtin/apply.c:940 +#: builtin/apply.c:937 #, 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" -#: builtin/apply.c:944 +#: builtin/apply.c:942 #, 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" -#: builtin/apply.c:945 +#: builtin/apply.c:943 #, 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" -#: builtin/apply.c:952 +#: builtin/apply.c:949 #, 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" -#: builtin/apply.c:1415 +#: builtin/apply.c:1406 #, c-format msgid "recount: unexpected line: %.*s" msgstr "chi tiαΊΏt: dΓ²ng khΓ΄ng cαΊ§n: %.*s" -#: builtin/apply.c:1472 +#: builtin/apply.c:1463 #, 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" -#: builtin/apply.c:1489 +#: builtin/apply.c:1480 #, c-format msgid "" "git diff header lacks filename information when removing %d leading pathname " @@ -2970,76 +3243,76 @@ 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)" -#: builtin/apply.c:1655 +#: builtin/apply.c:1646 msgid "new file depends on old contents" msgstr "tαΊp tin mα»i phα»₯ thuα»c vΓ o nα»i dung cΕ©" -#: builtin/apply.c:1657 +#: builtin/apply.c:1648 msgid "deleted file still has contents" msgstr "tαΊp tin ΔΓ£ xΓ³a vαΊ«n cΓ²n nα»i dung" -#: builtin/apply.c:1683 +#: builtin/apply.c:1674 #, c-format msgid "corrupt patch at line %d" msgstr "miαΊΏng vΓ‘ hα»ng tαΊ‘i dΓ²ng %d" -#: builtin/apply.c:1719 +#: builtin/apply.c:1710 #, 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Ε©" -#: builtin/apply.c:1721 +#: builtin/apply.c:1712 #, c-format msgid "deleted file %s still has contents" msgstr "tαΊp tin ΔΓ£ xΓ³a %s vαΊ«n cΓ²n nα»i dung" -#: builtin/apply.c:1724 +#: builtin/apply.c:1715 #, 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" -#: builtin/apply.c:1870 +#: builtin/apply.c:1861 #, 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" -#: builtin/apply.c:1899 +#: builtin/apply.c:1895 #, 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" -#: builtin/apply.c:2050 +#: builtin/apply.c:2048 #, c-format msgid "patch with only garbage at line %d" msgstr "vΓ‘ chα» vα»i βrΓ‘cβ tαΊ‘i dΓ²ng %d" -#: builtin/apply.c:2140 +#: builtin/apply.c:2138 #, c-format msgid "unable to read symlink %s" msgstr "khΓ΄ng thα» Δα»c liΓͺn kαΊΏt mα»m %s" -#: builtin/apply.c:2144 +#: builtin/apply.c:2142 #, c-format msgid "unable to open or read %s" msgstr "khΓ΄ng thα» mα» hay Δα»c %s" -#: builtin/apply.c:2777 +#: builtin/apply.c:2775 #, c-format msgid "invalid start of line: '%c'" msgstr "sai khα»i ΔαΊ§u dΓ²ng: β%cβ" -#: builtin/apply.c:2896 +#: builtin/apply.c:2894 #, 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)." -#: builtin/apply.c:2908 +#: builtin/apply.c:2906 #, 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" -#: builtin/apply.c:2914 +#: builtin/apply.c:2912 #, c-format msgid "" "while searching for:\n" @@ -3048,324 +3321,334 @@ msgstr "" "trong khi Δang tΓ¬m kiαΊΏm cho:\n" "%.*s" -#: builtin/apply.c:2934 +#: builtin/apply.c:2932 #, 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β" -#: builtin/apply.c:3035 +#: builtin/apply.c:3033 #, 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β" -#: builtin/apply.c:3041 +#: builtin/apply.c:3039 #, 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)" -#: builtin/apply.c:3062 +#: builtin/apply.c:3060 #, c-format msgid "patch failed: %s:%ld" msgstr "gαΊ·p lα»i khi vΓ‘: %s:%ld" -#: builtin/apply.c:3186 +#: builtin/apply.c:3184 #, c-format msgid "cannot checkout %s" msgstr "khΓ΄ng thα» lαΊ₯y ra %s" -#: builtin/apply.c:3231 builtin/apply.c:3242 builtin/apply.c:3287 +#: builtin/apply.c:3229 builtin/apply.c:3240 builtin/apply.c:3285 #, c-format msgid "read of %s failed" msgstr "Δα»c %s gαΊ·p lα»i" -#: builtin/apply.c:3239 +#: builtin/apply.c:3237 #, c-format msgid "reading from '%s' beyond a symbolic link" msgstr "Δα»c tα»« β%sβ vượt ra ngoΓ i liΓͺn kαΊΏt mα»m" -#: builtin/apply.c:3267 builtin/apply.c:3489 +#: builtin/apply.c:3265 builtin/apply.c:3487 #, c-format msgid "path %s has been renamed/deleted" msgstr "ΔΖ°α»ng dαΊ«n %s ΔΓ£ bα» xΓ³a hoαΊ·c Δα»i tΓͺn" -#: builtin/apply.c:3348 builtin/apply.c:3503 +#: builtin/apply.c:3346 builtin/apply.c:3501 #, c-format msgid "%s: does not exist in index" msgstr "%s: khΓ΄ng tα»n tαΊ‘i trong bαΊ£ng mα»₯c lα»₯c" -#: builtin/apply.c:3352 builtin/apply.c:3495 builtin/apply.c:3517 +#: builtin/apply.c:3350 builtin/apply.c:3493 builtin/apply.c:3515 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3357 builtin/apply.c:3511 +#: builtin/apply.c:3355 builtin/apply.c:3509 #, c-format msgid "%s: does not match index" msgstr "%s: khΓ΄ng khα»p trong mα»₯c lα»₯c" -#: builtin/apply.c:3459 +#: builtin/apply.c:3457 msgid "removal patch leaves file contents" msgstr "loαΊ‘i bα» miαΊΏng vΓ‘ Δα» lαΊ‘i nα»i dung tαΊp tin" -#: builtin/apply.c:3528 +#: builtin/apply.c:3526 #, c-format msgid "%s: wrong type" msgstr "%s: sai kiα»u" -#: builtin/apply.c:3530 +#: builtin/apply.c:3528 #, c-format msgid "%s has type %o, expected %o" msgstr "%s cΓ³ kiα»u %o, cαΊ§n %o" -#: builtin/apply.c:3689 builtin/apply.c:3691 +#: builtin/apply.c:3687 builtin/apply.c:3689 #, c-format msgid "invalid path '%s'" msgstr "ΔΖ°α»ng dαΊ«n khΓ΄ng hợp lα» β%sβ" -#: builtin/apply.c:3746 +#: builtin/apply.c:3744 #, c-format msgid "%s: already exists in index" msgstr "%s: ΔΓ£ cΓ³ tα»« trΖ°α»c trong bαΊ£ng mα»₯c lα»₯c" -#: builtin/apply.c:3749 +#: builtin/apply.c:3747 #, c-format msgid "%s: already exists in working directory" msgstr "%s: ΔΓ£ sαΊ΅n cΓ³ trong thΖ° mα»₯c Δang lΓ m viα»c" -#: builtin/apply.c:3769 +#: builtin/apply.c:3767 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "chαΊΏ Δα» mα»i (%o) của %s khΓ΄ng khα»p vα»i chαΊΏ Δα» cΕ© (%o)" -#: builtin/apply.c:3774 +#: builtin/apply.c:3772 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "chαΊΏ Δα» mα»i (%o) của %s khΓ΄ng khα»p vα»i chαΊΏ Δα» cΕ© (%o) của %s" -#: builtin/apply.c:3794 +#: builtin/apply.c:3792 #, c-format msgid "affected file '%s' is beyond a symbolic link" msgstr "tαΊp tin chα»u tΓ‘c Δα»ng β%sβ vượt ra ngoΓ i liΓͺn kαΊΏt mα»m" -#: builtin/apply.c:3798 +#: builtin/apply.c:3796 #, c-format msgid "%s: patch does not apply" msgstr "%s: miαΊΏng vΓ‘ khΓ΄ng Δược Γ‘p dα»₯ng" -#: builtin/apply.c:3812 +#: builtin/apply.c:3810 #, c-format msgid "Checking patch %s..." msgstr "Δang kiα»m tra miαΊΏng vΓ‘ %sβ¦" -#: builtin/apply.c:3905 builtin/checkout.c:233 builtin/reset.c:135 +#: builtin/apply.c:3903 builtin/checkout.c:233 builtin/reset.c:135 #, 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β" -#: builtin/apply.c:4048 +#: builtin/apply.c:4046 #, c-format msgid "unable to remove %s from index" msgstr "khΓ΄ng thα» gα»‘ bα» %s tα»« mα»₯c lα»₯c" -#: builtin/apply.c:4077 +#: builtin/apply.c:4075 #, c-format msgid "corrupt patch for submodule %s" msgstr "miαΊΏng vΓ‘ sai hα»ng cho mΓ΄-Δun-con %s" -#: builtin/apply.c:4081 +#: builtin/apply.c:4079 #, c-format msgid "unable to stat newly created file '%s'" msgstr "khΓ΄ng thα» lαΊ₯y thα»ng kα» vα» tαΊp tin %s mα»i hΖ‘n ΔΓ£ Δược tαΊ‘o" -#: builtin/apply.c:4086 +#: builtin/apply.c:4084 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "khΓ΄ng thα» tαΊ‘o βkho lΖ°u ΔαΊ±ng sauβ cho tαΊp tin Δược tαΊ‘o mα»i hΖ‘n %s" -#: builtin/apply.c:4089 builtin/apply.c:4197 +#: builtin/apply.c:4087 builtin/apply.c:4195 #, c-format msgid "unable to add cache entry for %s" msgstr "khΓ΄ng thα» thΓͺm mα»₯c nhα» Δα»m cho %s" -#: builtin/apply.c:4122 +#: builtin/apply.c:4120 #, c-format msgid "closing file '%s'" msgstr "Δang ΔΓ³ng tαΊp tin β%sβ" -#: builtin/apply.c:4171 +#: builtin/apply.c:4169 #, c-format msgid "unable to write file '%s' mode %o" msgstr "khΓ΄ng thα» ghi vΓ o tαΊp tin β%sβ chαΊΏ Δα» %o" -#: builtin/apply.c:4258 +#: builtin/apply.c:4256 #, c-format msgid "Applied patch %s cleanly." msgstr "ΔΓ£ Γ‘p dα»₯ng miαΊΏng vΓ‘ %s mα»t cΓ‘ch sαΊ‘ch sαΊ½." -#: builtin/apply.c:4266 +#: builtin/apply.c:4264 msgid "internal error" msgstr "lα»i nα»i bα»" -#: builtin/apply.c:4269 +#: builtin/apply.c:4267 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "Δang Γ‘p dα»₯ng miαΊΏng vΓ‘ %%s vα»i %d lαΊ§n tα»« chα»iβ¦" -#: builtin/apply.c:4279 +#: builtin/apply.c:4277 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "Δang cαΊ―t ngαΊ―n tΓͺn tαΊp tin .rej thΓ nh %.*s.rej" -#: builtin/apply.c:4300 +#: builtin/apply.c:4285 +#, c-format +msgid "cannot open %s: %s" +msgstr "khΓ΄ng thα» mα» %s: %s" + +#: builtin/apply.c:4298 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Khα»i nhα» #%d Δược Γ‘p dα»₯ng gα»n gΓ ng." -#: builtin/apply.c:4303 +#: builtin/apply.c:4301 #, c-format msgid "Rejected hunk #%d." msgstr "ΔoαΊ‘n dα»― liα»u #%d bα» tα»« chα»i." -#: builtin/apply.c:4393 +#: builtin/apply.c:4387 +#, c-format +msgid "Skipped patch '%s'." +msgstr "bα» qua ΔΖ°α»ng dαΊ«n β%sβ." + +#: builtin/apply.c:4395 msgid "unrecognized input" msgstr "khΓ΄ng thα»«a nhαΊn ΔαΊ§u vΓ o" -#: builtin/apply.c:4404 +#: builtin/apply.c:4406 msgid "unable to read index file" msgstr "khΓ΄ng thα» Δα»c tαΊp tin lΖ°u bαΊ£ng mα»₯c lα»₯c" -#: builtin/apply.c:4507 +#: builtin/apply.c:4509 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" -#: builtin/apply.c:4510 +#: builtin/apply.c:4512 msgid "apply changes matching the given path" msgstr "Γ‘p dα»₯ng cΓ‘c thay Δα»i khα»p vα»i ΔΖ°α»ng dαΊ«n ΔΓ£ cho" -#: builtin/apply.c:4513 +#: builtin/apply.c:4515 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" -#: builtin/apply.c:4516 +#: builtin/apply.c:4518 msgid "ignore additions made by the patch" msgstr "lα» Δi phαΊ§n bα» xung Δược tαΊ‘o ra bα»i miαΊΏng vΓ‘" -#: builtin/apply.c:4518 +#: builtin/apply.c:4520 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" -#: builtin/apply.c:4522 +#: builtin/apply.c:4524 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" -#: builtin/apply.c:4524 +#: builtin/apply.c:4526 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" -#: builtin/apply.c:4526 +#: builtin/apply.c:4528 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" -#: builtin/apply.c:4528 +#: builtin/apply.c:4530 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" -#: builtin/apply.c:4530 +#: builtin/apply.c:4532 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" -#: builtin/apply.c:4532 +#: builtin/apply.c:4534 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" -#: builtin/apply.c:4534 +#: builtin/apply.c:4536 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)" -#: builtin/apply.c:4536 +#: builtin/apply.c:4538 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" -#: builtin/apply.c:4538 +#: builtin/apply.c:4540 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" -#: builtin/apply.c:4541 builtin/checkout-index.c:169 builtin/ls-files.c:425 +#: builtin/apply.c:4543 builtin/checkout-index.c:169 builtin/ls-files.c:425 msgid "paths are separated with NUL character" msgstr "cΓ‘c ΔΖ°α»ng dαΊ«n bα» ngΔn cΓ‘ch bα»i kΓ½ tα»± NULL" -#: builtin/apply.c:4543 +#: builtin/apply.c:4545 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" -#: builtin/apply.c:4545 +#: builtin/apply.c:4547 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" -#: builtin/apply.c:4548 builtin/apply.c:4551 +#: builtin/apply.c:4550 builtin/apply.c:4553 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" -#: builtin/apply.c:4554 +#: builtin/apply.c:4556 msgid "apply the patch in reverse" msgstr "Γ‘p dα»₯ng miαΊΏng vΓ‘ theo chiα»u ngược" -#: builtin/apply.c:4556 +#: builtin/apply.c:4558 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" -#: builtin/apply.c:4558 +#: builtin/apply.c:4560 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" -#: builtin/apply.c:4560 +#: builtin/apply.c:4562 msgid "allow overlapping hunks" msgstr "cho phΓ©p chα»ng khα»i nhα»" -#: builtin/apply.c:4563 +#: builtin/apply.c:4565 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" -#: builtin/apply.c:4566 +#: builtin/apply.c:4568 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" -#: builtin/apply.c:4569 +#: builtin/apply.c:4571 msgid "prepend <root> to all filenames" msgstr "treo thΓͺm <root> vΓ o tαΊ₯t cαΊ£ cΓ‘c tΓͺn tαΊp tin" -#: builtin/apply.c:4591 +#: builtin/apply.c:4593 msgid "--3way outside a repository" msgstr "--3way α» ngoΓ i mα»t kho chα»©a" -#: builtin/apply.c:4599 +#: builtin/apply.c:4601 msgid "--index outside a repository" msgstr "--index α» ngoΓ i mα»t kho chα»©a" -#: builtin/apply.c:4602 +#: builtin/apply.c:4604 msgid "--cached outside a repository" msgstr "--cached α» ngoΓ i mα»t kho chα»©a" -#: builtin/apply.c:4621 +#: builtin/apply.c:4623 #, c-format msgid "can't open patch '%s'" msgstr "khΓ΄ng thα» mα» miαΊΏng vΓ‘ β%sβ" -#: builtin/apply.c:4635 +#: builtin/apply.c:4637 #, 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" -#: builtin/apply.c:4641 builtin/apply.c:4651 +#: builtin/apply.c:4643 builtin/apply.c:4653 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -3431,101 +3714,101 @@ msgstr "<rev-opts> Δược mΓ΄ tαΊ£ trong tΓ i liα»u git-rev-list(1)" msgid "Blaming lines" msgstr "CΓ‘c dΓ²ng blame" -#: builtin/blame.c:2530 +#: builtin/blame.c:2531 msgid "Show blame entries as we find them, incrementally" msgstr "Hiα»n thα» cΓ‘c mα»₯c βblameβ nhΖ° lΓ chΓΊng ta thαΊ₯y chΓΊng, tΔng dαΊ§n" -#: builtin/blame.c:2531 +#: builtin/blame.c:2532 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" "Hiα»n thα» SHA-1 trαΊ―ng cho nhα»―ng lαΊ§n chuyα»n giao biΓͺn giα»i (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2532 +#: builtin/blame.c:2533 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "KhΓ΄ng coi cΓ‘c lαΊ§n chuyα»n giao gα»c lΓ giα»i hαΊ‘n (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2533 +#: builtin/blame.c:2534 msgid "Show work cost statistics" msgstr "Hiα»n thα» thα»ng kΓͺ cΓ΄ng sα»©c lΓ m viα»c" -#: builtin/blame.c:2534 +#: builtin/blame.c:2535 msgid "Force progress reporting" msgstr "Γp buα»c bΓ‘o cΓ‘o tiαΊΏn triα»n cΓ΄ng viα»c" -#: builtin/blame.c:2535 +#: builtin/blame.c:2536 msgid "Show output score for blame entries" msgstr "Hiα»n thα» kαΊΏt xuαΊ₯t Δiα»m sα» cΓ³ cΓ‘c mα»₯c tin βblameβ" -#: builtin/blame.c:2536 +#: builtin/blame.c:2537 msgid "Show original filename (Default: auto)" msgstr "Hiα»n thα» tΓͺn tαΊp tin gα»c (MαΊ·c Δα»nh: auto)" -#: builtin/blame.c:2537 +#: builtin/blame.c:2538 msgid "Show original linenumber (Default: off)" msgstr "Hiα»n thα» sα» dΓ²ng gα»c (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2538 +#: builtin/blame.c:2539 msgid "Show in a format designed for machine consumption" msgstr "Hiα»n thα» α» Δα»nh dαΊ‘ng ΔΓ£ thiαΊΏt kαΊΏ cho sα»± tiΓͺu dΓΉng bαΊ±ng mΓ‘y" -#: builtin/blame.c:2539 +#: builtin/blame.c:2540 msgid "Show porcelain format with per-line commit information" msgstr "Hiα»n thα» Δα»nh dαΊ‘ng βporcelainβ vα»i thΓ΄ng tin chuyα»n giao mα»i dΓ²ng" -#: builtin/blame.c:2540 +#: builtin/blame.c:2541 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "DΓΉng cΓΉng chαΊΏ Δα» xuαΊ₯t ra vα»i git-annotate (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2541 +#: builtin/blame.c:2542 msgid "Show raw timestamp (Default: off)" msgstr "Hiα»n thα» dαΊ₯u vαΊΏt thα»i gian dαΊ‘ng thΓ΄ (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2542 +#: builtin/blame.c:2543 msgid "Show long commit SHA1 (Default: off)" msgstr "Hiα»n thα» SHA1 của lαΊ§n chuyα»n giao dαΊ‘ng dΓ i (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2543 +#: builtin/blame.c:2544 msgid "Suppress author name and timestamp (Default: off)" msgstr "KhΓ΄ng hiα»n thα» tΓͺn tΓ‘c giαΊ£ vΓ dαΊ₯u vαΊΏt thα»i gian (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2544 +#: builtin/blame.c:2545 msgid "Show author email instead of name (Default: off)" msgstr "Hiα»n thα» thΖ° Δiα»n tα» của tΓ‘c giαΊ£ thay vΓ¬ tΓͺn (MαΊ·c Δα»nh: off)" -#: builtin/blame.c:2545 +#: builtin/blame.c:2546 msgid "Ignore whitespace differences" msgstr "Bα» qua cΓ‘c khΓ‘c biα»t do khoαΊ£ng trαΊ―ng gΓ’y ra" -#: builtin/blame.c:2546 +#: builtin/blame.c:2547 msgid "Spend extra cycles to find better match" msgstr "TiΓͺu thα»₯ thΓͺm nΔng tΓ i nguyΓͺn mΓ‘y mΓ³c Δα» tΓ¬m kiαΊΏm tα»t hΖ‘n nα»―a" -#: builtin/blame.c:2547 +#: builtin/blame.c:2548 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "" "Sα» dα»₯ng Δiα»m xΓ©t duyα»t (revision) tα»« <tαΊp tin> thay vΓ¬ gα»i βgit-rev-listβ" -#: builtin/blame.c:2548 +#: builtin/blame.c:2549 msgid "Use <file>'s contents as the final image" msgstr "Sα» dα»₯ng nα»i dung của <tαΊp tin> nhΖ° lΓ αΊ£nh cuα»i cΓΉng" -#: builtin/blame.c:2549 builtin/blame.c:2550 +#: builtin/blame.c:2550 builtin/blame.c:2551 msgid "score" msgstr "Δiα»m sα»" -#: builtin/blame.c:2549 +#: builtin/blame.c:2550 msgid "Find line copies within and across files" msgstr "TΓ¬m cΓ‘c bαΊ£n sao chΓ©p dΓ²ng trong vΓ ngang qua tαΊp tin" -#: builtin/blame.c:2550 +#: builtin/blame.c:2551 msgid "Find line movements within and across files" msgstr "TΓ¬m cΓ‘c di chuyα»n dΓ²ng trong vΓ ngang qua tαΊp tin" -#: builtin/blame.c:2551 +#: builtin/blame.c:2552 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2551 +#: builtin/blame.c:2552 msgid "Process only line range n,m, counting from 1" msgstr "Xα» lΓ½ chα» dΓ²ng vΓΉng n,m, tΓnh tα»« 1" @@ -3535,31 +3818,31 @@ msgstr "Xα» lΓ½ chα» dΓ²ng vΓΉng n,m, tΓnh tα»« 1" #. takes 22 places, is the longest among various forms of #. relative timestamps, but your language may need more or #. fewer display columns. -#: builtin/blame.c:2640 +#: builtin/blame.c:2641 msgid "4 years, 11 months ago" msgstr "4 nΔm, 11 thΓ‘ng trΖ°α»c" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [<options>] [-r | -a] [--merged | --no-merged]" msgstr "git branch [<cΓ‘c-tΓΉy-chα»n>] [-r | -a] [--merged | --no-merged]" -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [<options>] [-l] [-f] <branch-name> [<start-point>]" msgstr "git branch [<cΓ‘c-tΓΉy-chα»n>] [-l] [-f] <tΓͺn-nhΓ‘nh> [<Δiα»m-ΔαΊ§u>]" -#: builtin/branch.c:27 +#: builtin/branch.c:28 msgid "git branch [<options>] [-r] (-d | -D) <branch-name>..." msgstr "git branch [<cΓ‘c-tΓΉy-chα»n>] [-r] (-d | -D) <tΓͺn-nhΓ‘nh> β¦" -#: builtin/branch.c:28 +#: builtin/branch.c:29 msgid "git branch [<options>] (-m | -M) [<old-branch>] <new-branch>" msgstr "git branch [<cΓ‘c-tΓΉy-chα»n>] (-m | -M) [<nhΓ‘nh-cΕ©>] <nhΓ‘nh-mα»i>" -#: builtin/branch.c:29 +#: builtin/branch.c:30 msgid "git branch [<options>] [-r | -a] [--points-at]" msgstr "git branch [<cΓ‘c-tΓΉy-chα»n>] [-r | -a] [--points-at]" -#: builtin/branch.c:142 +#: builtin/branch.c:143 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -3568,7 +3851,7 @@ msgstr "" "Δang xΓ³a nhΓ‘nh β%sβ mΓ nΓ³ lαΊ‘i ΔΓ£ Δược hΓ²a trα»n vΓ o\n" " β%sβ, nhΖ°ng vαΊ«n chΖ°a Δược hΓ²a trα»n vΓ o HEAD." -#: builtin/branch.c:146 +#: builtin/branch.c:147 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -3577,12 +3860,12 @@ msgstr "" "khΓ΄ng xΓ³a nhΓ‘nh β%sβ cΓ‘i mΓ chΖ°a Δược hΓ²a trα»n vΓ o\n" " β%sβ, cho dΓΉ lΓ nΓ³ ΔΓ£ Δược hΓ²a trα»n vΓ o HEAD." -#: builtin/branch.c:160 +#: builtin/branch.c:161 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "KhΓ΄ng thα» tΓ¬m kiαΊΏm Δα»i tượng chuyα»n giao cho β%sβ" -#: builtin/branch.c:164 +#: builtin/branch.c:165 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -3591,298 +3874,319 @@ msgstr "" "NhΓ‘nh β%sβ khΓ΄ng Δược trα»n mα»t cΓ‘ch ΔαΊ§y Δủ.\n" "NαΊΏu bαΊ‘n thα»±c sα»± muα»n xΓ³a nΓ³, thΓ¬ chαΊ‘y lα»nh βgit branch -D %sβ." -#: builtin/branch.c:177 +#: builtin/branch.c:178 msgid "Update of config-file failed" msgstr "CαΊp nhαΊt tαΊp tin cαΊ₯u hΓ¬nh gαΊ·p lα»i" -#: builtin/branch.c:205 +#: builtin/branch.c:206 msgid "cannot use -a with -d" msgstr "khΓ΄ng thα» dΓΉng tΓΉy chα»n -a vα»i -d" -#: builtin/branch.c:211 +#: builtin/branch.c:212 msgid "Couldn't look up commit object for HEAD" msgstr "KhΓ΄ng thα» tΓ¬m kiαΊΏm Δα»i tượng chuyα»n giao cho HEAD" -#: builtin/branch.c:219 +#: builtin/branch.c:226 #, c-format -msgid "Cannot delete the branch '%s' which you are currently on." -msgstr "KhΓ΄ng thα» xΓ³a nhΓ‘nh β%sβ cΓ‘i mΓ bαΊ‘n hiα»n nay Δang α»." +msgid "Cannot delete branch '%s' checked out at '%s'" +msgstr "KhΓ΄ng thα» xΓ³a nhΓ‘nh β%sβ ΔΓ£ Δược lαΊ₯y ra tαΊ‘i β%sβ" -#: builtin/branch.c:235 +#: builtin/branch.c:241 #, c-format msgid "remote-tracking branch '%s' not found." msgstr "khΓ΄ng tΓ¬m thαΊ₯y nhΓ‘nh theo dΓ΅i mΓ‘y chủ β%sβ." -#: builtin/branch.c:236 +#: builtin/branch.c:242 #, c-format msgid "branch '%s' not found." msgstr "khΓ΄ng tΓ¬m thαΊ₯y nhΓ‘nh β%sβ." -#: builtin/branch.c:251 +#: builtin/branch.c:257 #, c-format msgid "Error deleting remote-tracking branch '%s'" msgstr "GαΊ·p lα»i khi Δang xΓ³a nhΓ‘nh theo dΓ΅i mΓ‘y chủ β%sβ" -#: builtin/branch.c:252 +#: builtin/branch.c:258 #, c-format msgid "Error deleting branch '%s'" msgstr "GαΊ·p lα»i khi xΓ³a bα» nhΓ‘nh β%sβ" -#: builtin/branch.c:259 +#: builtin/branch.c:265 #, c-format msgid "Deleted remote-tracking branch %s (was %s).\n" msgstr "ΔΓ£ xΓ³a nhΓ‘nh theo dΓ΅i mΓ‘y chủ \"%s\" (tα»«ng lΓ %s).\n" -#: builtin/branch.c:260 +#: builtin/branch.c:266 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "NhΓ‘nh β%sβ ΔΓ£ bα» xΓ³a (tα»«ng lΓ %s)\n" -#: builtin/branch.c:303 +#: builtin/branch.c:309 #, c-format msgid "[%s: gone]" msgstr "[%s: ΔΓ£ ra Δi]" -#: builtin/branch.c:308 +#: builtin/branch.c:314 #, c-format msgid "[%s]" msgstr "[%s]" -#: builtin/branch.c:313 +#: builtin/branch.c:319 #, c-format msgid "[%s: behind %d]" msgstr "[%s: Δα»©ng sau %d]" -#: builtin/branch.c:315 +#: builtin/branch.c:321 #, c-format msgid "[behind %d]" msgstr "[ΔαΊ±ng sau %d]" -#: builtin/branch.c:319 +#: builtin/branch.c:325 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: phΓa trΖ°α»c %d]" -#: builtin/branch.c:321 +#: builtin/branch.c:327 #, c-format msgid "[ahead %d]" msgstr "[phΓa trΖ°α»c %d]" -#: builtin/branch.c:324 +#: builtin/branch.c:330 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: trΖ°α»c %d, sau %d]" -#: builtin/branch.c:327 +#: builtin/branch.c:333 #, c-format msgid "[ahead %d, behind %d]" msgstr "[trΖ°α»c %d, sau %d]" -#: builtin/branch.c:340 +#: builtin/branch.c:346 msgid " **** invalid ref ****" msgstr " **** tham chiαΊΏu khΓ΄ng hợp lα» ****" -#: builtin/branch.c:366 +#: builtin/branch.c:372 #, c-format msgid "(no branch, rebasing %s)" msgstr "(khΓ΄ng nhΓ‘nh, Δang cαΊ£i tα» %s)" -#: builtin/branch.c:369 +#: builtin/branch.c:375 #, 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)" -#: builtin/branch.c:375 +#. TRANSLATORS: make sure this matches +#. "HEAD detached at " in wt-status.c +#: builtin/branch.c:381 #, c-format msgid "(HEAD detached at %s)" msgstr "(HEAD Δược tΓ‘ch rα»i tαΊ‘i %s)" -#: builtin/branch.c:378 +#. TRANSLATORS: make sure this matches +#. "HEAD detached from " in wt-status.c +#: builtin/branch.c:386 #, c-format msgid "(HEAD detached from %s)" msgstr "(HEAD Δược tΓ‘ch rα»i tα»« %s)" -#: builtin/branch.c:382 +#: builtin/branch.c:390 msgid "(no branch)" msgstr "(khΓ΄ng nhΓ‘nh)" -#: builtin/branch.c:524 +#: builtin/branch.c:541 +#, c-format +msgid "Branch %s is being rebased at %s" +msgstr "NhΓ‘nh %s Δang Δược cαΊ£i tα» lαΊ‘i tαΊ‘i %s" + +#: builtin/branch.c:545 +#, c-format +msgid "Branch %s is being bisected at %s" +msgstr "NhΓ‘nh %s Δang Δược di chuyα»n phΓ’n ΔΓ΄i (bisect) tαΊ‘i %s" + +#: builtin/branch.c:560 msgid "cannot rename the current branch while not on any." msgstr "khΓ΄ng thα» Δα»i tΓͺn nhΓ‘nh hiα»n hΓ nh trong khi nΓ³ chαΊ³ng α» ΔΓ’u cαΊ£." -#: builtin/branch.c:534 +#: builtin/branch.c:570 #, c-format msgid "Invalid branch name: '%s'" msgstr "TΓͺn nhΓ‘nh khΓ΄ng hợp lα»: β%sβ" -#: builtin/branch.c:549 +#: builtin/branch.c:587 msgid "Branch rename failed" msgstr "GαΊ·p lα»i khi Δα»i tΓͺn nhΓ‘nh" -#: builtin/branch.c:553 +#: builtin/branch.c:591 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "ΔΓ£ Δα»i tΓͺn nhΓ‘nh khuyαΊΏt danh β%sβ Δi" -#: builtin/branch.c:557 +#: builtin/branch.c:594 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "NhΓ‘nh bα» Δα»i tΓͺn thΓ nh %s, nhΖ°ng HEAD lαΊ‘i khΓ΄ng Δược cαΊp nhαΊt!" -#: builtin/branch.c:564 +#: builtin/branch.c:601 msgid "Branch is renamed, but update of config-file failed" msgstr "NhΓ‘nh bα» Δα»i tΓͺn, nhΖ°ng cαΊp nhαΊt tαΊp tin cαΊ₯u hΓ¬nh gαΊ·p lα»i" -#: builtin/branch.c:586 -#, c-format -msgid "could not write branch description template: %s" -msgstr "khΓ΄ng thα» ghi vΓ o mαΊ«u mΓ΄ tαΊ£ nhΓ‘nh: %s" +#: builtin/branch.c:623 +msgid "could not write branch description template" +msgstr "khΓ΄ng thα» ghi mαΊ«u mΓ΄ tαΊ£ nhΓ‘nh" -#: builtin/branch.c:615 +#: builtin/branch.c:651 msgid "Generic options" msgstr "TΓΉy chα»n chung" -#: builtin/branch.c:617 +#: builtin/branch.c:653 msgid "show hash and subject, give twice for upstream branch" msgstr "hiα»n thα» mΓ£ bΔm vΓ chủ Δα», ΔΖ°a ra hai lαΊ§n cho nhΓ‘nh thượng nguα»n" -#: builtin/branch.c:618 +#: builtin/branch.c:654 msgid "suppress informational messages" msgstr "khΓ΄ng xuαΊ₯t cΓ‘c thΓ΄ng tin" -#: builtin/branch.c:619 +#: builtin/branch.c:655 msgid "set up tracking mode (see git-pull(1))" msgstr "cΓ i ΔαΊ·t chαΊΏ Δα» theo dΓ΅i (xem git-pull(1))" -#: builtin/branch.c:621 +#: builtin/branch.c:657 msgid "change upstream info" msgstr "thay Δα»i thΓ΄ng tin thượng nguα»n" -#: builtin/branch.c:625 +#: builtin/branch.c:659 +msgid "upstream" +msgstr "thượng nguα»n" + +#: builtin/branch.c:659 +msgid "change the upstream info" +msgstr "thay Δα»i thΓ΄ng tin thượng nguα»n" + +#: builtin/branch.c:661 msgid "use colored output" msgstr "tΓ΄ mΓ u kαΊΏt xuαΊ₯t" -#: builtin/branch.c:626 +#: builtin/branch.c:662 msgid "act on remote-tracking branches" msgstr "thao tΓ‘c trΓͺn nhΓ‘nh βremote-trackingβ" -#: builtin/branch.c:628 builtin/branch.c:629 +#: builtin/branch.c:664 builtin/branch.c:665 msgid "print only branches that contain the commit" msgstr "chα» hiα»n thα» nhα»―ng nhΓ‘nh mΓ nΓ³ chα»©a lαΊ§n chuyα»n giao" -#: builtin/branch.c:632 +#: builtin/branch.c:668 msgid "Specific git-branch actions:" msgstr "HΓ nh Δα»ng git-branch:" -#: builtin/branch.c:633 +#: builtin/branch.c:669 msgid "list both remote-tracking and local branches" msgstr "liα»t kΓͺ cαΊ£ nhΓ‘nh βremote-trackingβ vΓ nα»i bα»" -#: builtin/branch.c:635 +#: builtin/branch.c:671 msgid "delete fully merged branch" msgstr "xΓ³a mα»t toΓ n bα» nhΓ‘nh ΔΓ£ hΓ²a trα»n" -#: builtin/branch.c:636 +#: builtin/branch.c:672 msgid "delete branch (even if not merged)" msgstr "xΓ³a nhΓ‘nh (cho dΓΉ lΓ chΖ°a Δược hΓ²a trα»n)" -#: builtin/branch.c:637 +#: builtin/branch.c:673 msgid "move/rename a branch and its reflog" msgstr "di chuyα»n hay Δα»i tΓͺn mα»t nhΓ‘nh vΓ reflog của nΓ³" -#: builtin/branch.c:638 +#: builtin/branch.c:674 msgid "move/rename a branch, even if target exists" msgstr "di chuyα»n hoαΊ·c Δα»i tΓͺn mα»t nhΓ‘nh ngay cαΊ£ khi ΔΓch ΔΓ£ cΓ³ sαΊ΅n" -#: builtin/branch.c:639 +#: builtin/branch.c:675 msgid "list branch names" msgstr "liα»t kΓͺ cΓ‘c tΓͺn nhΓ‘nh" -#: builtin/branch.c:640 +#: builtin/branch.c:676 msgid "create the branch's reflog" msgstr "tαΊ‘o reflog của nhΓ‘nh" -#: builtin/branch.c:642 +#: builtin/branch.c:678 msgid "edit the description for the branch" msgstr "sα»a mΓ΄ tαΊ£ cho nhΓ‘nh" -#: builtin/branch.c:643 +#: builtin/branch.c:679 msgid "force creation, move/rename, deletion" msgstr "buα»c tαΊ‘o, di chuyα»n/Δα»i tΓͺn, xΓ³a" -#: builtin/branch.c:644 +#: builtin/branch.c:680 msgid "print only branches that are merged" msgstr "chα» hiα»n thα» nhα»―ng nhΓ‘nh mΓ nΓ³ Δược hΓ²a trα»n" -#: builtin/branch.c:645 +#: builtin/branch.c:681 msgid "print only branches that are not merged" msgstr "chα» hiα»n thα» nhα»―ng nhΓ‘nh mΓ nΓ³ khΓ΄ng Δược hΓ²a trα»n" -#: builtin/branch.c:646 +#: builtin/branch.c:682 msgid "list branches in columns" msgstr "liα»t kΓͺ cΓ‘c nhΓ‘nh trong cΓ‘c cα»t" -#: builtin/branch.c:647 builtin/for-each-ref.c:38 builtin/tag.c:366 +#: builtin/branch.c:683 builtin/for-each-ref.c:38 builtin/tag.c:366 msgid "key" msgstr "khΓ³a" -#: builtin/branch.c:648 builtin/for-each-ref.c:39 builtin/tag.c:367 +#: builtin/branch.c:684 builtin/for-each-ref.c:39 builtin/tag.c:367 msgid "field name to sort on" msgstr "tΓͺn trΖ°α»ng cαΊ§n sαΊ―p xαΊΏp" -#: builtin/branch.c:650 builtin/for-each-ref.c:41 builtin/notes.c:401 +#: builtin/branch.c:686 builtin/for-each-ref.c:41 builtin/notes.c:401 #: builtin/notes.c:404 builtin/notes.c:564 builtin/notes.c:567 #: builtin/tag.c:369 msgid "object" msgstr "Δα»i tượng" -#: builtin/branch.c:651 +#: builtin/branch.c:687 msgid "print only branches of the object" msgstr "chα» hiα»n thα» cΓ‘c nhΓ‘nh của Δα»i tượng" -#: builtin/branch.c:669 +#: builtin/branch.c:705 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α»." -#: builtin/branch.c:673 builtin/clone.c:705 +#: builtin/branch.c:709 builtin/clone.c:707 msgid "HEAD not found below refs/heads!" msgstr "khΓ΄ng tΓ¬m thαΊ₯y HEAD α» dΖ°α»i refs/heads!" -#: builtin/branch.c:693 +#: builtin/branch.c:729 msgid "--column and --verbose are incompatible" msgstr "tΓΉy chα»n --column vΓ --verbose xung khαΊ―c nhau" -#: builtin/branch.c:704 builtin/branch.c:746 +#: builtin/branch.c:740 builtin/branch.c:782 msgid "branch name required" msgstr "cαΊ§n chα» ra tΓͺn nhΓ‘nh" -#: builtin/branch.c:722 +#: builtin/branch.c:758 msgid "Cannot give description to detached HEAD" msgstr "KhΓ΄ng thα» ΔΖ°a ra mΓ΄ tαΊ£ HEAD ΔΓ£ tΓ‘ch rα»i" -#: builtin/branch.c:727 +#: builtin/branch.c:763 msgid "cannot edit description of more than one branch" msgstr "khΓ΄ng thα» sα»a mΓ΄ tαΊ£ cho nhiα»u hΖ‘n mα»t nhΓ‘nh" -#: builtin/branch.c:734 +#: builtin/branch.c:770 #, c-format msgid "No commit on branch '%s' yet." msgstr "VαΊ«n chΖ°a chuyα»n giao trΓͺn nhΓ‘nh β%sβ." -#: builtin/branch.c:737 +#: builtin/branch.c:773 #, c-format msgid "No branch named '%s'." msgstr "KhΓ΄ng cΓ³ nhΓ‘nh nΓ o cΓ³ tΓͺn β%sβ." -#: builtin/branch.c:752 +#: builtin/branch.c:788 msgid "too many branches for a rename operation" msgstr "quΓ‘ nhiα»u nhΓ‘nh dΓ nh cho thao tΓ‘c Δα»i tΓͺn" -#: builtin/branch.c:757 +#: builtin/branch.c:793 msgid "too many branches to set new upstream" msgstr "quΓ‘ nhiα»u nhΓ‘nh Δược ΔαΊ·t cho thượng nguα»n mα»i" -#: builtin/branch.c:761 +#: builtin/branch.c:797 #, c-format msgid "" "could not set upstream of HEAD to %s when it does not point to any branch." @@ -3890,40 +4194,40 @@ 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:764 builtin/branch.c:786 builtin/branch.c:807 +#: builtin/branch.c:800 builtin/branch.c:822 builtin/branch.c:843 #, c-format msgid "no such branch '%s'" msgstr "khΓ΄ng cΓ³ nhΓ‘nh nΓ o nhΖ° thαΊΏ β%sβ" -#: builtin/branch.c:768 +#: builtin/branch.c:804 #, c-format msgid "branch '%s' does not exist" msgstr "chΖ°a cΓ³ nhΓ‘nh β%sβ" -#: builtin/branch.c:780 +#: builtin/branch.c:816 msgid "too many branches to unset upstream" msgstr "quΓ‘ nhiα»u nhΓ‘nh Δα» bα» ΔαΊ·t thượng nguα»n" -#: builtin/branch.c:784 +#: builtin/branch.c:820 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:790 +#: builtin/branch.c:826 #, 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:804 +#: builtin/branch.c:840 msgid "it does not make sense to create 'HEAD' manually" msgstr "khΓ΄ng hợp lΓ½ khi tαΊ‘o βHEADβ thủ cΓ΄ng" -#: builtin/branch.c:810 +#: builtin/branch.c:846 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:813 +#: builtin/branch.c:849 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -3932,7 +4236,7 @@ msgstr "" "Cα» --set-upstream ΔΓ£ lαΊ‘c hαΊu vΓ sαΊ½ bα» xΓ³a bα». NΓͺn dΓΉng --track hoαΊ·c --set-" "upstream-to\n" -#: builtin/branch.c:830 +#: builtin/branch.c:866 #, c-format msgid "" "\n" @@ -3943,16 +4247,6 @@ msgstr "" "NαΊΏu bαΊ‘n muα»n β%sβ theo dΓ΅i β%sβ, thα»±c hiα»n lα»nh sau:\n" "\n" -#: builtin/branch.c:831 -#, c-format -msgid " git branch -d %s\n" -msgstr " git branch -d %s\n" - -#: builtin/branch.c:832 -#, c-format -msgid " git branch --set-upstream-to %s\n" -msgstr " git branch --set-upstream-to %s\n" - #: builtin/bundle.c:51 #, c-format msgid "%s is okay\n" @@ -4051,7 +4345,7 @@ msgstr "Δα»c tΓͺn tαΊp tin tα»« ΔαΊ§u vΓ o tiΓͺu chuαΊ©n" 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:18 builtin/checkout.c:1136 builtin/gc.c:325 +#: builtin/check-ignore.c:18 builtin/checkout.c:1135 builtin/gc.c:325 msgid "suppress progress reporting" msgstr "chαΊ·n cΓ‘c bΓ‘o cΓ‘o tiαΊΏn trΓ¬nh hoαΊ‘t Δα»ng" @@ -4142,8 +4436,9 @@ msgid "write the content to temporary files" msgstr "ghi nα»i dung vΓ o tαΊp tin tαΊ‘m" #: builtin/checkout-index.c:174 builtin/column.c:30 -#: builtin/submodule--helper.c:166 builtin/submodule--helper.c:169 -#: builtin/submodule--helper.c:172 builtin/submodule--helper.c:175 +#: builtin/submodule--helper.c:491 builtin/submodule--helper.c:494 +#: builtin/submodule--helper.c:497 builtin/submodule--helper.c:500 +#: builtin/submodule--helper.c:774 msgid "string" msgstr "chuα»i" @@ -4193,80 +4488,80 @@ msgstr "ΔΖ°α»ng dαΊ«n β%sβ: khΓ΄ng thα» hΓ²a trα»n" 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:251 builtin/checkout.c:254 builtin/checkout.c:257 -#: builtin/checkout.c:260 +#: builtin/checkout.c:250 builtin/checkout.c:253 builtin/checkout.c:256 +#: builtin/checkout.c:259 #, 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:263 builtin/checkout.c:266 +#: builtin/checkout.c:262 builtin/checkout.c:265 #, c-format msgid "'%s' cannot be used with %s" msgstr "khΓ΄ng Δược dΓΉng β%sβ vα»i %s" -#: builtin/checkout.c:269 +#: builtin/checkout.c:268 #, 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:280 builtin/checkout.c:474 +#: builtin/checkout.c:279 builtin/checkout.c:473 msgid "corrupt index file" msgstr "tαΊp tin ghi bαΊ£ng mα»₯c lα»₯c bα» hα»ng" -#: builtin/checkout.c:340 builtin/checkout.c:347 +#: builtin/checkout.c:339 builtin/checkout.c:346 #, c-format msgid "path '%s' is unmerged" msgstr "ΔΖ°α»ng dαΊ«n β%sβ khΓ΄ng Δược hΓ²a trα»n" -#: builtin/checkout.c:496 +#: builtin/checkout.c:495 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:623 +#: builtin/checkout.c:622 #, 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:661 +#: builtin/checkout.c:660 msgid "HEAD is now at" msgstr "HEAD hiα»n giα» tαΊ‘i" -#: builtin/checkout.c:665 builtin/clone.c:659 +#: builtin/checkout.c:664 builtin/clone.c:661 msgid "unable to update HEAD" msgstr "khΓ΄ng thα» cαΊp nhαΊt HEAD" -#: builtin/checkout.c:669 +#: builtin/checkout.c:668 #, c-format msgid "Reset branch '%s'\n" msgstr "ΔαΊ·t lαΊ‘i nhΓ‘nh β%sβ\n" -#: builtin/checkout.c:672 +#: builtin/checkout.c:671 #, c-format msgid "Already on '%s'\n" msgstr "ΔΓ£ sαΊ΅n sΓ ng trΓͺn β%sβ\n" -#: builtin/checkout.c:676 +#: builtin/checkout.c:675 #, 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:678 builtin/checkout.c:1068 +#: builtin/checkout.c:677 builtin/checkout.c:1067 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "ΔΓ£ chuyα»n ΔαΊΏn nhΓ‘nh mα»i β%sβ\n" -#: builtin/checkout.c:680 +#: builtin/checkout.c:679 #, c-format msgid "Switched to branch '%s'\n" msgstr "ΔΓ£ chuyα»n ΔαΊΏn nhΓ‘nh β%sβ\n" -#: builtin/checkout.c:732 +#: builtin/checkout.c:731 #, c-format msgid " ... and %d more.\n" msgstr " β¦ vΓ nhiα»u hΖ‘n %d.\n" -#: builtin/checkout.c:738 +#: builtin/checkout.c:737 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -4285,7 +4580,7 @@ msgstr[0] "" "\n" "%s\n" -#: builtin/checkout.c:757 +#: builtin/checkout.c:756 #, c-format msgid "" "If you want to keep it by creating a new branch, this may be a good time\n" @@ -4306,152 +4601,152 @@ msgstr[0] "" " git branch <tΓͺn_nhΓ‘nh_mα»i> %s\n" "\n" -#: builtin/checkout.c:793 +#: builtin/checkout.c:792 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:797 +#: builtin/checkout.c:796 msgid "Previous HEAD position was" msgstr "Vα» trΓ trΖ°α»c kia của HEAD lΓ " -#: builtin/checkout.c:824 builtin/checkout.c:1063 +#: builtin/checkout.c:823 builtin/checkout.c:1062 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:969 +#: builtin/checkout.c:968 #, 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:1009 builtin/worktree.c:211 +#: builtin/checkout.c:1008 builtin/worktree.c:212 #, c-format msgid "invalid reference: %s" msgstr "tham chiαΊΏu khΓ΄ng hợp lα»: %s" -#: builtin/checkout.c:1038 +#: builtin/checkout.c:1037 #, 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:1077 +#: builtin/checkout.c:1076 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:1080 builtin/checkout.c:1084 +#: builtin/checkout.c:1079 builtin/checkout.c:1083 #, 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:1088 builtin/checkout.c:1091 builtin/checkout.c:1096 -#: builtin/checkout.c:1099 +#: builtin/checkout.c:1087 builtin/checkout.c:1090 builtin/checkout.c:1095 +#: builtin/checkout.c:1098 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "β%sβ khΓ΄ng thα» Δược dΓΉng vα»i β%sβ" -#: builtin/checkout.c:1104 +#: builtin/checkout.c:1103 #, 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:1137 builtin/checkout.c:1139 builtin/clone.c:84 -#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:318 -#: builtin/worktree.c:320 +#: builtin/checkout.c:1136 builtin/checkout.c:1138 builtin/clone.c:88 +#: builtin/remote.c:165 builtin/remote.c:167 builtin/worktree.c:323 +#: builtin/worktree.c:325 msgid "branch" msgstr "nhΓ‘nh" -#: builtin/checkout.c:1138 +#: builtin/checkout.c:1137 msgid "create and checkout a new branch" msgstr "tαΊ‘o vΓ checkout mα»t nhΓ‘nh mα»i" -#: builtin/checkout.c:1140 +#: builtin/checkout.c:1139 msgid "create/reset and checkout a branch" msgstr "tαΊ‘o/ΔαΊ·t_lαΊ‘i vΓ checkout mα»t nhΓ‘nh" -#: builtin/checkout.c:1141 +#: builtin/checkout.c:1140 msgid "create reflog for new branch" msgstr "tαΊ‘o reflog cho nhΓ‘nh mα»i" -#: builtin/checkout.c:1142 +#: builtin/checkout.c:1141 msgid "detach the HEAD at named commit" msgstr "rα»i bα» HEAD tαΊ‘i lαΊ§n chuyα»n giao danh nghΔ©a" -#: builtin/checkout.c:1143 +#: builtin/checkout.c:1142 msgid "set upstream info for new branch" msgstr "ΔαΊ·t thΓ΄ng tin thượng nguα»n cho nhΓ‘nh mα»i" -#: builtin/checkout.c:1145 +#: builtin/checkout.c:1144 msgid "new-branch" msgstr "nhΓ‘nh-mα»i" -#: builtin/checkout.c:1145 +#: builtin/checkout.c:1144 msgid "new unparented branch" msgstr "nhΓ‘nh khΓ΄ng cha mα»i" -#: builtin/checkout.c:1146 +#: builtin/checkout.c:1145 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:1148 +#: builtin/checkout.c:1147 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:1150 +#: builtin/checkout.c:1149 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:1151 +#: builtin/checkout.c:1150 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:1152 builtin/merge.c:227 +#: builtin/checkout.c:1151 builtin/merge.c:230 msgid "update ignored files (default)" msgstr "cαΊp nhαΊt cΓ‘c tαΊp tin bα» bα» qua (mαΊ·c Δα»nh)" -#: builtin/checkout.c:1153 builtin/log.c:1269 parse-options.h:250 +#: builtin/checkout.c:1152 builtin/log.c:1432 parse-options.h:250 msgid "style" msgstr "kiα»u" -#: builtin/checkout.c:1154 +#: builtin/checkout.c:1153 msgid "conflict style (merge or diff3)" msgstr "xung Δα»t kiα»u (hΓ²a trα»n hoαΊ·c diff3)" -#: builtin/checkout.c:1157 +#: builtin/checkout.c:1156 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:1159 +#: builtin/checkout.c:1158 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:1161 +#: builtin/checkout.c:1160 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:1162 builtin/clone.c:58 builtin/fetch.c:116 -#: builtin/merge.c:224 builtin/pull.c:113 builtin/push.c:526 +#: builtin/checkout.c:1161 builtin/clone.c:60 builtin/fetch.c:116 +#: builtin/merge.c:227 builtin/pull.c:116 builtin/push.c:526 #: builtin/send-pack.c:168 msgid "force progress reporting" msgstr "Γ©p buα»c bΓ‘o cΓ‘o tiαΊΏn triα»n cΓ΄ng viα»c" -#: builtin/checkout.c:1193 +#: builtin/checkout.c:1192 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:1210 +#: builtin/checkout.c:1209 msgid "--track needs a branch name" msgstr "--track cαΊ§n tΓͺn mα»t nhΓ‘nh" -#: builtin/checkout.c:1215 +#: builtin/checkout.c:1214 msgid "Missing branch name; try -b" msgstr "ThiαΊΏu tΓͺn nhΓ‘nh; hΓ£y thα» -b" -#: builtin/checkout.c:1251 +#: builtin/checkout.c:1250 msgid "invalid path specification" msgstr "ΔΖ°α»ng dαΊ«n ΔΓ£ cho khΓ΄ng hợp lα»" -#: builtin/checkout.c:1258 +#: builtin/checkout.c:1257 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -4461,12 +4756,12 @@ msgstr "" "BαΊ‘n ΔΓ£ cΓ³ Γ½ Δα»nh checkout β%sβ cΓ‘i mΓ khΓ΄ng thα» Δược phΓ’n giαΊ£i nhΖ° lΓ lαΊ§n " "chuyα»n giao?" -#: builtin/checkout.c:1263 +#: builtin/checkout.c:1262 #, 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:1267 +#: builtin/checkout.c:1266 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -4617,8 +4912,8 @@ msgstr "dα»n bαΊ±ng kiα»u tΖ°Ζ‘ng tΓ‘c" msgid "remove whole directories" msgstr "gα»‘ bα» toΓ n bα» thΖ° mα»₯c" -#: builtin/clean.c:875 builtin/describe.c:407 builtin/grep.c:722 -#: builtin/ls-files.c:456 builtin/name-rev.c:307 builtin/show-ref.c:182 +#: builtin/clean.c:875 builtin/describe.c:407 builtin/grep.c:724 +#: builtin/ls-files.c:456 builtin/name-rev.c:314 builtin/show-ref.c:182 msgid "pattern" msgstr "mαΊ«u" @@ -4658,103 +4953,112 @@ msgstr "" msgid "git clone [<options>] [--] <repo> [<dir>]" msgstr "git clone [<cΓ‘c-tΓΉy-chα»n>] [--] <kho> [<t.mα»₯c>]" -#: builtin/clone.c:60 +#: builtin/clone.c:62 msgid "don't create a checkout" msgstr "khΓ΄ng tαΊ‘o mα»t checkout" -#: builtin/clone.c:61 builtin/clone.c:63 builtin/init-db.c:469 +#: builtin/clone.c:63 builtin/clone.c:65 builtin/init-db.c:473 msgid "create a bare repository" msgstr "tαΊ‘o kho thuαΊ§n" -#: builtin/clone.c:65 +#: builtin/clone.c:67 msgid "create a mirror repository (implies bare)" msgstr "tαΊ‘o kho bαΊ£n sao (Γ½ lΓ kho thuαΊ§n)" -#: builtin/clone.c:67 +#: builtin/clone.c:69 msgid "to clone from a local repository" msgstr "Δα» nhΓ’n bαΊ£n tα»« kho nα»i bα»" -#: builtin/clone.c:69 +#: builtin/clone.c:71 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:71 +#: builtin/clone.c:73 msgid "setup as shared repository" msgstr "cΓ i ΔαΊ·t ΔΓ’y lΓ kho chia sαΊ»" -#: builtin/clone.c:73 builtin/clone.c:75 +#: builtin/clone.c:75 builtin/clone.c:77 msgid "initialize submodules in the clone" msgstr "khα»i tαΊ‘o mΓ΄-Δun-con trong bαΊ£n sao" -#: builtin/clone.c:76 builtin/init-db.c:466 +#: builtin/clone.c:79 +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:80 builtin/init-db.c:470 msgid "template-directory" msgstr "thΖ°-mα»₯c-mαΊ«u" -#: builtin/clone.c:77 builtin/init-db.c:467 +#: builtin/clone.c:81 builtin/init-db.c:471 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:79 builtin/submodule--helper.c:173 +#: builtin/clone.c:83 builtin/submodule--helper.c:498 +#: builtin/submodule--helper.c:777 msgid "reference repository" msgstr "kho tham chiαΊΏu" -#: builtin/clone.c:81 +#: builtin/clone.c:85 msgid "use --reference only while cloning" msgstr "chα» dΓΉng --reference khi nhΓ’n bαΊ£n" -#: builtin/clone.c:82 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:86 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "tΓͺn" -#: builtin/clone.c:83 +#: builtin/clone.c:87 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:85 +#: builtin/clone.c:89 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:87 +#: builtin/clone.c:91 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:88 builtin/fetch.c:117 builtin/grep.c:665 builtin/pull.c:193 +#: builtin/clone.c:92 builtin/fetch.c:117 builtin/grep.c:667 builtin/pull.c:201 msgid "depth" msgstr "Δα»-sΓ’u" -#: builtin/clone.c:89 +#: builtin/clone.c:93 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:91 +#: builtin/clone.c:95 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:92 builtin/init-db.c:475 +#: builtin/clone.c:97 +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:98 builtin/init-db.c:479 msgid "gitdir" msgstr "gitdir" -#: builtin/clone.c:93 builtin/init-db.c:476 +#: builtin/clone.c:99 builtin/init-db.c:480 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:94 +#: builtin/clone.c:100 msgid "key=value" msgstr "khΓ³a=giΓ‘_trα»" -#: builtin/clone.c:95 +#: builtin/clone.c:101 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:96 builtin/fetch.c:131 builtin/push.c:536 +#: builtin/clone.c:102 builtin/fetch.c:131 builtin/push.c:536 msgid "use IPv4 addresses only" msgstr "chα» dΓΉng Δα»a chα» IPv4" -#: builtin/clone.c:98 builtin/fetch.c:133 builtin/push.c:538 +#: builtin/clone.c:104 builtin/fetch.c:133 builtin/push.c:538 msgid "use IPv6 addresses only" msgstr "chα» dΓΉng Δα»a chα» IPv6" -#: builtin/clone.c:239 +#: builtin/clone.c:241 msgid "" "No directory name could be guessed.\n" "Please specify a directory on the command line" @@ -4762,57 +5066,52 @@ 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:305 +#: builtin/clone.c:307 #, 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ợ." -#: builtin/clone.c:307 +#: builtin/clone.c:309 #, 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α»." -#: builtin/clone.c:312 +#: builtin/clone.c:314 #, c-format msgid "reference repository '%s' is shallow" msgstr "kho tham chiαΊΏu β%sβ lΓ nΓ΄ng" -#: builtin/clone.c:315 +#: builtin/clone.c:317 #, c-format msgid "reference repository '%s' is grafted" msgstr "kho tham chiαΊΏu β%sβ bα» cαΊ₯y ghΓ©p" -#: builtin/clone.c:380 builtin/diff.c:84 -#, c-format -msgid "failed to stat '%s'" -msgstr "gαΊ·p lα»i khi lαΊ₯y thα»ng kΓͺ vα» β%sβ" - -#: builtin/clone.c:382 +#: builtin/clone.c:384 #, 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:396 +#: builtin/clone.c:398 #, 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:418 +#: builtin/clone.c:420 #, 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:422 +#: builtin/clone.c:424 #, 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:447 builtin/clone.c:631 +#: builtin/clone.c:449 builtin/clone.c:633 #, c-format msgid "done.\n" msgstr "hoΓ n tαΊ₯t.\n" -#: builtin/clone.c:459 +#: builtin/clone.c:461 msgid "" "Clone succeeded, but checkout failed.\n" "You can inspect what was checked out with 'git status'\n" @@ -4822,126 +5121,126 @@ 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:536 +#: builtin/clone.c:538 #, 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:626 +#: builtin/clone.c:628 #, c-format msgid "Checking connectivity... " msgstr "Δang kiα»m tra kαΊΏt nα»iβ¦ " -#: builtin/clone.c:629 +#: builtin/clone.c:631 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" -#: builtin/clone.c:647 +#: builtin/clone.c:649 #, c-format msgid "unable to update %s" msgstr "khΓ΄ng thα» cαΊp nhαΊt %s" -#: builtin/clone.c:696 +#: builtin/clone.c:698 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:727 +#: builtin/clone.c:729 msgid "unable to checkout working tree" msgstr "khΓ΄ng thα» lαΊ₯y ra (checkout) cΓ’y lΓ m viα»c" -#: builtin/clone.c:753 +#: builtin/clone.c:767 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:816 +#: builtin/clone.c:830 msgid "cannot repack to clean up" msgstr "khΓ΄ng thα» ΔΓ³ng gΓ³i Δα» dα»n dαΊΉp" -#: builtin/clone.c:818 +#: builtin/clone.c:832 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:850 +#: builtin/clone.c:864 builtin/receive-pack.c:1731 msgid "Too many arguments." msgstr "CΓ³ quΓ‘ nhiα»u Δα»i sα»." -#: builtin/clone.c:854 +#: builtin/clone.c:868 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:865 +#: builtin/clone.c:879 #, 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:868 +#: builtin/clone.c:882 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:881 +#: builtin/clone.c:895 #, c-format msgid "repository '%s' does not exist" msgstr "kho chα»©a β%sβ chΖ°a tα»n tαΊ‘i" -#: builtin/clone.c:887 builtin/fetch.c:1174 +#: builtin/clone.c:901 builtin/fetch.c:1174 #, 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:897 +#: builtin/clone.c:911 #, 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:907 +#: builtin/clone.c:921 #, 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:922 builtin/clone.c:933 builtin/submodule--helper.c:218 -#: builtin/worktree.c:219 builtin/worktree.c:246 +#: builtin/clone.c:936 builtin/clone.c:947 builtin/submodule--helper.c:547 +#: builtin/worktree.c:220 builtin/worktree.c:247 #, 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:925 +#: builtin/clone.c:939 #, 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:943 +#: builtin/clone.c:957 #, 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:945 +#: builtin/clone.c:959 #, c-format msgid "Cloning into '%s'...\n" msgstr "Δang nhΓ’n bαΊ£n thΓ nh β%sββ¦\n" -#: builtin/clone.c:984 +#: builtin/clone.c:998 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:987 +#: builtin/clone.c:1001 msgid "source repository is shallow, ignoring --local" msgstr "kho nguα»n lΓ nΓ΄ng, nΓͺn bα» qua --local" -#: builtin/clone.c:992 +#: builtin/clone.c:1006 msgid "--local is ignored" msgstr "--local bα» lα» Δi" -#: builtin/clone.c:996 +#: builtin/clone.c:1010 #, c-format msgid "Don't know how to clone %s" msgstr "KhΓ΄ng biαΊΏt lΓ m cΓ‘ch nΓ o Δα» nhΓ’n bαΊ£n (clone) %s" -#: builtin/clone.c:1045 builtin/clone.c:1053 +#: builtin/clone.c:1059 builtin/clone.c:1067 #, 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:1056 +#: builtin/clone.c:1070 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." @@ -5092,68 +5391,68 @@ 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:305 +#: builtin/commit.c:307 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:346 +#: builtin/commit.c:348 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:352 +#: builtin/commit.c:354 msgid "interactive add failed" msgstr "gαΊ·p lα»i khi thΓͺm bαΊ±ng cΓ‘ch tΖ°Ζ‘ng" -#: builtin/commit.c:365 +#: builtin/commit.c:367 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:367 +#: builtin/commit.c:369 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:391 builtin/commit.c:414 builtin/commit.c:463 +#: builtin/commit.c:393 builtin/commit.c:416 builtin/commit.c:465 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:445 +#: builtin/commit.c:447 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:447 +#: builtin/commit.c:449 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:456 +#: builtin/commit.c:458 msgid "cannot read the index" msgstr "khΓ΄ng Δα»c Δược bαΊ£ng mα»₯c lα»₯c" -#: builtin/commit.c:475 +#: builtin/commit.c:477 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:580 +#: builtin/commit.c:582 #, 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:582 +#: builtin/commit.c:584 #, 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:601 +#: builtin/commit.c:603 msgid "malformed --author parameter" msgstr "Δα»i sα» cho --author bα» dα» hΓ¬nh" -#: builtin/commit.c:609 +#: builtin/commit.c:611 #, c-format msgid "invalid date format: %s" msgstr "ngΓ y thΓ‘ng khΓ΄ng hợp lα»: %s" -#: builtin/commit.c:653 +#: builtin/commit.c:655 msgid "" "unable to select a comment character that is not used\n" "in the current commit message" @@ -5161,38 +5460,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:690 builtin/commit.c:723 builtin/commit.c:1080 +#: builtin/commit.c:692 builtin/commit.c:725 builtin/commit.c:1091 #, 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:702 builtin/shortlog.c:285 +#: builtin/commit.c:704 builtin/shortlog.c:285 #, 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:704 +#: builtin/commit.c:706 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:708 +#: builtin/commit.c:710 #, c-format msgid "could not read log file '%s'" msgstr "khΓ΄ng Δα»c Δược tα»p nhαΊt kΓ½ β%sβ" -#: builtin/commit.c:730 -msgid "could not read MERGE_MSG" -msgstr "khΓ΄ng thα» Δα»c MERGE_MSG" - -#: builtin/commit.c:734 +#: builtin/commit.c:737 builtin/commit.c:745 msgid "could not read SQUASH_MSG" msgstr "khΓ΄ng thα» Δα»c SQUASH_MSG" -#: builtin/commit.c:785 +#: builtin/commit.c:742 +msgid "could not read MERGE_MSG" +msgstr "khΓ΄ng thα» Δα»c MERGE_MSG" + +#: builtin/commit.c:796 msgid "could not write commit template" msgstr "khΓ΄ng thα» ghi mαΊ«u chuyα»n giao" -#: builtin/commit.c:803 +#: builtin/commit.c:814 #, c-format msgid "" "\n" @@ -5207,7 +5506,7 @@ msgstr "" "\t%s\n" "vΓ thα» lαΊ‘i.\n" -#: builtin/commit.c:808 +#: builtin/commit.c:819 #, c-format msgid "" "\n" @@ -5222,7 +5521,7 @@ msgstr "" "\t%s\n" "vΓ thα» lαΊ‘i.\n" -#: builtin/commit.c:821 +#: builtin/commit.c:832 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -5233,7 +5532,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:828 +#: builtin/commit.c:839 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -5245,157 +5544,157 @@ 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:848 +#: builtin/commit.c:859 #, c-format msgid "%sAuthor: %.*s <%.*s>" msgstr "%sTΓ‘c giαΊ£: %.*s <%.*s>" -#: builtin/commit.c:856 +#: builtin/commit.c:867 #, c-format msgid "%sDate: %s" msgstr "%sNgΓ y thΓ‘ng: %s" -#: builtin/commit.c:863 +#: builtin/commit.c:874 #, c-format msgid "%sCommitter: %.*s <%.*s>" msgstr "%sNgΖ°α»i chuyα»n giao: %.*s <%.*s>" -#: builtin/commit.c:881 +#: builtin/commit.c:892 msgid "Cannot read index" msgstr "KhΓ΄ng Δα»c Δược bαΊ£ng mα»₯c lα»₯c" -#: builtin/commit.c:938 +#: builtin/commit.c:949 msgid "Error building trees" msgstr "GαΊ·p lα»i khi xΓ’y dα»±ng cΓ’y" -#: builtin/commit.c:953 builtin/tag.c:266 +#: builtin/commit.c:964 builtin/tag.c:266 #, 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:1055 +#: builtin/commit.c:1066 #, 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:1070 builtin/commit.c:1310 +#: builtin/commit.c:1081 builtin/commit.c:1321 #, 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:1107 +#: builtin/commit.c:1118 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:1137 +#: builtin/commit.c:1148 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:1146 +#: builtin/commit.c:1157 msgid "You have nothing to amend." msgstr "KhΓ΄ng cΓ³ gΓ¬ Δα» mΓ βtu bα»β cαΊ£." -#: builtin/commit.c:1149 +#: builtin/commit.c:1160 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:1151 +#: builtin/commit.c:1162 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:1154 +#: builtin/commit.c:1165 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:1164 +#: builtin/commit.c:1175 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" -#: builtin/commit.c:1166 +#: builtin/commit.c:1177 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "TΓΉy chα»n -m khΓ΄ng thα» Δược tα» hợp cΓΉng vα»i -c/-C/-F/--fixup." -#: builtin/commit.c:1174 +#: builtin/commit.c:1185 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:1191 +#: builtin/commit.c:1202 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:1193 +#: builtin/commit.c:1204 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:1195 +#: builtin/commit.c:1206 msgid "Clever... amending the last one with dirty index." msgstr "Giα»iβ¦ βtu bα»β cΓ‘i cuα»i vα»i bαΊ£ng mα»₯c lα»₯c bαΊ©n." -#: builtin/commit.c:1197 +#: builtin/commit.c:1208 msgid "Explicit paths specified without -i or -o; assuming --only paths..." msgstr "" "Nhα»―ng ΔΖ°α»ng dαΊ«n rΓ΅ rΓ ng Δược chα» ra khΓ΄ng cΓ³ tΓΉy chα»n -i cΕ©ng khΓ΄ng -o; coi " "lΓ --only nhα»―ng ΔΖ°α»ng dαΊ«n" -#: builtin/commit.c:1209 builtin/tag.c:475 +#: builtin/commit.c:1220 builtin/tag.c:474 #, c-format msgid "Invalid cleanup mode %s" msgstr "ChαΊΏ Δα» dα»n dαΊΉp khΓ΄ng hợp lα» %s" -#: builtin/commit.c:1214 +#: builtin/commit.c:1225 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:1324 builtin/commit.c:1605 +#: builtin/commit.c:1335 builtin/commit.c:1621 msgid "show status concisely" msgstr "hiα»n thα» trαΊ‘ng thΓ‘i α» dαΊ‘ng sΓΊc tΓch" -#: builtin/commit.c:1326 builtin/commit.c:1607 +#: builtin/commit.c:1337 builtin/commit.c:1623 msgid "show branch information" msgstr "hiα»n thα» thΓ΄ng tin nhΓ‘nh" -#: builtin/commit.c:1328 builtin/commit.c:1609 builtin/push.c:512 -#: builtin/worktree.c:430 +#: builtin/commit.c:1339 builtin/commit.c:1625 builtin/push.c:512 +#: builtin/worktree.c:437 msgid "machine-readable output" msgstr "kαΊΏt xuαΊ₯t dαΊ‘ng mΓ‘y-cΓ³-thα»-Δα»c" -#: builtin/commit.c:1331 builtin/commit.c:1611 +#: builtin/commit.c:1342 builtin/commit.c:1627 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:1334 builtin/commit.c:1614 +#: builtin/commit.c:1345 builtin/commit.c:1630 msgid "terminate entries with NUL" msgstr "chαΊ₯m dα»©t cΓ‘c mα»₯c bαΊ±ng NUL" -#: builtin/commit.c:1336 builtin/commit.c:1617 builtin/fast-export.c:981 +#: builtin/commit.c:1347 builtin/commit.c:1633 builtin/fast-export.c:981 #: builtin/fast-export.c:984 builtin/tag.c:353 msgid "mode" msgstr "chαΊΏ Δα»" -#: builtin/commit.c:1337 builtin/commit.c:1617 +#: builtin/commit.c:1348 builtin/commit.c:1633 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:1340 +#: builtin/commit.c:1351 msgid "show ignored files" msgstr "hiα»n thα» cΓ‘c tαΊp tin αΊ©n" -#: builtin/commit.c:1341 parse-options.h:155 +#: builtin/commit.c:1352 parse-options.h:155 msgid "when" msgstr "khi" -#: builtin/commit.c:1342 +#: builtin/commit.c:1353 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -5403,205 +5702,205 @@ 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:1344 +#: builtin/commit.c:1355 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:1430 +#: builtin/commit.c:1441 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" -#: builtin/commit.c:1432 +#: builtin/commit.c:1443 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" -#: builtin/commit.c:1477 +#: builtin/commit.c:1488 msgid "detached HEAD" msgstr "ΔΓ£ rα»i khα»i HEAD" -#: builtin/commit.c:1480 +#: builtin/commit.c:1491 msgid " (root-commit)" msgstr " (root-commit)" -#: builtin/commit.c:1575 +#: builtin/commit.c:1591 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:1576 +#: builtin/commit.c:1592 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:1578 +#: builtin/commit.c:1594 msgid "Commit message options" msgstr "CΓ‘c tΓΉy chα»n ghi chΓΊ commit" -#: builtin/commit.c:1579 builtin/tag.c:351 +#: builtin/commit.c:1595 builtin/tag.c:351 msgid "read message from file" msgstr "Δα»c chΓΊ thΓch tα»« tαΊp tin" -#: builtin/commit.c:1580 +#: builtin/commit.c:1596 msgid "author" msgstr "tΓ‘c giαΊ£" -#: builtin/commit.c:1580 +#: builtin/commit.c:1596 msgid "override author for commit" msgstr "ghi ΔΓ¨ tΓ‘c giαΊ£ cho commit" -#: builtin/commit.c:1581 builtin/gc.c:326 +#: builtin/commit.c:1597 builtin/gc.c:326 msgid "date" msgstr "ngΓ y thΓ‘ng" -#: builtin/commit.c:1581 +#: builtin/commit.c:1597 msgid "override date for commit" msgstr "ghi ΔΓ¨ ngΓ y thΓ‘ng cho lαΊ§n chuyα»n giao" -#: builtin/commit.c:1582 builtin/merge.c:218 builtin/notes.c:395 +#: builtin/commit.c:1598 builtin/merge.c:219 builtin/notes.c:395 #: builtin/notes.c:558 builtin/tag.c:349 msgid "message" msgstr "chΓΊ thΓch" -#: builtin/commit.c:1582 +#: builtin/commit.c:1598 msgid "commit message" msgstr "chΓΊ thΓch của lαΊ§n chuyα»n giao" -#: builtin/commit.c:1583 builtin/commit.c:1584 builtin/commit.c:1585 -#: builtin/commit.c:1586 parse-options.h:256 ref-filter.h:79 +#: builtin/commit.c:1599 builtin/commit.c:1600 builtin/commit.c:1601 +#: builtin/commit.c:1602 parse-options.h:256 ref-filter.h:79 msgid "commit" msgstr "lαΊ§n_chuyα»n_giao" -#: builtin/commit.c:1583 +#: builtin/commit.c:1599 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:1584 +#: builtin/commit.c:1600 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:1585 +#: builtin/commit.c:1601 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:1586 +#: builtin/commit.c:1602 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:1587 +#: builtin/commit.c:1603 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:1588 builtin/log.c:1219 builtin/revert.c:86 +#: builtin/commit.c:1604 builtin/log.c:1382 builtin/revert.c:86 msgid "add Signed-off-by:" msgstr "(nΓͺn dΓΉng) thΓͺm dΓ²ng Signed-off-by:" -#: builtin/commit.c:1589 +#: builtin/commit.c:1605 msgid "use specified template file" msgstr "sα» dα»₯ng tαΊp tin mαΊ«u ΔΓ£ cho" -#: builtin/commit.c:1590 +#: builtin/commit.c:1606 msgid "force edit of commit" msgstr "Γ©p buα»c sα»a lαΊ§n commit" -#: builtin/commit.c:1591 +#: builtin/commit.c:1607 msgid "default" msgstr "mαΊ·c Δα»nh" -#: builtin/commit.c:1591 builtin/tag.c:354 +#: builtin/commit.c:1607 builtin/tag.c:354 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:1592 +#: builtin/commit.c:1608 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:1594 builtin/merge.c:226 builtin/pull.c:160 +#: builtin/commit.c:1610 builtin/merge.c:229 builtin/pull.c:165 #: builtin/revert.c:93 msgid "GPG sign commit" msgstr "kΓ½ lαΊ§n chuyα»n giao dΓΉng GPG" -#: builtin/commit.c:1597 +#: builtin/commit.c:1613 msgid "Commit contents options" msgstr "CΓ‘c tΓΉy nα»i dung ghi chΓΊ commit" -#: builtin/commit.c:1598 +#: builtin/commit.c:1614 msgid "commit all changed files" msgstr "chuyα»n giao tαΊ₯t cαΊ£ cΓ‘c tαΊp tin cΓ³ thay Δα»i" -#: builtin/commit.c:1599 +#: builtin/commit.c:1615 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:1600 +#: builtin/commit.c:1616 msgid "interactively add files" msgstr "thΓͺm cΓ‘c tαΊp-tin bαΊ±ng tΖ°Ζ‘ng tΓ‘c" -#: builtin/commit.c:1601 +#: builtin/commit.c:1617 msgid "interactively add changes" msgstr "thΓͺm cΓ‘c thay Δα»i bαΊ±ng tΖ°Ζ‘ng tΓ‘c" -#: builtin/commit.c:1602 +#: builtin/commit.c:1618 msgid "commit only specified files" msgstr "chα» chuyα»n giao cΓ‘c tαΊp tin ΔΓ£ chα» ra" -#: builtin/commit.c:1603 +#: builtin/commit.c:1619 msgid "bypass pre-commit hook" msgstr "vΓ²ng qua mΓ³c (hook) pre-commit" -#: builtin/commit.c:1604 +#: builtin/commit.c:1620 msgid "show what would be committed" msgstr "hiα»n thα» xem cΓ‘i gΓ¬ cΓ³ thα» Δược chuyα»n giao" -#: builtin/commit.c:1615 +#: builtin/commit.c:1631 msgid "amend previous commit" msgstr "βtu bα»β (amend) lαΊ§n commit trΖ°α»c" -#: builtin/commit.c:1616 +#: builtin/commit.c:1632 msgid "bypass post-rewrite hook" msgstr "vΓ²ng qua mΓ³c (hook) post-rewrite" -#: builtin/commit.c:1621 +#: builtin/commit.c:1637 msgid "ok to record an empty change" msgstr "ok Δα» ghi lαΊ‘i mα»t thay Δα»i trα»ng rα»ng" -#: builtin/commit.c:1623 +#: builtin/commit.c:1639 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:1652 +#: builtin/commit.c:1668 msgid "could not parse HEAD commit" msgstr "khΓ΄ng thα» phΓ’n tΓch commit (lαΊ§n chuyα»n giao) HEAD" -#: builtin/commit.c:1698 +#: builtin/commit.c:1718 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "TαΊp tin MERGE_HEAD sai hα»ng (%s)" -#: builtin/commit.c:1705 +#: builtin/commit.c:1725 msgid "could not read MERGE_MODE" msgstr "khΓ΄ng thα» Δα»c MERGE_MODE" -#: builtin/commit.c:1724 +#: builtin/commit.c:1744 #, c-format msgid "could not read commit message: %s" msgstr "khΓ΄ng thα» Δα»c phαΊ§n chΓΊ thΓch (message) của llαΊ§n chuyα»n giao: %s" -#: builtin/commit.c:1735 +#: builtin/commit.c:1755 #, 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:1740 +#: builtin/commit.c:1760 #, 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:1788 +#: builtin/commit.c:1808 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full and quota is\n" @@ -5750,7 +6049,7 @@ msgstr "" 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:469 +#: builtin/config.c:472 #, c-format msgid "" "# This is Git's per-user configuration file.\n" @@ -5765,7 +6064,7 @@ msgstr "" "#\tname = %s\n" "#\temail = %s\n" -#: builtin/config.c:611 +#: builtin/config.c:614 #, c-format msgid "cannot create configuration file %s" msgstr "khΓ΄ng thα» tαΊ‘o tαΊp tin cαΊ₯u hΓ¬nh β%sβ" @@ -5801,7 +6100,7 @@ msgstr "thαΊ» Δược chΓΊ giαΊ£i %s khΓ΄ng cΓ³ tΓͺn nhΓΊng" msgid "tag '%s' is really '%s' here" msgstr "thαΊ» β%sβ ΔΓ£ thα»±c sα»± α» ΔΓ’y β%sβ rα»i" -#: builtin/describe.c:250 builtin/log.c:459 +#: builtin/describe.c:250 builtin/log.c:465 #, c-format msgid "Not a valid object name %s" msgstr "KhΓ΄ng phαΊ£i tΓͺn Δα»i tượng %s hợp lα»" @@ -5894,7 +6193,7 @@ msgstr "coi nhΖ° <n> thαΊ» gαΊ§n ΔΓ’y nhαΊ₯t (mαΊ·c Δα»nh: 10)" 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:410 builtin/name-rev.c:314 +#: builtin/describe.c:410 builtin/name-rev.c:321 msgid "show abbreviated commit object as fallback" msgstr "hiα»n thα» Δα»i tượng chuyα»n giao vαΊ―n tαΊ―t nhΖ° lΓ fallback" @@ -5928,21 +6227,21 @@ msgstr "β%sβ: khΓ΄ng phαΊ£i tαΊp tin bΓ¬nh thΖ°α»ng hay liΓͺn kαΊΏt mα»m" msgid "invalid option: %s" msgstr "tΓΉy chα»n khΓ΄ng hợp lα»: %s" -#: builtin/diff.c:358 +#: builtin/diff.c:360 msgid "Not a git repository" msgstr "KhΓ΄ng phαΊ£i lΓ kho git" -#: builtin/diff.c:401 +#: builtin/diff.c:403 #, c-format msgid "invalid object '%s' given." msgstr "Δα»i tượng ΔΓ£ cho β%sβ khΓ΄ng hợp lα»." -#: builtin/diff.c:410 +#: builtin/diff.c:412 #, c-format msgid "more than two blobs given: '%s'" msgstr "ΔΓ£ cho nhiα»u hΖ‘n hai Δα»i tượng blob: β%sβ" -#: builtin/diff.c:417 +#: builtin/diff.c:419 #, c-format msgid "unhandled object '%s' given." msgstr "ΔΓ£ cho Δα»i tượng khΓ΄ng thα» nαΊ―m giα»― β%sβ." @@ -6015,19 +6314,19 @@ 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:92 builtin/pull.c:166 +#: builtin/fetch.c:92 builtin/pull.c:174 msgid "fetch from all remotes" msgstr "lαΊ₯y vα» tα»« tαΊ₯t cαΊ£ cΓ‘c mΓ‘y chủ" -#: builtin/fetch.c:94 builtin/pull.c:169 +#: builtin/fetch.c:94 builtin/pull.c:177 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:96 builtin/pull.c:172 +#: builtin/fetch.c:96 builtin/pull.c:180 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" -#: builtin/fetch.c:97 builtin/pull.c:174 +#: builtin/fetch.c:97 builtin/pull.c:182 msgid "force overwrite of local branch" msgstr "Γ©p buα»c ghi ΔΓ¨ lΓͺn nhΓ‘nh nα»i bα»" @@ -6035,7 +6334,7 @@ msgstr "Γ©p buα»c ghi ΔΓ¨ lΓͺn nhΓ‘nh nα»i bα»" msgid "fetch from multiple remotes" msgstr "lαΊ₯y tα»« nhiα»u mΓ‘y chủ cΓΉng lΓΊc" -#: builtin/fetch.c:101 builtin/pull.c:176 +#: builtin/fetch.c:101 builtin/pull.c:184 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Γ³" @@ -6047,21 +6346,21 @@ 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:107 builtin/pull.c:179 +#: builtin/fetch.c:107 builtin/pull.c:187 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ủ " "nα»―a" -#: builtin/fetch.c:108 builtin/pull.c:182 +#: builtin/fetch.c:108 builtin/pull.c:190 msgid "on-demand" msgstr "khi-cαΊ§n" -#: builtin/fetch.c:109 builtin/pull.c:183 +#: builtin/fetch.c:109 builtin/pull.c:191 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:113 builtin/pull.c:191 +#: builtin/fetch.c:113 builtin/pull.c:199 msgid "keep downloaded pack" msgstr "giα»― lαΊ‘i gΓ³i ΔΓ£ tαΊ£i vα»" @@ -6069,15 +6368,15 @@ 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:118 builtin/pull.c:194 +#: builtin/fetch.c:118 builtin/pull.c:202 msgid "deepen history of shallow clone" msgstr "lΓ m sΓ’u hΖ‘n lα»ch sα» của bαΊ£n sao" -#: builtin/fetch.c:120 builtin/pull.c:197 +#: builtin/fetch.c:120 builtin/pull.c:205 msgid "convert to a complete repository" msgstr "chuyα»n Δα»i hoΓ n toΓ n sang kho git" -#: builtin/fetch.c:122 builtin/log.c:1236 +#: builtin/fetch.c:122 builtin/log.c:1399 msgid "dir" msgstr "tmα»₯c" @@ -6089,15 +6388,15 @@ msgstr "soαΊ‘n sαΊ΅n cΓ‘i nΓ y cho kαΊΏt xuαΊ₯t ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con" msgid "default mode for recursion" msgstr "chαΊΏ Δα» mαΊ·c Δα»nh cho Δα» qui" -#: builtin/fetch.c:128 builtin/pull.c:200 +#: builtin/fetch.c:128 builtin/pull.c:208 msgid "accept refs that update .git/shallow" msgstr "chαΊ₯p nhαΊn tham chiαΊΏu cαΊp nhαΊt .git/shallow" -#: builtin/fetch.c:129 builtin/pull.c:202 +#: builtin/fetch.c:129 builtin/pull.c:210 msgid "refmap" msgstr "refmap" -#: builtin/fetch.c:130 builtin/pull.c:203 +#: builtin/fetch.c:130 builtin/pull.c:211 msgid "specify fetch refmap" msgstr "chα» ra refmap cαΊ§n lαΊ₯y vα»" @@ -6155,11 +6454,6 @@ msgstr "cΖ°α»‘ng bα»©c cαΊp nhαΊt" msgid "(non-fast-forward)" msgstr "(khΓ΄ng-chuyα»n-tiαΊΏp-nhanh)" -#: builtin/fetch.c:610 builtin/fetch.c:851 -#, c-format -msgid "cannot open %s: %s\n" -msgstr "khΓ΄ng thα» mα» %s: %s\n" - #: builtin/fetch.c:619 #, c-format msgid "%s did not send all necessary objects\n" @@ -6362,55 +6656,55 @@ msgstr "Δang kiα»m tra kαΊΏt nα»i" msgid "Checking object directories" msgstr "Δang kiα»m tra cΓ‘c thΖ° mα»₯c Δα»i tượng" -#: builtin/fsck.c:553 +#: builtin/fsck.c:552 msgid "git fsck [<options>] [<object>...]" msgstr "git fsck [<cΓ‘c-tΓΉy-chα»n>] [<Δα»i-tượng>β¦]" -#: builtin/fsck.c:559 +#: builtin/fsck.c:558 msgid "show unreachable objects" msgstr "hiα»n thα» cΓ‘c Δα»i tượng khΓ΄ng thα» Δα»c Δược" -#: builtin/fsck.c:560 +#: builtin/fsck.c:559 msgid "show dangling objects" msgstr "hiα»n thα» cΓ‘c Δα»i tượng khΓ΄ng Δược quαΊ£n lΓ½" -#: builtin/fsck.c:561 +#: builtin/fsck.c:560 msgid "report tags" msgstr "bΓ‘o cΓ‘o cΓ‘c thαΊ»" -#: builtin/fsck.c:562 +#: builtin/fsck.c:561 msgid "report root nodes" msgstr "bΓ‘o cΓ‘o node gα»c" -#: builtin/fsck.c:563 +#: builtin/fsck.c:562 msgid "make index objects head nodes" msgstr "tαΊ‘o βindex objects head nodesβ" -#: builtin/fsck.c:564 +#: builtin/fsck.c:563 msgid "make reflogs head nodes (default)" msgstr "tαΊ‘o βreflogs head nodesβ (mαΊ·c Δα»nh)" -#: builtin/fsck.c:565 +#: builtin/fsck.c:564 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:566 +#: builtin/fsck.c:565 msgid "check only connectivity" msgstr "chα» kiα»m tra kαΊΏt nα»i" -#: builtin/fsck.c:567 +#: builtin/fsck.c:566 msgid "enable more strict checking" msgstr "cho phΓ©p kiα»m tra hαΊ‘n chαΊΏ hΖ‘n" -#: builtin/fsck.c:569 +#: builtin/fsck.c:568 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:570 builtin/prune.c:107 +#: builtin/fsck.c:569 builtin/prune.c:107 msgid "show progress" msgstr "hiα»n thα» quΓ‘ trΓ¬nh" -#: builtin/fsck.c:631 +#: builtin/fsck.c:630 msgid "Checking objects" msgstr "Δang kiα»m tra cΓ‘c Δα»i tượng" @@ -6515,217 +6809,217 @@ msgstr "khΓ΄ng thα» Δα»c cΓ’y (%s)" 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:558 +#: builtin/grep.c:560 #, 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:575 +#: builtin/grep.c:577 #, c-format msgid "cannot open '%s'" msgstr "khΓ΄ng mα» Δược β%sβ" -#: builtin/grep.c:644 +#: builtin/grep.c:646 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:646 +#: builtin/grep.c:648 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:648 +#: builtin/grep.c:650 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:650 +#: builtin/grep.c:652 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:653 +#: builtin/grep.c:655 msgid "show non-matching lines" msgstr "hiα»n thα» nhα»―ng dΓ²ng khΓ΄ng khα»p vα»i mαΊ«u" -#: builtin/grep.c:655 +#: builtin/grep.c:657 msgid "case insensitive matching" msgstr "phΓ’n biα»t HOA/thΖ°α»ng" -#: builtin/grep.c:657 +#: builtin/grep.c:659 msgid "match patterns only at word boundaries" msgstr "chα» khα»p mαΊ«u tαΊ‘i ΔΖ°α»ng ranh giα»i tα»«" -#: builtin/grep.c:659 +#: builtin/grep.c:661 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:661 +#: builtin/grep.c:663 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:664 +#: builtin/grep.c:666 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:666 +#: builtin/grep.c:668 msgid "descend at most <depth> levels" msgstr "hαΊ‘ xuα»ng Γt nhαΊ₯t lΓ mα»©c <sΓ’u>" -#: builtin/grep.c:670 +#: builtin/grep.c:672 msgid "use extended POSIX regular expressions" msgstr "dΓΉng biα»u thα»©c chΓnh qui POSIX cΓ³ mα» rα»ng" -#: builtin/grep.c:673 +#: builtin/grep.c:675 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:676 +#: builtin/grep.c:678 msgid "interpret patterns as fixed strings" msgstr "diα»
n dα»ch cΓ‘c mαΊ«u nhΖ° lΓ chuα»i cα» Δα»nh" -#: builtin/grep.c:679 +#: builtin/grep.c:681 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:682 +#: builtin/grep.c:684 msgid "show line numbers" msgstr "hiα»n thα» sα» của dΓ²ng" -#: builtin/grep.c:683 +#: builtin/grep.c:685 msgid "don't show filenames" msgstr "khΓ΄ng hiα»n thα» tΓͺn tαΊp tin" -#: builtin/grep.c:684 +#: builtin/grep.c:686 msgid "show filenames" msgstr "hiα»n thα» cΓ‘c tΓͺn tαΊp tin" -#: builtin/grep.c:686 +#: builtin/grep.c:688 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:688 +#: builtin/grep.c:690 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:690 +#: builtin/grep.c:692 msgid "synonym for --files-with-matches" msgstr "Δα»ng nghΔ©a vα»i --files-with-matches" -#: builtin/grep.c:693 +#: builtin/grep.c:695 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:695 +#: builtin/grep.c:697 msgid "print NUL after filenames" msgstr "thΓͺm NUL vΓ o sau tΓͺn tαΊp tin" -#: builtin/grep.c:697 +#: builtin/grep.c:699 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:698 +#: builtin/grep.c:700 msgid "highlight matches" msgstr "tΓ΄ sΓ‘ng phαΊ§n khα»p mαΊ«u" -#: builtin/grep.c:700 +#: builtin/grep.c:702 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:702 +#: builtin/grep.c:704 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:705 +#: builtin/grep.c:707 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:708 +#: builtin/grep.c:710 msgid "show <n> context lines before matches" msgstr "hiα»n thα» <n> dΓ²ng nα»i dung trΖ°α»c khα»p" -#: builtin/grep.c:710 +#: builtin/grep.c:712 msgid "show <n> context lines after matches" msgstr "hiα»n thα» <n> dΓ²ng nα»i dung sau khα»p" -#: builtin/grep.c:712 +#: builtin/grep.c:714 msgid "use <n> worker threads" msgstr "dΓΉng <n> tuyαΊΏn trΓ¬nh lΓ m viα»c" -#: builtin/grep.c:713 +#: builtin/grep.c:715 msgid "shortcut for -C NUM" msgstr "dαΊ‘ng viαΊΏt tαΊ―t của -C Sα»" -#: builtin/grep.c:716 +#: builtin/grep.c:718 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:718 +#: builtin/grep.c:720 msgid "show the surrounding function" msgstr "hiα»n thα» hΓ m bao quanh" -#: builtin/grep.c:721 +#: builtin/grep.c:723 msgid "read patterns from file" msgstr "Δα»c mαΊ«u tα»« tαΊp-tin" -#: builtin/grep.c:723 +#: builtin/grep.c:725 msgid "match <pattern>" msgstr "match <mαΊ«u>" -#: builtin/grep.c:725 +#: builtin/grep.c:727 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:737 +#: builtin/grep.c:739 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:739 +#: builtin/grep.c:741 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:741 +#: builtin/grep.c:743 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:745 +#: builtin/grep.c:747 msgid "pager" msgstr "dΓ n trang" -#: builtin/grep.c:745 +#: builtin/grep.c:747 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:748 +#: builtin/grep.c:750 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:811 +#: builtin/grep.c:813 msgid "no pattern given." msgstr "chΖ°a chα» ra mαΊ«u." -#: builtin/grep.c:843 builtin/index-pack.c:1475 +#: builtin/grep.c:845 builtin/index-pack.c:1477 #, c-format msgid "invalid number of threads specified (%d)" msgstr "sα» tuyαΊΏn chα» ra khΓ΄ng hợp lα» (%d)" -#: builtin/grep.c:873 +#: builtin/grep.c:875 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:899 +#: builtin/grep.c:901 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:904 +#: builtin/grep.c:906 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 cΓ‘c tΓΉy chα»n liΓͺn " "quan ΔαΊΏn revs." -#: builtin/grep.c:907 +#: builtin/grep.c:909 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:915 +#: builtin/grep.c:917 msgid "both --cached and trees are given." msgstr "cαΊ£ hai --cached vΓ cΓ‘c cΓ’y phαΊ£i Δược chα» ra." @@ -6814,8 +7108,8 @@ msgstr "phiΓͺn bαΊ£n của emacsclient β%dβ quΓ‘ cΕ© (< 22)." #: builtin/help.c:130 builtin/help.c:151 builtin/help.c:160 builtin/help.c:168 #, c-format -msgid "failed to exec '%s': %s" -msgstr "gαΊ·p lα»i khi thα»±c thi β%sβ: %s" +msgid "failed to exec '%s'" +msgstr "gαΊ·p lα»i khi thα»±c thi β%sβ" #: builtin/help.c:205 #, c-format @@ -7071,104 +7365,105 @@ msgstr "lα»n xα»n hΖ‘n cαΊ£ ΔiΓͺn rα»" #: builtin/index-pack.c:1253 #, c-format -msgid "completed with %d local objects" -msgstr "ΔαΊ§y Δủ vα»i %d Δα»i tượng nα»i bα»" +msgid "completed with %d local object" +msgid_plural "completed with %d local objects" +msgstr[0] "ΔαΊ§y Δủ vα»i %d Δα»i tượng nα»i bα»" -#: builtin/index-pack.c:1263 +#: builtin/index-pack.c:1265 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" -msgstr "Tα»ng kiα»m tra tail khΓ΄ng nhΖ° mong Δợi cho %s (ΔΔ©a hα»ng?)" +msgstr "GαΊ·p tα»ng kiα»m tra tail khΓ΄ng cαΊ§n cho %s (ΔΔ©a hα»ng?)" -#: builtin/index-pack.c:1267 +#: builtin/index-pack.c:1269 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "gΓ³i cΓ³ %d delta chΖ°a Δược giαΊ£i quyαΊΏt" -#: builtin/index-pack.c:1291 +#: builtin/index-pack.c:1293 #, c-format msgid "unable to deflate appended object (%d)" msgstr "khΓ΄ng thα» xαΊ£ nΓ©n Δα»i tượng nα»i thΓͺm (%d)" -#: builtin/index-pack.c:1367 +#: builtin/index-pack.c:1369 #, c-format msgid "local object %s is corrupt" msgstr "Δα»i tượng nα»i bα» %s bα» hα»ng" -#: builtin/index-pack.c:1391 +#: builtin/index-pack.c:1393 msgid "error while closing pack file" msgstr "gαΊ·p lα»i trong khi ΔΓ³ng tαΊp tin gΓ³i" -#: builtin/index-pack.c:1404 +#: builtin/index-pack.c:1406 #, c-format msgid "cannot write keep file '%s'" msgstr "khΓ΄ng thα» ghi tαΊp tin giα»― lαΊ‘i β%sβ" -#: builtin/index-pack.c:1412 +#: builtin/index-pack.c:1414 #, c-format msgid "cannot close written keep file '%s'" msgstr "khΓ΄ng thα» ΔΓ³ng tαΊp tin giα»― lαΊ‘i ΔΓ£ Δược ghi β%sβ" -#: builtin/index-pack.c:1425 +#: builtin/index-pack.c:1427 msgid "cannot store pack file" msgstr "khΓ΄ng thα» lΖ°u tαΊp tin gΓ³i" -#: builtin/index-pack.c:1436 +#: builtin/index-pack.c:1438 msgid "cannot store index file" msgstr "khΓ΄ng thα» lΖ°u trα»― tαΊp tin ghi mα»₯c lα»₯c" -#: builtin/index-pack.c:1469 +#: builtin/index-pack.c:1471 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "sai pack.indexversion=%<PRIu32>" -#: builtin/index-pack.c:1479 builtin/index-pack.c:1664 +#: builtin/index-pack.c:1481 builtin/index-pack.c:1678 #, c-format msgid "no threads support, ignoring %s" msgstr "khΓ΄ng hα» trợ Δa tuyαΊΏn, bα» qua %s" -#: builtin/index-pack.c:1538 +#: builtin/index-pack.c:1540 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "KhΓ΄ng thα» mα» tαΊp tin gΓ³i ΔΓ£ sαΊ΅n cΓ³ β%sβ" -#: builtin/index-pack.c:1540 +#: builtin/index-pack.c:1542 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "KhΓ΄ng thα» mα» tαΊp tin idx của gΓ³i cho β%sβ" -#: builtin/index-pack.c:1587 +#: builtin/index-pack.c:1589 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "khΓ΄ng delta: %d Δα»i tượng" -#: builtin/index-pack.c:1594 +#: builtin/index-pack.c:1596 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "chiα»u dΓ i xΓch = %d: %lu Δα»i tượng" -#: builtin/index-pack.c:1624 +#: builtin/index-pack.c:1609 +#, c-format +msgid "packfile name '%s' does not end with '.pack'" +msgstr "tΓͺn tαΊp tin tαΊp tin gΓ³i β%sβ khΓ΄ng Δược kαΊΏt thΓΊc bαΊ±ng ΔuΓ΄i β.packβ" + +#: builtin/index-pack.c:1638 msgid "Cannot come back to cwd" msgstr "KhΓ΄ng thα» quay lαΊ‘i cwd" -#: builtin/index-pack.c:1676 builtin/index-pack.c:1679 -#: builtin/index-pack.c:1691 builtin/index-pack.c:1695 +#: builtin/index-pack.c:1690 builtin/index-pack.c:1693 +#: builtin/index-pack.c:1705 builtin/index-pack.c:1709 #, c-format msgid "bad %s" msgstr "%s sai" -#: builtin/index-pack.c:1709 +#: builtin/index-pack.c:1723 msgid "--fix-thin cannot be used without --stdin" msgstr "--fix-thin khΓ΄ng thα» Δược dΓΉng mΓ khΓ΄ng cΓ³ --stdin" -#: builtin/index-pack.c:1713 builtin/index-pack.c:1722 -#, c-format -msgid "packfile name '%s' does not end with '.pack'" -msgstr "tΓͺn tαΊp tin tαΊp tin gΓ³i β%sβ khΓ΄ng Δược kαΊΏt thΓΊc bαΊ±ng ΔuΓ΄i β.packβ" - -#: builtin/index-pack.c:1730 +#: builtin/index-pack.c:1731 msgid "--verify with no packfile name given" msgstr "dΓΉng tΓΉy chα»n --verify mΓ khΓ΄ng ΔΖ°a ra tΓͺn packfile" @@ -7207,27 +7502,27 @@ msgstr "khΓ΄ng thα» sao chΓ©p β%sβ sang β%sβ" msgid "ignoring template %s" msgstr "Δang lα» Δi mαΊ«u β%sβ" -#: builtin/init-db.c:118 +#: builtin/init-db.c:120 #, c-format msgid "templates not found %s" msgstr "cΓ‘c mαΊ«u khΓ΄ng Δược tΓ¬m thαΊ₯y %s" -#: builtin/init-db.c:131 +#: builtin/init-db.c:135 #, c-format -msgid "not copying templates of a wrong format version %d from '%s'" -msgstr "khΓ΄ng sao chΓ©p cΓ‘c mαΊ«u của phiΓͺn bαΊ£n sai Δα»nh dαΊ‘ng %d tα»« β%sβ" +msgid "not copying templates from '%s': %s" +msgstr "khΓ΄ng sao chΓ©p cΓ‘c mαΊ«u tα»« β%sβ: %s" -#: builtin/init-db.c:309 builtin/init-db.c:312 +#: builtin/init-db.c:312 builtin/init-db.c:315 #, c-format msgid "%s already exists" msgstr "%s ΔΓ£ cΓ³ tα»« trΖ°α»c rα»i" -#: builtin/init-db.c:340 +#: builtin/init-db.c:344 #, c-format msgid "unable to handle file type %d" msgstr "khΓ΄ng thα» xα» lΓ½ (handle) tαΊp tin kiα»u %d" -#: builtin/init-db.c:343 +#: builtin/init-db.c:347 #, c-format msgid "unable to move %s to %s" msgstr "khΓ΄ng di chuyα»n Δược %s vΓ o %s" @@ -7235,24 +7530,24 @@ msgstr "khΓ΄ng di chuyα»n Δược %s vΓ o %s" #. TRANSLATORS: The first '%s' is either "Reinitialized #. existing" or "Initialized empty", the second " shared" or #. "", and the last '%s%s' is the verbatim directory name. -#: builtin/init-db.c:399 +#: builtin/init-db.c:403 #, c-format msgid "%s%s Git repository in %s%s\n" msgstr "%s%s kho Git trong %s%s\n" -#: builtin/init-db.c:400 +#: builtin/init-db.c:404 msgid "Reinitialized existing" msgstr "Khα»i tαΊ‘o lαΊ‘i ΔΓ£ sαΊ΅n cΓ³ rα»i" -#: builtin/init-db.c:400 +#: builtin/init-db.c:404 msgid "Initialized empty" msgstr "Khα»i tαΊ‘o trα»ng rα»ng" -#: builtin/init-db.c:401 +#: builtin/init-db.c:405 msgid " shared" msgstr " ΔΓ£ chia sαΊ»" -#: builtin/init-db.c:448 +#: builtin/init-db.c:452 msgid "" "git init [-q | --quiet] [--bare] [--template=<template-directory>] [--" "shared[=<permissions>]] [<directory>]" @@ -7260,25 +7555,25 @@ msgstr "" "git init [-q | --quiet] [--bare] [--template=<thΖ°-mα»₯c-tαΊ‘m>] [--shared[=<cΓ‘c-" "quyα»n>]] [thΖ°-mα»₯c]" -#: builtin/init-db.c:471 +#: builtin/init-db.c:475 msgid "permissions" msgstr "cΓ‘c quyα»n" -#: builtin/init-db.c:472 +#: builtin/init-db.c:476 msgid "specify that the git repository is to be shared amongst several users" msgstr "chα» ra cΓ‘i mΓ kho git Δược chia sαΊ» giα»―a nhiα»u ngΖ°α»i dΓΉng" -#: builtin/init-db.c:506 builtin/init-db.c:511 +#: builtin/init-db.c:510 builtin/init-db.c:515 #, c-format msgid "cannot mkdir %s" msgstr "khΓ΄ng thα» mkdir (tαΊ‘o thΖ° mα»₯c): %s" -#: builtin/init-db.c:515 +#: builtin/init-db.c:519 #, c-format msgid "cannot chdir to %s" msgstr "khΓ΄ng thα» chdir (chuyα»n Δα»i thΖ° mα»₯c) sang %s" -#: builtin/init-db.c:536 +#: builtin/init-db.c:540 #, c-format msgid "" "%s (or --work-tree=<directory>) not allowed without specifying %s (or --git-" @@ -7287,7 +7582,7 @@ msgstr "" "%s (hoαΊ·c --work-tree=<thΖ°-mα»₯c>) khΓ΄ng cho phΓ©p khΓ΄ng chα» Δα»nh %s (hoαΊ·c --git-" "dir=<thΖ°-mα»₯c>)" -#: builtin/init-db.c:564 +#: builtin/init-db.c:568 #, c-format msgid "Cannot access work tree '%s'" msgstr "khΓ΄ng thα» truy cαΊp cΓ’y (tree) lΓ m viα»c β%sβ" @@ -7333,264 +7628,316 @@ msgstr "git show [<cΓ‘c-tΓΉy-chα»n>] <Δα»i-tượng>β¦" msgid "invalid --decorate option: %s" msgstr "tΓΉy chα»n--decorate khΓ΄ng hợp lα»: %s" -#: builtin/log.c:131 +#: builtin/log.c:137 msgid "suppress diff output" msgstr "chαΊ·n mα»i kαΊΏt xuαΊ₯t tα»« diff" -#: builtin/log.c:132 +#: builtin/log.c:138 msgid "show source" msgstr "hiα»n thα» mΓ£ nguα»n" -#: builtin/log.c:133 +#: builtin/log.c:139 msgid "Use mail map file" msgstr "Sα» dα»₯ng tαΊp tin Γ‘nh xαΊ‘ thΖ°" -#: builtin/log.c:134 +#: builtin/log.c:140 msgid "decorate options" msgstr "cΓ‘c tΓΉy chα»n trang trΓ" -#: builtin/log.c:137 +#: builtin/log.c:143 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:233 +#: builtin/log.c:239 #, c-format msgid "Final output: %d %s\n" msgstr "KαΊΏt xuαΊ₯t cuα»i cΓΉng: %d %s\n" -#: builtin/log.c:465 +#: builtin/log.c:471 #, c-format msgid "git show %s: bad file" msgstr "git show %s: sai tαΊp tin" -#: builtin/log.c:479 builtin/log.c:572 +#: builtin/log.c:485 builtin/log.c:578 #, c-format msgid "Could not read object %s" msgstr "KhΓ΄ng thα» Δα»c Δα»i tượng %s" -#: builtin/log.c:596 +#: builtin/log.c:602 #, c-format msgid "Unknown type: %d" msgstr "KhΓ΄ng nhαΊn ra kiα»u: %d" -#: builtin/log.c:715 +#: builtin/log.c:722 msgid "format.headers without value" msgstr "format.headers khΓ΄ng cΓ³ giΓ‘ trα» cα»₯ thα»" -#: builtin/log.c:801 +#: builtin/log.c:812 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:816 +#: builtin/log.c:827 #, c-format msgid "Cannot open patch file %s" msgstr "KhΓ΄ng thα» mα» tαΊp tin miαΊΏng vΓ‘: %s" -#: builtin/log.c:830 +#: builtin/log.c:841 msgid "Need exactly one range." msgstr "CαΊ§n chΓnh xΓ‘c mα»t vΓΉng." -#: builtin/log.c:840 +#: builtin/log.c:851 msgid "Not a range." msgstr "KhΓ΄ng phαΊ£i lΓ mα»t vΓΉng." -#: builtin/log.c:946 +#: builtin/log.c:957 msgid "Cover letter needs email format" msgstr "βCover letterβ cαΊ§n cho Δα»nh dαΊ‘ng thΖ°" -#: builtin/log.c:1025 +#: builtin/log.c:1036 #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to ΔiΓͺn rα»: %s" -#: builtin/log.c:1053 +#: builtin/log.c:1064 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:1098 +#: builtin/log.c:1109 msgid "Two output directories?" msgstr "Hai thΖ° mα»₯c kαΊΏt xuαΊ₯t?" -#: builtin/log.c:1214 +#: builtin/log.c:1216 builtin/log.c:1857 builtin/log.c:1859 builtin/log.c:1871 +#, c-format +msgid "Unknown commit %s" +msgstr "KhΓ΄ng hiα»u lαΊ§n chuyα»n giao %s" + +#: builtin/log.c:1226 builtin/notes.c:253 builtin/notes.c:304 +#: builtin/notes.c:306 builtin/notes.c:369 builtin/notes.c:424 +#: builtin/notes.c:510 builtin/notes.c:515 builtin/notes.c:593 +#: builtin/notes.c:656 builtin/notes.c:881 builtin/tag.c:455 +#, 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:1231 +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:1235 +msgid "" +"Failed to get upstream, if you want to record base commit automatically,\n" +"please use git branch --set-upstream-to to track a remote branch.\n" +"Or you could specify base commit by --base=<base-commit-id> manually." +msgstr "" +"GαΊ·p lα»i khi lαΊ₯y thượng nguα»n, nαΊΏu bαΊ‘n muα»n ghi lαΊ‘i lαΊ§n chuyα»n giao nα»n mα»t\n" +"cΓ‘ch tα»± Δα»ng, vui lΓ²ng dΓΉng \"git branch --set-upstream-to\" Δα» theo dΓ΅i\n" +"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:1255 +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." + +#: builtin/log.c:1266 +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:1270 +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:1319 +msgid "cannot get patch id" +msgstr "khΓ΄ng thα» lαΊ₯y mΓ£ miαΊΏng vΓ‘" + +#: builtin/log.c:1377 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:1217 +#: builtin/log.c:1380 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:1221 +#: builtin/log.c:1384 msgid "print patches to standard out" msgstr "hiα»n thα» miαΊΏng vΓ‘ ra ΔαΊ§u ra chuαΊ©n" -#: builtin/log.c:1223 +#: builtin/log.c:1386 msgid "generate a cover letter" msgstr "tαΊ‘o bΓ¬ thΖ°" -#: builtin/log.c:1225 +#: builtin/log.c:1388 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:1226 +#: builtin/log.c:1389 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1227 +#: builtin/log.c:1390 msgid "use <sfx> instead of '.patch'" msgstr "sα» dα»₯ng <sfx> thay cho β.patchβ" -#: builtin/log.c:1229 +#: builtin/log.c:1392 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:1231 +#: builtin/log.c:1394 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:1233 +#: builtin/log.c:1396 msgid "Use [<prefix>] instead of [PATCH]" msgstr "DΓΉng [<tiα»n-tα»>] thay cho [VΓ]" -#: builtin/log.c:1236 +#: builtin/log.c:1399 msgid "store resulting files in <dir>" msgstr "lΖ°u cΓ‘c tαΊp tin kαΊΏt quαΊ£ trong <t.mα»₯c>" -#: builtin/log.c:1239 +#: builtin/log.c:1402 msgid "don't strip/add [PATCH]" msgstr "khΓ΄ng strip/add [VΓ]" -#: builtin/log.c:1242 +#: builtin/log.c:1405 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:1244 +#: builtin/log.c:1407 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:1246 +#: builtin/log.c:1409 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:1248 +#: builtin/log.c:1411 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:1250 +#: builtin/log.c:1413 msgid "Messaging" msgstr "Lα»i nhαΊ―n" -#: builtin/log.c:1251 +#: builtin/log.c:1414 msgid "header" msgstr "ΔαΊ§u Δα» thΖ°" -#: builtin/log.c:1252 +#: builtin/log.c:1415 msgid "add email header" msgstr "thΓͺm ΔαΊ§u Δα» thΖ°" -#: builtin/log.c:1253 builtin/log.c:1255 +#: builtin/log.c:1416 builtin/log.c:1418 msgid "email" msgstr "thΖ° Δiα»n tα»" -#: builtin/log.c:1253 +#: builtin/log.c:1416 msgid "add To: header" msgstr "thΓͺm To: ΔαΊ§u Δα» thΖ°" -#: builtin/log.c:1255 +#: builtin/log.c:1418 msgid "add Cc: header" msgstr "thΓͺm Cc: ΔαΊ§u Δα» thΖ°" -#: builtin/log.c:1257 +#: builtin/log.c:1420 msgid "ident" msgstr "thα»₯t lα»" -#: builtin/log.c:1258 +#: builtin/log.c:1421 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:1260 +#: builtin/log.c:1423 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1261 +#: builtin/log.c:1424 msgid "make first mail a reply to <message-id>" msgstr "dΓΉng thΖ° ΔαΊ§u tiΓͺn Δα» trαΊ£ lα»i <message-id>" -#: builtin/log.c:1262 builtin/log.c:1265 +#: builtin/log.c:1425 builtin/log.c:1428 msgid "boundary" msgstr "ranh giα»i" -#: builtin/log.c:1263 +#: builtin/log.c:1426 msgid "attach the patch" msgstr "ΔΓnh kΓ¨m miαΊΏng vΓ‘" -#: builtin/log.c:1266 +#: builtin/log.c:1429 msgid "inline the patch" msgstr "dΓΉng miαΊΏng vΓ‘ lΓ m nα»i dung" -#: builtin/log.c:1270 +#: builtin/log.c:1433 msgid "enable message threading, styles: shallow, deep" msgstr "cho phΓ©p luα»ng lα»i nhαΊ―n, kiα»u: βshallowβ, βdeepβ" -#: builtin/log.c:1272 +#: builtin/log.c:1435 msgid "signature" msgstr "chα»― kΓ½" -#: builtin/log.c:1273 +#: builtin/log.c:1436 msgid "add a signature" msgstr "thΓͺm chα»― kΓ½" -#: builtin/log.c:1275 +#: builtin/log.c:1437 +msgid "base-commit" +msgstr "lαΊ§n_chuyα»n_giao_nα»n" + +#: builtin/log.c:1438 +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:1440 msgid "add a signature from a file" msgstr "thΓͺm chα»― kΓ½ tα»« mα»t tαΊp tin" -#: builtin/log.c:1276 +#: builtin/log.c:1441 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:1365 +#: builtin/log.c:1531 msgid "-n and -k are mutually exclusive." msgstr "-n vΓ -k loαΊ‘i tα»« lαΊ«n nhau." -#: builtin/log.c:1367 +#: builtin/log.c:1533 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix vΓ -k xung khαΊ―c nhau." -#: builtin/log.c:1375 +#: builtin/log.c:1541 msgid "--name-only does not make sense" msgstr "--name-only khΓ΄ng hợp lΓ½" -#: builtin/log.c:1377 +#: builtin/log.c:1543 msgid "--name-status does not make sense" msgstr "--name-status khΓ΄ng hợp lΓ½" -#: builtin/log.c:1379 +#: builtin/log.c:1545 msgid "--check does not make sense" msgstr "--check khΓ΄ng hợp lΓ½" -#: builtin/log.c:1407 +#: builtin/log.c:1573 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:1409 +#: builtin/log.c:1575 #, c-format msgid "Could not create directory '%s'" msgstr "KhΓ΄ng thα» tαΊ‘o thΖ° mα»₯c β%sβ" -#: builtin/log.c:1506 +#: builtin/log.c:1672 #, c-format msgid "unable to read signature file '%s'" msgstr "khΓ΄ng thα» Δα»c tαΊp tin chα»― kΓ½ β%sβ" -#: builtin/log.c:1569 +#: builtin/log.c:1743 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:1617 +#: builtin/log.c:1792 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<thượng-nguα»n> [<ΔαΊ§u> [<giα»i-hαΊ‘n>]]]" -#: builtin/log.c:1671 +#: builtin/log.c:1846 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -7598,11 +7945,6 @@ 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/log.c:1682 builtin/log.c:1684 builtin/log.c:1696 -#, c-format -msgid "Unknown commit %s" -msgstr "KhΓ΄ng hiα»u lαΊ§n chuyα»n giao %s" - #: builtin/ls-files.c:378 msgid "git ls-files [<options>] [<file>...]" msgstr "git ls-files [<cΓ‘c-tΓΉy-chα»n>] [<tαΊp-tin>β¦]" @@ -7796,174 +8138,178 @@ msgstr "git merge [<cΓ‘c-tΓΉy-chα»n>] <tin-nhαΊ―n> HEAD <commit>" msgid "git merge --abort" msgstr "git merge --abort" -#: builtin/merge.c:100 +#: builtin/merge.c:101 msgid "switch `m' requires a value" msgstr "switch βmβ yΓͺu cαΊ§u mα»t giΓ‘ trα»" -#: builtin/merge.c:137 +#: builtin/merge.c:138 #, 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:138 +#: builtin/merge.c:139 #, c-format msgid "Available strategies are:" msgstr "CΓ‘c chiαΊΏn lược sαΊ΅n sΓ ng lΓ :" -#: builtin/merge.c:143 +#: builtin/merge.c:144 #, 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:193 builtin/pull.c:123 +#: builtin/merge.c:194 builtin/pull.c:126 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:196 builtin/pull.c:126 +#: builtin/merge.c:197 builtin/pull.c:129 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:197 builtin/pull.c:129 +#: builtin/merge.c:198 builtin/pull.c:132 msgid "(synonym to --stat)" msgstr "(Δα»ng nghΔ©a vα»i --stat)" -#: builtin/merge.c:199 builtin/pull.c:132 +#: builtin/merge.c:200 builtin/pull.c:135 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:202 builtin/pull.c:135 +#: builtin/merge.c:203 builtin/pull.c:138 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:204 builtin/pull.c:138 +#: builtin/merge.c:205 builtin/pull.c:141 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:206 builtin/pull.c:141 +#: builtin/merge.c:207 builtin/pull.c:144 msgid "edit message before committing" msgstr "sα»a chΓΊ thΓch trΖ°α»c khi chuyα»n giao" -#: builtin/merge.c:207 +#: builtin/merge.c:208 msgid "allow fast-forward (default)" msgstr "cho phΓ©p chuyα»n-tiαΊΏp-nhanh (mαΊ·c Δα»nh)" -#: builtin/merge.c:209 builtin/pull.c:147 +#: builtin/merge.c:210 builtin/pull.c:150 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:213 +#: builtin/merge.c:214 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:214 builtin/notes.c:770 builtin/pull.c:152 +#: builtin/merge.c:215 builtin/notes.c:771 builtin/pull.c:157 #: builtin/revert.c:89 msgid "strategy" msgstr "chiαΊΏn lược" -#: builtin/merge.c:215 builtin/pull.c:153 +#: builtin/merge.c:216 builtin/pull.c:158 msgid "merge strategy to use" msgstr "chiαΊΏn lược hΓ²a trα»n sαΊ½ dΓΉng" -#: builtin/merge.c:216 builtin/pull.c:156 +#: builtin/merge.c:217 builtin/pull.c:161 msgid "option=value" msgstr "tΓΉy_chα»n=giΓ‘_trα»" -#: builtin/merge.c:217 builtin/pull.c:157 +#: builtin/merge.c:218 builtin/pull.c:162 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:219 +#: builtin/merge.c:220 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:223 +#: builtin/merge.c:224 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:251 +#: builtin/merge.c:226 builtin/pull.c:169 +msgid "allow merging unrelated histories" +msgstr "cho phΓ©p hΓ²a trα»n lα»ch sα» khΓ΄ng liΓͺn quan" + +#: builtin/merge.c:254 msgid "could not run stash." msgstr "khΓ΄ng thα» chαΊ‘y stash." -#: builtin/merge.c:256 +#: builtin/merge.c:259 msgid "stash failed" msgstr "lα»nh tαΊ‘m cαΊ₯t gαΊ·p lα»i" -#: builtin/merge.c:261 +#: builtin/merge.c:264 #, 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:280 builtin/merge.c:297 +#: builtin/merge.c:283 builtin/merge.c:300 msgid "read-tree failed" msgstr "read-tree gαΊ·p lα»i" -#: builtin/merge.c:327 +#: builtin/merge.c:330 msgid " (nothing to squash)" msgstr " (khΓ΄ng cΓ³ gΓ¬ Δα» squash)" -#: builtin/merge.c:340 +#: builtin/merge.c:343 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Squash commit -- khΓ΄ng cαΊp nhαΊt HEAD\n" -#: builtin/merge.c:344 builtin/merge.c:764 builtin/merge.c:976 -#: builtin/merge.c:989 +#: builtin/merge.c:347 builtin/merge.c:767 builtin/merge.c:987 +#: builtin/merge.c:1000 #, c-format msgid "Could not write to '%s'" msgstr "KhΓ΄ng thα» ghi vΓ o β%sβ" -#: builtin/merge.c:372 +#: builtin/merge.c:375 msgid "Writing SQUASH_MSG" msgstr "Δang ghi SQUASH_MSG" -#: builtin/merge.c:374 +#: builtin/merge.c:377 msgid "Finishing SQUASH_MSG" msgstr "HoΓ n thΓ nh SQUASH_MSG" -#: builtin/merge.c:397 +#: builtin/merge.c:400 #, 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:448 +#: builtin/merge.c:451 #, 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:538 +#: builtin/merge.c:541 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Chuα»i branch.%s.mergeoptions sai: %s" -#: builtin/merge.c:657 +#: builtin/merge.c:660 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" -#: builtin/merge.c:671 +#: builtin/merge.c:674 #, 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:684 +#: builtin/merge.c:687 #, c-format msgid "unable to write %s" msgstr "khΓ΄ng thα» ghi %s" -#: builtin/merge.c:773 +#: builtin/merge.c:776 #, c-format msgid "Could not read from '%s'" msgstr "KhΓ΄ng thα» Δα»c tα»« β%sβ" -#: builtin/merge.c:782 +#: builtin/merge.c:785 #, 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:788 +#: builtin/merge.c:791 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -7981,55 +8327,55 @@ msgstr "" "rα»ng\n" "sαΊ½ hủy bα» lαΊ§n chuyα»n giao.\n" -#: builtin/merge.c:812 +#: builtin/merge.c:815 msgid "Empty commit message." msgstr "ChΓΊ thΓch của lαΊ§n commit (chuyα»n giao) bα» trα»ng rα»ng." -#: builtin/merge.c:824 +#: builtin/merge.c:835 #, c-format msgid "Wonderful.\n" msgstr "Tuyα»t vα»i.\n" -#: builtin/merge.c:879 +#: builtin/merge.c:890 #, 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:895 +#: builtin/merge.c:906 #, c-format msgid "'%s' is not a commit" msgstr "%s khΓ΄ng phαΊ£i lΓ mα»t lαΊ§n commit (chuyα»n giao)" -#: builtin/merge.c:936 +#: builtin/merge.c:947 msgid "No current branch." msgstr "khΓ΄ng phαΊ£i nhΓ‘nh hiα»n hΓ nh" -#: builtin/merge.c:938 +#: builtin/merge.c:949 msgid "No remote for the current branch." msgstr "KhΓ΄ng cΓ³ mΓ‘y chủ cho nhΓ‘nh hiα»n hΓ nh." -#: builtin/merge.c:940 +#: builtin/merge.c:951 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:945 +#: builtin/merge.c:956 #, 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:1080 +#: builtin/merge.c:1091 #, c-format msgid "could not close '%s'" msgstr "khΓ΄ng thα» ΔΓ³ng β%sβ" -#: builtin/merge.c:1207 +#: builtin/merge.c:1219 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:1223 +#: builtin/merge.c:1235 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you merge." @@ -8037,7 +8383,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:1230 +#: builtin/merge.c:1242 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you merge." @@ -8045,103 +8391,107 @@ 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:1233 +#: builtin/merge.c:1245 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:1242 +#: builtin/merge.c:1254 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:1250 +#: builtin/merge.c:1262 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:1267 +#: builtin/merge.c:1279 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:1269 +#: builtin/merge.c:1281 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:1275 +#: builtin/merge.c:1286 #, c-format msgid "%s - not something we can merge" msgstr "%s - khΓ΄ng phαΊ£i lΓ mα»t sα» thα»© chΓΊng tΓ΄i cΓ³ thα» hΓ²a trα»n" -#: builtin/merge.c:1277 +#: builtin/merge.c:1288 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:1332 +#: builtin/merge.c:1344 #, 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." -#: builtin/merge.c:1335 +#: builtin/merge.c:1347 #, 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." -#: builtin/merge.c:1338 +#: builtin/merge.c:1350 #, c-format msgid "Commit %s does not have a GPG signature." msgstr "LαΊ§n chuyα»n giao %s khΓ΄ng cΓ³ chα»― kΓ½ GPG." -#: builtin/merge.c:1341 +#: builtin/merge.c:1353 #, 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" -#: builtin/merge.c:1424 +#: builtin/merge.c:1415 +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:1439 #, c-format msgid "Updating %s..%s\n" msgstr "Δang cαΊp nhαΊt %s..%s\n" -#: builtin/merge.c:1461 +#: builtin/merge.c:1476 #, 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:1468 +#: builtin/merge.c:1483 #, c-format msgid "Nope.\n" msgstr "KhΓ΄ng.\n" -#: builtin/merge.c:1500 +#: builtin/merge.c:1515 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:1523 builtin/merge.c:1602 +#: builtin/merge.c:1538 builtin/merge.c:1617 #, 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:1527 +#: builtin/merge.c:1542 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Δang thα» chiαΊΏn lược hΓ²a trα»n %sβ¦\n" -#: builtin/merge.c:1593 +#: builtin/merge.c:1608 #, 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:1595 +#: builtin/merge.c:1610 #, 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:1604 +#: builtin/merge.c:1619 #, 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:1616 +#: builtin/merge.c:1631 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -8253,7 +8603,7 @@ msgstr "git mv [<cΓ‘c-tΓΉy-chα»n>] <nguα»n>β¦ <ΔΓch>" 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:72 +#: builtin/mv.c:72 builtin/rm.c:317 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Γ½" @@ -8332,49 +8682,49 @@ msgstr "%s, nguα»n=%s, ΔΓch=%s" msgid "Renaming %s to %s\n" msgstr "Δα»i tΓͺn %s thΓ nh %s\n" -#: builtin/mv.c:257 builtin/remote.c:714 builtin/repack.c:365 +#: builtin/mv.c:260 builtin/remote.c:714 builtin/repack.c:365 #, c-format msgid "renaming '%s' failed" msgstr "gαΊ·p lα»i khi Δα»i tΓͺn β%sβ" -#: builtin/name-rev.c:251 +#: builtin/name-rev.c:258 msgid "git name-rev [<options>] <commit>..." msgstr "git name-rev [<cΓ‘c-tΓΉy-chα»n>] <commit>β¦" -#: builtin/name-rev.c:252 +#: builtin/name-rev.c:259 msgid "git name-rev [<options>] --all" msgstr "git name-rev [<cΓ‘c-tΓΉy-chα»n>] --all" -#: builtin/name-rev.c:253 +#: builtin/name-rev.c:260 msgid "git name-rev [<options>] --stdin" msgstr "git name-rev [<cΓ‘c-tΓΉy-chα»n>] --stdin" -#: builtin/name-rev.c:305 +#: builtin/name-rev.c:312 msgid "print only names (no SHA-1)" msgstr "chα» hiα»n thα» tΓͺn (khΓ΄ng SHA-1)" -#: builtin/name-rev.c:306 +#: builtin/name-rev.c:313 msgid "only use tags to name the commits" msgstr "chα» dΓΉng cΓ‘c thαΊ» Δα» ΔαΊ·t tΓͺn cho cΓ‘c lαΊ§n chuyα»n giao" -#: builtin/name-rev.c:308 +#: builtin/name-rev.c:315 msgid "only use refs matching <pattern>" msgstr "chα» sα» dα»₯ng cΓ‘c tham chiαΊΏu khα»p vα»i <mαΊ«u>" -#: builtin/name-rev.c:310 +#: builtin/name-rev.c:317 msgid "list all commits reachable from all refs" msgstr "" "liα»t kΓͺ tαΊ₯t cαΊ£ cΓ‘c lαΊ§n chuyα»n giao cΓ³ thα» Δα»c Δược tα»« tαΊ₯t cαΊ£ cΓ‘c tham chiαΊΏu" -#: builtin/name-rev.c:311 +#: builtin/name-rev.c:318 msgid "read from stdin" msgstr "Δα»c tα»« ΔαΊ§u vΓ o tiΓͺu chuαΊ©n" -#: builtin/name-rev.c:312 +#: builtin/name-rev.c:319 msgid "allow to print `undefined` names (default)" msgstr "cho phΓ©p in cΓ‘c tΓͺn βchΖ°a Δα»nh nghΔ©aβ (mαΊ·c Δα»nh)" -#: builtin/name-rev.c:318 +#: builtin/name-rev.c:325 msgid "dereference tags in the input (internal use)" msgstr "bΓ£i bα» tham chiαΊΏu cΓ‘c thαΊ» trong ΔαΊ§u vΓ o (dΓΉng nα»i bα»)" @@ -8521,24 +8871,16 @@ msgstr "khΓ΄ng thα» ghi Δα»i tượng ghi chΓΊ (note)" msgid "The note contents have been left in %s" msgstr "Nα»i dung ghi chΓΊ cΓ²n lαΊ‘i %s" -#: builtin/notes.c:232 builtin/tag.c:440 +#: builtin/notes.c:232 builtin/tag.c:439 #, c-format msgid "cannot read '%s'" msgstr "khΓ΄ng thα» Δα»c β%sβ" -#: builtin/notes.c:234 builtin/tag.c:443 +#: builtin/notes.c:234 builtin/tag.c:442 #, c-format msgid "could not open or read '%s'" msgstr "khΓ΄ng thα» mα» hay Δα»c β%sβ" -#: builtin/notes.c:253 builtin/notes.c:304 builtin/notes.c:306 -#: builtin/notes.c:369 builtin/notes.c:424 builtin/notes.c:510 -#: builtin/notes.c:515 builtin/notes.c:593 builtin/notes.c:656 -#: builtin/notes.c:880 builtin/tag.c:456 -#, 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/notes.c:256 #, c-format msgid "Failed to read object '%s'." @@ -8551,7 +8893,7 @@ msgstr "khΓ΄ng thα» Δα»c dα»― liα»u ghi chΓΊ tα»« Δα»i tượng khΓ΄ng-blo #: builtin/notes.c:362 builtin/notes.c:417 builtin/notes.c:493 #: builtin/notes.c:505 builtin/notes.c:581 builtin/notes.c:649 -#: builtin/notes.c:945 +#: builtin/notes.c:946 msgid "too many parameters" msgstr "quΓ‘ nhiα»u Δα»i sα»" @@ -8598,7 +8940,7 @@ msgstr "" 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:460 builtin/notes.c:621 builtin/notes.c:885 +#: builtin/notes.c:460 builtin/notes.c:621 builtin/notes.c:886 #, c-format msgid "Removing note for object %s\n" msgstr "Δang gα»‘ bα» ghi chΓΊ (note) cho Δα»i tượng %s\n" @@ -8638,15 +8980,15 @@ 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:767 +#: builtin/notes.c:768 msgid "General options" msgstr "TΓΉy chα»n chung" -#: builtin/notes.c:769 +#: builtin/notes.c:770 msgid "Merge options" msgstr "TΓΉy chα»n vα» hΓ²a trα»n" -#: builtin/notes.c:771 +#: builtin/notes.c:772 msgid "" "resolve notes conflicts using the given strategy (manual/ours/theirs/union/" "cat_sort_uniq)" @@ -8654,51 +8996,51 @@ 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:773 +#: builtin/notes.c:774 msgid "Committing unmerged notes" msgstr "Chuyα»n giao cΓ‘c note chΖ°a Δược hΓ²a trα»n" -#: builtin/notes.c:775 +#: builtin/notes.c:776 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:777 +#: builtin/notes.c:778 msgid "Aborting notes merge resolution" msgstr "Hủy bα» phΓ’n giαΊ£i ghi chΓΊ (note) hΓ²a trα»n" -#: builtin/notes.c:779 +#: builtin/notes.c:780 msgid "abort notes merge" msgstr "bα» qua hΓ²a trα»n cΓ‘c ghi chΓΊ (note)" -#: builtin/notes.c:856 +#: builtin/notes.c:857 #, c-format msgid "A notes merge into %s is already in-progress at %s" msgstr "CΓ‘c ghi chΓΊ hΓ²a trα»n vΓ o %s ΔΓ£ sαΊ΅n trong quΓ‘ trΓ¬nh xα» lΓ½ tαΊ‘i %s" -#: builtin/notes.c:883 +#: builtin/notes.c:884 #, c-format msgid "Object %s has no note\n" msgstr "Δα»i tượng %s khΓ΄ng cΓ³ ghi chΓΊ (note)\n" -#: builtin/notes.c:895 +#: builtin/notes.c:896 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:898 +#: builtin/notes.c:899 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:979 +#: builtin/notes.c:980 msgid "notes-ref" msgstr "notes-ref" -#: builtin/notes.c:980 +#: builtin/notes.c:981 msgid "use notes from <notes-ref>" msgstr "dΓΉng βnotesβ tα»« <notes-ref>" -#: builtin/notes.c:1015 builtin/remote.c:1626 +#: builtin/notes.c:1016 builtin/remote.c:1628 #, c-format msgid "Unknown subcommand: %s" msgstr "KhΓ΄ng hiα»u cΓ’u lα»nh con: %s" @@ -8722,166 +9064,170 @@ msgstr "" msgid "deflate error (%d)" msgstr "lα»i giαΊ£i nΓ©n (%d)" -#: builtin/pack-objects.c:772 +#: builtin/pack-objects.c:763 +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:776 msgid "Writing objects" msgstr "Δang ghi lαΊ‘i cΓ‘c Δα»i tượng" -#: builtin/pack-objects.c:1012 +#: builtin/pack-objects.c:1017 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:2172 +#: builtin/pack-objects.c:2177 msgid "Compressing objects" msgstr "Δang nΓ©n cΓ‘c Δα»i tượng" -#: builtin/pack-objects.c:2558 +#: builtin/pack-objects.c:2563 #, c-format msgid "unsupported index version %s" msgstr "phiΓͺn bαΊ£n mα»₯c lα»₯c khΓ΄ng Δược hα» trợ %s" -#: builtin/pack-objects.c:2562 +#: builtin/pack-objects.c:2567 #, c-format msgid "bad index version '%s'" msgstr "phiΓͺn bαΊ£n mα»₯c lα»₯c sai β%sβ" -#: builtin/pack-objects.c:2592 +#: builtin/pack-objects.c:2597 msgid "do not show progress meter" msgstr "khΓ΄ng hiα»n thα» bα» Δo tiαΊΏn trΓ¬nh" -#: builtin/pack-objects.c:2594 +#: builtin/pack-objects.c:2599 msgid "show progress meter" msgstr "hiα»n thα» bα» Δo tiαΊΏn trΓ¬nh" -#: builtin/pack-objects.c:2596 +#: builtin/pack-objects.c:2601 msgid "show progress meter during object writing phase" msgstr "hiα»n thα» bα» Δo tiαΊΏn triα»n trong suα»t pha ghi Δα»i tượng" -#: builtin/pack-objects.c:2599 +#: builtin/pack-objects.c:2604 msgid "similar to --all-progress when progress meter is shown" msgstr "tΖ°Ζ‘ng tα»± --all-progress khi bα» Δo tiαΊΏn trΓ¬nh Δược xuαΊ₯t hiα»n" -#: builtin/pack-objects.c:2600 +#: builtin/pack-objects.c:2605 msgid "version[,offset]" msgstr "phiΓͺn bαΊ£n[,offset]" -#: builtin/pack-objects.c:2601 +#: builtin/pack-objects.c:2606 msgid "write the pack index file in the specified idx format version" msgstr "ghi tαΊp tin bαΊ£ng mα»₯c lα»₯c gΓ³i (pack) α» phiΓͺn bαΊ£n Δα»nh dαΊ‘ng idx ΔΓ£ cho" -#: builtin/pack-objects.c:2604 +#: builtin/pack-objects.c:2609 msgid "maximum size of each output pack file" msgstr "kcΓh thΖ°α»c tα»i Δa cho tαΊp tin gΓ³i Δược tαΊ‘o" -#: builtin/pack-objects.c:2606 +#: builtin/pack-objects.c:2611 msgid "ignore borrowed objects from alternate object store" msgstr "bα» qua cΓ‘c Δα»i tượng vay mượn tα»« kho Δα»i tượng thay thαΊΏ" -#: builtin/pack-objects.c:2608 +#: builtin/pack-objects.c:2613 msgid "ignore packed objects" msgstr "bα» qua cΓ‘c Δα»i tượng ΔΓ³ng gΓ³i" -#: builtin/pack-objects.c:2610 +#: builtin/pack-objects.c:2615 msgid "limit pack window by objects" msgstr "giα»i hαΊ‘n cα»a sα» ΔΓ³ng gΓ³i theo Δα»i tượng" -#: builtin/pack-objects.c:2612 +#: builtin/pack-objects.c:2617 msgid "limit pack window by memory in addition to object limit" msgstr "giα»i hαΊ‘n cα»a sα» ΔΓ³ng gΓ³i theo bα» nhα» cα»ng thΓͺm vα»i giα»i hαΊ‘n Δα»i tượng" -#: builtin/pack-objects.c:2614 +#: builtin/pack-objects.c:2619 msgid "maximum length of delta chain allowed in the resulting pack" msgstr "Δα» dΓ i tα»i Δa của chuα»i mΓ³c xΓch βdeltaβ Δược phΓ©p trong gΓ³i kαΊΏt quαΊ£" -#: builtin/pack-objects.c:2616 +#: builtin/pack-objects.c:2621 msgid "reuse existing deltas" msgstr "dΓΉng lαΊ‘i cΓ‘c delta sαΊ΅n cΓ³" -#: builtin/pack-objects.c:2618 +#: builtin/pack-objects.c:2623 msgid "reuse existing objects" msgstr "dΓΉng lαΊ‘i cΓ‘c Δα»i tượng sαΊ΅n cΓ³" -#: builtin/pack-objects.c:2620 +#: builtin/pack-objects.c:2625 msgid "use OFS_DELTA objects" msgstr "dΓΉng cΓ‘c Δα»i tượng OFS_DELTA" -#: builtin/pack-objects.c:2622 +#: builtin/pack-objects.c:2627 msgid "use threads when searching for best delta matches" msgstr "sα» dα»₯ng cΓ‘c tuyαΊΏn trΓ¬nh khi tΓ¬m kiαΊΏm cho cΓ‘c mαΊ«u khα»p delta tα»t nhαΊ₯t" -#: builtin/pack-objects.c:2624 +#: builtin/pack-objects.c:2629 msgid "do not create an empty pack output" msgstr "khΓ΄ng thα» tαΊ‘o kαΊΏt xuαΊ₯t gΓ³i trα»ng rα»ng" -#: builtin/pack-objects.c:2626 +#: builtin/pack-objects.c:2631 msgid "read revision arguments from standard input" msgstr " Δα»c tham sα» βrevisionβ tα»« thiαΊΏt bα» nhαΊp chuαΊ©n" -#: builtin/pack-objects.c:2628 +#: builtin/pack-objects.c:2633 msgid "limit the objects to those that are not yet packed" msgstr "giα»i hαΊ‘n cΓ‘c Δα»i tượng thΓ nh nhα»―ng cΓ‘i mΓ chΓΊng vαΊ«n chΖ°a Δược ΔΓ³ng gΓ³i" -#: builtin/pack-objects.c:2631 +#: builtin/pack-objects.c:2636 msgid "include objects reachable from any reference" msgstr "bao gα»m cΓ‘c Δα»i tượng cΓ³ thα» Δα»c Δược tα»« bαΊ₯t kα»³ tham chiαΊΏu nΓ o" -#: builtin/pack-objects.c:2634 +#: builtin/pack-objects.c:2639 msgid "include objects referred by reflog entries" msgstr "bao gα»m cΓ‘c Δα»i tượng Δược tham chiαΊΏu bα»i cΓ‘c mα»₯c reflog" -#: builtin/pack-objects.c:2637 +#: builtin/pack-objects.c:2642 msgid "include objects referred to by the index" msgstr "bao gα»m cΓ‘c Δα»i tượng Δược tham chiαΊΏu bα»i mα»₯c lα»₯c" -#: builtin/pack-objects.c:2640 +#: builtin/pack-objects.c:2645 msgid "output pack to stdout" msgstr "xuαΊ₯t gΓ³i ra ΔαΊ§u ra tiΓͺu chuαΊ©n" -#: builtin/pack-objects.c:2642 +#: builtin/pack-objects.c:2647 msgid "include tag objects that refer to objects to be packed" msgstr "bao gα»m cΓ‘c Δα»i tượng tham chiαΊΏu ΔαΊΏn cΓ‘c Δα»i tượng Δược ΔΓ³ng gΓ³i" -#: builtin/pack-objects.c:2644 +#: builtin/pack-objects.c:2649 msgid "keep unreachable objects" msgstr "giα»― lαΊ‘i cΓ‘c Δα»i tượng khΓ΄ng thα» Δα»c Δược" -#: builtin/pack-objects.c:2645 parse-options.h:142 +#: builtin/pack-objects.c:2650 parse-options.h:142 msgid "time" msgstr "thα»i-gian" -#: builtin/pack-objects.c:2646 +#: builtin/pack-objects.c:2651 msgid "unpack unreachable objects newer than <time>" 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:2649 +#: builtin/pack-objects.c:2654 msgid "create thin packs" msgstr "tαΊ‘o gΓ³i nhαΊΉ" -#: builtin/pack-objects.c:2651 +#: builtin/pack-objects.c:2656 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:2653 +#: builtin/pack-objects.c:2658 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:2655 +#: builtin/pack-objects.c:2660 msgid "pack compression level" msgstr "mα»©c nΓ©n gΓ³i" -#: builtin/pack-objects.c:2657 +#: builtin/pack-objects.c:2662 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:2659 +#: builtin/pack-objects.c:2664 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:2661 +#: builtin/pack-objects.c:2666 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:2752 +#: builtin/pack-objects.c:2757 msgid "Counting objects" msgstr "Δang ΔαΊΏm cΓ‘c Δα»i tượng" @@ -8909,15 +9255,15 @@ msgstr "Δang gα»‘ cΓ‘c Δα»i tượng trΓΉng lαΊ·p" msgid "git prune [-n] [-v] [--expire <time>] [--] [<head>...]" msgstr "git prune [-n] [-v] [--expire <thα»i-gian>] [--] [<head>β¦]" -#: builtin/prune.c:105 builtin/worktree.c:124 +#: builtin/prune.c:105 builtin/worktree.c:125 msgid "do not remove, show only" msgstr "khΓ΄ng gα»‘ bα», chα» hiα»n thα»" -#: builtin/prune.c:106 builtin/worktree.c:125 +#: builtin/prune.c:106 builtin/worktree.c:126 msgid "report pruned objects" msgstr "bΓ‘o cΓ‘o cΓ‘c Δα»i tượng ΔΓ£ prune" -#: builtin/prune.c:109 builtin/worktree.c:127 +#: builtin/prune.c:109 builtin/worktree.c:128 msgid "expire objects older than <time>" msgstr "cΓ‘c Δα»i tượng hαΊΏt hαΊ‘n cΕ© hΖ‘n khoαΊ£ng <thα»i gian>" @@ -8929,50 +9275,54 @@ msgstr "khΓ΄ng thα» tα»a bα»t trong mα»t kho Δα»i_tượng_vΔ©_ΔαΊ‘i" msgid "git pull [<options>] [<repository> [<refspec>...]]" msgstr "git pull [<cΓ‘c-tΓΉy-chα»n>] [<kho-chα»©a> [<refspec>β¦]]" -#: builtin/pull.c:117 +#: builtin/pull.c:120 msgid "Options related to merging" msgstr "CΓ‘c tΓΉy chα»n liΓͺn quan ΔαΊΏn hΓ²a trα»n" -#: builtin/pull.c:120 +#: builtin/pull.c:123 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:144 builtin/revert.c:105 +#: builtin/pull.c:147 builtin/revert.c:105 msgid "allow fast-forward" msgstr "cho phΓ©p chuyα»n-tiαΊΏp-nhanh" -#: builtin/pull.c:150 +#: builtin/pull.c:153 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/pull.c:164 +#: builtin/pull.c:156 +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:172 msgid "Options related to fetching" msgstr "CΓ‘c tΓΉy chα»n liΓͺn quan ΔαΊΏn lα»nh lαΊ₯y vα»" -#: builtin/pull.c:186 +#: builtin/pull.c:194 msgid "number of submodules pulled in parallel" msgstr "sα» lượng mΓ΄-Δun-con Δược ΔαΊ©y lΓͺn Δα»ng thα»i" -#: builtin/pull.c:275 +#: builtin/pull.c:283 #, c-format msgid "Invalid value for pull.ff: %s" msgstr "GiΓ‘ trα» khΓ΄ng hợp lα» cho pull.ff: %s" -#: builtin/pull.c:359 +#: builtin/pull.c:379 msgid "Cannot pull with rebase: You have unstaged changes." msgstr "" "KhΓ΄ng thα» pull vα»i cαΊ£i tα»: BαΊ‘n cΓ³ cΓ‘c thay Δα»i chΖ°a Δược ΔΖ°a lΓͺn bα» phΓ³ng." -#: builtin/pull.c:365 +#: builtin/pull.c:385 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." -#: builtin/pull.c:367 +#: builtin/pull.c:387 msgid "Cannot pull with rebase: Your index contains uncommitted changes." msgstr "KhΓ΄ng thα» pull vα»i cαΊ£i tα»: BαΊ‘n cΓ³ cΓ‘c thay Δα»i chΖ°a Δược chuyα»n giao." -#: builtin/pull.c:443 +#: builtin/pull.c:463 msgid "" "There is no candidate for rebasing against among the refs that you just " "fetched." @@ -8980,14 +9330,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:445 +#: builtin/pull.c:465 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:446 +#: builtin/pull.c:466 msgid "" "Generally this means that you provided a wildcard refspec which had no\n" "matches on the remote end." @@ -8996,7 +9346,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:449 +#: builtin/pull.c:469 #, c-format msgid "" "You asked to pull from the remote '%s', but did not specify\n" @@ -9008,40 +9358,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:454 +#: builtin/pull.c:474 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:456 builtin/pull.c:471 +#: builtin/pull.c:476 builtin/pull.c:491 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:458 builtin/pull.c:473 +#: builtin/pull.c:478 builtin/pull.c:493 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:459 builtin/pull.c:474 +#: builtin/pull.c:479 builtin/pull.c:494 msgid "See git-pull(1) for details." msgstr "Xem git-pull(1) Δα» biαΊΏt thΓͺm chi tiαΊΏt." -#: builtin/pull.c:469 +#: builtin/pull.c:481 builtin/pull.c:487 builtin/pull.c:496 +#: git-parse-remote.sh:64 +msgid "<remote>" +msgstr "<mΓ‘y chủ>" + +#: builtin/pull.c:481 builtin/pull.c:496 builtin/pull.c:501 +#: git-parse-remote.sh:65 +msgid "<branch>" +msgstr "<nhΓ‘nh>" + +#: builtin/pull.c:489 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:478 -#, c-format +#: builtin/pull.c:498 git-parse-remote.sh:95 msgid "" -"If you wish to set tracking information for this branch you can do so with:\n" -"\n" -" git branch --set-upstream-to=%s/<branch> %s\n" +"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:\n" -"\n" -" git branch --set-upstream-to=%s/<nhΓ‘nh> %s\n" -"\n" +"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:483 +#: builtin/pull.c:503 #, c-format msgid "" "Your configuration specifies to merge with the ref '%s'\n" @@ -9050,13 +9403,17 @@ 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:841 +#: builtin/pull.c:864 +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:872 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:870 +#: builtin/pull.c:900 #, c-format msgid "" "fetch updated the current branch head.\n" @@ -9067,7 +9424,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:875 +#: builtin/pull.c:905 #, c-format msgid "" "Cannot fast-forward your working tree.\n" @@ -9085,11 +9442,11 @@ msgstr "" "$ git reset --hard\n" "Δα» khΓ΄i phα»₯c lαΊ‘i." -#: builtin/pull.c:890 +#: builtin/pull.c:920 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:894 +#: builtin/pull.c:924 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." @@ -9459,6 +9816,18 @@ msgstr "bα» qua Γ‘p dα»₯ng bα» lα»c lαΊ₯y ra (checkout) thΖ°a thα»t" msgid "debug unpack-trees" msgstr "gα»‘ lα»i βunpack-treesβ" +#: builtin/receive-pack.c:25 +msgid "git receive-pack <git-dir>" +msgstr "git receive-pack <thΖ°-mα»₯c-git>" + +#: builtin/receive-pack.c:1719 +msgid "quiet" +msgstr "im lαΊ·ng" + +#: builtin/receive-pack.c:1733 +msgid "You must specify a directory." +msgstr "BαΊ‘n phαΊ£i chα» Δα»nh thΖ° mα»₯c." + #: builtin/reflog.c:423 #, c-format msgid "'%s' for '%s' is not a valid timestamp" @@ -9780,173 +10149,175 @@ msgstr "* mΓ‘y chủ %s" msgid " Fetch URL: %s" msgstr " URL Δα» lαΊ₯y vα»: %s" -#: builtin/remote.c:1148 builtin/remote.c:1299 +#: builtin/remote.c:1148 builtin/remote.c:1301 msgid "(no URL)" msgstr "(khΓ΄ng cΓ³ URL)" -#: builtin/remote.c:1157 builtin/remote.c:1159 +#. TRANSLATORS: the colon ':' should align with +#. the one in " Fetch URL: %s" translation +#: builtin/remote.c:1159 builtin/remote.c:1161 #, c-format msgid " Push URL: %s" msgstr " URL Δα» ΔαΊ©y lΓͺn: %s" -#: builtin/remote.c:1161 builtin/remote.c:1163 builtin/remote.c:1165 +#: builtin/remote.c:1163 builtin/remote.c:1165 builtin/remote.c:1167 #, c-format msgid " HEAD branch: %s" msgstr " NhΓ‘nh HEAD: %s" -#: builtin/remote.c:1167 +#: builtin/remote.c:1169 #, c-format msgid "" " HEAD branch (remote HEAD is ambiguous, may be one of the following):\n" msgstr " nhΓ‘nh HEAD (HEAD mΓ‘y chủ chΖ°a rΓ΅ rΓ ng, cΓ³ lαΊ½ lΓ mα»t trong sα» sau):\n" -#: builtin/remote.c:1179 +#: builtin/remote.c:1181 #, c-format msgid " Remote branch:%s" msgid_plural " Remote branches:%s" msgstr[0] " Nhα»―ng nhΓ‘nh trΓͺn mΓ‘y chủ:%s" -#: builtin/remote.c:1182 builtin/remote.c:1209 +#: builtin/remote.c:1184 builtin/remote.c:1211 msgid " (status not queried)" msgstr " (trαΊ‘ng thΓ‘i khΓ΄ng Δược yΓͺu cαΊ§u)" -#: builtin/remote.c:1191 +#: builtin/remote.c:1193 msgid " Local branch configured for 'git pull':" msgid_plural " Local branches configured for 'git pull':" msgstr[0] " Nhα»―ng nhΓ‘nh nα»i bα» ΔΓ£ Δược cαΊ₯u hΓ¬nh cho lα»nh βgit pullβ:" -#: builtin/remote.c:1199 +#: builtin/remote.c:1201 msgid " Local refs will be mirrored by 'git push'" msgstr " refs nα»i bα» sαΊ½ Δược phαΊ£n chiαΊΏu bα»i lα»nh βgit pushβ" -#: builtin/remote.c:1206 +#: builtin/remote.c:1208 #, c-format msgid " Local ref configured for 'git push'%s:" msgid_plural " Local refs configured for 'git push'%s:" msgstr[0] " Nhα»―ng tham chiαΊΏu nα»i bα» Δược cαΊ₯u hΓ¬nh cho lα»nh βgit pushβ%s:" -#: builtin/remote.c:1227 +#: builtin/remote.c:1229 msgid "set refs/remotes/<name>/HEAD according to remote" msgstr "ΔαΊ·t refs/remotes/<tΓͺn>/HEAD cho phΓΉ hợp vα»i mΓ‘y chủ" -#: builtin/remote.c:1229 +#: builtin/remote.c:1231 msgid "delete refs/remotes/<name>/HEAD" msgstr "xΓ³a refs/remotes/<tΓͺn>/HEAD" -#: builtin/remote.c:1244 +#: builtin/remote.c:1246 msgid "Cannot determine remote HEAD" msgstr "KhΓ΄ng thα» xΓ‘c Δα»nh Δược HEAD mΓ‘y chủ" -#: builtin/remote.c:1246 +#: builtin/remote.c:1248 msgid "Multiple remote HEAD branches. Please choose one explicitly with:" msgstr "Nhiα»u nhΓ‘nh HEAD mΓ‘y chủ. HΓ£y chα»n rΓ΅ rΓ ng mα»t:" -#: builtin/remote.c:1256 +#: builtin/remote.c:1258 #, c-format msgid "Could not delete %s" msgstr "KhΓ΄ng thα» xΓ³a bα» %s" -#: builtin/remote.c:1264 +#: builtin/remote.c:1266 #, c-format msgid "Not a valid ref: %s" msgstr "KhΓ΄ng phαΊ£i lΓ tham chiαΊΏu hợp lα»: %s" -#: builtin/remote.c:1266 +#: builtin/remote.c:1268 #, c-format msgid "Could not setup %s" msgstr "KhΓ΄ng thα» cΓ i ΔαΊ·t %s" -#: builtin/remote.c:1284 +#: builtin/remote.c:1286 #, c-format msgid " %s will become dangling!" msgstr " %s sαΊ½ trα» thΓ nh khΓ΄ng ΔαΊ§u (khΓ΄ng Δược quαΊ£n lΓ½)!" -#: builtin/remote.c:1285 +#: builtin/remote.c:1287 #, c-format msgid " %s has become dangling!" msgstr " %s ΔΓ£ trα» thΓ nh khΓ΄ng ΔαΊ§u (khΓ΄ng Δược quαΊ£n lΓ½)!" -#: builtin/remote.c:1295 +#: builtin/remote.c:1297 #, c-format msgid "Pruning %s" msgstr "Δang xΓ©n bα»t %s" -#: builtin/remote.c:1296 +#: builtin/remote.c:1298 #, c-format msgid "URL: %s" msgstr "URL: %s" -#: builtin/remote.c:1312 +#: builtin/remote.c:1314 #, c-format msgid " * [would prune] %s" msgstr " * [nΓͺn xΓ©n bα»t] %s" -#: builtin/remote.c:1315 +#: builtin/remote.c:1317 #, c-format msgid " * [pruned] %s" msgstr " * [ΔΓ£ bα» xΓ©n] %s" -#: builtin/remote.c:1360 +#: builtin/remote.c:1362 msgid "prune remotes after fetching" msgstr "cαΊ―t mΓ‘y chủ sau khi lαΊ₯y vα»" -#: builtin/remote.c:1423 builtin/remote.c:1477 builtin/remote.c:1545 +#: builtin/remote.c:1425 builtin/remote.c:1479 builtin/remote.c:1547 #, c-format msgid "No such remote '%s'" msgstr "KhΓ΄ng cΓ³ mΓ‘y chủ nΓ o cΓ³ tΓͺn β%sβ" -#: builtin/remote.c:1439 +#: builtin/remote.c:1441 msgid "add branch" msgstr "thΓͺm nhΓ‘nh" -#: builtin/remote.c:1446 +#: builtin/remote.c:1448 msgid "no remote specified" msgstr "chΖ°a chα» ra mΓ‘y chủ nΓ o" -#: builtin/remote.c:1463 +#: builtin/remote.c:1465 msgid "query push URLs rather than fetch URLs" msgstr "truy vαΊ₯n ΔαΊ©y URL thay vΓ¬ lαΊ₯y" -#: builtin/remote.c:1465 +#: builtin/remote.c:1467 msgid "return all URLs" msgstr "trαΊ£ vα» mα»i URL" -#: builtin/remote.c:1493 +#: builtin/remote.c:1495 #, c-format msgid "no URLs configured for remote '%s'" msgstr "khΓ΄ng cΓ³ URL nΓ o Δược cαΊ₯u hΓ¬nh cho nhΓ‘nh β%sβ" -#: builtin/remote.c:1519 +#: builtin/remote.c:1521 msgid "manipulate push URLs" msgstr "ΔαΊ©y cΓ‘c βURLβ bαΊ±ng tay" -#: builtin/remote.c:1521 +#: builtin/remote.c:1523 msgid "add URL" msgstr "thΓͺm URL" -#: builtin/remote.c:1523 +#: builtin/remote.c:1525 msgid "delete URLs" msgstr "xΓ³a URLs" -#: builtin/remote.c:1530 +#: builtin/remote.c:1532 msgid "--add --delete doesn't make sense" msgstr "--add --delete khΓ΄ng hợp lΓ½" -#: builtin/remote.c:1571 +#: builtin/remote.c:1573 #, c-format msgid "Invalid old URL pattern: %s" msgstr "Kiα»u mαΊ«u URL cΕ© khΓ΄ng hợp lα»: %s" -#: builtin/remote.c:1579 +#: builtin/remote.c:1581 #, c-format msgid "No such URL found: %s" msgstr "KhΓ΄ng tΓ¬m thαΊ₯y URL nhΖ° vαΊy: %s" -#: builtin/remote.c:1581 +#: builtin/remote.c:1583 msgid "Will not delete all non-push URLs" msgstr "SαΊ½ khΓ΄ng xΓ³a nhα»―ng Δα»a chα» URL khΓ΄ng-push" -#: builtin/remote.c:1595 +#: builtin/remote.c:1597 msgid "be verbose; must be placed before a subcommand" msgstr "chi tiαΊΏt; phαΊ£i Δược ΔαΊ·t trΖ°α»c mα»t lα»nh-con" @@ -10450,12 +10821,6 @@ msgstr "cho phΓ©p gα»‘ bα» Δα» qui" 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:317 -msgid "Please, stage your changes to .gitmodules or stash them to proceed" -msgstr "" -"Vui lΓ²ng ΔΖ°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:335 #, c-format msgid "not removing '%s' recursively without -r" @@ -10662,84 +11027,184 @@ msgstr "giα»― vΓ xΓ³a bα» mα»i dΓ²ng bαΊ―t ΔαΊ§u bαΊ±ng kΓ½ tα»± ghi chΓΊ" msgid "prepend comment character and space to each line" msgstr "treo trΖ°α»c kΓ½ tα»± ghi chΓΊ vΓ kΓ½ tα»± khoαΊ£ng trαΊ―ng cho tα»«ng dΓ²ng" -#: builtin/submodule--helper.c:73 builtin/submodule--helper.c:161 +#: builtin/submodule--helper.c:24 +#, c-format +msgid "No such ref: %s" +msgstr "KhΓ΄ng cΓ³ tham chiαΊΏu nΓ o nhΖ° thαΊΏ: %s" + +#: builtin/submodule--helper.c:31 +#, 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:71 +#, 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:278 builtin/submodule--helper.c:405 +#: builtin/submodule--helper.c:486 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:78 +#: builtin/submodule--helper.c:283 msgid "git submodule--helper list [--prefix=<path>] [<path>...]" -msgstr "git submodule--helper list [--prefix=<ΔΖ°α»ng/dαΊ«n>] [<ΔΖ°α»ng/dαΊ«n>β¦]" +msgstr "git submodule--helper list [--prefix=</ΔΖ°α»ng/dαΊ«n>] [</ΔΖ°α»ng/dαΊ«n>β¦]" -#: builtin/submodule--helper.c:108 +#: builtin/submodule--helper.c:326 builtin/submodule--helper.c:340 +#, 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:366 +#, 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:370 +#, 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:380 +#, 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:387 +#, 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:406 +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:411 +msgid "git submodule--helper init [<path>]" +msgstr "git submodule--helper init [</ΔΖ°α»ng/dαΊ«n>]" + +#: builtin/submodule--helper.c:432 msgid "git submodule--helper name <path>" -msgstr "git submodule--helper name <ΔΖ°α»ng/dαΊ«n>" +msgstr "git submodule--helper name </ΔΖ°α»ng/dαΊ«n>" -#: builtin/submodule--helper.c:114 +#: builtin/submodule--helper.c:438 #, 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 " "β%sβ" -#: builtin/submodule--helper.c:164 +#: builtin/submodule--helper.c:489 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:167 +#: builtin/submodule--helper.c:492 msgid "name of the new submodule" msgstr "tΓͺn của mΓ΄-Δun-con mα»i" -#: builtin/submodule--helper.c:170 +#: builtin/submodule--helper.c:495 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:176 +#: builtin/submodule--helper.c:501 msgid "depth for shallow clones" msgstr "chiα»u sΓ’u lα»ch sα» khi tαΊ‘o bαΊ£n sao" -#: builtin/submodule--helper.c:182 +#: builtin/submodule--helper.c:507 msgid "" "git submodule--helper clone [--prefix=<path>] [--quiet] [--reference " -"<repository>] [--name <name>] [--url <url>][--depth <depth>] [--] [<path>...]" +"<repository>] [--name <name>] [--depth <depth>] --url <url> --path <path>" msgstr "" -"git submodule--helper clone [--prefix=<ΔΖ°α»ng/dαΊ«n>] [--quiet] [--reference " -"<kho>] [--name <tΓͺn>] [--url <url>][--depth <ΔΖ°α»ng/dαΊ«n>] [--] [<ΔΖ°α»ng/dαΊ«n>β¦]" +"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:196 builtin/submodule--helper.c:202 -#: builtin/submodule--helper.c:210 +#: builtin/submodule--helper.c:532 builtin/submodule--helper.c:538 #, c-format msgid "could not create directory '%s'" msgstr "khΓ΄ng thα» tαΊ‘o thΖ° mα»₯c β%sβ" -#: builtin/submodule--helper.c:198 +#: builtin/submodule--helper.c:534 #, 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" -#: builtin/submodule--helper.c:221 +#: builtin/submodule--helper.c:550 #, c-format msgid "cannot open file '%s'" msgstr "khΓ΄ng thα» mα» tαΊp tin β%sβ" -#: builtin/submodule--helper.c:226 +#: builtin/submodule--helper.c:555 #, c-format msgid "could not close file %s" msgstr "khΓ΄ng thα» ΔΓ³ng tαΊp tin %s" -#: builtin/submodule--helper.c:241 +#: builtin/submodule--helper.c:562 #, 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:267 -msgid "fatal: submodule--helper subcommand must be called with a subcommand" +#: builtin/submodule--helper.c:609 +#, 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:613 +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:639 +#, 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:660 +#, c-format +msgid "Skipping submodule '%s'" +msgstr "Bα» qua mΓ΄-Δun-con β%sβ" + +#: builtin/submodule--helper.c:768 +msgid "path into the working tree" +msgstr "ΔΖ°α»ng dαΊ«n ΔαΊΏn cΓ’y lΓ m viα»c" + +#: builtin/submodule--helper.c:771 +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:775 +msgid "rebase, merge, checkout or none" +msgstr "rebase, merge, checkout hoαΊ·c khΓ΄ng lΓ m gΓ¬ cαΊ£" + +#: builtin/submodule--helper.c:779 +msgid "Create a shallow clone truncated to the specified number of revisions" msgstr "" -"lα»i nghiΓͺm trα»ng: lα»nh con submodule--helper phαΊ£i Δược gΓ³i vα»i mα»t lα»nh con" +"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:782 +msgid "parallel jobs" +msgstr "cΓ΄ng viα»c Δα»ng thα»i" + +#: builtin/submodule--helper.c:783 +msgid "don't print cloning progress" +msgstr "Δα»«ng in tiαΊΏn trΓ¬nh nhΓ’n bαΊ£n" + +#: builtin/submodule--helper.c:788 +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:798 +msgid "bad value for update parameter" +msgstr "giΓ‘ trα» cho tham sα» cαΊp nhαΊt bα» sai" + +#: builtin/submodule--helper.c:855 +msgid "submodule--helper subcommand must be called with a subcommand" +msgstr "lα»nh con submodule--helper phαΊ£i Δược gα»i vα»i mα»t lα»nh con" -#: builtin/submodule--helper.c:274 +#: builtin/submodule--helper.c:862 #, c-format -msgid "fatal: '%s' is not a valid submodule--helper subcommand" -msgstr "lα»i nghiΓͺm trα»ng: β%sβ khΓ΄ng phαΊ£i lΓ lα»nh con submodule--helper hợp lα»" +msgid "'%s' is not a valid submodule--helper subcommand" +msgstr "β%sβ khΓ΄ng phαΊ£i lΓ lα»nh con submodule--helper hợp lα»" #: builtin/symbolic-ref.c:7 msgid "git symbolic-ref [<options>] <name> [<ref>]" @@ -10794,27 +11259,22 @@ msgstr "" msgid "git tag -v <tagname>..." msgstr "git tag -v <tΓͺn-thαΊ»>β¦" -#: builtin/tag.c:80 +#: builtin/tag.c:81 #, c-format msgid "tag name too long: %.*s..." msgstr "tΓͺn thαΊ» quΓ‘ dΓ i: %.*sβ¦" -#: builtin/tag.c:85 +#: builtin/tag.c:86 #, c-format msgid "tag '%s' not found." msgstr "khΓ΄ng tΓ¬m thαΊ₯y tΓ¬m thαΊ₯y thαΊ» β%sβ." -#: builtin/tag.c:100 +#: builtin/tag.c:101 #, c-format msgid "Deleted tag '%s' (was %s)\n" msgstr "ThαΊ» ΔΓ£ bα» xΓ³a β%sβ (tα»«ng lΓ %s)\n" -#: builtin/tag.c:112 -#, c-format -msgid "could not verify the tag '%s'" -msgstr "khΓ΄ng thα» thαΊ©m tra thαΊ» β%sβ" - -#: builtin/tag.c:122 +#: builtin/tag.c:117 #, c-format msgid "" "\n" @@ -10827,7 +11287,7 @@ msgstr "" " %s\n" "Nhα»―ng dΓ²ng Δược bαΊ―t ΔαΊ§u bαΊ±ng β%cβ sαΊ½ Δược bα» qua.\n" -#: builtin/tag.c:126 +#: builtin/tag.c:121 #, c-format msgid "" "\n" @@ -10959,21 +11419,21 @@ msgstr "tΓΉy chα»n --merged vΓ --no-merged chα» cho phΓ©p dΓΉng vα»i -l." msgid "only one -F or -m option is allowed." msgstr "chα» cΓ³ mα»t tΓΉy chα»n -F hoαΊ·c -m lΓ Δược phΓ©p." -#: builtin/tag.c:453 +#: builtin/tag.c:452 msgid "too many params" msgstr "quΓ‘ nhiα»u Δα»i sα»" -#: builtin/tag.c:459 +#: builtin/tag.c:458 #, c-format msgid "'%s' is not a valid tag name." msgstr "β%sβ khΓ΄ng phαΊ£i thαΊ» hợp lα»." -#: builtin/tag.c:464 +#: builtin/tag.c:463 #, c-format msgid "tag '%s' already exists" msgstr "ThαΊ» β%sβ ΔΓ£ tα»n tαΊ‘i rα»i" -#: builtin/tag.c:489 +#: builtin/tag.c:491 #, c-format msgid "Updated tag '%s' (was %s)\n" msgstr "ΔΓ£ cαΊp nhαΊt thαΊ» β%sβ (trΖ°α»c lΓ %s)\n" @@ -11227,7 +11687,7 @@ msgstr "git verify-commit [-v | --verbose] <lαΊ§n_chuyα»n_giao>β¦" msgid "print commit contents" msgstr "hiα»n thα» nα»i dung của lαΊ§n chuyα»n giao" -#: builtin/verify-commit.c:73 builtin/verify-tag.c:84 +#: builtin/verify-commit.c:73 builtin/verify-tag.c:35 msgid "print raw gpg status output" msgstr "in kαΊΏt xuαΊ₯t trαΊ‘ng thΓ‘i gpg dαΊ‘ng thΓ΄" @@ -11247,7 +11707,7 @@ msgstr "chα» hiα»n thα» thα»ng kΓͺ" msgid "git verify-tag [-v | --verbose] <tag>..." msgstr "git verify-tag [-v | --verbose] <thαΊ»>β¦" -#: builtin/verify-tag.c:83 +#: builtin/verify-tag.c:34 msgid "print tag contents" msgstr "hiα»n thα» nα»i dung của thαΊ»" @@ -11263,68 +11723,72 @@ msgstr "git worktree prune [<cΓ‘c-tΓΉy-chα»n>]" msgid "git worktree list [<options>]" msgstr "git worktree list [<cΓ‘c-tΓΉy-chα»n>]" -#: builtin/worktree.c:39 +#: builtin/worktree.c:40 #, 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:45 +#: builtin/worktree.c:46 #, 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:50 +#: builtin/worktree.c:51 #, 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:61 +#: builtin/worktree.c:62 #, 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:77 +#: builtin/worktree.c:78 #, 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:112 +#: builtin/worktree.c:113 #, c-format -msgid "failed to remove: %s" -msgstr "gαΊ·p lα»i khi gα»‘ bα»: %s" +msgid "failed to remove '%s'" +msgstr "gαΊ·p lα»i khi gα»‘ bα» β%sβ" -#: builtin/worktree.c:201 +#: builtin/worktree.c:202 #, c-format msgid "'%s' already exists" msgstr "β%sβ ΔΓ£ cΓ³ tα»« trΖ°α»c rα»i" -#: builtin/worktree.c:233 +#: builtin/worktree.c:234 #, c-format msgid "could not create directory of '%s'" msgstr "khΓ΄ng thα» tαΊ‘o thΖ° mα»₯c của β%sβ" -#: builtin/worktree.c:269 +#: builtin/worktree.c:270 #, c-format msgid "Preparing %s (identifier %s)" msgstr "Δang chuαΊ©n bα» %s (Δα»nh danh %s)" -#: builtin/worktree.c:317 +#: builtin/worktree.c:322 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:319 +#: builtin/worktree.c:324 msgid "create a new branch" msgstr "tαΊ‘o nhΓ‘nh mα»i" -#: builtin/worktree.c:321 +#: builtin/worktree.c:326 msgid "create or reset a branch" msgstr "tαΊ‘o hay ΔαΊ·t lαΊ‘i mα»t nhΓ‘nh" -#: builtin/worktree.c:322 +#: builtin/worktree.c:327 msgid "detach HEAD at named commit" msgstr "rα»i bα» HEAD tαΊ‘i lαΊ§n chuyα»n giao theo tΓͺn" -#: builtin/worktree.c:329 +#: builtin/worktree.c:328 +msgid "populate the new working tree" +msgstr "di chuyα»n cΓ’y lΓ m viα»c mα»i" + +#: builtin/worktree.c:336 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" @@ -11344,7 +11808,7 @@ msgstr "ghi Δα»i tượng cΓ’y (tree) cho <tiα»n tα»> thΖ° mα»₯c con" msgid "only useful for debugging" msgstr "chα» hα»―u Γch khi cαΊ§n gα»‘ lα»i" -#: credential-cache--daemon.c:262 +#: credential-cache--daemon.c:271 msgid "print debugging messages to stderr" msgstr "in thΓ΄ng tin gα»‘ lα»i ra ΔαΊ§u ra lα»i tiΓͺu chuαΊ©n" @@ -11358,7 +11822,7 @@ 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α»." -#: http.c:321 +#: http.c:322 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" @@ -11488,7 +11952,7 @@ msgstr "im lαΊ·ng hΖ‘n nα»―a" msgid "use <n> digits to display SHA-1s" msgstr "sα» dα»₯ng <n> chα»― sα» Δα» hiα»n thα» SHA-1s" -#: rerere.h:38 +#: rerere.h:40 msgid "update the index with reused conflict resolution if possible" msgstr "cαΊp nhαΊt bαΊ£ng mα»₯c lα»₯c vα»i phΓ’n giαΊ£i xung Δα»t dΓΉng lαΊ‘i nαΊΏu Δược" @@ -11704,16 +12168,16 @@ msgstr "" "Δα» phα»₯c hα»i lαΊ‘i thΓ nh nhΓ‘nh nguyΓͺn thủy vΓ dα»«ng viα»c vΓ‘ lαΊ‘i thΓ¬ chαΊ‘y \"git " "rebase --abort\"." -#: git-rebase.sh:165 +#: git-rebase.sh:168 msgid "Applied autostash." msgstr "ΔΓ£ Γ‘p dα»₯ng autostash." -#: git-rebase.sh:168 +#: git-rebase.sh:171 #, sh-format msgid "Cannot store $stash_sha1" msgstr "KhΓ΄ng thα» lΖ°u $stash_sha1" -#: git-rebase.sh:169 +#: git-rebase.sh:172 msgid "" "Applying autostash resulted in conflicts.\n" "Your changes are safe in the stash.\n" @@ -11724,35 +12188,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" -#: git-rebase.sh:208 +#: git-rebase.sh:211 msgid "The pre-rebase hook refused to rebase." msgstr "MΓ³c (hook) pre-rebase tα»« chα»i rebase." -#: git-rebase.sh:213 +#: git-rebase.sh:216 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α» chαΊ‘y lα»nh " "rebase." -#: git-rebase.sh:354 -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" - -#: git-rebase.sh:359 +#: git-rebase.sh:357 msgid "No rebase in progress?" msgstr "KhΓ΄ng cΓ³ tiαΊΏn trΓ¬nh rebase nΓ o phαΊ£i khΓ΄ng?" -#: git-rebase.sh:370 +#: git-rebase.sh:368 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." -#: git-rebase.sh:377 +#: git-rebase.sh:375 msgid "Cannot read HEAD" msgstr "KhΓ΄ng thα» Δα»c HEAD" -#: git-rebase.sh:380 +#: git-rebase.sh:378 msgid "" "You must edit all merge conflicts and then\n" "mark them as resolved using git add" @@ -11760,12 +12220,12 @@ 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" -#: git-rebase.sh:398 +#: git-rebase.sh:396 #, sh-format msgid "Could not move back to $head_name" msgstr "KhΓ΄ng thα» quay trα» lαΊ‘i $head_name" -#: git-rebase.sh:417 +#: git-rebase.sh:415 #, sh-format msgid "" "It seems that there is already a $state_dir_base directory, and\n" @@ -11786,64 +12246,64 @@ 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-rebase.sh:468 +#: git-rebase.sh:466 #, sh-format msgid "invalid upstream $upstream_name" msgstr "thượng nguα»n khΓ΄ng hợp lα» $upstream_name" -#: git-rebase.sh:492 +#: git-rebase.sh:490 #, 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-rebase.sh:495 git-rebase.sh:499 +#: git-rebase.sh:493 git-rebase.sh:497 #, 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-rebase.sh:504 +#: git-rebase.sh:502 #, 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-rebase.sh:527 +#: git-rebase.sh:525 #, sh-format msgid "fatal: no such branch: $branch_name" msgstr "nghiΓͺm trα»ng: khΓ΄ng cΓ³ nhΓ‘nh nhΖ° thαΊΏ: $branch_name" -#: git-rebase.sh:560 +#: git-rebase.sh:558 msgid "Cannot autostash" msgstr "KhΓ΄ng thα» autostash" -#: git-rebase.sh:565 +#: git-rebase.sh:563 #, sh-format msgid "Created autostash: $stash_abbrev" msgstr "ΔΓ£ tαΊ‘o autostash: $stash_abbrev" -#: git-rebase.sh:569 +#: git-rebase.sh:567 msgid "Please commit or stash them." msgstr "Xin hΓ£y chuyα»n giao hoαΊ·c tαΊ‘m cαΊ₯t (stash) chΓΊng." -#: git-rebase.sh:589 +#: git-rebase.sh:587 #, 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-rebase.sh:593 +#: git-rebase.sh:591 #, 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-rebase.sh:604 +#: git-rebase.sh:602 #, sh-format msgid "Changes from $mb to $onto:" msgstr "Thay Δα»i tα»« $mb thΓ nh $onto:" -#: git-rebase.sh:613 +#: git-rebase.sh:611 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-rebase.sh:623 +#: git-rebase.sh:621 #, sh-format msgid "Fast-forwarded $branch_name to $onto_name." msgstr "Chuyα»n-tiαΊΏp-nhanh $branch_name thΓ nh $onto_name." @@ -11989,29 +12449,24 @@ msgstr "ChΖ°a chα» ra tΓͺn của nhΓ‘nh" msgid "(To restore them type \"git stash apply\")" msgstr "(Δα» phα»₯c hα»i lαΊ‘i chΓΊng hΓ£y gΓ΅ \"git stash apply\")" -#: git-submodule.sh:104 -#, sh-format -msgid "cannot strip one component off url '$remoteurl'" -msgstr "khΓ΄ng thα» thΓ‘o bα» mα»t thΓ nh phαΊ§n ra khα»i β$remoteurlβ url" - -#: git-submodule.sh:281 +#: git-submodule.sh:219 msgid "Relative path can only be used from the toplevel of the working tree" msgstr "" "ΔΖ°α»ng dαΊ«n tΖ°Ζ‘ng Δα»i chα» cΓ³ thα» dΓΉng tα»« thΖ° mα»₯c α» mα»©c cao nhαΊ₯t của cΓ’y lΓ m " "viα»c" -#: git-submodule.sh:291 +#: git-submodule.sh:229 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "" "repo URL: β$repoβ phαΊ£i lΓ ΔΖ°α»ng dαΊ«n tuyα»t Δα»i hoαΊ·c lΓ bαΊ―t ΔαΊ§u bαΊ±ng ./|../" -#: git-submodule.sh:308 +#: git-submodule.sh:246 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "β$sm_pathβ thα»±c sα»± ΔΓ£ tα»n tαΊ‘i α» bαΊ£ng mα»₯c lα»₯c rα»i" -#: git-submodule.sh:312 +#: git-submodule.sh:250 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -12023,36 +12478,36 @@ msgstr "" "$sm_path\n" "Sα» dα»₯ng -f nαΊΏu bαΊ‘n thα»±c sα»± muα»n thΓͺm nΓ³ vΓ o." -#: git-submodule.sh:330 +#: git-submodule.sh:268 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "Δang thΓͺm repo cΓ³ sαΊ΅n tαΊ‘i β$sm_pathβ vΓ o bαΊ£ng mα»₯c lα»₯c" -#: git-submodule.sh:332 +#: git-submodule.sh:270 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "β$sm_pathβ ΔΓ£ tα»n tαΊ‘i tα»« trΖ°α»c vΓ khΓ΄ng phαΊ£i lΓ mα»t kho git hợp lα»" -#: git-submodule.sh:340 +#: git-submodule.sh:278 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "" "ThΖ° mα»₯c git cho β$sm_nameβ Δược tΓ¬m thαΊ₯y mα»t cΓ‘ch cα»₯c bα» vα»i cΓ‘c mΓ‘y chủ:" -#: git-submodule.sh:342 +#: git-submodule.sh:280 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" msgstr "NαΊΏu bαΊ‘n muα»n dΓΉng lαΊ‘i thΖ° mα»₯c git nα»i bα» nΓ y thay vΓ¬ nhΓ’n bαΊ£n tα»« nΓ³" -#: git-submodule.sh:344 +#: git-submodule.sh:282 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" msgstr "" "dΓΉng tΓΉy chα»n β--forceβ. NαΊΏu thΖ° mα»₯c git nα»i bα» khΓ΄ng phαΊ£i lΓ repo (kho) ΔΓΊng" -#: git-submodule.sh:345 +#: git-submodule.sh:283 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " @@ -12061,71 +12516,53 @@ msgstr "" "hay bαΊ‘n khΓ΄ng chαΊ―c chαΊ―n Δiα»u ΔΓ³ cΓ³ nghΔ©a gΓ¬ chα»n tΓͺn khΓ‘c vα»i tΓΉy chα»n β--" "nameβ." -#: git-submodule.sh:347 +#: git-submodule.sh:285 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "" "Phα»₯c hα»i sα»± hoαΊ‘t Δα»ng của thΖ° mα»₯c git nα»i bα» cho mΓ΄-Δun-con β$sm_nameβ." -#: git-submodule.sh:359 +#: git-submodule.sh:297 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "KhΓ΄ng thα» lαΊ₯y ra mΓ΄-Δun-con β$sm_pathβ" -#: git-submodule.sh:364 +#: git-submodule.sh:302 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "GαΊ·p lα»i khi thΓͺm mΓ΄-Δun-con β$sm_pathβ" -#: git-submodule.sh:373 +#: git-submodule.sh:311 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "GαΊ·p lα»i khi ΔΔng kΓ½ vα»i hα» thα»ng mΓ΄-Δun-con β$sm_pathβ" -#: git-submodule.sh:417 -#, sh-format -msgid "Entering '$prefix$displaypath'" -msgstr "Δang vΓ o β$prefix$displaypathβ" - -#: git-submodule.sh:437 -#, sh-format -msgid "Stopping at '$prefix$displaypath'; script returned non-zero status." -msgstr "" -"Dα»«ng lαΊ‘i tαΊ‘i β$prefix$displaypathβ; script trαΊ£ vα» trαΊ‘ng thΓ‘i khΓ‘c khΓ΄ng." - -#: git-submodule.sh:483 +#: git-submodule.sh:355 #, sh-format -msgid "No url found for submodule path '$displaypath' in .gitmodules" -msgstr "" -"KhΓ΄ng tΓ¬m thαΊ₯y url cho ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ trong .gitmodules" +msgid "Entering '$displaypath'" +msgstr "Δang vΓ o β$displaypathβ" -#: git-submodule.sh:492 +#: git-submodule.sh:375 #, sh-format -msgid "Failed to register url for submodule path '$displaypath'" -msgstr "GαΊ·p lα»i khi ΔΔng kΓ½ url cho ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" +msgid "Stopping at '$displaypath'; script returned non-zero status." +msgstr "Dα»«ng lαΊ‘i tαΊ‘i β$displaypathβ; script trαΊ£ vα» trαΊ‘ng thΓ‘i khΓ‘c khΓ΄ng." -#: git-submodule.sh:494 +#: git-submodule.sh:448 #, sh-format -msgid "Submodule '$name' ($url) registered for path '$displaypath'" -msgstr "MΓ΄-Δun-con β$nameβ ($url) Δược ΔΔng kΓ½ cho ΔΖ°α»ng dαΊ«n β$displaypathβ" - -#: git-submodule.sh:511 -#, sh-format -msgid "Failed to register update mode for submodule path '$displaypath'" -msgstr "" -"GαΊ·p lα»i khi ΔΔng kΓ½ chαΊΏ Δα» cαΊp nhαΊt cho ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" +msgid "pathspec and --all are incompatible" +msgstr "ΔαΊ·c tαΊ£ ΔΖ°α»ng dαΊ«n vΓ --all xung khαΊ―c nhau" -#: git-submodule.sh:549 +#: git-submodule.sh:453 #, sh-format -msgid "Use '.' if you really want to deinitialize all submodules" -msgstr "DΓΉng β.β nαΊΏu bαΊ‘n thα»±c sα»± muα»n gα»‘ bα» mα»i mΓ΄-Δun-con" +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" -#: git-submodule.sh:566 +#: git-submodule.sh:470 #, sh-format msgid "Submodule work tree '$displaypath' contains a .git directory" msgstr "CΓ’y lΓ m viα»c mΓ΄-Δun-con β$displaypathβ cΓ³ chα»©a thΖ° mα»₯c .git" -#: git-submodule.sh:567 +#: git-submodule.sh:471 #, sh-format msgid "" "(use 'rm -rf' if you really want to remove it including all of its history)" @@ -12133,7 +12570,7 @@ msgstr "" "(dΓΉng βrm -rfβ nαΊΏu bαΊ‘n thα»±c sα»± muα»n gα»‘ bα» nΓ³ cΓΉng vα»i tαΊ₯t cαΊ£ lα»ch sα» của " "chΓΊng)" -#: git-submodule.sh:573 +#: git-submodule.sh:477 #, sh-format msgid "" "Submodule work tree '$displaypath' contains local modifications; use '-f' to " @@ -12142,141 +12579,178 @@ msgstr "" "CΓ’y lΓ m viα»c mΓ΄-Δun-con β$displaypathβ chα»©a cΓ‘c thay Δα»i nα»i bα»; hΓ£y dΓΉng β-" "fβ Δα» loαΊ‘i bα» chΓΊng Δi" -#: git-submodule.sh:576 +#: git-submodule.sh:480 #, sh-format msgid "Cleared directory '$displaypath'" msgstr "ΔΓ£ tαΊ‘o thΖ° mα»₯c β$displaypathβ" -#: git-submodule.sh:577 +#: git-submodule.sh:481 #, sh-format msgid "Could not remove submodule work tree '$displaypath'" msgstr "KhΓ΄ng thα» gα»‘ bα» cΓ’y lΓ m viα»c mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:580 +#: git-submodule.sh:484 #, sh-format msgid "Could not create empty submodule directory '$displaypath'" msgstr "KhΓ΄ng thα» tαΊ‘o thΖ° mα»₯c mΓ΄-Δun-con rα»ng β$displaypathβ" -#: git-submodule.sh:589 +#: git-submodule.sh:493 #, sh-format msgid "Submodule '$name' ($url) unregistered for path '$displaypath'" msgstr "MΓ΄-Δun-con β$nameβ ($url) Δược bα» ΔΔng kΓ½ cho ΔΖ°α»ng dαΊ«n β$displaypathβ" -#: git-submodule.sh:723 -#, sh-format -msgid "" -"Submodule path '$displaypath' not initialized\n" -"Maybe you want to use 'update --init'?" -msgstr "" -"ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ chΖ°a Δược khα»i tαΊ‘o.\n" -"CΓ³ lαΊ½ bαΊ‘n muα»n sα» dα»₯ng lα»nh βupdate --initβ?" - -#: git-submodule.sh:736 +#: git-submodule.sh:635 #, sh-format msgid "Unable to find current revision in submodule path '$displaypath'" msgstr "" "KhΓ΄ng tΓ¬m thαΊ₯y Δiα»m xΓ©t duyα»t hiα»n hΓ nh trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con " "β$displaypathβ" -#: git-submodule.sh:745 +#: git-submodule.sh:644 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "KhΓ΄ng thα» lαΊ₯y vα» trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$sm_pathβ" -#: git-submodule.sh:768 +#: git-submodule.sh:667 #, sh-format msgid "Unable to fetch in submodule path '$displaypath'" msgstr "KhΓ΄ng thα» lαΊ₯y vα» trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:788 +#: git-submodule.sh:680 #, sh-format msgid "Unable to checkout '$sha1' in submodule path '$displaypath'" msgstr "KhΓ΄ng thα» lαΊ₯y ra β$sha1β trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:789 +#: git-submodule.sh:681 #, sh-format msgid "Submodule path '$displaypath': checked out '$sha1'" msgstr "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ: ΔΓ£ checkout β$sha1β" -#: git-submodule.sh:793 +#: git-submodule.sh:685 #, sh-format msgid "Unable to rebase '$sha1' in submodule path '$displaypath'" msgstr "KhΓ΄ng thα» cαΊ£i tα» β$sha1β trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:794 +#: git-submodule.sh:686 #, sh-format msgid "Submodule path '$displaypath': rebased into '$sha1'" msgstr "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ: Δược rebase vΓ o trong β$sha1β" -#: git-submodule.sh:799 +#: git-submodule.sh:691 #, sh-format msgid "Unable to merge '$sha1' in submodule path '$displaypath'" msgstr "" "KhΓ΄ng thα» hΓ²a trα»n (merge) β$sha1β trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:800 +#: git-submodule.sh:692 #, sh-format msgid "Submodule path '$displaypath': merged in '$sha1'" msgstr "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ: Δược hΓ²a trα»n vΓ o β$sha1β" -#: git-submodule.sh:805 +#: git-submodule.sh:697 #, sh-format -msgid "" -"Execution of '$command $sha1' failed in submodule path '$prefix$sm_path'" +msgid "Execution of '$command $sha1' failed in submodule path '$displaypath'" msgstr "" "Thα»±c hiα»n khΓ΄ng thΓ nh cΓ΄ng lα»nh β$command $sha1β trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con " -"β$prefix$sm_pathβ" +"β$displaypathβ" -#: git-submodule.sh:806 +#: git-submodule.sh:698 #, sh-format -msgid "Submodule path '$prefix$sm_path': '$command $sha1'" -msgstr "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$prefix$sm_pathβ: β$command $sha1β" +msgid "Submodule path '$displaypath': '$command $sha1'" +msgstr "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ: β$command $sha1β" -#: git-submodule.sh:836 +#: git-submodule.sh:729 #, sh-format msgid "Failed to recurse into submodule path '$displaypath'" msgstr "GαΊ·p lα»i khi Δα» quy vΓ o trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ" -#: git-submodule.sh:944 +#: git-submodule.sh:837 msgid "The --cached option cannot be used with the --files option" msgstr "TΓΉy chα»n --cached khΓ΄ng thα» dΓΉng cΓΉng vα»i tΓΉy chα»n --files" -#: git-submodule.sh:996 +#: git-submodule.sh:889 #, sh-format msgid "unexpected mode $mod_dst" msgstr "chαΊΏ Δα» khΓ΄ng nhΖ° mong chα» $mod_dst" -#: git-submodule.sh:1016 +#: git-submodule.sh:909 #, sh-format msgid " Warn: $display_name doesn't contain commit $sha1_src" msgstr " CαΊ£nh bΓ‘o: $display_name khΓ΄ng chα»©a lαΊ§n chuyα»n giao $sha1_src" -#: git-submodule.sh:1019 +#: git-submodule.sh:912 #, sh-format msgid " Warn: $display_name doesn't contain commit $sha1_dst" msgstr " CαΊ£nh bΓ‘o: $display_name khΓ΄ng chα»©a lαΊ§n chuyα»n giao $sha1_dst" -#: git-submodule.sh:1022 +#: git-submodule.sh:915 #, sh-format msgid " Warn: $display_name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" " CαΊ£nh bΓ‘o: $display_name khΓ΄ng chα»©a nhα»―ng lαΊ§n chuyα»n giao $sha1_src vΓ " "$sha1_dst" -#: git-submodule.sh:1047 +#: git-submodule.sh:940 msgid "blob" msgstr "blob" -#: git-submodule.sh:1165 +#: git-submodule.sh:1059 #, sh-format msgid "Failed to recurse into submodule path '$sm_path'" msgstr "GαΊ·p lα»i khi Δα» quy vΓ o trong ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$sm_pathβ" -#: git-submodule.sh:1229 +#: git-submodule.sh:1123 #, sh-format msgid "Synchronizing submodule url for '$displaypath'" msgstr "Url MΓ΄-Δun-con Δα»ng bα» hΓ³a cho β$displaypathβ" +#: git-parse-remote.sh:89 +#, sh-format +msgid "See git-${cmd}(1) for details." +msgstr "Xem git-${cmd}(1) Δα» biαΊΏt thΓͺm chi tiαΊΏt." + +#~ msgid "'%s': %s" +#~ msgstr "β%sβ: %s" + +#~ msgid "unable to access '%s': %s" +#~ msgstr "khΓ΄ng thα» truy cαΊp β%sβ: %s" + +#~ msgid "could not open '%s' for reading: %s" +#~ msgstr "khΓ΄ng thα» mα» β%sβ Δα» Δα»c: %s" + +#~ msgid "could not open '%s' for writing: %s" +#~ msgstr "KhΓ΄ng thα» mα» β%sβ Δα» ghi: %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 "khΓ΄ng thα» mα» %s: %s\n" + +#~ msgid "Please, stage your changes to .gitmodules or stash them to proceed" +#~ msgstr "" +#~ "Vui lΓ²ng ΔΖ°a cΓ‘c thay Δα»i của bαΊ‘n vΓ o β.gitmodulesβ hay tαΊ‘m cαΊ₯t chΓΊng Δi " +#~ "Δα» xα» lΓ½" + +#~ msgid "could not verify the tag '%s'" +#~ msgstr "khΓ΄ng thα» thαΊ©m tra thαΊ» β%sβ" + +#~ 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'?" +#~ msgstr "" +#~ "ΔΖ°α»ng dαΊ«n mΓ΄-Δun-con β$displaypathβ chΖ°a Δược khα»i tαΊ‘o.\n" +#~ "CΓ³ lαΊ½ bαΊ‘n muα»n sα» dα»₯ng lα»nh βupdate --initβ?" + #~ msgid "Forward-port local commits to the updated upstream head" #~ msgstr "" #~ "Chuyα»n tiαΊΏp nhα»―ng lαΊ§n chuyα»n giao nα»i bα» tα»i head thượng nguα»n ΔΓ£ cαΊp nhαΊt" @@ -12339,9 +12813,6 @@ msgstr "Url MΓ΄-Δun-con Δα»ng bα» hΓ³a cho β$displaypathβ" #~ msgid "Could not append '%s'" #~ msgstr "KhΓ΄ng thα» nα»i thΓͺm β%sβ" -#~ msgid "Could not set '%s'" -#~ msgstr "KhΓ΄ng thα» ΔαΊ·t β%sβ" - #~ msgid "unable to look up current user in the passwd file: %s" #~ msgstr "khΓ΄ng tΓ¬m thαΊ₯y ngΖ°α»i dΓΉng hiα»n tαΊ‘i trong tαΊp tin passwd: %s" @@ -12689,13 +13160,6 @@ msgstr "Url MΓ΄-Δun-con Δα»ng bα» hΓ³a cho β$displaypathβ" #~ msgstr "cΓ‘c ΔΖ°α»ng dαΊ«n Δược ngΔn cΓ‘ch bα»i kΓ½ tα»± null" #~ msgid "" -#~ "The following untracked files would NOT be saved but need to be removed " -#~ "by stash save:" -#~ msgstr "" -#~ "CΓ‘c tαΊp tin chΖ°a Δược theo dΓ΅i sau ΔΓ’y KHΓNG Δược ghi lαΊ‘i nhΖ°ng cαΊ§n Δược " -#~ "gα»‘ bα» bα»i viα»c ghi lαΊ‘i stash:" - -#~ msgid "" #~ "Aborting. Consider using either the --force or --include-untracked option." #~ msgstr "" #~ "BΓ£i bα». CΓ’n nhαΊ―c dΓΉng mα»t trong hai tΓΉy chα»n --force vΓ --include-" diff --git a/reachable.c b/reachable.c index ed35201896..d0199cace4 100644 --- a/reachable.c +++ b/reachable.c @@ -119,8 +119,7 @@ static int add_recent_loose(const unsigned char *sha1, */ if (errno == ENOENT) return 0; - return error("unable to stat %s: %s", - sha1_to_hex(sha1), strerror(errno)); + return error_errno("unable to stat %s", sha1_to_hex(sha1)); } add_recent_object(sha1, st.st_mtime, data); @@ -1080,3 +1080,152 @@ int rename_ref_available(const char *oldname, const char *newname) strbuf_release(&err); return ret; } + +int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + struct object_id oid; + int flag; + + if (submodule) { + if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0) + return fn("HEAD", &oid, 0, cb_data); + + return 0; + } + + if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag)) + return fn("HEAD", &oid, flag, cb_data); + + return 0; +} + +int head_ref(each_ref_fn fn, void *cb_data) +{ + return head_ref_submodule(NULL, fn, cb_data); +} + +int for_each_ref(each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(NULL, "", fn, 0, 0, cb_data); +} + +int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(submodule, "", fn, 0, 0, cb_data); +} + +int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(NULL, prefix, fn, strlen(prefix), 0, cb_data); +} + +int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken) +{ + unsigned int flag = 0; + + if (broken) + flag = DO_FOR_EACH_INCLUDE_BROKEN; + return do_for_each_ref(NULL, prefix, fn, 0, flag, cb_data); +} + +int for_each_ref_in_submodule(const char *submodule, const char *prefix, + each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(submodule, prefix, fn, strlen(prefix), 0, cb_data); +} + +int for_each_replace_ref(each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(NULL, git_replace_ref_base, fn, + strlen(git_replace_ref_base), 0, cb_data); +} + +int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) +{ + struct strbuf buf = STRBUF_INIT; + int ret; + strbuf_addf(&buf, "%srefs/", get_git_namespace()); + ret = do_for_each_ref(NULL, buf.buf, fn, 0, 0, cb_data); + strbuf_release(&buf); + return ret; +} + +int for_each_rawref(each_ref_fn fn, void *cb_data) +{ + return do_for_each_ref(NULL, "", fn, 0, + DO_FOR_EACH_INCLUDE_BROKEN, cb_data); +} + +/* This function needs to return a meaningful errno on failure */ +const char *resolve_ref_unsafe(const char *refname, int resolve_flags, + unsigned char *sha1, int *flags) +{ + static struct strbuf sb_refname = STRBUF_INIT; + int unused_flags; + int symref_count; + + if (!flags) + flags = &unused_flags; + + *flags = 0; + + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || + !refname_is_safe(refname)) { + errno = EINVAL; + return NULL; + } + + /* + * dwim_ref() uses REF_ISBROKEN to distinguish between + * missing refs and refs that were present but invalid, + * to complain about the latter to stderr. + * + * We don't know whether the ref exists, so don't set + * REF_ISBROKEN yet. + */ + *flags |= REF_BAD_NAME; + } + + for (symref_count = 0; symref_count < SYMREF_MAXDEPTH; symref_count++) { + unsigned int read_flags = 0; + + if (read_raw_ref(refname, sha1, &sb_refname, &read_flags)) { + *flags |= read_flags; + if (errno != ENOENT || (resolve_flags & RESOLVE_REF_READING)) + return NULL; + hashclr(sha1); + if (*flags & REF_BAD_NAME) + *flags |= REF_ISBROKEN; + return refname; + } + + *flags |= read_flags; + + if (!(read_flags & REF_ISSYMREF)) { + if (*flags & REF_BAD_NAME) { + hashclr(sha1); + *flags |= REF_ISBROKEN; + } + return refname; + } + + refname = sb_refname.buf; + if (resolve_flags & RESOLVE_REF_NO_RECURSE) { + hashclr(sha1); + return refname; + } + if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { + if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || + !refname_is_safe(refname)) { + errno = EINVAL; + return NULL; + } + + *flags |= REF_ISBROKEN | REF_BAD_NAME; + } + } + + errno = ELOOP; + return NULL; +} diff --git a/refs/files-backend.c b/refs/files-backend.c index ea78ce9d90..1f38076411 100644 --- a/refs/files-backend.c +++ b/refs/files-backend.c @@ -513,9 +513,6 @@ static void sort_ref_dir(struct ref_dir *dir) dir->sorted = dir->nr = i; } -/* Include broken references in a do_for_each_ref*() iteration: */ -#define DO_FOR_EACH_INCLUDE_BROKEN 0x01 - /* * Return true iff the reference described by entry can be resolved to * an object in the database. Emit a warning if the referred-to @@ -1272,8 +1269,6 @@ static struct ref_dir *get_loose_refs(struct ref_cache *refs) return get_ref_dir(refs->loose); } -/* We allow "recursive" symbolic refs. Only within reason, though */ -#define MAXDEPTH 5 #define MAXREFLEN (1024) /* @@ -1303,7 +1298,7 @@ static int resolve_gitlink_ref_recursive(struct ref_cache *refs, char buffer[128], *p; char *path; - if (recursion > MAXDEPTH || strlen(refname) > MAXREFLEN) + if (recursion > SYMREF_MAXDEPTH || strlen(refname) > MAXREFLEN) return -1; path = *refs->name ? git_pathdup_submodule(refs->name, "%s", refname) @@ -1371,13 +1366,11 @@ static struct ref_entry *get_packed_ref(const char *refname) } /* - * A loose ref file doesn't exist; check for a packed ref. The - * options are forwarded from resolve_safe_unsafe(). + * A loose ref file doesn't exist; check for a packed ref. */ static int resolve_missing_loose_ref(const char *refname, - int resolve_flags, unsigned char *sha1, - int *flags) + unsigned int *flags) { struct ref_entry *entry; @@ -1388,205 +1381,158 @@ static int resolve_missing_loose_ref(const char *refname, entry = get_packed_ref(refname); if (entry) { hashcpy(sha1, entry->u.value.oid.hash); - if (flags) - *flags |= REF_ISPACKED; - return 0; - } - /* The reference is not a packed reference, either. */ - if (resolve_flags & RESOLVE_REF_READING) { - errno = ENOENT; - return -1; - } else { - hashclr(sha1); + *flags |= REF_ISPACKED; return 0; } + /* refname is not a packed reference. */ + return -1; } -/* This function needs to return a meaningful errno on failure */ -static const char *resolve_ref_1(const char *refname, - int resolve_flags, - unsigned char *sha1, - int *flags, - struct strbuf *sb_refname, - struct strbuf *sb_path, - struct strbuf *sb_contents) +/* + * Read a raw ref from the filesystem or packed refs file. + * + * If the ref is a sha1, fill in sha1 and return 0. + * + * If the ref is symbolic, fill in *symref with the referrent + * (e.g. "refs/heads/master") and return 0. The caller is responsible + * for validating the referrent. Set REF_ISSYMREF in flags. + * + * If the ref doesn't exist, set errno to ENOENT and return -1. + * + * If the ref exists but is neither a symbolic ref nor a sha1, it is + * broken. Set REF_ISBROKEN in flags, set errno to EINVAL, and return + * -1. + * + * If there is another error reading the ref, set errno appropriately and + * return -1. + * + * Backend-specific flags might be set in flags as well, regardless of + * outcome. + * + * sb_path is workspace: the caller should allocate and free it. + * + * It is OK for refname to point into symref. In this case: + * - if the function succeeds with REF_ISSYMREF, symref will be + * overwritten and the memory pointed to by refname might be changed + * or even freed. + * - in all other cases, symref will be untouched, and therefore + * refname will still be valid and unchanged. + */ +int read_raw_ref(const char *refname, unsigned char *sha1, + struct strbuf *symref, unsigned int *flags) { - int depth = MAXDEPTH; - int bad_name = 0; + struct strbuf sb_contents = STRBUF_INIT; + struct strbuf sb_path = STRBUF_INIT; + const char *path; + const char *buf; + struct stat st; + int fd; + int ret = -1; + int save_errno; - if (flags) - *flags = 0; + strbuf_reset(&sb_path); + strbuf_git_path(&sb_path, "%s", refname); + path = sb_path.buf; - if (check_refname_format(refname, REFNAME_ALLOW_ONELEVEL)) { - if (flags) - *flags |= REF_BAD_NAME; +stat_ref: + /* + * We might have to loop back here to avoid a race + * condition: first we lstat() the file, then we try + * to read it as a link or as a file. But if somebody + * changes the type of the file (file <-> directory + * <-> symlink) between the lstat() and reading, then + * we don't want to report that as an error but rather + * try again starting with the lstat(). + */ - if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || - !refname_is_safe(refname)) { - errno = EINVAL; - return NULL; + if (lstat(path, &st) < 0) { + if (errno != ENOENT) + goto out; + if (resolve_missing_loose_ref(refname, sha1, flags)) { + errno = ENOENT; + goto out; } - /* - * dwim_ref() uses REF_ISBROKEN to distinguish between - * missing refs and refs that were present but invalid, - * to complain about the latter to stderr. - * - * We don't know whether the ref exists, so don't set - * REF_ISBROKEN yet. - */ - bad_name = 1; + ret = 0; + goto out; } - for (;;) { - const char *path; - struct stat st; - char *buf; - int fd; - - if (--depth < 0) { - errno = ELOOP; - return NULL; - } - - strbuf_reset(sb_path); - strbuf_git_path(sb_path, "%s", refname); - path = sb_path->buf; - - /* - * We might have to loop back here to avoid a race - * condition: first we lstat() the file, then we try - * to read it as a link or as a file. But if somebody - * changes the type of the file (file <-> directory - * <-> symlink) between the lstat() and reading, then - * we don't want to report that as an error but rather - * try again starting with the lstat(). - */ - stat_ref: - if (lstat(path, &st) < 0) { - if (errno != ENOENT) - return NULL; - if (resolve_missing_loose_ref(refname, resolve_flags, - sha1, flags)) - return NULL; - if (bad_name) { - hashclr(sha1); - if (flags) - *flags |= REF_ISBROKEN; - } - return refname; - } - - /* Follow "normalized" - ie "refs/.." symlinks by hand */ - if (S_ISLNK(st.st_mode)) { - strbuf_reset(sb_contents); - if (strbuf_readlink(sb_contents, path, 0) < 0) { - if (errno == ENOENT || errno == EINVAL) - /* inconsistent with lstat; retry */ - goto stat_ref; - else - return NULL; - } - if (starts_with(sb_contents->buf, "refs/") && - !check_refname_format(sb_contents->buf, 0)) { - strbuf_swap(sb_refname, sb_contents); - refname = sb_refname->buf; - if (flags) - *flags |= REF_ISSYMREF; - if (resolve_flags & RESOLVE_REF_NO_RECURSE) { - hashclr(sha1); - return refname; - } - continue; - } - } - /* Is it a directory? */ - if (S_ISDIR(st.st_mode)) { - errno = EISDIR; - return NULL; - } - - /* - * Anything else, just open it and try to use it as - * a ref - */ - fd = open(path, O_RDONLY); - if (fd < 0) { - if (errno == ENOENT) + /* Follow "normalized" - ie "refs/.." symlinks by hand */ + if (S_ISLNK(st.st_mode)) { + strbuf_reset(&sb_contents); + if (strbuf_readlink(&sb_contents, path, 0) < 0) { + if (errno == ENOENT || errno == EINVAL) /* inconsistent with lstat; retry */ goto stat_ref; else - return NULL; + goto out; } - strbuf_reset(sb_contents); - if (strbuf_read(sb_contents, fd, 256) < 0) { - int save_errno = errno; - close(fd); - errno = save_errno; - return NULL; + if (starts_with(sb_contents.buf, "refs/") && + !check_refname_format(sb_contents.buf, 0)) { + strbuf_swap(&sb_contents, symref); + *flags |= REF_ISSYMREF; + ret = 0; + goto out; } - close(fd); - strbuf_rtrim(sb_contents); + } - /* - * Is it a symbolic ref? - */ - if (!starts_with(sb_contents->buf, "ref:")) { - /* - * Please note that FETCH_HEAD has a second - * line containing other data. - */ - if (get_sha1_hex(sb_contents->buf, sha1) || - (sb_contents->buf[40] != '\0' && !isspace(sb_contents->buf[40]))) { - if (flags) - *flags |= REF_ISBROKEN; - errno = EINVAL; - return NULL; - } - if (bad_name) { - hashclr(sha1); - if (flags) - *flags |= REF_ISBROKEN; - } - return refname; - } - if (flags) - *flags |= REF_ISSYMREF; - buf = sb_contents->buf + 4; + /* Is it a directory? */ + if (S_ISDIR(st.st_mode)) { + errno = EISDIR; + goto out; + } + + /* + * Anything else, just open it and try to use it as + * a ref + */ + fd = open(path, O_RDONLY); + if (fd < 0) { + if (errno == ENOENT) + /* inconsistent with lstat; retry */ + goto stat_ref; + else + goto out; + } + strbuf_reset(&sb_contents); + if (strbuf_read(&sb_contents, fd, 256) < 0) { + int save_errno = errno; + close(fd); + errno = save_errno; + goto out; + } + close(fd); + strbuf_rtrim(&sb_contents); + buf = sb_contents.buf; + if (starts_with(buf, "ref:")) { + buf += 4; while (isspace(*buf)) buf++; - strbuf_reset(sb_refname); - strbuf_addstr(sb_refname, buf); - refname = sb_refname->buf; - if (resolve_flags & RESOLVE_REF_NO_RECURSE) { - hashclr(sha1); - return refname; - } - if (check_refname_format(buf, REFNAME_ALLOW_ONELEVEL)) { - if (flags) - *flags |= REF_ISBROKEN; - - if (!(resolve_flags & RESOLVE_REF_ALLOW_BAD_NAME) || - !refname_is_safe(buf)) { - errno = EINVAL; - return NULL; - } - bad_name = 1; - } + + strbuf_reset(symref); + strbuf_addstr(symref, buf); + *flags |= REF_ISSYMREF; + ret = 0; + goto out; } -} -const char *resolve_ref_unsafe(const char *refname, int resolve_flags, - unsigned char *sha1, int *flags) -{ - static struct strbuf sb_refname = STRBUF_INIT; - struct strbuf sb_contents = STRBUF_INIT; - struct strbuf sb_path = STRBUF_INIT; - const char *ret; + /* + * Please note that FETCH_HEAD has additional + * data after the sha. + */ + if (get_sha1_hex(buf, sha1) || + (buf[40] != '\0' && !isspace(buf[40]))) { + *flags |= REF_ISBROKEN; + errno = EINVAL; + goto out; + } + + ret = 0; - ret = resolve_ref_1(refname, resolve_flags, sha1, flags, - &sb_refname, &sb_path, &sb_contents); +out: + save_errno = errno; strbuf_release(&sb_path); strbuf_release(&sb_contents); + errno = save_errno; return ret; } @@ -1727,10 +1673,13 @@ static int do_for_each_entry(struct ref_cache *refs, const char *base, * value, stop the iteration and return that value; otherwise, return * 0. */ -static int do_for_each_ref(struct ref_cache *refs, const char *base, - each_ref_fn fn, int trim, int flags, void *cb_data) +int do_for_each_ref(const char *submodule, const char *base, + each_ref_fn fn, int trim, int flags, void *cb_data) { struct ref_entry_cb data; + struct ref_cache *refs; + + refs = get_ref_cache(submodule); data.base = base; data.trim = trim; data.flags = flags; @@ -1745,86 +1694,6 @@ static int do_for_each_ref(struct ref_cache *refs, const char *base, return do_for_each_entry(refs, base, do_one_ref, &data); } -static int do_head_ref(const char *submodule, each_ref_fn fn, void *cb_data) -{ - struct object_id oid; - int flag; - - if (submodule) { - if (resolve_gitlink_ref(submodule, "HEAD", oid.hash) == 0) - return fn("HEAD", &oid, 0, cb_data); - - return 0; - } - - if (!read_ref_full("HEAD", RESOLVE_REF_READING, oid.hash, &flag)) - return fn("HEAD", &oid, flag, cb_data); - - return 0; -} - -int head_ref(each_ref_fn fn, void *cb_data) -{ - return do_head_ref(NULL, fn, cb_data); -} - -int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return do_head_ref(submodule, fn, cb_data); -} - -int for_each_ref(each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(&ref_cache, "", fn, 0, 0, cb_data); -} - -int for_each_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(get_ref_cache(submodule), "", fn, 0, 0, cb_data); -} - -int for_each_ref_in(const char *prefix, each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(&ref_cache, prefix, fn, strlen(prefix), 0, cb_data); -} - -int for_each_fullref_in(const char *prefix, each_ref_fn fn, void *cb_data, unsigned int broken) -{ - unsigned int flag = 0; - - if (broken) - flag = DO_FOR_EACH_INCLUDE_BROKEN; - return do_for_each_ref(&ref_cache, prefix, fn, 0, flag, cb_data); -} - -int for_each_ref_in_submodule(const char *submodule, const char *prefix, - each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data); -} - -int for_each_replace_ref(each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(&ref_cache, git_replace_ref_base, fn, - strlen(git_replace_ref_base), 0, cb_data); -} - -int for_each_namespaced_ref(each_ref_fn fn, void *cb_data) -{ - struct strbuf buf = STRBUF_INIT; - int ret; - strbuf_addf(&buf, "%srefs/", get_git_namespace()); - ret = do_for_each_ref(&ref_cache, buf.buf, fn, 0, 0, cb_data); - strbuf_release(&buf); - return ret; -} - -int for_each_rawref(each_ref_fn fn, void *cb_data) -{ - return do_for_each_ref(&ref_cache, "", fn, 0, - DO_FOR_EACH_INCLUDE_BROKEN, cb_data); -} - static void unlock_ref(struct ref_lock *lock) { /* Do not free lock->lk -- atexit() still looks at them */ @@ -3481,7 +3350,8 @@ int reflog_expire(const char *refname, const unsigned char *sha1, * reference itself, plus we might need to update the * reference if --updateref was specified: */ - lock = lock_ref_sha1_basic(refname, sha1, NULL, NULL, 0, &type, &err); + lock = lock_ref_sha1_basic(refname, sha1, NULL, NULL, REF_NODEREF, + &type, &err); if (!lock) { error("cannot lock ref '%s': %s", refname, err.buf); strbuf_release(&err); diff --git a/refs/refs-internal.h b/refs/refs-internal.h index c7dded35f4..3a4f634cb4 100644 --- a/refs/refs-internal.h +++ b/refs/refs-internal.h @@ -197,4 +197,19 @@ const char *find_descendant_ref(const char *dirname, int rename_ref_available(const char *oldname, const char *newname); +/* We allow "recursive" symbolic refs. Only within reason, though */ +#define SYMREF_MAXDEPTH 5 + +/* Include broken references in a do_for_each_ref*() iteration: */ +#define DO_FOR_EACH_INCLUDE_BROKEN 0x01 + +/* + * The common backend for the for_each_*ref* functions + */ +int do_for_each_ref(const char *submodule, const char *base, + each_ref_fn fn, int trim, int flags, void *cb_data); + +int read_raw_ref(const char *refname, unsigned char *sha1, + struct strbuf *symref, unsigned int *flags); + #endif /* REFS_REFS_INTERNAL_H */ diff --git a/remote-curl.c b/remote-curl.c index 15e48e25fb..672b382e5a 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -474,7 +474,7 @@ static int run_slot(struct active_request_slot *slot, static int probe_rpc(struct rpc_state *rpc, struct slot_results *results) { struct active_request_slot *slot; - struct curl_slist *headers = NULL; + struct curl_slist *headers = http_copy_default_headers(); struct strbuf buf = STRBUF_INIT; int err; @@ -503,7 +503,7 @@ static int probe_rpc(struct rpc_state *rpc, struct slot_results *results) static int post_rpc(struct rpc_state *rpc) { struct active_request_slot *slot; - struct curl_slist *headers = NULL; + struct curl_slist *headers = http_copy_default_headers(); int use_gzip = rpc->gzip_request; char *gzip_body = NULL; size_t gzip_size = 0; @@ -1660,7 +1660,7 @@ int branch_merge_matches(struct branch *branch, return refname_match(branch->merge[i]->src, refname); } -__attribute((format (printf,2,3))) +__attribute__((format (printf,2,3))) static const char *error_buf(struct strbuf *err, const char *fmt, ...) { if (err) { @@ -2108,7 +2108,7 @@ int format_tracking_info(struct branch *branch, struct strbuf *sb) "Your branch and '%s' have diverged,\n" "and have %d and %d different commits each, " "respectively.\n", - theirs), + ours + theirs), base, ours, theirs); if (advice_status_hints) strbuf_addf(sb, @@ -8,6 +8,7 @@ #include "ll-merge.h" #include "attr.h" #include "pathspec.h" +#include "sha1-lookup.h" #define RESOLVED 0 #define PUNTED 1 @@ -20,6 +21,29 @@ static int rerere_enabled = -1; /* automatically update cleanly resolved paths to the index */ static int rerere_autoupdate; +static int rerere_dir_nr; +static int rerere_dir_alloc; + +#define RR_HAS_POSTIMAGE 1 +#define RR_HAS_PREIMAGE 2 +static struct rerere_dir { + unsigned char sha1[20]; + int status_alloc, status_nr; + unsigned char *status; +} **rerere_dir; + +static void free_rerere_dirs(void) +{ + int i; + for (i = 0; i < rerere_dir_nr; i++) { + free(rerere_dir[i]->status); + free(rerere_dir[i]); + } + free(rerere_dir); + rerere_dir_nr = rerere_dir_alloc = 0; + rerere_dir = NULL; +} + static void free_rerere_id(struct string_list_item *item) { free(item->util); @@ -27,7 +51,33 @@ static void free_rerere_id(struct string_list_item *item) static const char *rerere_id_hex(const struct rerere_id *id) { - return id->hex; + return sha1_to_hex(id->collection->sha1); +} + +static void fit_variant(struct rerere_dir *rr_dir, int variant) +{ + variant++; + ALLOC_GROW(rr_dir->status, variant, rr_dir->status_alloc); + if (rr_dir->status_nr < variant) { + memset(rr_dir->status + rr_dir->status_nr, + '\0', variant - rr_dir->status_nr); + rr_dir->status_nr = variant; + } +} + +static void assign_variant(struct rerere_id *id) +{ + int variant; + struct rerere_dir *rr_dir = id->collection; + + variant = id->variant; + if (variant < 0) { + for (variant = 0; variant < rr_dir->status_nr; variant++) + if (!rr_dir->status[variant]) + break; + } + fit_variant(rr_dir, variant); + id->variant = variant; } const char *rerere_path(const struct rerere_id *id, const char *file) @@ -35,20 +85,103 @@ const char *rerere_path(const struct rerere_id *id, const char *file) if (!file) return git_path("rr-cache/%s", rerere_id_hex(id)); - return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); + if (id->variant <= 0) + return git_path("rr-cache/%s/%s", rerere_id_hex(id), file); + + return git_path("rr-cache/%s/%s.%d", + rerere_id_hex(id), file, id->variant); +} + +static int is_rr_file(const char *name, const char *filename, int *variant) +{ + const char *suffix; + char *ep; + + if (!strcmp(name, filename)) { + *variant = 0; + return 1; + } + if (!skip_prefix(name, filename, &suffix) || *suffix != '.') + return 0; + + errno = 0; + *variant = strtol(suffix + 1, &ep, 10); + if (errno || *ep) + return 0; + return 1; +} + +static void scan_rerere_dir(struct rerere_dir *rr_dir) +{ + struct dirent *de; + DIR *dir = opendir(git_path("rr-cache/%s", sha1_to_hex(rr_dir->sha1))); + + if (!dir) + return; + while ((de = readdir(dir)) != NULL) { + int variant; + + if (is_rr_file(de->d_name, "postimage", &variant)) { + fit_variant(rr_dir, variant); + rr_dir->status[variant] |= RR_HAS_POSTIMAGE; + } else if (is_rr_file(de->d_name, "preimage", &variant)) { + fit_variant(rr_dir, variant); + rr_dir->status[variant] |= RR_HAS_PREIMAGE; + } + } + closedir(dir); +} + +static const unsigned char *rerere_dir_sha1(size_t i, void *table) +{ + struct rerere_dir **rr_dir = table; + return rr_dir[i]->sha1; +} + +static struct rerere_dir *find_rerere_dir(const char *hex) +{ + unsigned char sha1[20]; + struct rerere_dir *rr_dir; + int pos; + + if (get_sha1_hex(hex, sha1)) + return NULL; /* BUG */ + pos = sha1_pos(sha1, rerere_dir, rerere_dir_nr, rerere_dir_sha1); + if (pos < 0) { + rr_dir = xmalloc(sizeof(*rr_dir)); + hashcpy(rr_dir->sha1, sha1); + rr_dir->status = NULL; + rr_dir->status_nr = 0; + rr_dir->status_alloc = 0; + pos = -1 - pos; + + /* Make sure the array is big enough ... */ + ALLOC_GROW(rerere_dir, rerere_dir_nr + 1, rerere_dir_alloc); + /* ... and add it in. */ + rerere_dir_nr++; + memmove(rerere_dir + pos + 1, rerere_dir + pos, + (rerere_dir_nr - pos - 1) * sizeof(*rerere_dir)); + rerere_dir[pos] = rr_dir; + scan_rerere_dir(rr_dir); + } + return rerere_dir[pos]; } static int has_rerere_resolution(const struct rerere_id *id) { - struct stat st; + const int both = RR_HAS_POSTIMAGE|RR_HAS_PREIMAGE; + int variant = id->variant; - return !stat(rerere_path(id, "postimage"), &st); + if (variant < 0) + return 0; + return ((id->collection->status[variant] & both) == both); } static struct rerere_id *new_rerere_id_hex(char *hex) { struct rerere_id *id = xmalloc(sizeof(*id)); - xsnprintf(id->hex, sizeof(id->hex), "%s", hex); + id->collection = find_rerere_dir(hex); + id->variant = -1; /* not known yet */ return id; } @@ -75,16 +208,26 @@ static void read_rr(struct string_list *rr) char *path; unsigned char sha1[20]; struct rerere_id *id; + int variant; /* There has to be the hash, tab, path and then NUL */ if (buf.len < 42 || get_sha1_hex(buf.buf, sha1)) die("corrupt MERGE_RR"); - if (buf.buf[40] != '\t') + if (buf.buf[40] != '.') { + variant = 0; + path = buf.buf + 40; + } else { + errno = 0; + variant = strtol(buf.buf + 41, &path, 10); + if (errno) + die("corrupt MERGE_RR"); + } + if (*(path++) != '\t') die("corrupt MERGE_RR"); buf.buf[40] = '\0'; - path = buf.buf + 41; id = new_rerere_id_hex(buf.buf); + id->variant = variant; string_list_insert(rr, path)->util = id; } strbuf_release(&buf); @@ -105,9 +248,16 @@ static int write_rr(struct string_list *rr, int out_fd) id = rr->items[i].util; if (!id) continue; - strbuf_addf(&buf, "%s\t%s%c", - rerere_id_hex(id), - rr->items[i].string, 0); + assert(id->variant >= 0); + if (0 < id->variant) + strbuf_addf(&buf, "%s.%d\t%s%c", + rerere_id_hex(id), id->variant, + rr->items[i].string, 0); + else + strbuf_addf(&buf, "%s\t%s%c", + rerere_id_hex(id), + rr->items[i].string, 0); + if (write_in_full(out_fd, buf.buf, buf.len) != buf.len) die("unable to write rerere record"); @@ -351,8 +501,7 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output error("There were errors while writing %s (%s)", path, strerror(io.io.wrerror)); if (io.io.output && fclose(io.io.output)) - io.io.wrerror = error("Failed to flush %s: %s", - path, strerror(errno)); + io.io.wrerror = error_errno("Failed to flush %s", path); if (hunk_no < 0) { if (output) @@ -365,103 +514,6 @@ static int handle_file(const char *path, unsigned char *sha1, const char *output } /* - * Subclass of rerere_io that reads from an in-core buffer that is a - * strbuf - */ -struct rerere_io_mem { - struct rerere_io io; - struct strbuf input; -}; - -/* - * ... and its getline() method implementation - */ -static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_) -{ - struct rerere_io_mem *io = (struct rerere_io_mem *)io_; - char *ep; - size_t len; - - strbuf_release(sb); - if (!io->input.len) - return -1; - ep = memchr(io->input.buf, '\n', io->input.len); - if (!ep) - ep = io->input.buf + io->input.len; - else if (*ep == '\n') - ep++; - len = ep - io->input.buf; - strbuf_add(sb, io->input.buf, len); - strbuf_remove(&io->input, 0, len); - return 0; -} - -static int handle_cache(const char *path, unsigned char *sha1, const char *output) -{ - mmfile_t mmfile[3] = {{NULL}}; - mmbuffer_t result = {NULL, 0}; - const struct cache_entry *ce; - int pos, len, i, hunk_no; - struct rerere_io_mem io; - int marker_size = ll_merge_marker_size(path); - - /* - * Reproduce the conflicted merge in-core - */ - len = strlen(path); - pos = cache_name_pos(path, len); - if (0 <= pos) - return -1; - pos = -pos - 1; - - while (pos < active_nr) { - enum object_type type; - unsigned long size; - - ce = active_cache[pos++]; - if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) - break; - i = ce_stage(ce) - 1; - if (!mmfile[i].ptr) { - mmfile[i].ptr = read_sha1_file(ce->sha1, &type, &size); - mmfile[i].size = size; - } - } - for (i = 0; i < 3; i++) - if (!mmfile[i].ptr && !mmfile[i].size) - mmfile[i].ptr = xstrdup(""); - - /* - * NEEDSWORK: handle conflicts from merges with - * merge.renormalize set, too - */ - ll_merge(&result, path, &mmfile[0], NULL, - &mmfile[1], "ours", - &mmfile[2], "theirs", NULL); - for (i = 0; i < 3; i++) - free(mmfile[i].ptr); - - memset(&io, 0, sizeof(io)); - io.io.getline = rerere_mem_getline; - if (output) - io.io.output = fopen(output, "w"); - else - io.io.output = NULL; - strbuf_init(&io.input, 0); - strbuf_attach(&io.input, result.ptr, result.size, result.size); - - /* - * Grab the conflict ID and optionally write the original - * contents with conflict markers out. - */ - hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); - strbuf_release(&io.input); - if (io.io.output) - fclose(io.io.output); - return hunk_no; -} - -/* * Look at a cache entry at "i" and see if it is not conflicting, * conflicting and we are willing to handle, or conflicting and * we are unable to handle, and return the determination in *type. @@ -569,6 +621,33 @@ int rerere_remaining(struct string_list *merge_rr) } /* + * Try using the given conflict resolution "ID" to see + * if that recorded conflict resolves cleanly what we + * got in the "cur". + */ +static int try_merge(const struct rerere_id *id, const char *path, + mmfile_t *cur, mmbuffer_t *result) +{ + int ret; + mmfile_t base = {NULL, 0}, other = {NULL, 0}; + + if (read_mmfile(&base, rerere_path(id, "preimage")) || + read_mmfile(&other, rerere_path(id, "postimage"))) + ret = 1; + else + /* + * A three-way merge. Note that this honors user-customizable + * low-level merge driver settings. + */ + ret = ll_merge(result, path, &base, NULL, cur, "", &other, "", NULL); + + free(base.ptr); + free(other.ptr); + + return ret; +} + +/* * Find the conflict identified by "id"; the change between its * "preimage" (i.e. a previous contents with conflict markers) and its * "postimage" (i.e. the corresponding contents with conflicts @@ -582,30 +661,20 @@ static int merge(const struct rerere_id *id, const char *path) { FILE *f; int ret; - mmfile_t cur = {NULL, 0}, base = {NULL, 0}, other = {NULL, 0}; + mmfile_t cur = {NULL, 0}; mmbuffer_t result = {NULL, 0}; /* * Normalize the conflicts in path and write it out to * "thisimage" temporary file. */ - if (handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) { - ret = 1; - goto out; - } - - if (read_mmfile(&cur, rerere_path(id, "thisimage")) || - read_mmfile(&base, rerere_path(id, "preimage")) || - read_mmfile(&other, rerere_path(id, "postimage"))) { + if ((handle_file(path, NULL, rerere_path(id, "thisimage")) < 0) || + read_mmfile(&cur, rerere_path(id, "thisimage"))) { ret = 1; goto out; } - /* - * A three-way merge. Note that this honors user-customizable - * low-level merge driver settings. - */ - ret = ll_merge(&result, path, &base, NULL, &cur, "", &other, "", NULL); + ret = try_merge(id, path, &cur, &result); if (ret) goto out; @@ -614,25 +683,20 @@ static int merge(const struct rerere_id *id, const char *path) * Mark that "postimage" was used to help gc. */ if (utime(rerere_path(id, "postimage"), NULL) < 0) - warning("failed utime() on %s: %s", - rerere_path(id, "postimage"), - strerror(errno)); + warning_errno("failed utime() on %s", + rerere_path(id, "postimage")); /* Update "path" with the resolution */ f = fopen(path, "w"); if (!f) - return error("Could not open %s: %s", path, - strerror(errno)); + return error_errno("Could not open %s", path); if (fwrite(result.ptr, result.size, 1, f) != 1) - error("Could not write %s: %s", path, strerror(errno)); + error_errno("Could not write %s", path); if (fclose(f)) - return error("Writing %s failed: %s", path, - strerror(errno)); + return error_errno("Writing %s failed", path); out: free(cur.ptr); - free(base.ptr); - free(other.ptr); free(result.ptr); return ret; @@ -661,6 +725,13 @@ static void update_paths(struct string_list *update) rollback_lock_file(&index_lock); } +static void remove_variant(struct rerere_id *id) +{ + unlink_or_warn(rerere_path(id, "postimage")); + unlink_or_warn(rerere_path(id, "preimage")); + id->collection->status[id->variant] = 0; +} + /* * The path indicated by rr_item may still have conflict for which we * have a recorded resolution, in which case replay it and optionally @@ -672,12 +743,47 @@ static void do_rerere_one_path(struct string_list_item *rr_item, struct string_list *update) { const char *path = rr_item->string; - const struct rerere_id *id = rr_item->util; + struct rerere_id *id = rr_item->util; + struct rerere_dir *rr_dir = id->collection; + int variant; + + variant = id->variant; + + /* Has the user resolved it already? */ + if (variant >= 0) { + if (!handle_file(path, NULL, NULL)) { + copy_file(rerere_path(id, "postimage"), path, 0666); + id->collection->status[variant] |= RR_HAS_POSTIMAGE; + fprintf(stderr, "Recorded resolution for '%s'.\n", path); + free_rerere_id(rr_item); + rr_item->util = NULL; + return; + } + /* + * There may be other variants that can cleanly + * replay. Try them and update the variant number for + * this one. + */ + } + + /* Does any existing resolution apply cleanly? */ + for (variant = 0; variant < rr_dir->status_nr; variant++) { + const int both = RR_HAS_PREIMAGE | RR_HAS_POSTIMAGE; + struct rerere_id vid = *id; + + if ((rr_dir->status[variant] & both) != both) + continue; + + vid.variant = variant; + if (merge(&vid, path)) + continue; /* failed to replay */ - /* Is there a recorded resolution we could attempt to apply? */ - if (has_rerere_resolution(id)) { - if (merge(id, path)) - return; /* failed to replay */ + /* + * If there already is a different variant that applies + * cleanly, there is no point maintaining our own variant. + */ + if (0 <= id->variant && id->variant != variant) + remove_variant(id); if (rerere_autoupdate) string_list_insert(update, path); @@ -685,15 +791,24 @@ static void do_rerere_one_path(struct string_list_item *rr_item, fprintf(stderr, "Resolved '%s' using previous resolution.\n", path); - } else if (!handle_file(path, NULL, NULL)) { - /* The user has resolved it. */ - copy_file(rerere_path(id, "postimage"), path, 0666); - fprintf(stderr, "Recorded resolution for '%s'.\n", path); - } else { + free_rerere_id(rr_item); + rr_item->util = NULL; return; } - free_rerere_id(rr_item); - rr_item->util = NULL; + + /* None of the existing one applies; we need a new variant */ + assign_variant(id); + + variant = id->variant; + handle_file(path, NULL, rerere_path(id, "preimage")); + if (id->collection->status[variant] & RR_HAS_POSTIMAGE) { + const char *path = rerere_path(id, "postimage"); + if (unlink(path)) + die_errno("cannot unlink stray '%s'", path); + id->collection->status[variant] &= ~RR_HAS_POSTIMAGE; + } + id->collection->status[variant] |= RR_HAS_PREIMAGE; + fprintf(stderr, "Recorded preimage for '%s'\n", path); } static int do_plain_rerere(struct string_list *rr, int fd) @@ -731,24 +846,8 @@ static int do_plain_rerere(struct string_list *rr, int fd) id = new_rerere_id(sha1); string_list_insert(rr, path)->util = id; - /* - * If the directory does not exist, create - * it. mkdir_in_gitdir() will fail with - * EEXIST if there already is one. - * - * NEEDSWORK: make sure "gc" does not remove - * preimage without removing the directory. - */ - if (mkdir_in_gitdir(rerere_path(id, NULL))) - continue; - - /* - * We are the first to encounter this - * conflict. Ask handle_file() to write the - * normalized contents to the "preimage" file. - */ - handle_file(path, NULL, rerere_path(id, "preimage")); - fprintf(stderr, "Recorded preimage for '%s'\n", path); + /* Ensure that the directory exists. */ + mkdir_in_gitdir(rerere_path(id, NULL)); } for (i = 0; i < rr->nr; i++) @@ -812,12 +911,111 @@ int setup_rerere(struct string_list *merge_rr, int flags) int rerere(int flags) { struct string_list merge_rr = STRING_LIST_INIT_DUP; - int fd; + int fd, status; fd = setup_rerere(&merge_rr, flags); if (fd < 0) return 0; - return do_plain_rerere(&merge_rr, fd); + status = do_plain_rerere(&merge_rr, fd); + free_rerere_dirs(); + return status; +} + +/* + * Subclass of rerere_io that reads from an in-core buffer that is a + * strbuf + */ +struct rerere_io_mem { + struct rerere_io io; + struct strbuf input; +}; + +/* + * ... and its getline() method implementation + */ +static int rerere_mem_getline(struct strbuf *sb, struct rerere_io *io_) +{ + struct rerere_io_mem *io = (struct rerere_io_mem *)io_; + char *ep; + size_t len; + + strbuf_release(sb); + if (!io->input.len) + return -1; + ep = memchr(io->input.buf, '\n', io->input.len); + if (!ep) + ep = io->input.buf + io->input.len; + else if (*ep == '\n') + ep++; + len = ep - io->input.buf; + strbuf_add(sb, io->input.buf, len); + strbuf_remove(&io->input, 0, len); + return 0; +} + +static int handle_cache(const char *path, unsigned char *sha1, const char *output) +{ + mmfile_t mmfile[3] = {{NULL}}; + mmbuffer_t result = {NULL, 0}; + const struct cache_entry *ce; + int pos, len, i, hunk_no; + struct rerere_io_mem io; + int marker_size = ll_merge_marker_size(path); + + /* + * Reproduce the conflicted merge in-core + */ + len = strlen(path); + pos = cache_name_pos(path, len); + if (0 <= pos) + return -1; + pos = -pos - 1; + + while (pos < active_nr) { + enum object_type type; + unsigned long size; + + ce = active_cache[pos++]; + if (ce_namelen(ce) != len || memcmp(ce->name, path, len)) + break; + i = ce_stage(ce) - 1; + if (!mmfile[i].ptr) { + mmfile[i].ptr = read_sha1_file(ce->sha1, &type, &size); + mmfile[i].size = size; + } + } + for (i = 0; i < 3; i++) + if (!mmfile[i].ptr && !mmfile[i].size) + mmfile[i].ptr = xstrdup(""); + + /* + * NEEDSWORK: handle conflicts from merges with + * merge.renormalize set, too? + */ + ll_merge(&result, path, &mmfile[0], NULL, + &mmfile[1], "ours", + &mmfile[2], "theirs", NULL); + for (i = 0; i < 3; i++) + free(mmfile[i].ptr); + + memset(&io, 0, sizeof(io)); + io.io.getline = rerere_mem_getline; + if (output) + io.io.output = fopen(output, "w"); + else + io.io.output = NULL; + strbuf_init(&io.input, 0); + strbuf_attach(&io.input, result.ptr, result.size, result.size); + + /* + * Grab the conflict ID and optionally write the original + * contents with conflict markers out. + */ + hunk_no = handle_path(sha1, (struct rerere_io *)&io, marker_size); + strbuf_release(&io.input); + if (io.io.output) + fclose(io.io.output); + return hunk_no; } static int rerere_forget_one_path(const char *path, struct string_list *rr) @@ -838,11 +1036,43 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr) /* Nuke the recorded resolution for the conflict */ id = new_rerere_id(sha1); + + for (id->variant = 0; + id->variant < id->collection->status_nr; + id->variant++) { + mmfile_t cur = { NULL, 0 }; + mmbuffer_t result = {NULL, 0}; + int cleanly_resolved; + + if (!has_rerere_resolution(id)) + continue; + + handle_cache(path, sha1, rerere_path(id, "thisimage")); + if (read_mmfile(&cur, rerere_path(id, "thisimage"))) { + free(cur.ptr); + error("Failed to update conflicted state in '%s'", path); + goto fail_exit; + } + cleanly_resolved = !try_merge(id, path, &cur, &result); + free(result.ptr); + free(cur.ptr); + if (cleanly_resolved) + break; + } + + if (id->collection->status_nr <= id->variant) { + error("no remembered resolution for '%s'", path); + goto fail_exit; + } + filename = rerere_path(id, "postimage"); - if (unlink(filename)) - return (errno == ENOENT - ? error("no remembered resolution for %s", path) - : error("cannot unlink %s: %s", filename, strerror(errno))); + if (unlink(filename)) { + if (errno == ENOENT) + error("no remembered resolution for %s", path); + else + error_errno("cannot unlink %s", filename); + goto fail_exit; + } /* * Update the preimage so that the user can resolve the @@ -861,6 +1091,10 @@ static int rerere_forget_one_path(const char *path, struct string_list *rr) item->util = id; fprintf(stderr, "Forgot resolution for %s\n", path); return 0; + +fail_exit: + free(id); + return -1; } int rerere_forget(struct pathspec *pathspec) @@ -897,29 +1131,16 @@ int rerere_forget(struct pathspec *pathspec) * Garbage collection support */ -/* - * Note that this is not reentrant but is used only one-at-a-time - * so it does not matter right now. - */ -static struct rerere_id *dirname_to_id(const char *name) -{ - static struct rerere_id id; - xsnprintf(id.hex, sizeof(id.hex), "%s", name); - return &id; -} - -static time_t rerere_created_at(const char *dir_name) +static time_t rerere_created_at(struct rerere_id *id) { struct stat st; - struct rerere_id *id = dirname_to_id(dir_name); return stat(rerere_path(id, "preimage"), &st) ? (time_t) 0 : st.st_mtime; } -static time_t rerere_last_used_at(const char *dir_name) +static time_t rerere_last_used_at(struct rerere_id *id) { struct stat st; - struct rerere_id *id = dirname_to_id(dir_name); return stat(rerere_path(id, "postimage"), &st) ? (time_t) 0 : st.st_mtime; } @@ -929,15 +1150,28 @@ static time_t rerere_last_used_at(const char *dir_name) */ static void unlink_rr_item(struct rerere_id *id) { - unlink(rerere_path(id, "thisimage")); - unlink(rerere_path(id, "preimage")); - unlink(rerere_path(id, "postimage")); - /* - * NEEDSWORK: what if this rmdir() fails? Wouldn't we then - * assume that we already have preimage recorded in - * do_plain_rerere()? - */ - rmdir(rerere_path(id, NULL)); + unlink_or_warn(rerere_path(id, "thisimage")); + remove_variant(id); + id->collection->status[id->variant] = 0; +} + +static void prune_one(struct rerere_id *id, time_t now, + int cutoff_resolve, int cutoff_noresolve) +{ + time_t then; + int cutoff; + + then = rerere_last_used_at(id); + if (then) + cutoff = cutoff_resolve; + else { + then = rerere_created_at(id); + if (!then) + return; + cutoff = cutoff_noresolve; + } + if (then < now - cutoff * 86400) + unlink_rr_item(id); } void rerere_gc(struct string_list *rr) @@ -945,8 +1179,8 @@ void rerere_gc(struct string_list *rr) struct string_list to_remove = STRING_LIST_INIT_DUP; DIR *dir; struct dirent *e; - int i, cutoff; - time_t now = time(NULL), then; + int i; + time_t now = time(NULL); int cutoff_noresolve = 15; int cutoff_resolve = 60; @@ -961,25 +1195,32 @@ void rerere_gc(struct string_list *rr) die_errno("unable to open rr-cache directory"); /* Collect stale conflict IDs ... */ while ((e = readdir(dir))) { + struct rerere_dir *rr_dir; + struct rerere_id id; + int now_empty; + if (is_dot_or_dotdot(e->d_name)) continue; - - then = rerere_last_used_at(e->d_name); - if (then) { - cutoff = cutoff_resolve; - } else { - then = rerere_created_at(e->d_name); - if (!then) - continue; - cutoff = cutoff_noresolve; + rr_dir = find_rerere_dir(e->d_name); + if (!rr_dir) + continue; /* or should we remove e->d_name? */ + + now_empty = 1; + for (id.variant = 0, id.collection = rr_dir; + id.variant < id.collection->status_nr; + id.variant++) { + prune_one(&id, now, cutoff_resolve, cutoff_noresolve); + if (id.collection->status[id.variant]) + now_empty = 0; } - if (then < now - cutoff * 86400) + if (now_empty) string_list_append(&to_remove, e->d_name); } closedir(dir); - /* ... and then remove them one-by-one */ + + /* ... and then remove the empty directories */ for (i = 0; i < to_remove.nr; i++) - unlink_rr_item(dirname_to_id(to_remove.items[i].string)); + rmdir(git_path("rr-cache/%s", to_remove.items[i].string)); string_list_clear(&to_remove, 0); rollback_lock_file(&write_lock); } @@ -1000,8 +1241,10 @@ void rerere_clear(struct string_list *merge_rr) for (i = 0; i < merge_rr->nr; i++) { struct rerere_id *id = merge_rr->items[i].util; - if (!has_rerere_resolution(id)) + if (!has_rerere_resolution(id)) { unlink_rr_item(id); + rmdir(rerere_path(id, NULL)); + } } unlink_or_warn(git_path_merge_rr()); rollback_lock_file(&write_lock); @@ -16,8 +16,10 @@ struct pathspec; */ extern void *RERERE_RESOLVED; +struct rerere_dir; struct rerere_id { - char hex[41]; + struct rerere_dir *collection; + int variant; }; extern int setup_rerere(struct string_list *, int); diff --git a/revision.c b/revision.c index b683476b9c..d30d1c4f80 100644 --- a/revision.c +++ b/revision.c @@ -59,10 +59,10 @@ static void mark_tree_contents_uninteresting(struct tree *tree) while (tree_entry(&desc, &entry)) { switch (object_type(entry.mode)) { case OBJ_TREE: - mark_tree_uninteresting(lookup_tree(entry.sha1)); + mark_tree_uninteresting(lookup_tree(entry.oid->hash)); break; case OBJ_BLOB: - mark_blob_uninteresting(lookup_blob(entry.sha1)); + mark_blob_uninteresting(lookup_blob(entry.oid->hash)); break; default: /* Subproject commit - not in this repository */ diff --git a/run-command.c b/run-command.c index 8c7115ade4..af0c8a10df 100644 --- a/run-command.c +++ b/run-command.c @@ -233,7 +233,7 @@ static int wait_or_whine(pid_t pid, const char *argv0, int in_signal) if (waiting < 0) { failed_errno = errno; - error("waitpid for %s failed: %s", argv0, strerror(errno)); + error_errno("waitpid for %s failed", argv0); } else if (waiting != pid) { error("waitpid is confused (%s)", argv0); } else if (WIFSIGNALED(status)) { @@ -420,8 +420,7 @@ fail_pipe: } } if (cmd->pid < 0) - error("cannot fork() for %s: %s", cmd->argv[0], - strerror(errno)); + error_errno("cannot fork() for %s", cmd->argv[0]); else if (cmd->clean_on_exit) mark_child_for_cleanup(cmd->pid); @@ -482,7 +481,7 @@ fail_pipe: cmd->dir, fhin, fhout, fherr); failed_errno = errno; if (cmd->pid < 0 && (!cmd->silent_exec_failure || errno != ENOENT)) - error("cannot spawn %s: %s", cmd->argv[0], strerror(errno)); + error_errno("cannot spawn %s", cmd->argv[0]); if (cmd->clean_on_exit && cmd->pid >= 0) mark_child_for_cleanup(cmd->pid); @@ -590,6 +589,16 @@ static void *run_thread(void *data) struct async *async = data; intptr_t ret; + if (async->isolate_sigpipe) { + sigset_t mask; + sigemptyset(&mask); + sigaddset(&mask, SIGPIPE); + if (pthread_sigmask(SIG_BLOCK, &mask, NULL) < 0) { + ret = error("unable to block SIGPIPE in async thread"); + return (void *)ret; + } + } + pthread_setspecific(async_key, async); ret = async->proc(async->proc_in, async->proc_out, async->data); return (void *)ret; @@ -693,7 +702,7 @@ int start_async(struct async *async) if (pipe(fdin) < 0) { if (async->out > 0) close(async->out); - return error("cannot create pipe: %s", strerror(errno)); + return error_errno("cannot create pipe"); } async->in = fdin[1]; } @@ -705,7 +714,7 @@ int start_async(struct async *async) close_pair(fdin); else if (async->in) close(async->in); - return error("cannot create pipe: %s", strerror(errno)); + return error_errno("cannot create pipe"); } async->out = fdout[0]; } @@ -730,7 +739,7 @@ int start_async(struct async *async) async->pid = fork(); if (async->pid < 0) { - error("fork (async) failed: %s", strerror(errno)); + error_errno("fork (async) failed"); goto error; } if (!async->pid) { @@ -777,7 +786,7 @@ int start_async(struct async *async) { int err = pthread_create(&async->tid, NULL, run_thread, async); if (err) { - error("cannot create thread: %s", strerror(err)); + error_errno("cannot create thread"); goto error; } } @@ -815,7 +824,10 @@ const char *find_hook(const char *name) static struct strbuf path = STRBUF_INIT; strbuf_reset(&path); - strbuf_git_path(&path, "hooks/%s", name); + if (git_hooks_path) + strbuf_addf(&path, "%s/%s", git_hooks_path, name); + else + strbuf_git_path(&path, "hooks/%s", name); if (access(path.buf, X_OK) < 0) return NULL; return path.buf; diff --git a/run-command.h b/run-command.h index de1727efab..11f76b04ed 100644 --- a/run-command.h +++ b/run-command.h @@ -116,6 +116,7 @@ struct async { int proc_in; int proc_out; #endif + int isolate_sigpipe; }; int start_async(struct async *async); diff --git a/send-pack.c b/send-pack.c index 047bd18fde..37ee04ea3b 100644 --- a/send-pack.c +++ b/send-pack.c @@ -518,6 +518,7 @@ int send_pack(struct send_pack_args *args, demux.proc = sideband_demux; demux.data = fd; demux.out = -1; + demux.isolate_sigpipe = 1; if (start_async(&demux)) die("send-pack: unable to fork off sideband demultiplexer"); in = demux.out; @@ -531,8 +532,10 @@ int send_pack(struct send_pack_args *args, close(out); if (git_connection_is_socket(conn)) shutdown(fd[0], SHUT_WR); - if (use_sideband) + if (use_sideband) { + close(demux.out); finish_async(&demux); + } fd[1] = -1; return -1; } @@ -551,11 +554,11 @@ int send_pack(struct send_pack_args *args, packet_flush(out); if (use_sideband && cmds_sent) { + close(demux.out); if (finish_async(&demux)) { error("error in sideband demultiplexer"); ret = -1; } - close(demux.out); } if (ret < 0) diff --git a/sequencer.c b/sequencer.c index e66f2fe0f0..4687ad4b80 100644 --- a/sequencer.c +++ b/sequencer.c @@ -875,8 +875,7 @@ static int sequencer_rollback(struct replay_opts *opts) return rollback_single_pick(); } if (!f) - return error(_("cannot open %s: %s"), git_path_head_file(), - strerror(errno)); + return error_errno(_("cannot open %s"), git_path_head_file()); if (strbuf_getline_lf(&buf, f)) { error(_("cannot read %s: %s"), git_path_head_file(), ferror(f) ? strerror(errno) : _("unexpected end of file")); diff --git a/server-info.c b/server-info.c index 5a86e297b5..75dd677413 100644 --- a/server-info.c +++ b/server-info.c @@ -36,7 +36,7 @@ static int update_info_file(char *path, int (*generate)(FILE *)) out: if (ret) { - error("unable to update %s: %s", path, strerror(errno)); + error_errno("unable to update %s", path); if (fp) fclose(fp); else if (fd >= 0) diff --git a/sha1_file.c b/sha1_file.c index d0f2aa029b..d5e11217f5 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -301,7 +301,7 @@ static int link_alt_odb_entry(const char *entry, const char *relative_base, return -1; } } - if (!strcmp_icase(ent->base, normalized_objdir)) { + if (!fspathcmp(ent->base, normalized_objdir)) { free(ent); return -1; } @@ -1107,9 +1107,8 @@ unsigned char *use_pack(struct packed_git *p, PROT_READ, MAP_PRIVATE, p->pack_fd, win->offset); if (win->base == MAP_FAILED) - die("packfile %s cannot be mapped: %s", - p->pack_name, - strerror(errno)); + die_errno("packfile %s cannot be mapped", + p->pack_name); if (!win->offset && win->len == p->pack_size && !p->do_not_close) close_pack_fd(p); @@ -1279,8 +1278,8 @@ static void prepare_packed_git_one(char *objdir, int local) dir = opendir(path.buf); if (!dir) { if (errno != ENOENT) - error("unable to open object pack directory: %s: %s", - path.buf, strerror(errno)); + error_errno("unable to open object pack directory: %s", + path.buf); strbuf_release(&path); return; } @@ -2984,7 +2983,7 @@ int finalize_object_file(const char *tmpfile, const char *filename) unlink_or_warn(tmpfile); if (ret) { if (ret != EEXIST) { - return error("unable to write sha1 filename %s: %s", filename, strerror(ret)); + return error_errno("unable to write sha1 filename %s", filename); } /* FIXME!!! Collision check here ? */ } @@ -2998,7 +2997,7 @@ out: static int write_buffer(int fd, const void *buf, size_t len) { if (write_in_full(fd, buf, len) < 0) - return error("file write error (%s)", strerror(errno)); + return error_errno("file write error"); return 0; } @@ -3081,7 +3080,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, if (errno == EACCES) return error("insufficient permission for adding an object to repository database %s", get_object_directory()); else - return error("unable to create temporary file: %s", strerror(errno)); + return error_errno("unable to create temporary file"); } /* Set it up */ @@ -3126,8 +3125,7 @@ static int write_loose_object(const unsigned char *sha1, char *hdr, int hdrlen, utb.actime = mtime; utb.modtime = mtime; if (utime(tmp_file.buf, &utb) < 0) - warning("failed utime() on %s: %s", - tmp_file.buf, strerror(errno)); + warning_errno("failed utime() on %s", tmp_file.buf); } return finalize_object_file(tmp_file.buf, filename); @@ -3360,7 +3358,7 @@ static int index_core(unsigned char *sha1, int fd, size_t size, if (size == read_in_full(fd, buf, size)) ret = index_mem(sha1, buf, size, type, path, flags); else - ret = error("short read %s", strerror(errno)); + ret = error_errno("short read"); free(buf); } else { void *buf = xmmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); @@ -3425,18 +3423,14 @@ int index_path(unsigned char *sha1, const char *path, struct stat *st, unsigned case S_IFREG: fd = open(path, O_RDONLY); if (fd < 0) - return error("open(\"%s\"): %s", path, - strerror(errno)); + return error_errno("open(\"%s\")", path); if (index_fd(sha1, fd, st, OBJ_BLOB, path, flags) < 0) return error("%s: failed to insert into database", path); break; case S_IFLNK: - if (strbuf_readlink(&sb, path, st->st_size)) { - char *errstr = strerror(errno); - return error("readlink(\"%s\"): %s", path, - errstr); - } + if (strbuf_readlink(&sb, path, st->st_size)) + return error_errno("readlink(\"%s\")", path); if (!(flags & HASH_WRITE_OBJECT)) hash_sha1_file(sb.buf, sb.len, blob_type, sha1); else if (write_sha1_file(sb.buf, sb.len, blob_type, sha1)) @@ -3492,7 +3486,7 @@ static int for_each_file_in_obj_subdir(int subdir_nr, if (!dir) { if (errno == ENOENT) return 0; - return error("unable to open %s: %s", path->buf, strerror(errno)); + return error_errno("unable to open %s", path->buf); } while ((de = readdir(dir))) { diff --git a/sha1_name.c b/sha1_name.c index 776101e8d7..ca7ddd6f2c 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -1215,6 +1215,15 @@ int get_sha1(const char *name, unsigned char *sha1) } /* + * This is like "get_sha1()", but for struct object_id. + */ +int get_oid(const char *name, struct object_id *oid) +{ + return get_sha1(name, oid->hash); +} + + +/* * Many callers know that the user meant to name a commit-ish by * syntactical positions where the object name appears. Calling this * function allows the machinery to disambiguate shorter-than-unique diff --git a/split-index.c b/split-index.c index 968b780a06..3c75d4b9ce 100644 --- a/split-index.c +++ b/split-index.c @@ -60,7 +60,7 @@ static void mark_base_index_entries(struct index_state *base) * To keep track of the shared entries between * istate->base->cache[] and istate->cache[], base entry * position is stored in each base entry. All positions start - * from 1 instead of 0, which is resrved to say "this is a new + * from 1 instead of 0, which is reserved to say "this is a new * entry". */ for (i = 0; i < base->cache_nr; i++) diff --git a/string-list.c b/string-list.c index 2a32a3f1f5..62d20846cb 100644 --- a/string-list.c +++ b/string-list.c @@ -231,12 +231,12 @@ void string_list_sort(struct string_list *list) struct string_list_item *unsorted_string_list_lookup(struct string_list *list, const char *string) { - int i; + struct string_list_item *item; compare_strings_fn cmp = list->cmp ? list->cmp : strcmp; - for (i = 0; i < list->nr; i++) - if (!cmp(string, list->items[i].string)) - return list->items + i; + for_each_string_list_item(item, list) + if (!cmp(string, item->string)) + return item; return NULL; } diff --git a/submodule-config.c b/submodule-config.c index 8ac5031ade..debab294d4 100644 --- a/submodule-config.c +++ b/submodule-config.c @@ -30,7 +30,7 @@ enum lookup_type { lookup_path }; -static struct submodule_cache cache; +static struct submodule_cache the_submodule_cache; static int is_cache_init; static int config_path_cmp(const struct submodule_entry *a, @@ -470,14 +470,14 @@ static void ensure_cache_init(void) if (is_cache_init) return; - cache_init(&cache); + cache_init(&the_submodule_cache); is_cache_init = 1; } int parse_submodule_config_option(const char *var, const char *value) { struct parse_config_parameter parameter; - parameter.cache = &cache; + parameter.cache = &the_submodule_cache; parameter.commit_sha1 = NULL; parameter.gitmodules_sha1 = null_sha1; parameter.overwrite = 1; @@ -490,18 +490,18 @@ const struct submodule *submodule_from_name(const unsigned char *commit_sha1, const char *name) { ensure_cache_init(); - return config_from_name(&cache, commit_sha1, name); + return config_from_name(&the_submodule_cache, commit_sha1, name); } const struct submodule *submodule_from_path(const unsigned char *commit_sha1, const char *path) { ensure_cache_init(); - return config_from_path(&cache, commit_sha1, path); + return config_from_path(&the_submodule_cache, commit_sha1, path); } void submodule_free(void) { - cache_free(&cache); + cache_free(&the_submodule_cache); is_cache_init = 0; } diff --git a/submodule.c b/submodule.c index 90825e17fa..4532b11d66 100644 --- a/submodule.c +++ b/submodule.c @@ -13,6 +13,7 @@ #include "argv-array.h" #include "blob.h" #include "thread-utils.h" +#include "quote.h" static int config_fetch_recurse_submodules = RECURSE_SUBMODULES_ON_DEMAND; static int parallel_jobs = 1; @@ -237,6 +238,27 @@ int parse_submodule_update_strategy(const char *value, return 0; } +const char *submodule_strategy_to_string(const struct submodule_update_strategy *s) +{ + struct strbuf sb = STRBUF_INIT; + switch (s->type) { + case SM_UPDATE_CHECKOUT: + return "checkout"; + case SM_UPDATE_MERGE: + return "merge"; + case SM_UPDATE_REBASE: + return "rebase"; + case SM_UPDATE_NONE: + return "none"; + case SM_UPDATE_UNSPECIFIED: + return NULL; + case SM_UPDATE_COMMAND: + strbuf_addf(&sb, "!%s", s->command); + return strbuf_detach(&sb, NULL); + } + return NULL; +} + void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *arg) { @@ -393,7 +415,7 @@ static int submodule_needs_pushing(const char *path, const unsigned char sha1[20 argv[1] = sha1_to_hex(sha1); cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -480,7 +502,7 @@ static int push_submodule(const char *path) const char *argv[] = {"push", NULL}; cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -526,7 +548,7 @@ static int is_submodule_commit_present(const char *path, unsigned char sha1[20]) argv[3] = sha1_to_hex(sha1); cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.dir = path; @@ -709,7 +731,7 @@ static int get_next_submodule(struct child_process *cp, if (is_directory(git_dir)) { child_process_init(cp); cp->dir = strbuf_detach(&submodule_path, NULL); - cp->env = local_repo_env; + prepare_submodule_repo_env(&cp->env_array); cp->git_cmd = 1; if (!spf->quiet) strbuf_addf(err, "Fetching submodule %s%s\n", @@ -824,7 +846,7 @@ unsigned is_submodule_modified(const char *path, int ignore_untracked) argv[2] = "-uno"; cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -885,7 +907,7 @@ int submodule_uses_gitfile(const char *path) /* Now test that all nested submodules use a gitfile too */ cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.no_stderr = 1; @@ -918,7 +940,7 @@ int ok_to_remove_submodule(const char *path) return 0; cp.argv = argv; - cp.env = local_repo_env; + prepare_submodule_repo_env(&cp.env_array); cp.git_cmd = 1; cp.no_stdin = 1; cp.out = -1; @@ -1129,3 +1151,13 @@ int parallel_submodules(void) { return parallel_jobs; } + +void prepare_submodule_repo_env(struct argv_array *out) +{ + const char * const *var; + + for (var = local_repo_env; *var; var++) { + if (strcmp(*var, CONFIG_DATA_ENVIRONMENT)) + argv_array_push(out, *var); + } +} diff --git a/submodule.h b/submodule.h index 7ef3775184..2af9390998 100644 --- a/submodule.h +++ b/submodule.h @@ -39,6 +39,7 @@ int submodule_config(const char *var, const char *value, void *cb); void gitmodules_config(void); int parse_submodule_update_strategy(const char *value, struct submodule_update_strategy *dst); +const char *submodule_strategy_to_string(const struct submodule_update_strategy *s); void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *); void show_submodule_summary(FILE *f, const char *path, const char *line_prefix, @@ -61,4 +62,11 @@ int push_unpushed_submodules(unsigned char new_sha1[20], const char *remotes_nam void connect_work_tree_and_git_dir(const char *work_tree, const char *git_dir); int parallel_submodules(void); +/* + * Prepare the "env_array" parameter of a "struct child_process" for executing + * a submodule by clearing any repo-specific envirionment variables, but + * retaining any config in the environment. + */ +void prepare_submodule_repo_env(struct argv_array *out); + #endif @@ -84,9 +84,9 @@ appropriately before running "make". -x:: Turn on shell tracing (i.e., `set -x`) during the tests - themselves. Implies `--verbose`. Note that this can cause - failures in some tests which redirect and test the - output of shell functions. Use with caution. + themselves. Implies `--verbose`. Note that in non-bash shells, + this can cause failures in some tests which redirect and test + the output of shell functions. Use with caution. -d:: --debug:: diff --git a/t/helper/.gitignore b/t/helper/.gitignore new file mode 100644 index 0000000000..d6e8b36798 --- /dev/null +++ b/t/helper/.gitignore @@ -0,0 +1,33 @@ +/test-chmtime +/test-ctype +/test-config +/test-date +/test-delta +/test-dump-cache-tree +/test-dump-split-index +/test-dump-untracked-cache +/test-fake-ssh +/test-scrap-cache-tree +/test-genrandom +/test-hashmap +/test-index-version +/test-line-buffer +/test-match-trees +/test-mergesort +/test-mktemp +/test-parse-options +/test-path-utils +/test-prio-queue +/test-read-cache +/test-regex +/test-revision-walking +/test-run-command +/test-sha1 +/test-sha1-array +/test-sigchain +/test-string-list +/test-submodule-config +/test-subprocess +/test-svn-fe +/test-urlmatch-normalization +/test-wildmatch diff --git a/test-chmtime.c b/t/helper/test-chmtime.c index dfe8a83261..dfe8a83261 100644 --- a/test-chmtime.c +++ b/t/helper/test-chmtime.c diff --git a/test-config.c b/t/helper/test-config.c index 6a77552210..6a77552210 100644 --- a/test-config.c +++ b/t/helper/test-config.c diff --git a/test-ctype.c b/t/helper/test-ctype.c index 707a821f03..707a821f03 100644 --- a/test-ctype.c +++ b/t/helper/test-ctype.c diff --git a/test-date.c b/t/helper/test-date.c index 63f373557e..63f373557e 100644 --- a/test-date.c +++ b/t/helper/test-date.c diff --git a/test-delta.c b/t/helper/test-delta.c index 4595cd6433..4595cd6433 100644 --- a/test-delta.c +++ b/t/helper/test-delta.c diff --git a/test-dump-cache-tree.c b/t/helper/test-dump-cache-tree.c index bb53c0aa65..bb53c0aa65 100644 --- a/test-dump-cache-tree.c +++ b/t/helper/test-dump-cache-tree.c diff --git a/test-dump-split-index.c b/t/helper/test-dump-split-index.c index 861d28c9b6..861d28c9b6 100644 --- a/test-dump-split-index.c +++ b/t/helper/test-dump-split-index.c diff --git a/test-dump-untracked-cache.c b/t/helper/test-dump-untracked-cache.c index 0a1c285246..0a1c285246 100644 --- a/test-dump-untracked-cache.c +++ b/t/helper/test-dump-untracked-cache.c diff --git a/test-fake-ssh.c b/t/helper/test-fake-ssh.c index 980de216e1..980de216e1 100644 --- a/test-fake-ssh.c +++ b/t/helper/test-fake-ssh.c diff --git a/test-genrandom.c b/t/helper/test-genrandom.c index 54824d0754..54824d0754 100644 --- a/test-genrandom.c +++ b/t/helper/test-genrandom.c diff --git a/test-hashmap.c b/t/helper/test-hashmap.c index cc2891dd97..cc2891dd97 100644 --- a/test-hashmap.c +++ b/t/helper/test-hashmap.c diff --git a/test-index-version.c b/t/helper/test-index-version.c index 05d4699c4a..05d4699c4a 100644 --- a/test-index-version.c +++ b/t/helper/test-index-version.c diff --git a/test-line-buffer.c b/t/helper/test-line-buffer.c index 1e58f0476f..1e58f0476f 100644 --- a/test-line-buffer.c +++ b/t/helper/test-line-buffer.c diff --git a/test-match-trees.c b/t/helper/test-match-trees.c index 4dad7095f1..d446b8eaca 100644 --- a/test-match-trees.c +++ b/t/helper/test-match-trees.c @@ -3,24 +3,24 @@ int main(int ac, char **av) { - unsigned char hash1[20], hash2[20], shifted[20]; + struct object_id hash1, hash2, shifted; struct tree *one, *two; setup_git_directory(); - if (get_sha1(av[1], hash1)) + if (get_oid(av[1], &hash1)) die("cannot parse %s as an object name", av[1]); - if (get_sha1(av[2], hash2)) + if (get_oid(av[2], &hash2)) die("cannot parse %s as an object name", av[2]); - one = parse_tree_indirect(hash1); + one = parse_tree_indirect(hash1.hash); if (!one) die("not a tree-ish %s", av[1]); - two = parse_tree_indirect(hash2); + two = parse_tree_indirect(hash2.hash); if (!two) die("not a tree-ish %s", av[2]); - shift_tree(one->object.oid.hash, two->object.oid.hash, shifted, -1); - printf("shifted: %s\n", sha1_to_hex(shifted)); + shift_tree(&one->object.oid, &two->object.oid, &shifted, -1); + printf("shifted: %s\n", oid_to_hex(&shifted)); exit(0); } diff --git a/test-mergesort.c b/t/helper/test-mergesort.c index ea3b959e94..ea3b959e94 100644 --- a/test-mergesort.c +++ b/t/helper/test-mergesort.c diff --git a/test-mktemp.c b/t/helper/test-mktemp.c index c8c54213a3..c8c54213a3 100644 --- a/test-mktemp.c +++ b/t/helper/test-mktemp.c diff --git a/test-parse-options.c b/t/helper/test-parse-options.c index 2c8c8f18ed..8a1235d03e 100644 --- a/test-parse-options.c +++ b/t/helper/test-parse-options.c @@ -7,16 +7,25 @@ static int integer = 0; static unsigned long magnitude = 0; static unsigned long timestamp; static int abbrev = 7; -static int verbose = 0, dry_run = 0, quiet = 0; +static int verbose = -1; /* unspecified */ +static int dry_run = 0, quiet = 0; static char *string = NULL; static char *file = NULL; static int ambiguous; static struct string_list list; +static struct { + int called; + const char *arg; + int unset; +} length_cb; + static int length_callback(const struct option *opt, const char *arg, int unset) { - printf("Callback: \"%s\", %d\n", - (arg ? arg : "not set"), unset); + length_cb.called = 1; + length_cb.arg = arg; + length_cb.unset = unset; + if (unset) return 1; /* do not support unset */ @@ -30,6 +39,61 @@ static int number_callback(const struct option *opt, const char *arg, int unset) return 0; } +static int collect_expect(const struct option *opt, const char *arg, int unset) +{ + struct string_list *expect; + struct string_list_item *item; + struct strbuf label = STRBUF_INIT; + const char *colon; + + if (!arg || unset) + die("malformed --expect option"); + + expect = (struct string_list *)opt->value; + colon = strchr(arg, ':'); + if (!colon) + die("malformed --expect option, lacking a colon"); + strbuf_add(&label, arg, colon - arg); + item = string_list_insert(expect, strbuf_detach(&label, NULL)); + if (item->util) + die("malformed --expect option, duplicate %s", label.buf); + item->util = (void *)arg; + return 0; +} + +__attribute__((format (printf,3,4))) +static void show(struct string_list *expect, int *status, const char *fmt, ...) +{ + struct string_list_item *item; + struct strbuf buf = STRBUF_INIT; + va_list args; + + va_start(args, fmt); + strbuf_vaddf(&buf, fmt, args); + va_end(args); + + if (!expect->nr) + printf("%s\n", buf.buf); + else { + char *colon = strchr(buf.buf, ':'); + if (!colon) + die("malformed output format, output lacking colon: %s", fmt); + *colon = '\0'; + item = string_list_lookup(expect, buf.buf); + *colon = ':'; + if (!item) + ; /* not among entries being checked */ + else { + if (strcmp((const char *)item->util, buf.buf)) { + printf("-%s\n", (char *)item->util); + printf("+%s\n", buf.buf); + *status = 1; + } + } + } + strbuf_release(&buf); +} + int main(int argc, char **argv) { const char *prefix = "prefix/"; @@ -37,6 +101,7 @@ int main(int argc, char **argv) "test-parse-options <options>", NULL }; + struct string_list expect = STRING_LIST_INIT_NODUP; struct option options[] = { OPT_BOOL(0, "yes", &boolean, "get a boolean"), OPT_BOOL('D', "no-doubt", &boolean, "begins with 'no-'"), @@ -77,28 +142,38 @@ int main(int argc, char **argv) OPT__VERBOSE(&verbose, "be verbose"), OPT__DRY_RUN(&dry_run, "dry run"), OPT__QUIET(&quiet, "be quiet"), + OPT_CALLBACK(0, "expect", &expect, "string", + "expected output in the variable dump", + collect_expect), OPT_END(), }; int i; + int ret = 0; argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0); - printf("boolean: %d\n", boolean); - printf("integer: %d\n", integer); - printf("magnitude: %lu\n", magnitude); - printf("timestamp: %lu\n", timestamp); - printf("string: %s\n", string ? string : "(not set)"); - printf("abbrev: %d\n", abbrev); - printf("verbose: %d\n", verbose); - printf("quiet: %s\n", quiet ? "yes" : "no"); - printf("dry run: %s\n", dry_run ? "yes" : "no"); - printf("file: %s\n", file ? file : "(not set)"); + if (length_cb.called) { + const char *arg = length_cb.arg; + int unset = length_cb.unset; + show(&expect, &ret, "Callback: \"%s\", %d", + (arg ? arg : "not set"), unset); + } + show(&expect, &ret, "boolean: %d", boolean); + show(&expect, &ret, "integer: %d", integer); + show(&expect, &ret, "magnitude: %lu", magnitude); + show(&expect, &ret, "timestamp: %lu", timestamp); + show(&expect, &ret, "string: %s", string ? string : "(not set)"); + show(&expect, &ret, "abbrev: %d", abbrev); + show(&expect, &ret, "verbose: %d", verbose); + show(&expect, &ret, "quiet: %d", quiet); + show(&expect, &ret, "dry run: %s", dry_run ? "yes" : "no"); + show(&expect, &ret, "file: %s", file ? file : "(not set)"); for (i = 0; i < list.nr; i++) - printf("list: %s\n", list.items[i].string); + show(&expect, &ret, "list: %s", list.items[i].string); for (i = 0; i < argc; i++) - printf("arg %02d: %s\n", i, argv[i]); + show(&expect, &ret, "arg %02d: %s", i, argv[i]); - return 0; + return ret; } diff --git a/test-path-utils.c b/t/helper/test-path-utils.c index ba805b374c..ba805b374c 100644 --- a/test-path-utils.c +++ b/t/helper/test-path-utils.c diff --git a/test-prio-queue.c b/t/helper/test-prio-queue.c index 7be72f0086..7be72f0086 100644 --- a/test-prio-queue.c +++ b/t/helper/test-prio-queue.c diff --git a/test-read-cache.c b/t/helper/test-read-cache.c index b25bcf139b..b25bcf139b 100644 --- a/test-read-cache.c +++ b/t/helper/test-read-cache.c diff --git a/test-regex.c b/t/helper/test-regex.c index 0dc598ecdc..0dc598ecdc 100644 --- a/test-regex.c +++ b/t/helper/test-regex.c diff --git a/test-revision-walking.c b/t/helper/test-revision-walking.c index 3d0313354b..3d0313354b 100644 --- a/test-revision-walking.c +++ b/t/helper/test-revision-walking.c diff --git a/test-run-command.c b/t/helper/test-run-command.c index 30a64a98dc..30a64a98dc 100644 --- a/test-run-command.c +++ b/t/helper/test-run-command.c diff --git a/test-scrap-cache-tree.c b/t/helper/test-scrap-cache-tree.c index 6efee31a48..6efee31a48 100644 --- a/test-scrap-cache-tree.c +++ b/t/helper/test-scrap-cache-tree.c diff --git a/test-sha1-array.c b/t/helper/test-sha1-array.c index 60ea1d5f14..60ea1d5f14 100644 --- a/test-sha1-array.c +++ b/t/helper/test-sha1-array.c diff --git a/test-sha1.c b/t/helper/test-sha1.c index e57eae10bf..e57eae10bf 100644 --- a/test-sha1.c +++ b/t/helper/test-sha1.c diff --git a/test-sha1.sh b/t/helper/test-sha1.sh index cef4bcc866..750b95a0a1 100755 --- a/test-sha1.sh +++ b/t/helper/test-sha1.sh @@ -1,7 +1,7 @@ #!/bin/sh dd if=/dev/zero bs=1048576 count=100 2>/dev/null | -/usr/bin/time ./test-sha1 >/dev/null +/usr/bin/time t/helper/test-sha1 >/dev/null while read expect cnt pfx do @@ -11,7 +11,7 @@ do test -z "$pfx" || echo "$pfx" dd if=/dev/zero bs=1048576 count=$cnt 2>/dev/null | perl -pe 'y/\000/g/' - } | ./test-sha1 $cnt + } | ./t/helper/test-sha1 $cnt ) if test "$expect" = "$actual" then diff --git a/test-sigchain.c b/t/helper/test-sigchain.c index e499fce60f..e499fce60f 100644 --- a/test-sigchain.c +++ b/t/helper/test-sigchain.c diff --git a/test-string-list.c b/t/helper/test-string-list.c index 14bdf9d215..14bdf9d215 100644 --- a/test-string-list.c +++ b/t/helper/test-string-list.c diff --git a/test-submodule-config.c b/t/helper/test-submodule-config.c index dab8c27768..dab8c27768 100644 --- a/test-submodule-config.c +++ b/t/helper/test-submodule-config.c diff --git a/test-subprocess.c b/t/helper/test-subprocess.c index 56881a0324..56881a0324 100644 --- a/test-subprocess.c +++ b/t/helper/test-subprocess.c diff --git a/test-svn-fe.c b/t/helper/test-svn-fe.c index 120ec96b0d..120ec96b0d 100644 --- a/test-svn-fe.c +++ b/t/helper/test-svn-fe.c diff --git a/test-urlmatch-normalization.c b/t/helper/test-urlmatch-normalization.c index 090bf219a7..090bf219a7 100644 --- a/test-urlmatch-normalization.c +++ b/t/helper/test-urlmatch-normalization.c diff --git a/test-wildmatch.c b/t/helper/test-wildmatch.c index 578b164fe6..578b164fe6 100644 --- a/test-wildmatch.c +++ b/t/helper/test-wildmatch.c diff --git a/t/lib-git-p4.sh b/t/lib-git-p4.sh index f9ae1d780d..54fd5a6ca0 100644 --- a/t/lib-git-p4.sh +++ b/t/lib-git-p4.sh @@ -33,7 +33,7 @@ fi # Older versions of perforce were available compiled natively for # cygwin. Those do not accept native windows paths, so make sure # not to convert for them. -native_path() { +native_path () { path="$1" && if test_have_prereq CYGWIN && ! p4 -V | grep -q CYGWIN then @@ -49,8 +49,8 @@ native_path() { # Attention: This function is not safe again against time offset updates # at runtime (e.g. via NTP). The 'clock_gettime(CLOCK_MONOTONIC)' # function could fix that but it is not in Python until 3.3. -time_in_seconds() { - python -c 'import time; print int(time.time())' +time_in_seconds () { + (cd / && "$PYTHON_PATH" -c 'import time; print(int(time.time()))') } # Try to pick a unique port: guess a large number, then hope @@ -75,7 +75,7 @@ git="$TRASH_DIRECTORY/git" pidfile="$TRASH_DIRECTORY/p4d.pid" # Sometimes "prove" seems to hang on exit because p4d is still running -cleanup() { +cleanup () { if test -f "$pidfile" then kill -9 $(cat "$pidfile") 2>/dev/null && exit 255 @@ -89,7 +89,7 @@ trap cleanup EXIT TMPDIR="$TRASH_DIRECTORY" export TMPDIR -start_p4d() { +start_p4d () { mkdir -p "$db" "$cli" "$git" && rm -f "$pidfile" && ( @@ -151,7 +151,7 @@ start_p4d() { return 0 } -p4_add_user() { +p4_add_user () { name=$1 && p4 user -f -i <<-EOF User: $name @@ -160,7 +160,16 @@ p4_add_user() { EOF } -retry_until_success() { +p4_add_job () { + p4 job -f -i <<-EOF + Job: $1 + Status: open + User: dummy + Description: + EOF +} + +retry_until_success () { timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) until "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout do @@ -168,7 +177,7 @@ retry_until_success() { done } -retry_until_fail() { +retry_until_fail () { timeout=$(($(time_in_seconds) + $RETRY_TIMEOUT)) until ! "$@" 2>/dev/null || test $(time_in_seconds) -gt $timeout do @@ -176,7 +185,7 @@ retry_until_fail() { done } -kill_p4d() { +kill_p4d () { pid=$(cat "$pidfile") retry_until_fail kill $pid retry_until_fail kill -9 $pid @@ -186,21 +195,22 @@ kill_p4d() { retry_until_fail kill -9 $watchdog_pid } -cleanup_git() { +cleanup_git () { retry_until_success rm -r "$git" test_must_fail test -d "$git" && retry_until_success mkdir "$git" } -marshal_dump() { +marshal_dump () { what=$1 && line=${2:-1} && cat >"$TRASH_DIRECTORY/marshal-dump.py" <<-EOF && import marshal import sys + instream = getattr(sys.stdin, 'buffer', sys.stdin) for i in range($line): - d = marshal.load(sys.stdin) - print d['$what'] + d = marshal.load(instream) + print(d[b'$what'].decode('utf-8')) EOF "$PYTHON_PATH" "$TRASH_DIRECTORY/marshal-dump.py" } @@ -208,7 +218,7 @@ marshal_dump() { # # Construct a client with this list of View lines # -client_view() { +client_view () { ( cat <<-EOF && Client: $P4CLIENT @@ -222,7 +232,7 @@ client_view() { ) | p4 client -i } -is_cli_file_writeable() { +is_cli_file_writeable () { # cygwin version of p4 does not set read-only attr, # will be marked 444 but -w is true file="$1" && diff --git a/t/lib-git-svn.sh b/t/lib-git-svn.sh index 6a50b8793e..fb8823224e 100644 --- a/t/lib-git-svn.sh +++ b/t/lib-git-svn.sh @@ -1,8 +1,5 @@ . ./test-lib.sh -remotes_git_svn=remotes/git""-svn -git_svn_id=git""-svn-id - if test -n "$NO_SVN_TESTS" then skip_all='skipping git svn tests, NO_SVN_TESTS defined' diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 9317ba0858..018a83a5a1 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -102,6 +102,10 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_HTTP_EXPORT_ALL Header set Set-Cookie name=value </LocationMatch> +<LocationMatch /smart_headers/> + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} + SetEnv GIT_HTTP_EXPORT_ALL +</LocationMatch> ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 ScriptAlias /broken_smart/ broken-smart-http.sh/ ScriptAlias /error/ error.sh/ @@ -128,6 +132,18 @@ RewriteRule ^/ftp-redir/(.*)$ ftp://localhost:1000/$1 [R=302] RewriteRule ^/loop-redir/x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-x-(.*) /$1 [R=302] RewriteRule ^/loop-redir/(.*)$ /loop-redir/x-$1 [R=302] +# Apache 2.2 does not understand <RequireAll>, so we use RewriteCond. +# And as RewriteCond does not allow testing for non-matches, we match +# the desired case first (one has abra, two has cadabra), and let it +# pass by marking the RewriteRule as [L], "last rule, do not process +# any other matching RewriteRules after this"), and then have another +# RewriteRule that matches all other cases and lets them fail via '[F]', +# "fail the request". +RewriteCond %{HTTP:x-magic-one} =abra +RewriteCond %{HTTP:x-magic-two} =cadabra +RewriteRule ^/smart_headers/.* - [L] +RewriteRule ^/smart_headers/.* - [F] + <IfDefine SSL> LoadModule ssl_module modules/mod_ssl.so diff --git a/t/perf/p3404-rebase-interactive.sh b/t/perf/p3404-rebase-interactive.sh new file mode 100755 index 0000000000..88f47de282 --- /dev/null +++ b/t/perf/p3404-rebase-interactive.sh @@ -0,0 +1,36 @@ +#!/bin/sh + +test_description='Tests rebase -i performance' +. ./perf-lib.sh + +test_perf_default_repo + +# This commit merges a sufficiently long topic branch for reasonable +# performance testing +branch_merge=ba5312da19c6fdb6c6747d479f58932aae6e900c^{commit} +export branch_merge + +git rev-parse --verify $branch_merge >/dev/null 2>&1 || { + skip_all='skipping because $branch_merge was not found' + test_done +} + +write_script swap-first-two.sh <<\EOF +case "$1" in +*/COMMIT_EDITMSG) + mv "$1" "$1".bak && + sed -e '1{h;d}' -e 2G <"$1".bak >"$1" + ;; +esac +EOF + +test_expect_success 'setup' ' + git config core.editor "\"$PWD"/swap-first-two.sh\" && + git checkout -f $branch_merge^2 +' + +test_perf 'rebase -i' ' + git rebase -i $branch_merge^ +' + +test_done diff --git a/t/perf/perf-lib.sh b/t/perf/perf-lib.sh index 5cf74eddec..5ef17440c0 100644 --- a/t/perf/perf-lib.sh +++ b/t/perf/perf-lib.sh @@ -80,23 +80,26 @@ test_perf_create_repo_from () { error "bug in the test script: not 2 parameters to test-create-repo" repo="$1" source="$2" - source_git=$source/$(cd "$source" && git rev-parse --git-dir) + source_git="$(git -C "$source" rev-parse --git-dir)" + objects_dir="$(git -C "$source" rev-parse --git-path objects)" mkdir -p "$repo/.git" ( - cd "$repo/.git" && - { cp -Rl "$source_git/objects" . 2>/dev/null || - cp -R "$source_git/objects" .; } && + { cp -Rl "$objects_dir" "$repo/.git/" 2>/dev/null || + cp -R "$objects_dir" "$repo/.git/"; } && for stuff in "$source_git"/*; do case "$stuff" in - */objects|*/hooks|*/config) + */objects|*/hooks|*/config|*/commondir) ;; *) - cp -R "$stuff" . || exit 1 + cp -R "$stuff" "$repo/.git/" || exit 1 ;; esac done && - cd .. && - git init -q && + cd "$repo" && + git init -q && { + test_have_prereq SYMLINKS || + git config core.symlinks false + } && mv .git/hooks .git/hooks-disabled 2>/dev/null ) || error "failed to copy repository '$source' to '$repo'" } diff --git a/t/t0000-basic.sh b/t/t0000-basic.sh index 79b9074172..60811a3a7c 100755 --- a/t/t0000-basic.sh +++ b/t/t0000-basic.sh @@ -98,7 +98,7 @@ check_sub_test_lib_test () { } check_sub_test_lib_test_err () { - name="$1" # stdin is the expected output output from the test + name="$1" # stdin is the expected output from the test # expected error output is in descriptior 3 ( cd "$name" && diff --git a/t/t0001-init.sh b/t/t0001-init.sh index a5b9e7a4c7..a6fdd5ef3a 100755 --- a/t/t0001-init.sh +++ b/t/t0001-init.sh @@ -354,4 +354,34 @@ test_expect_success SYMLINKS 're-init to move gitdir symlink' ' test_path_is_dir realgitdir/refs ' +# Tests for the hidden file attribute on windows +is_hidden () { + # Use the output of `attrib`, ignore the absolute path + case "$(attrib "$1")" in *H*?:*) return 0;; esac + return 1 +} + +test_expect_success MINGW '.git hidden' ' + rm -rf newdir && + ( + unset GIT_DIR GIT_WORK_TREE + mkdir newdir && + cd newdir && + git init && + is_hidden .git + ) && + check_config newdir/.git false unset +' + +test_expect_success MINGW 'bare git dir not hidden' ' + rm -rf newdir && + ( + unset GIT_DIR GIT_WORK_TREE GIT_CONFIG + mkdir newdir && + cd newdir && + git --bare init + ) && + ! is_hidden newdir +' + test_done diff --git a/t/t0027-auto-crlf.sh b/t/t0027-auto-crlf.sh index f33962b178..93725895a4 100755 --- a/t/t0027-auto-crlf.sh +++ b/t/t0027-auto-crlf.sh @@ -12,7 +12,7 @@ fi compare_files () { tr '\015\000' QN <"$1" >"$1".expect && - tr '\015\000' QN <"$2" >"$2".actual && + tr '\015\000' QN <"$2" | tr -d 'Z' >"$2".actual && test_cmp "$1".expect "$2".actual && rm "$1".expect "$2".actual } @@ -52,14 +52,17 @@ create_gitattributes () { create_NNO_files () { for crlf in false true input do - for attr in "" auto text -text lf crlf + for attr in "" auto text -text do - pfx=NNO_${crlf}_attr_${attr} && - cp CRLF_mix_LF ${pfx}_LF.txt && - cp CRLF_mix_LF ${pfx}_CRLF.txt && - cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt && - cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt && - cp CRLF_mix_LF ${pfx}_CRLF_nul.txt + for aeol in "" lf crlf + do + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} + cp CRLF_mix_LF ${pfx}_LF.txt && + cp CRLF_mix_LF ${pfx}_CRLF.txt && + cp CRLF_mix_LF ${pfx}_CRLF_mix_LF.txt && + cp CRLF_mix_LF ${pfx}_LF_mix_CR.txt && + cp CRLF_mix_LF ${pfx}_CRLF_nul.txt + done done done } @@ -100,20 +103,22 @@ commit_check_warn () { } commit_chk_wrnNNO () { - crlf=$1 - attr=$2 - lfwarn=$3 - crlfwarn=$4 - lfmixcrlf=$5 - lfmixcr=$6 - crlfnul=$7 - pfx=NNO_${crlf}_attr_${attr} + attr=$1 ; shift + aeol=$1 ; shift + crlf=$1 ; shift + lfwarn=$1 ; shift + crlfwarn=$1 ; shift + lfmixcrlf=$1 ; shift + lfmixcr=$1 ; shift + crlfnul=$1 ; shift + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} #Commit files on top of existing file - create_gitattributes "$attr" && + create_gitattributes "$attr" $aeol && for f in LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul do fname=${pfx}_$f.txt && cp $f $fname && + printf Z >>"$fname" && git -c core.autocrlf=$crlf add $fname 2>/dev/null && git -c core.autocrlf=$crlf commit -m "commit_$fname" $fname >"${pfx}_$f.err" 2>&1 done @@ -121,19 +126,19 @@ commit_chk_wrnNNO () { test_expect_success "commit NNO files crlf=$crlf attr=$attr LF" ' check_warning "$lfwarn" ${pfx}_LF.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF" ' check_warning "$crlfwarn" ${pfx}_CRLF.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_mix_LF" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_mix_LF" ' check_warning "$lfmixcrlf" ${pfx}_CRLF_mix_LF.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr LF_mix_cr" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf LF_mix_cr" ' check_warning "$lfmixcr" ${pfx}_LF_mix_CR.err ' - test_expect_success "commit NNO files crlf=$crlf attr=$attr CRLF_nul" ' + test_expect_success "commit NNO files attr=$attr aeol=$aeol crlf=$crlf CRLF_nul" ' check_warning "$crlfnul" ${pfx}_CRLF_nul.err ' } @@ -162,6 +167,7 @@ stats_ascii () { # contruct the attr/ returned by git ls-files --eol # Take none (=empty), one or two args +# convert.c: eol=XX overrides text=auto attr_ascii () { case $1,$2 in -text,*) echo "-text" ;; @@ -169,8 +175,8 @@ attr_ascii () { text,lf) echo "text eol=lf" ;; text,crlf) echo "text eol=crlf" ;; auto,) echo "text=auto" ;; - auto,lf) echo "text=auto eol=lf" ;; - auto,crlf) echo "text=auto eol=crlf" ;; + auto,lf) echo "text eol=lf" ;; + auto,crlf) echo "text eol=crlf" ;; lf,) echo "text eol=lf" ;; crlf,) echo "text eol=crlf" ;; ,) echo "" ;; @@ -195,28 +201,29 @@ check_files_in_repo () { } check_in_repo_NNO () { - crlf=$1 - attr=$2 - lfname=$3 - crlfname=$4 - lfmixcrlf=$5 - lfmixcr=$6 - crlfnul=$7 - pfx=NNO_${crlf}_attr_${attr}_ - test_expect_success "compare_files $lfname ${pfx}LF.txt" ' - compare_files $lfname ${pfx}LF.txt + attr=$1 ; shift + aeol=$1 ; shift + crlf=$1 ; shift + lfname=$1 ; shift + crlfname=$1 ; shift + lfmixcrlf=$1 ; shift + lfmixcr=$1 ; shift + crlfnul=$1 ; shift + pfx=NNO_attr_${attr}_aeol_${aeol}_${crlf} + test_expect_success "compare_files $lfname ${pfx}_LF.txt" ' + compare_files $lfname ${pfx}_LF.txt ' - test_expect_success "compare_files $crlfname ${pfx}CRLF.txt" ' - compare_files $crlfname ${pfx}CRLF.txt + test_expect_success "compare_files $crlfname ${pfx}_CRLF.txt" ' + compare_files $crlfname ${pfx}_CRLF.txt ' - test_expect_success "compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt" ' - compare_files $lfmixcrlf ${pfx}CRLF_mix_LF.txt + test_expect_success "compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt" ' + compare_files $lfmixcrlf ${pfx}_CRLF_mix_LF.txt ' - test_expect_success "compare_files $lfmixcr ${pfx}LF_mix_CR.txt" ' - compare_files $lfmixcr ${pfx}LF_mix_CR.txt + test_expect_success "compare_files $lfmixcr ${pfx}_LF_mix_CR.txt" ' + compare_files $lfmixcr ${pfx}_LF_mix_CR.txt ' - test_expect_success "compare_files $crlfnul ${pfx}CRLF_nul.txt" ' - compare_files $crlfnul ${pfx}CRLF_nul.txt + test_expect_success "compare_files $crlfnul ${pfx}_CRLF_nul.txt" ' + compare_files $crlfnul ${pfx}_CRLF_nul.txt ' } @@ -231,7 +238,7 @@ checkout_files () { lfmixcrlf=$1 ; shift lfmixcr=$1 ; shift crlfnul=$1 ; shift - create_gitattributes "$attr" "$ident" && + create_gitattributes "$attr" $ident $aeol && git config core.autocrlf $crlf && pfx=eol_${ceol}_crlf_${crlf}_attr_${attr}_ && for f in LF CRLF LF_mix_CR CRLF_mix_LF LF_nul @@ -244,7 +251,7 @@ checkout_files () { fi done - test_expect_success "ls-files --eol attr=$attr $ident $aeol core.autocrlf=$crlf core.eol=$ceol" ' + test_expect_success "ls-files --eol attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol" ' test_when_finished "rm expect actual" && sort <<-EOF >expect && i/crlf w/$(stats_ascii $crlfname) attr/$(attr_ascii $attr $aeol) crlf_false_attr__CRLF.txt @@ -259,19 +266,19 @@ checkout_files () { sort >actual && test_cmp expect actual ' - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF" " compare_ws_file $pfx $lfname crlf_false_attr__LF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF" " compare_ws_file $pfx $crlfname crlf_false_attr__CRLF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=CRLF_mix_LF" " compare_ws_file $pfx $lfmixcrlf crlf_false_attr__CRLF_mix_LF.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_mix_CR" " compare_ws_file $pfx $lfmixcr crlf_false_attr__LF_mix_CR.txt " - test_expect_success "checkout $ident $attr $aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" " + test_expect_success "checkout attr=$attr $ident aeol=$aeol core.autocrlf=$crlf core.eol=$ceol file=LF_nul" " compare_ws_file $pfx $crlfnul crlf_false_attr__LF_nul.txt " } @@ -385,31 +392,31 @@ test_expect_success 'commit files attr=crlf' ' commit_check_warn input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" ' -# attr LF CRLF CRLFmixLF LF_mix_CR CRLFNUL -commit_chk_wrnNNO false "" "" "" "" "" "" -commit_chk_wrnNNO true "" "LF_CRLF" "" "" "" "" -commit_chk_wrnNNO input "" "" "" "" "" "" - +# attr LF CRLF CRLFmixLF LF_mix_CR CRLFNUL +commit_chk_wrnNNO "" "" false "" "" "" "" "" +commit_chk_wrnNNO "" "" true LF_CRLF "" "" "" "" +commit_chk_wrnNNO "" "" input "" "" "" "" "" -commit_chk_wrnNNO false "auto" "$WILC" "$WICL" "$WAMIX" "" "" -commit_chk_wrnNNO true "auto" "LF_CRLF" "" "LF_CRLF" "" "" -commit_chk_wrnNNO input "auto" "" "CRLF_LF" "CRLF_LF" "" "" +commit_chk_wrnNNO "auto" "" false "$WILC" "$WICL" "$WAMIX" "" "" +commit_chk_wrnNNO "auto" "" true LF_CRLF "" LF_CRLF "" "" +commit_chk_wrnNNO "auto" "" input "" CRLF_LF CRLF_LF "" "" -commit_chk_wrnNNO false "text" "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" -commit_chk_wrnNNO true "text" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" -commit_chk_wrnNNO input "text" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" - -commit_chk_wrnNNO false "-text" "" "" "" "" "" -commit_chk_wrnNNO true "-text" "" "" "" "" "" -commit_chk_wrnNNO input "-text" "" "" "" "" "" - -commit_chk_wrnNNO false "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" -commit_chk_wrnNNO true "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" -commit_chk_wrnNNO input "lf" "" "CRLF_LF" "CRLF_LF" "" "CRLF_LF" +for crlf in true false input +do + commit_chk_wrnNNO -text "" $crlf "" "" "" "" "" + commit_chk_wrnNNO -text lf $crlf "" "" "" "" "" + commit_chk_wrnNNO -text crlf $crlf "" "" "" "" "" + commit_chk_wrnNNO "" lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO "" crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" + commit_chk_wrnNNO auto lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO auto crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" + commit_chk_wrnNNO text lf $crlf "" CRLF_LF CRLF_LF "" CRLF_LF + commit_chk_wrnNNO text crlf $crlf LF_CRLF "" LF_CRLF LF_CRLF "" +done -commit_chk_wrnNNO false "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" -commit_chk_wrnNNO true "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" -commit_chk_wrnNNO input "crlf" "LF_CRLF" "" "LF_CRLF" "LF_CRLF" "" +commit_chk_wrnNNO "text" "" false "$WILC" "$WICL" "$WAMIX" "$WILC" "$WICL" +commit_chk_wrnNNO "text" "" true LF_CRLF "" LF_CRLF LF_CRLF "" +commit_chk_wrnNNO "text" "" input "" CRLF_LF CRLF_LF "" CRLF_LF test_expect_success 'create files cleanup' ' rm -f *.txt && @@ -440,24 +447,20 @@ test_expect_success 'commit -text' ' check_files_in_repo input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul ' -# attr LF CRLF CRLF_mix_LF LF_mix_CR CRLFNUL -check_in_repo_NNO false "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_in_repo_NNO true "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_in_repo_NNO input "" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul - -check_in_repo_NNO false "auto" LF LF LF LF_mix_CR CRLF_nul -check_in_repo_NNO true "auto" LF LF LF LF_mix_CR CRLF_nul -check_in_repo_NNO input "auto" LF LF LF LF_mix_CR CRLF_nul - -check_in_repo_NNO false "text" LF LF LF LF_mix_CR LF_nul -check_in_repo_NNO true "text" LF LF LF LF_mix_CR LF_nul -check_in_repo_NNO input "text" LF LF LF LF_mix_CR LF_nul - -check_in_repo_NNO false "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_in_repo_NNO true "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul -check_in_repo_NNO input "-text" LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul - - +for crlf in true false input +do + # attr aeol LF CRLF CRLF_mix_LF LF_mix_CR CRLFNUL + check_in_repo_NNO "" "" $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text "" $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text lf $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO -text crlf $crlf LF CRLF CRLF_mix_LF LF_mix_CR CRLF_nul + check_in_repo_NNO auto "" $crlf LF LF LF LF_mix_CR CRLF_nul + check_in_repo_NNO auto lf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO auto crlf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text "" $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text lf $crlf LF LF LF LF_mix_CR LF_nul + check_in_repo_NNO text crlf $crlf LF LF LF LF_mix_CR LF_nul +done ################################################################################ # Check how files in the repo are changed when they are checked out # How to read the table below: @@ -489,89 +492,47 @@ LFNUL=LF_nul fi export CRLF_MIX_LF_CR MIX NL -checkout_files "" "" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true "" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true crlf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true lf CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" "" "" true native CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false "" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false crlf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" false native $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" "" "" true "" CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true crlf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true lf CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" "" "" true native CRLF CRLF CRLF LF_mix_CR LF_nul -checkout_files "auto" ident "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul -checkout_files "auto" ident "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - -for id in "" ident; +# Same handling with and without ident +for id in "" ident do - checkout_files "crlf" "$id" "" false "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" false native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" input "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" input lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "crlf" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "lf" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "lf" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" false "" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL - checkout_files "text" "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" false native $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL - checkout_files "text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "text" "$id" "" true "" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true lf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "text" "$id" "" true native CRLF CRLF CRLF CRLF_mix_CR CRLF_nul - checkout_files "-text" "$id" "" false "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" false native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" input "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" input lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true "" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true crlf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul - checkout_files "-text" "$id" "" true native LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + for ceol in lf crlf native + do + for crlf in true false input + do + # -text overrides core.autocrlf and core.eol + # text and eol=crlf or eol=lf override core.autocrlf and core.eol + checkout_files -text "$id" "" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files -text "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files -text "$id" "crlf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text + checkout_files text "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files text "$id" "crlf" "$crlf" "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + # currently the same as text, eol=XXX + checkout_files auto "$id" "lf" "$crlf" "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files auto "$id" "crlf" "$crlf" "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + done + + # core.autocrlf false, different core.eol + checkout_files "" "$id" "" false "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # core.autocrlf true + checkout_files "" "$id" "" true "$ceol" CRLF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text: core.autocrlf = true overrides core.eol + checkout_files auto "$id" "" true "$ceol" CRLF CRLF CRLF LF_mix_CR LF_nul + checkout_files text "$id" "" true "$ceol" CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + # text: core.autocrlf = input overrides core.eol + checkout_files text "$id" "" input "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + checkout_files auto "$id" "" input "$ceol" LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text=auto + eol=XXX + done + # text: core.autocrlf=false uses core.eol + checkout_files text "$id" "" false crlf CRLF CRLF CRLF CRLF_mix_CR CRLF_nul + checkout_files text "$id" "" false lf LF CRLF CRLF_mix_LF LF_mix_CR LF_nul + # text: core.autocrlf=false and core.eol unset(or native) uses native eol + checkout_files text "$id" "" false "" $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL + checkout_files text "$id" "" false native $NL CRLF $MIX_CRLF_LF $MIX_LF_CR $LFNUL + # auto: core.autocrlf=false and core.eol unset(or native) uses native eol + checkout_files auto "$id" "" false "" $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul + checkout_files auto "$id" "" false native $NL CRLF $MIX_CRLF_LF LF_mix_CR LF_nul done # Should be the last test case: remove some files from the worktree diff --git a/t/t0040-parse-options.sh b/t/t0040-parse-options.sh index 9be6411104..db5f60d0c5 100755 --- a/t/t0040-parse-options.sh +++ b/t/t0040-parse-options.sh @@ -7,7 +7,7 @@ test_description='our own option parser' . ./test-lib.sh -cat > expect << EOF +cat >expect <<\EOF usage: test-parse-options <options> --yes get a boolean @@ -45,63 +45,24 @@ Standard options -v, --verbose be verbose -n, --dry-run dry run -q, --quiet be quiet + --expect <string> expected output in the variable dump EOF test_expect_success 'test help' ' - test_must_fail test-parse-options -h > output 2> output.err && + test_must_fail test-parse-options -h >output 2>output.err && test_must_be_empty output.err && test_i18ncmp expect output ' mv expect expect.err -cat >expect.template <<EOF -boolean: 0 -integer: 0 -magnitude: 0 -timestamp: 0 -string: (not set) -abbrev: 7 -verbose: 0 -quiet: no -dry run: no -file: (not set) -EOF - -check() { +check () { what="$1" && shift && expect="$1" && shift && - sed "s/^$what .*/$what $expect/" <expect.template >expect && - test-parse-options $* >output 2>output.err && - test_must_be_empty output.err && - test_cmp expect output -} - -check_i18n() { - what="$1" && - shift && - expect="$1" && - shift && - sed "s/^$what .*/$what $expect/" <expect.template >expect && - test-parse-options $* >output 2>output.err && - test_must_be_empty output.err && - test_i18ncmp expect output -} - -check_unknown() { - case "$1" in - --*) - echo error: unknown option \`${1#--}\' >expect ;; - -*) - echo error: unknown switch \`${1#-}\' >expect ;; - esac && - cat expect.err >>expect && - test_must_fail test-parse-options $* >output 2>output.err && - test_must_be_empty output && - test_cmp expect output.err + test-parse-options --expect="$what $expect" "$@" } check_unknown_i18n() { @@ -156,7 +117,7 @@ test_expect_success 'OPT_MAGNITUDE() 3giga' ' check magnitude: 3221225472 -m 3g ' -cat > expect << EOF +cat >expect <<\EOF boolean: 2 integer: 1729 magnitude: 16384 @@ -164,7 +125,7 @@ timestamp: 0 string: 123 abbrev: 7 verbose: 2 -quiet: no +quiet: 0 dry run: yes file: prefix/my.file EOF @@ -176,7 +137,7 @@ test_expect_success 'short options' ' test_must_be_empty output.err ' -cat > expect << EOF +cat >expect <<\EOF boolean: 2 integer: 1729 magnitude: 16384 @@ -184,7 +145,7 @@ timestamp: 0 string: 321 abbrev: 10 verbose: 2 -quiet: no +quiet: 0 dry run: no file: prefix/fi.le EOF @@ -204,15 +165,15 @@ test_expect_success 'missing required value' ' test_expect_code 129 test-parse-options --file ' -cat > expect << EOF +cat >expect <<\EOF boolean: 1 integer: 13 magnitude: 0 timestamp: 0 string: 123 abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) arg 00: a1 @@ -222,32 +183,32 @@ EOF test_expect_success 'intermingled arguments' ' test-parse-options a1 --string 123 b1 --boolean -j 13 -- --boolean \ - > output 2> output.err && + >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect << EOF +cat >expect <<\EOF boolean: 0 integer: 2 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'unambiguously abbreviated option' ' - test-parse-options --int 2 --boolean --no-bo > output 2> output.err && + test-parse-options --int 2 --boolean --no-bo >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'unambiguously abbreviated option with "="' ' - test-parse-options --int=2 > output 2> output.err && + test-parse-options --int=2 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' @@ -256,74 +217,74 @@ test_expect_success 'ambiguously abbreviated option' ' test_expect_code 129 test-parse-options --strin 123 ' -cat > expect << EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: 123 abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'non ambiguous option (after two options it abbreviates)' ' - test-parse-options --st 123 > output 2> output.err && + test-parse-options --st 123 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > typo.err << EOF -error: did you mean \`--boolean\` (with two dashes ?) +cat >typo.err <<\EOF +error: did you mean `--boolean` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - test_must_fail test-parse-options -boolean > output 2> output.err && + test_must_fail test-parse-options -boolean >output 2>output.err && test_must_be_empty output && test_cmp typo.err output.err ' -cat > typo.err << EOF -error: did you mean \`--ambiguous\` (with two dashes ?) +cat >typo.err <<\EOF +error: did you mean `--ambiguous` (with two dashes ?) EOF test_expect_success 'detect possible typos' ' - test_must_fail test-parse-options -ambiguous > output 2> output.err && + test_must_fail test-parse-options -ambiguous >output 2>output.err && test_must_be_empty output && test_cmp typo.err output.err ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) arg 00: --quux EOF test_expect_success 'keep some options as arguments' ' - test-parse-options --quux > output 2> output.err && + test-parse-options --quux >output 2>output.err && test_must_be_empty output.err && - test_cmp expect output + test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 1 string: (not set) abbrev: 7 -verbose: 0 -quiet: yes +verbose: -1 +quiet: 1 dry run: no file: (not set) arg 00: foo @@ -331,12 +292,12 @@ EOF test_expect_success 'OPT_DATE() works' ' test-parse-options -t "1970-01-01 00:00:01 +0000" \ - foo -q > output 2> output.err && + foo -q >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF Callback: "four", 0 boolean: 5 integer: 4 @@ -344,112 +305,110 @@ magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_CALLBACK() and OPT_BIT() work' ' - test-parse-options --length=four -b -4 > output 2> output.err && + test-parse-options --length=four -b -4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF -Callback: "not set", 1 -EOF +>expect test_expect_success 'OPT_CALLBACK() and callback errors work' ' - test_must_fail test-parse-options --no-length > output 2> output.err && + test_must_fail test-parse-options --no-length >output 2>output.err && test_i18ncmp expect output && test_i18ncmp expect.err output.err ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 1 integer: 23 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_BIT() and OPT_SET_INT() work' ' - test-parse-options --set23 -bbbbb --no-or4 > output 2> output.err && + test-parse-options --set23 -bbbbb --no-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() and OPT_SET_INT() work' ' - test-parse-options --set23 -bbbbb --neg-or4 > output 2> output.err && + test-parse-options --set23 -bbbbb --neg-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 6 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_BIT() works' ' - test-parse-options -bb --or4 > output 2> output.err && + test-parse-options -bb --or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_NEGBIT() works' ' - test-parse-options -bb --no-neg-or4 > output 2> output.err && + test-parse-options -bb --no-neg-or4 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' test_expect_success 'OPT_COUNTUP() with PARSE_OPT_NODASH works' ' - test-parse-options + + + + + + > output 2> output.err && + test-parse-options + + + + + + >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat > expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 12345 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF test_expect_success 'OPT_NUMBER_CALLBACK() works' ' - test-parse-options -12345 > output 2> output.err && + test-parse-options -12345 >output 2>output.err && test_must_be_empty output.err && test_cmp expect output ' -cat >expect <<EOF +cat >expect <<\EOF boolean: 0 integer: 0 magnitude: 0 timestamp: 0 string: (not set) abbrev: 7 -verbose: 0 -quiet: no +verbose: -1 +quiet: 0 dry run: no file: (not set) EOF @@ -460,7 +419,7 @@ test_expect_success 'negation of OPT_NONEG flags is not ambiguous' ' test_cmp expect output ' -cat >>expect <<'EOF' +cat >>expect <<\EOF list: foo list: bar list: baz @@ -476,4 +435,118 @@ test_expect_success '--no-list resets list' ' test_cmp expect output ' +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 3 +dry run: no +file: (not set) +EOF + +test_expect_success 'multiple quiet levels' ' + test-parse-options -q -q -q >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 3 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success 'multiple verbose levels' ' + test-parse-options -v -v -v >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-quiet sets --quiet to 0' ' + test-parse-options --no-quiet >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: -1 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-quiet resets multiple -q to 0' ' + test-parse-options -q -q -q --no-quiet >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-verbose sets verbose to 0' ' + test-parse-options --no-verbose >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + +cat >expect <<\EOF +boolean: 0 +integer: 0 +magnitude: 0 +timestamp: 0 +string: (not set) +abbrev: 7 +verbose: 0 +quiet: 0 +dry run: no +file: (not set) +EOF + +test_expect_success '--no-verbose resets multiple verbose to 0' ' + test-parse-options -v -v -v --no-verbose >output 2>output.err && + test_must_be_empty output.err && + test_cmp expect output +' + test_done diff --git a/t/t0060-path-utils.sh b/t/t0060-path-utils.sh index 8532a028e7..bf2deee109 100755 --- a/t/t0060-path-utils.sh +++ b/t/t0060-path-utils.sh @@ -19,6 +19,13 @@ relative_path() { "test \"\$(test-path-utils relative_path '$1' '$2')\" = '$expected'" } +test_submodule_relative_url() { + test_expect_success "test_submodule_relative_url: $1 $2 $3 => $4" " + actual=\$(git submodule--helper resolve-relative-url-test '$1' '$2' '$3') && + test \"\$actual\" = '$4' + " +} + test_git_path() { test_expect_success "git-path $1 $2 => $3" " $1 git rev-parse --git-path $2 >actual && @@ -298,4 +305,43 @@ test_git_path GIT_COMMON_DIR=bar config bar/config test_git_path GIT_COMMON_DIR=bar packed-refs bar/packed-refs test_git_path GIT_COMMON_DIR=bar shallow bar/shallow +# In the tests below, the distinction between $PWD and $(pwd) is important: +# on Windows, $PWD is POSIX style (/c/foo), $(pwd) has drive letter (c:/foo). + +test_submodule_relative_url "../" "../foo" "../submodule" "../../submodule" +test_submodule_relative_url "../" "../foo/bar" "../submodule" "../../foo/submodule" +test_submodule_relative_url "../" "../foo/submodule" "../submodule" "../../foo/submodule" +test_submodule_relative_url "../" "./foo" "../submodule" "../submodule" +test_submodule_relative_url "../" "./foo/bar" "../submodule" "../foo/submodule" +test_submodule_relative_url "../../../" "../foo/bar" "../sub/a/b/c" "../../../../foo/sub/a/b/c" +test_submodule_relative_url "../" "$PWD/addtest" "../repo" "$(pwd)/repo" +test_submodule_relative_url "../" "foo/bar" "../submodule" "../foo/submodule" +test_submodule_relative_url "../" "foo" "../submodule" "../submodule" + +test_submodule_relative_url "(null)" "../foo/bar" "../sub/a/b/c" "../foo/sub/a/b/c" +test_submodule_relative_url "(null)" "../foo/bar" "../submodule" "../foo/submodule" +test_submodule_relative_url "(null)" "../foo/submodule" "../submodule" "../foo/submodule" +test_submodule_relative_url "(null)" "../foo" "../submodule" "../submodule" +test_submodule_relative_url "(null)" "./foo/bar" "../submodule" "foo/submodule" +test_submodule_relative_url "(null)" "./foo" "../submodule" "submodule" +test_submodule_relative_url "(null)" "//somewhere else/repo" "../subrepo" "//somewhere else/subrepo" +test_submodule_relative_url "(null)" "$PWD/subsuper_update_r" "../subsubsuper_update_r" "$(pwd)/subsubsuper_update_r" +test_submodule_relative_url "(null)" "$PWD/super_update_r2" "../subsuper_update_r" "$(pwd)/subsuper_update_r" +test_submodule_relative_url "(null)" "$PWD/." "../." "$(pwd)/." +test_submodule_relative_url "(null)" "$PWD" "./." "$(pwd)/." +test_submodule_relative_url "(null)" "$PWD/addtest" "../repo" "$(pwd)/repo" +test_submodule_relative_url "(null)" "$PWD" "./Γ₯ Àâ" "$(pwd)/Γ₯ Àâ" +test_submodule_relative_url "(null)" "$PWD/." "../submodule" "$(pwd)/submodule" +test_submodule_relative_url "(null)" "$PWD/submodule" "../submodule" "$(pwd)/submodule" +test_submodule_relative_url "(null)" "$PWD/home2/../remote" "../bundle1" "$(pwd)/home2/../bundle1" +test_submodule_relative_url "(null)" "$PWD/submodule_update_repo" "./." "$(pwd)/submodule_update_repo/." +test_submodule_relative_url "(null)" "file:///tmp/repo" "../subrepo" "file:///tmp/subrepo" +test_submodule_relative_url "(null)" "foo/bar" "../submodule" "foo/submodule" +test_submodule_relative_url "(null)" "foo" "../submodule" "submodule" +test_submodule_relative_url "(null)" "helper:://hostname/repo" "../subrepo" "helper:://hostname/subrepo" +test_submodule_relative_url "(null)" "ssh://hostname/repo" "../subrepo" "ssh://hostname/subrepo" +test_submodule_relative_url "(null)" "ssh://hostname:22/repo" "../subrepo" "ssh://hostname:22/subrepo" +test_submodule_relative_url "(null)" "user@host:path/to/repo" "../subrepo" "user@host:path/to/subrepo" +test_submodule_relative_url "(null)" "user@host:repo" "../subrepo" "user@host:subrepo" + test_done diff --git a/t/t1350-config-hooks-path.sh b/t/t1350-config-hooks-path.sh new file mode 100755 index 0000000000..5e3fb3a6af --- /dev/null +++ b/t/t1350-config-hooks-path.sh @@ -0,0 +1,37 @@ +#!/bin/sh + +test_description='Test the core.hooksPath configuration variable' + +. ./test-lib.sh + +test_expect_success 'set up a pre-commit hook in core.hooksPath' ' + mkdir -p .git/custom-hooks .git/hooks && + write_script .git/custom-hooks/pre-commit <<-\EOF && + echo CUSTOM >>actual + EOF + write_script .git/hooks/pre-commit <<-\EOF + echo NORMAL >>actual + EOF +' + +test_expect_success 'Check that various forms of specifying core.hooksPath work' ' + test_commit no_custom_hook && + git config core.hooksPath .git/custom-hooks && + test_commit have_custom_hook && + git config core.hooksPath .git/custom-hooks/ && + test_commit have_custom_hook_trailing_slash && + git config core.hooksPath "$PWD/.git/custom-hooks" && + test_commit have_custom_hook_abs_path && + git config core.hooksPath "$PWD/.git/custom-hooks/" && + test_commit have_custom_hook_abs_path_trailing_slash && + cat >expect <<-\EOF && + NORMAL + CUSTOM + CUSTOM + CUSTOM + CUSTOM + EOF + test_cmp expect actual +' + +test_done diff --git a/t/t1410-reflog.sh b/t/t1410-reflog.sh index c623824b4d..9cf91dc6d2 100755 --- a/t/t1410-reflog.sh +++ b/t/t1410-reflog.sh @@ -338,4 +338,14 @@ test_expect_failure 'reflog with non-commit entries displays all entries' ' test_line_count = 3 actual ' +test_expect_success 'reflog expire operates on symref not referrent' ' + git branch -l the_symref && + git branch -l referrent && + git update-ref referrent HEAD && + git symbolic-ref refs/heads/the_symref refs/heads/referrent && + test_when_finished "rm -f .git/refs/heads/referrent.lock" && + touch .git/refs/heads/referrent.lock && + git reflog expire --expire=all the_symref +' + test_done diff --git a/t/t1430-bad-ref-name.sh b/t/t1430-bad-ref-name.sh index c465abe8e3..25ddab4e98 100755 --- a/t/t1430-bad-ref-name.sh +++ b/t/t1430-bad-ref-name.sh @@ -42,7 +42,7 @@ test_expect_success 'git branch shows badly named ref as warning' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && git branch >output 2>error && - grep -e "broken\.\.\.ref" error && + test_i18ngrep -e "ignoring ref with broken name refs/heads/broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' @@ -147,35 +147,145 @@ test_expect_success 'rev-parse skips symref pointing to broken name' ' test_when_finished "rm -f .git/refs/heads/broken...ref" && git branch shadow one && cp .git/refs/heads/master .git/refs/heads/broken...ref && - git symbolic-ref refs/tags/shadow refs/heads/broken...ref && - + printf "ref: refs/heads/broken...ref\n" >.git/refs/tags/shadow && + test_when_finished "rm -f .git/refs/tags/shadow" && git rev-parse --verify one >expect && git rev-parse --verify shadow >actual 2>err && test_cmp expect actual && - test_i18ngrep "ignoring.*refs/tags/shadow" err + test_i18ngrep "ignoring dangling symref refs/tags/shadow" err ' -test_expect_success 'update-ref --no-deref -d can delete reference to broken name' ' - git symbolic-ref refs/heads/badname refs/heads/broken...ref && +test_expect_success 'for-each-ref emits warnings for broken names' ' + cp .git/refs/heads/master .git/refs/heads/broken...ref && + test_when_finished "rm -f .git/refs/heads/broken...ref" && + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && test_when_finished "rm -f .git/refs/heads/badname" && - test_path_is_file .git/refs/heads/badname && - git update-ref --no-deref -d refs/heads/badname && - test_path_is_missing .git/refs/heads/badname + printf "ref: refs/heads/master\n" >.git/refs/heads/broken...symref && + test_when_finished "rm -f .git/refs/heads/broken...symref" && + git for-each-ref >output 2>error && + ! grep -e "broken\.\.\.ref" output && + ! grep -e "badname" output && + ! grep -e "broken\.\.\.symref" output && + test_i18ngrep "ignoring ref with broken name refs/heads/broken\.\.\.ref" error && + test_i18ngrep "ignoring broken ref refs/heads/badname" error && + test_i18ngrep "ignoring ref with broken name refs/heads/broken\.\.\.symref" error ' test_expect_success 'update-ref -d can delete broken name' ' cp .git/refs/heads/master .git/refs/heads/broken...ref && test_when_finished "rm -f .git/refs/heads/broken...ref" && - git update-ref -d refs/heads/broken...ref && + git update-ref -d refs/heads/broken...ref >output 2>error && + test_must_be_empty output && + test_must_be_empty error && + git branch >output 2>error && + ! grep -e "broken\.\.\.ref" error && + ! grep -e "broken\.\.\.ref" output +' + +test_expect_success 'branch -d can delete broken name' ' + cp .git/refs/heads/master .git/refs/heads/broken...ref && + test_when_finished "rm -f .git/refs/heads/broken...ref" && + git branch -d broken...ref >output 2>error && + test_i18ngrep "Deleted branch broken...ref (was broken)" output && + test_must_be_empty error && git branch >output 2>error && ! grep -e "broken\.\.\.ref" error && ! grep -e "broken\.\.\.ref" output ' +test_expect_success 'update-ref --no-deref -d can delete symref to broken name' ' + cp .git/refs/heads/master .git/refs/heads/broken...ref && + test_when_finished "rm -f .git/refs/heads/broken...ref" && + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test_when_finished "rm -f .git/refs/heads/badname" && + git update-ref --no-deref -d refs/heads/badname >output 2>error && + test_path_is_missing .git/refs/heads/badname && + test_must_be_empty output && + test_must_be_empty error +' + +test_expect_success 'branch -d can delete symref to broken name' ' + cp .git/refs/heads/master .git/refs/heads/broken...ref && + test_when_finished "rm -f .git/refs/heads/broken...ref" && + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test_when_finished "rm -f .git/refs/heads/badname" && + git branch -d badname >output 2>error && + test_path_is_missing .git/refs/heads/badname && + test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && + test_must_be_empty error +' + +test_expect_success 'update-ref --no-deref -d can delete dangling symref to broken name' ' + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test_when_finished "rm -f .git/refs/heads/badname" && + git update-ref --no-deref -d refs/heads/badname >output 2>error && + test_path_is_missing .git/refs/heads/badname && + test_must_be_empty output && + test_must_be_empty error +' + +test_expect_success 'branch -d can delete dangling symref to broken name' ' + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test_when_finished "rm -f .git/refs/heads/badname" && + git branch -d badname >output 2>error && + test_path_is_missing .git/refs/heads/badname && + test_i18ngrep "Deleted branch badname (was refs/heads/broken\.\.\.ref)" output && + test_must_be_empty error +' + +test_expect_success 'update-ref -d can delete broken name through symref' ' + cp .git/refs/heads/master .git/refs/heads/broken...ref && + test_when_finished "rm -f .git/refs/heads/broken...ref" && + printf "ref: refs/heads/broken...ref\n" >.git/refs/heads/badname && + test_when_finished "rm -f .git/refs/heads/badname" && + git update-ref -d refs/heads/badname >output 2>error && + test_path_is_missing .git/refs/heads/broken...ref && + test_must_be_empty output && + test_must_be_empty error +' + +test_expect_success 'update-ref --no-deref -d can delete symref with broken name' ' + printf "ref: refs/heads/master\n" >.git/refs/heads/broken...symref && + test_when_finished "rm -f .git/refs/heads/broken...symref" && + git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && + test_path_is_missing .git/refs/heads/broken...symref && + test_must_be_empty output && + test_must_be_empty error +' + +test_expect_success 'branch -d can delete symref with broken name' ' + printf "ref: refs/heads/master\n" >.git/refs/heads/broken...symref && + test_when_finished "rm -f .git/refs/heads/broken...symref" && + git branch -d broken...symref >output 2>error && + test_path_is_missing .git/refs/heads/broken...symref && + test_i18ngrep "Deleted branch broken...symref (was refs/heads/master)" output && + test_must_be_empty error +' + +test_expect_success 'update-ref --no-deref -d can delete dangling symref with broken name' ' + printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && + test_when_finished "rm -f .git/refs/heads/broken...symref" && + git update-ref --no-deref -d refs/heads/broken...symref >output 2>error && + test_path_is_missing .git/refs/heads/broken...symref && + test_must_be_empty output && + test_must_be_empty error +' + +test_expect_success 'branch -d can delete dangling symref with broken name' ' + printf "ref: refs/heads/idonotexist\n" >.git/refs/heads/broken...symref && + test_when_finished "rm -f .git/refs/heads/broken...symref" && + git branch -d broken...symref >output 2>error && + test_path_is_missing .git/refs/heads/broken...symref && + test_i18ngrep "Deleted branch broken...symref (was refs/heads/idonotexist)" output && + test_must_be_empty error +' + test_expect_success 'update-ref -d cannot delete non-ref in .git dir' ' echo precious >.git/my-private-file && echo precious >expect && - test_must_fail git update-ref -d my-private-file && + test_must_fail git update-ref -d my-private-file >output 2>error && + test_must_be_empty output && + test_i18ngrep -e "cannot lock .*: unable to resolve reference" error && test_cmp expect .git/my-private-file ' diff --git a/t/t1450-fsck.sh b/t/t1450-fsck.sh index e66b7cb697..7ee8ea004f 100755 --- a/t/t1450-fsck.sh +++ b/t/t1450-fsck.sh @@ -427,6 +427,24 @@ test_expect_success 'fsck allows .Εit' ' ) ' +test_expect_success 'NUL in commit' ' + rm -fr nul-in-commit && + git init nul-in-commit && + ( + cd nul-in-commit && + git commit --allow-empty -m "initial commitQNUL after message" && + git cat-file commit HEAD >original && + q_to_nul <original >munged && + git hash-object -w -t commit --stdin <munged >name && + git branch bad $(cat name) && + + test_must_fail git -c fsck.nulInCommit=error fsck 2>warn.1 && + grep nulInCommit warn.1 && + git fsck 2>warn.2 && + grep nulInCommit warn.2 + ) +' + # create a static test repo which is broken by omitting # one particular object ($1, which is looked up via rev-parse # in the new repository). diff --git a/t/t2025-worktree-add.sh b/t/t2025-worktree-add.sh index 3acb9926f2..3a22fc55fc 100755 --- a/t/t2025-worktree-add.sh +++ b/t/t2025-worktree-add.sh @@ -4,6 +4,8 @@ test_description='test git worktree add' . ./test-lib.sh +. "$TEST_DIRECTORY"/lib-rebase.sh + test_expect_success 'setup' ' test_commit init ' @@ -225,4 +227,61 @@ test_expect_success '"add" worktree with --checkout' ' test_cmp init.t swamp2/init.t ' +test_expect_success 'put a worktree under rebase' ' + git worktree add under-rebase && + ( + cd under-rebase && + set_fake_editor && + FAKE_LINES="edit 1" git rebase -i HEAD^ && + git worktree list | grep "under-rebase.*detached HEAD" + ) +' + +test_expect_success 'add a worktree, checking out a rebased branch' ' + test_must_fail git worktree add new-rebase under-rebase && + ! test -d new-rebase +' + +test_expect_success 'checking out a rebased branch from another worktree' ' + git worktree add new-place && + test_must_fail git -C new-place checkout under-rebase +' + +test_expect_success 'not allow to delete a branch under rebase' ' + ( + cd under-rebase && + test_must_fail git branch -D under-rebase + ) +' + +test_expect_success 'rename a branch under rebase not allowed' ' + test_must_fail git branch -M under-rebase rebase-with-new-name +' + +test_expect_success 'check out from current worktree branch ok' ' + ( + cd under-rebase && + git checkout under-rebase && + git checkout - && + git rebase --abort + ) +' + +test_expect_success 'checkout a branch under bisect' ' + git worktree add under-bisect && + ( + cd under-bisect && + git bisect start && + git bisect bad && + git bisect good HEAD~2 && + git worktree list | grep "under-bisect.*detached HEAD" && + test_must_fail git worktree add new-bisect under-bisect && + ! test -d new-bisect + ) +' + +test_expect_success 'rename a branch under bisect not allowed' ' + test_must_fail git branch -M under-bisect bisect-with-new-name +' + test_done diff --git a/t/t3033-merge-toplevel.sh b/t/t3033-merge-toplevel.sh index c1379b00c2..d314599428 100755 --- a/t/t3033-merge-toplevel.sh +++ b/t/t3033-merge-toplevel.sh @@ -19,7 +19,7 @@ test_expect_success setup ' test_commit three && git checkout right && test_commit four && - git checkout --orphan five && + git checkout --orphan newroot && test_commit five && git checkout master ' diff --git a/t/t3402-rebase-merge.sh b/t/t3402-rebase-merge.sh index 8f64505e4f..488945e007 100755 --- a/t/t3402-rebase-merge.sh +++ b/t/t3402-rebase-merge.sh @@ -85,6 +85,15 @@ test_expect_success 'rebase -Xtheirs' ' ! grep 11 original ' +test_expect_success 'rebase -Xtheirs from orphan' ' + git checkout --orphan orphan-conflicting master~2 && + echo "AB $T" >> original && + git commit -morphan-conflicting original && + git rebase -Xtheirs master && + grep AB original && + ! grep 11 original +' + test_expect_success 'merge and rebase should match' ' git diff-tree -r test-rebase test-merge >difference && if test -s difference diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index d96d0e4c9b..66348f11d1 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -62,7 +62,7 @@ test_expect_success 'setup' ' # "exec" commands are ran with the user shell by default, but this may # be non-POSIX. For example, if SHELL=zsh then ">file" doesn't work -# to create a file. Unseting SHELL avoids such non-portable behavior +# to create a file. Unsetting SHELL avoids such non-portable behavior # in tests. It must be exported for it to take effect where needed. SHELL= export SHELL diff --git a/t/t3419-rebase-patch-id.sh b/t/t3419-rebase-patch-id.sh index 217dd79b2e..49f548cdb9 100755 --- a/t/t3419-rebase-patch-id.sh +++ b/t/t3419-rebase-patch-id.sh @@ -73,17 +73,17 @@ do_tests () { run git format-patch --stdout --ignore-if-in-upstream master " - test_expect_success $pr 'detect upstream patch' " + test_expect_success $pr 'detect upstream patch' ' git checkout -q master && scramble file && git add file && - git commit -q -m 'change big file again' && + git commit -q -m "change big file again" && git checkout -q other^{} && git rebase master && - test_must_fail test -n \"\$(git rev-list master...HEAD~)\" - " + test_must_fail test -n "$(git rev-list master...HEAD~)" + ' - test_expect_success $pr 'do not drop patch' " + test_expect_success $pr 'do not drop patch' ' git branch -f squashed master && git checkout -q -f squashed && git reset -q --soft HEAD~2 && @@ -91,7 +91,7 @@ do_tests () { git checkout -q other^{} && test_must_fail git rebase squashed && rm -rf .git/rebase-apply - " + ' } do_tests 500 diff --git a/t/t3421-rebase-topology-linear.sh b/t/t3421-rebase-topology-linear.sh index 9c55cba198..68fe2003ef 100755 --- a/t/t3421-rebase-topology-linear.sh +++ b/t/t3421-rebase-topology-linear.sh @@ -253,7 +253,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_run_rebase success -p @@ -268,7 +268,7 @@ test_run_rebase () { " } test_run_rebase success '' -test_run_rebase failure -m +test_run_rebase success -m test_run_rebase success -i test_run_rebase failure -p diff --git a/t/t3513-revert-submodule.sh b/t/t3513-revert-submodule.sh index a1c4e0216f..db9378142a 100755 --- a/t/t3513-revert-submodule.sh +++ b/t/t3513-revert-submodule.sh @@ -14,11 +14,11 @@ test_description='revert can handle submodules' git_revert () { git status -su >expect && ls -1pR * >>expect && - tar czf "$TRASH_DIRECTORY/tmp.tgz" * && + tar cf "$TRASH_DIRECTORY/tmp.tar" * && git checkout "$1" && git revert HEAD && rm -rf * && - tar xzf "$TRASH_DIRECTORY/tmp.tgz" && + tar xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && diff --git a/t/t3910-mac-os-precompose.sh b/t/t3910-mac-os-precompose.sh index 831935665e..26dd5b7f78 100755 --- a/t/t3910-mac-os-precompose.sh +++ b/t/t3910-mac-os-precompose.sh @@ -49,12 +49,54 @@ test_expect_success "setup" ' test_expect_success "setup case mac" ' git checkout -b mac_os ' +# This will test nfd2nfc in git diff +test_expect_success "git diff f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff f.$Adiarnfd >expect && + git diff f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' +# This will test nfd2nfc in git diff-files +test_expect_success "git diff-files f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff-files f.$Adiarnfd >expect && + git diff-files f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' +# This will test nfd2nfc in git diff-index +test_expect_success "git diff-index f.Adiar" ' + touch f.$Adiarnfc && + git add f.$Adiarnfc && + echo f.Adiarnfc >f.$Adiarnfc && + git diff-index HEAD f.$Adiarnfd >expect && + git diff-index HEAD f.$Adiarnfc >actual && + test_cmp expect actual && + git reset HEAD f.Adiarnfc && + rm f.$Adiarnfc expect actual +' # This will test nfd2nfc in readdir() test_expect_success "add file Adiarnfc" ' echo f.Adiarnfc >f.$Adiarnfc && git add f.$Adiarnfc && git commit -m "add f.$Adiarnfc" ' +# This will test nfd2nfc in git diff-tree +test_expect_success "git diff-tree f.Adiar" ' + echo f.Adiarnfc >>f.$Adiarnfc && + git diff-tree HEAD f.$Adiarnfd >expect && + git diff-tree HEAD f.$Adiarnfc >actual && + test_cmp expect actual && + git checkout f.$Adiarnfc && + rm expect actual +' # This will test nfd2nfc in git stage() test_expect_success "stage file d.Adiarnfd/f.Adiarnfd" ' mkdir d.$Adiarnfd && diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index eed2981b96..8049cad374 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -1460,4 +1460,109 @@ test_expect_success 'format-patch -o overrides format.outputDirectory' ' test_path_is_dir patchset ' +test_expect_success 'format-patch --base' ' + git checkout side && + git format-patch --stdout --base=HEAD~3 -1 >patch && + grep "^base-commit:" patch >actual && + grep "^prerequisite-patch-id:" patch >>actual && + echo "base-commit: $(git rev-parse HEAD~3)" >expected && + echo "prerequisite-patch-id: $(git show --patch HEAD~2 | git patch-id --stable | awk "{print \$1}")" >>expected && + echo "prerequisite-patch-id: $(git show --patch HEAD~1 | git patch-id --stable | awk "{print \$1}")" >>expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base errors out when base commit is in revision list' ' + test_must_fail git format-patch --base=HEAD -2 && + test_must_fail git format-patch --base=HEAD~1 -2 && + git format-patch --stdout --base=HEAD~2 -2 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse HEAD~2)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base errors out when base commit is not ancestor of revision list' ' + # For history as below: + # + # ---Q---P---Z---Y---*---X + # \ / + # ------------W + # + # If "format-patch Z..X" is given, P and Z can not be specified as the base commit + git checkout -b topic1 master && + git rev-parse HEAD >commit-id-base && + test_commit P && + git rev-parse HEAD >commit-id-P && + test_commit Z && + git rev-parse HEAD >commit-id-Z && + test_commit Y && + git checkout -b topic2 master && + test_commit W && + git merge topic1 && + test_commit X && + test_must_fail git format-patch --base=$(cat commit-id-P) -3 && + test_must_fail git format-patch --base=$(cat commit-id-Z) -3 && + git format-patch --stdout --base=$(cat commit-id-base) -3 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(cat commit-id-base)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base=auto' ' + git checkout -b upstream master && + git checkout -b local upstream && + git branch --set-upstream-to=upstream && + test_commit N1 && + test_commit N2 && + git format-patch --stdout --base=auto -2 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse upstream)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch errors out when history involves criss-cross' ' + # setup criss-cross history + # + # B---M1---D + # / \ / + # A X + # \ / \ + # C---M2---E + # + git checkout master && + test_commit A && + git checkout -b xb master && + test_commit B && + git checkout -b xc master && + test_commit C && + git checkout -b xbc xb -- && + git merge xc && + git checkout -b xcb xc -- && + git branch --set-upstream-to=xbc && + git merge xb && + git checkout xbc && + test_commit D && + git checkout xcb && + test_commit E && + test_must_fail git format-patch --base=auto -1 +' + +test_expect_success 'format-patch format.useAutoBaseoption' ' + test_when_finished "git config --unset format.useAutoBase" && + git checkout local && + git config format.useAutoBase true && + git format-patch --stdout -1 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse upstream)" >expected && + test_cmp expected actual +' + +test_expect_success 'format-patch --base overrides format.useAutoBase' ' + test_when_finished "git config --unset format.useAutoBase" && + git config format.useAutoBase true && + git format-patch --stdout --base=HEAD~1 -1 >patch && + grep "^base-commit:" patch >actual && + echo "base-commit: $(git rev-parse HEAD~1)" >expected && + test_cmp expected actual +' + test_done diff --git a/t/t4151-am-abort.sh b/t/t4151-am-abort.sh index ea5ace99a1..9473c2779e 100755 --- a/t/t4151-am-abort.sh +++ b/t/t4151-am-abort.sh @@ -82,7 +82,7 @@ test_expect_success 'am -3 --abort removes otherfile-4' ' test 4 = "$(cat otherfile-4)" && git am --abort && test_cmp_rev initial HEAD && - test -z $(git ls-files -u) && + test -z "$(git ls-files -u)" && test_path_is_missing otherfile-4 ' diff --git a/t/t4200-rerere.sh b/t/t4200-rerere.sh index ed9c91e25b..1a080e7823 100755 --- a/t/t4200-rerere.sh +++ b/t/t4200-rerere.sh @@ -184,12 +184,27 @@ test_expect_success 'rerere updates postimage timestamp' ' ' test_expect_success 'rerere clear' ' - rm $rr/postimage && + mv $rr/postimage .git/post-saved && echo "$sha1 a1" | perl -pe "y/\012/\000/" >.git/MERGE_RR && git rerere clear && ! test -d $rr ' +test_expect_success 'leftover directory' ' + git reset --hard && + mkdir -p $rr && + test_must_fail git merge first && + test -f $rr/preimage +' + +test_expect_success 'missing preimage' ' + git reset --hard && + mkdir -p $rr && + cp .git/post-saved $rr/postimage && + test_must_fail git merge first && + test -f $rr/preimage +' + test_expect_success 'set up for garbage collection tests' ' mkdir -p $rr && echo Hello >$rr/preimage && @@ -391,4 +406,157 @@ test_expect_success 'rerere -h' ' test_i18ngrep [Uu]sage help ' +concat_insert () { + last=$1 + shift + cat early && printf "%s\n" "$@" && cat late "$last" +} + +count_pre_post () { + find .git/rr-cache/ -type f -name "preimage*" >actual && + test_line_count = "$1" actual && + find .git/rr-cache/ -type f -name "postimage*" >actual && + test_line_count = "$2" actual +} + +test_expect_success 'rerere gc' ' + find .git/rr-cache -type f >original && + xargs test-chmtime -172800 <original && + + git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc && + find .git/rr-cache -type f >actual && + test_cmp original actual && + + git -c gc.rerereresolved=5 -c gc.rerereunresolved=0 rerere gc && + find .git/rr-cache -type f >actual && + test_cmp original actual && + + git -c gc.rerereresolved=0 -c gc.rerereunresolved=0 rerere gc && + find .git/rr-cache -type f >actual && + >expect && + test_cmp expect actual +' + +merge_conflict_resolve () { + git reset --hard && + test_must_fail git merge six.1 && + # Resolution is to replace 7 with 6.1 and 6.2 (i.e. take both) + concat_insert short 6.1 6.2 >file1 && + concat_insert long 6.1 6.2 >file2 +} + +test_expect_success 'multiple identical conflicts' ' + git reset --hard && + + test_seq 1 6 >early && + >late && + test_seq 11 15 >short && + test_seq 111 120 >long && + concat_insert short >file1 && + concat_insert long >file2 && + git add file1 file2 && + git commit -m base && + git tag base && + git checkout -b six.1 && + concat_insert short 6.1 >file1 && + concat_insert long 6.1 >file2 && + git add file1 file2 && + git commit -m 6.1 && + git checkout -b six.2 HEAD^ && + concat_insert short 6.2 >file1 && + concat_insert long 6.2 >file2 && + git add file1 file2 && + git commit -m 6.2 && + + # At this point, six.1 and six.2 + # - derive from common ancestor that has two files + # 1...6 7 11..15 (file1) and 1...6 7 111..120 (file2) + # - six.1 replaces these 7s with 6.1 + # - six.2 replaces these 7s with 6.2 + + merge_conflict_resolve && + + # Check that rerere knows that file1 and file2 have conflicts + + printf "%s\n" file1 file2 >expect && + git ls-files -u | sed -e "s/^.* //" | sort -u >actual && + test_cmp expect actual && + + git rerere status | sort >actual && + test_cmp expect actual && + + git rerere remaining >actual && + test_cmp expect actual && + + count_pre_post 2 0 && + + # Pretend that the conflicts were made quite some time ago + find .git/rr-cache/ -type f | xargs test-chmtime -172800 && + + # Unresolved entries have not expired yet + git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc && + count_pre_post 2 0 && + + # Unresolved entries have expired + git -c gc.rerereresolved=5 -c gc.rerereunresolved=1 rerere gc && + count_pre_post 0 0 && + + # Recreate the conflicted state + merge_conflict_resolve && + count_pre_post 2 0 && + + # Clear it + git rerere clear && + count_pre_post 0 0 && + + # Recreate the conflicted state + merge_conflict_resolve && + count_pre_post 2 0 && + + # We resolved file1 and file2 + git rerere && + >expect && + git rerere remaining >actual && + test_cmp expect actual && + + # We must have recorded both of them + count_pre_post 2 2 && + + # Now we should be able to resolve them both + git reset --hard && + test_must_fail git merge six.1 && + git rerere && + + >expect && + git rerere remaining >actual && + test_cmp expect actual && + + concat_insert short 6.1 6.2 >file1.expect && + concat_insert long 6.1 6.2 >file2.expect && + test_cmp file1.expect file1 && + test_cmp file2.expect file2 && + + # Forget resolution for file2 + git rerere forget file2 && + echo file2 >expect && + git rerere status >actual && + test_cmp expect actual && + count_pre_post 2 1 && + + # file2 already has correct resolution, so record it again + git rerere && + + # Pretend that the resolutions are old again + find .git/rr-cache/ -type f | xargs test-chmtime -172800 && + + # Resolved entries have not expired yet + git -c gc.rerereresolved=5 -c gc.rerereunresolved=5 rerere gc && + + count_pre_post 2 2 && + + # Resolved entries have expired + git -c gc.rerereresolved=1 -c gc.rerereunresolved=5 rerere gc && + count_pre_post 0 0 +' + test_done diff --git a/t/t5504-fetch-receive-strict.sh b/t/t5504-fetch-receive-strict.sh index a3e12d295a..44f3d5fb28 100755 --- a/t/t5504-fetch-receive-strict.sh +++ b/t/t5504-fetch-receive-strict.sh @@ -100,11 +100,8 @@ test_expect_success 'push with receive.fsckobjects' ' git config receive.fsckobjects true && git config transfer.fsckobjects false ) && - test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act && - { - test_cmp exp act || - ! test -s act - } + test_must_fail git push --porcelain dst master:refs/heads/test >act && + test_cmp exp act ' test_expect_success 'push with transfer.fsckobjects' ' @@ -114,7 +111,8 @@ test_expect_success 'push with transfer.fsckobjects' ' cd dst && git config transfer.fsckobjects true ) && - test_must_fail ok=sigpipe git push --porcelain dst master:refs/heads/test >act + test_must_fail git push --porcelain dst master:refs/heads/test >act && + test_cmp exp act ' cat >bogus-commit <<\EOF diff --git a/t/t5510-fetch.sh b/t/t5510-fetch.sh index 38321d19ef..454d896390 100755 --- a/t/t5510-fetch.sh +++ b/t/t5510-fetch.sh @@ -682,6 +682,7 @@ test_expect_success 'fetching with auto-gc does not lock up' ' ( cd auto-gc && git config gc.autoPackLimit 1 && + git config gc.autoDetach false && GIT_ASK_YESNO="$D/askyesno" git fetch >fetch.out 2>&1 && ! grep "Should I try again" fetch.out ) diff --git a/t/t5521-pull-options.sh b/t/t5521-pull-options.sh index 18372caa15..ded8f98dbe 100755 --- a/t/t5521-pull-options.sh +++ b/t/t5521-pull-options.sh @@ -144,4 +144,25 @@ test_expect_success 'git pull --all --dry-run' ' ) ' +test_expect_success 'git pull --allow-unrelated-histories' ' + test_when_finished "rm -fr src dst" && + git init src && + ( + cd src && + test_commit one && + test_commit two + ) && + git clone src dst && + ( + cd src && + git checkout --orphan side HEAD^ && + test_commit three + ) && + ( + cd dst && + test_must_fail git pull ../src side && + git pull --allow-unrelated-histories ../src side + ) +' + test_done diff --git a/t/t5550-http-fetch-dumb.sh b/t/t5550-http-fetch-dumb.sh index 48e2ab62da..3484b6f0f3 100755 --- a/t/t5550-http-fetch-dumb.sh +++ b/t/t5550-http-fetch-dumb.sh @@ -91,23 +91,55 @@ test_expect_success 'configured username does not override URL' ' expect_askpass pass user@host ' -test_expect_success 'cmdline credential config passes into submodules' ' +test_expect_success 'set up repo with http submodules' ' git init super && set_askpass user@host pass@host && ( cd super && git submodule add "$HTTPD_URL/auth/dumb/repo.git" sub && git commit -m "add submodule" - ) && + ) +' + +test_expect_success 'cmdline credential config passes to submodule via clone' ' set_askpass wrong pass@host && test_must_fail git clone --recursive super super-clone && rm -rf super-clone && + set_askpass wrong pass@host && - git -c "credential.$HTTP_URL.username=user@host" \ + git -c "credential.$HTTPD_URL.username=user@host" \ clone --recursive super super-clone && expect_askpass pass user@host ' +test_expect_success 'cmdline credential config passes submodule via fetch' ' + set_askpass wrong pass@host && + test_must_fail git -C super-clone fetch --recurse-submodules && + + set_askpass wrong pass@host && + git -C super-clone \ + -c "credential.$HTTPD_URL.username=user@host" \ + fetch --recurse-submodules && + expect_askpass pass user@host +' + +test_expect_success 'cmdline credential config passes submodule update' ' + # advance the submodule HEAD so that a fetch is required + git commit --allow-empty -m foo && + git push "$HTTPD_DOCUMENT_ROOT_PATH/auth/dumb/repo.git" HEAD && + sha1=$(git rev-parse HEAD) && + git -C super-clone update-index --cacheinfo 160000,$sha1,sub && + + set_askpass wrong pass@host && + test_must_fail git -C super-clone submodule update && + + set_askpass wrong pass@host && + git -C super-clone \ + -c "credential.$HTTPD_URL.username=user@host" \ + submodule update && + expect_askpass pass user@host +' + test_expect_success 'fetch changes via http' ' echo content >>file && git commit -a -m two && diff --git a/t/t5551-http-fetch-smart.sh b/t/t5551-http-fetch-smart.sh index 58207d8825..2f375eb94d 100755 --- a/t/t5551-http-fetch-smart.sh +++ b/t/t5551-http-fetch-smart.sh @@ -282,5 +282,22 @@ test_expect_success EXPENSIVE 'http can handle enormous ref negotiation' ' test_line_count = 100000 tags ' +test_expect_success 'custom http headers' ' + test_must_fail git -c http.extraheader="x-magic-two: cadabra" \ + fetch "$HTTPD_URL/smart_headers/repo.git" && + git -c http.extraheader="x-magic-one: abra" \ + -c http.extraheader="x-magic-two: cadabra" \ + fetch "$HTTPD_URL/smart_headers/repo.git" && + git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub && + git config -f .gitmodules submodule.sub.path sub && + git config -f .gitmodules submodule.sub.url \ + "$HTTPD_URL/smart_headers/repo.git" && + git submodule init sub && + test_must_fail git submodule update sub && + git -c http.extraheader="x-magic-one: abra" \ + -c http.extraheader="x-magic-two: cadabra" \ + submodule update sub +' + stop_httpd test_done diff --git a/t/t5601-clone.sh b/t/t5601-clone.sh index c1efb8e445..a433394200 100755 --- a/t/t5601-clone.sh +++ b/t/t5601-clone.sh @@ -308,7 +308,7 @@ test_expect_success 'clone checking out a tag' ' setup_ssh_wrapper () { test_expect_success 'setup ssh wrapper' ' - cp "$GIT_BUILD_DIR/test-fake-ssh$X" \ + cp "$GIT_BUILD_DIR/t/helper/test-fake-ssh$X" \ "$TRASH_DIRECTORY/ssh-wrapper$X" && GIT_SSH="$TRASH_DIRECTORY/ssh-wrapper$X" && export GIT_SSH && @@ -466,7 +466,7 @@ test_expect_success 'clone ssh://host.xz:22/~repo' ' #IPv6 for tuah in ::1 [::1] [::1]: user@::1 user@[::1] user@[::1]: [user@::1] [user@::1]: do - ehost=$(echo $tuah | sed -e "s/1]:/1]/ "| tr -d "[]") + ehost=$(echo $tuah | sed -e "s/1]:/1]/" | tr -d "[]") test_expect_success "clone ssh://$tuah/home/user/repo" " test_clone_url ssh://$tuah/home/user/repo $ehost /home/user/repo " diff --git a/t/t5611-clone-config.sh b/t/t5611-clone-config.sh index 27d730c0a7..e4850b778c 100755 --- a/t/t5611-clone-config.sh +++ b/t/t5611-clone-config.sh @@ -37,4 +37,24 @@ test_expect_success 'clone -c config is available during clone' ' test_cmp expect child/file ' +# Tests for the hidden file attribute on windows +is_hidden () { + # Use the output of `attrib`, ignore the absolute path + case "$(attrib "$1")" in *H*?:*) return 0;; esac + return 1 +} + +test_expect_success MINGW 'clone -c core.hideDotFiles' ' + test_commit attributes .gitattributes "" && + rm -rf child && + git clone -c core.hideDotFiles=false . child && + ! is_hidden child/.gitattributes && + rm -rf child && + git clone -c core.hideDotFiles=dotGitOnly . child && + ! is_hidden child/.gitattributes && + rm -rf child && + git clone -c core.hideDotFiles=true . child && + is_hidden child/.gitattributes +' + test_done diff --git a/t/t5614-clone-submodules.sh b/t/t5614-clone-submodules.sh new file mode 100755 index 0000000000..62044c5a02 --- /dev/null +++ b/t/t5614-clone-submodules.sh @@ -0,0 +1,85 @@ +#!/bin/sh + +test_description='Test shallow cloning of repos with submodules' + +. ./test-lib.sh + +pwd=$(pwd) + +test_expect_success 'setup' ' + git checkout -b master && + test_commit commit1 && + test_commit commit2 && + mkdir sub && + ( + cd sub && + git init && + test_commit subcommit1 && + test_commit subcommit2 && + test_commit subcommit3 + ) && + git submodule add "file://$pwd/sub" sub && + git commit -m "add submodule" +' + +test_expect_success 'nonshallow clone implies nonshallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 3 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + +test_expect_success 'shallow clone implies shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --depth 2 "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 2 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 1 lines + ) +' + +test_expect_success 'shallow clone with non shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --depth 2 --no-shallow-submodules "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 2 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 3 lines + ) +' + +test_expect_success 'non shallow clone with shallow submodule' ' + test_when_finished "rm -rf super_clone" && + git clone --recurse-submodules --no-local --shallow-submodules "file://$pwd/." super_clone && + ( + cd super_clone && + git log --oneline >lines && + test_line_count = 3 lines + ) && + ( + cd super_clone/sub && + git log --oneline >lines && + test_line_count = 1 lines + ) +' + +test_done diff --git a/t/t6024-recursive-merge.sh b/t/t6024-recursive-merge.sh index 755d30ce2a..3f59e58dfb 100755 --- a/t/t6024-recursive-merge.sh +++ b/t/t6024-recursive-merge.sh @@ -76,7 +76,7 @@ test_expect_success "result contains a conflict" "test_cmp expect a1" git ls-files --stage > out cat > expect << EOF -100644 439cc46de773d8a83c77799b7cc9191c128bfcff 1 a1 +100644 ec3fe2a791706733f2d8fa7ad45d9a9672031f5e 1 a1 100644 cf84443e49e1b366fac938711ddf4be2d4d1d9e9 2 a1 100644 fd7923529855d0b274795ae3349c5e0438333979 3 a1 EOF diff --git a/t/t6036-recursive-corner-cases.sh b/t/t6036-recursive-corner-cases.sh index 9d6621c056..18aa88b5c0 100755 --- a/t/t6036-recursive-corner-cases.sh +++ b/t/t6036-recursive-corner-cases.sh @@ -212,7 +212,8 @@ test_expect_success 'git detects differently handled merges conflict' ' -L "" \ -L "Temporary merge branch 1" \ merged empty merge-me && - test $(git rev-parse :1:new_a) = $(git hash-object merged) + sed -e "s/^\([<=>]\)/\1\1\1/" merged >merged-internal && + test $(git rev-parse :1:new_a) = $(git hash-object merged-internal) ' # @@ -299,89 +300,6 @@ test_expect_success 'git detects conflict merging criss-cross+modify/delete, rev ' # -# criss-cross + modify/modify with very contrived file contents: -# -# B D -# o---o -# / \ / \ -# A o X ? F -# \ / \ / -# o---o -# C E -# -# Commit A: file with contents 'A\n' -# Commit B: file with contents 'B\n' -# Commit C: file with contents 'C\n' -# Commit D: file with contents 'D\n' -# Commit E: file with contents: -# <<<<<<< Temporary merge branch 1 -# C -# ======= -# B -# >>>>>>> Temporary merge branch 2 -# -# Now, when we merge commits D & E, does git detect the conflict? - -test_expect_success 'setup differently handled merges of content conflict' ' - git clean -fdqx && - rm -rf .git && - git init && - - echo A >file && - git add file && - test_tick && - git commit -m A && - - git branch B && - git checkout -b C && - echo C >file && - git add file && - test_tick && - git commit -m C && - - git checkout B && - echo B >file && - git add file && - test_tick && - git commit -m B && - - git checkout B^0 && - test_must_fail git merge C && - echo D >file && - git add file && - test_tick && - git commit -m D && - git tag D && - - git checkout C^0 && - test_must_fail git merge B && - cat <<EOF >file && -<<<<<<< Temporary merge branch 1 -C -======= -B ->>>>>>> Temporary merge branch 2 -EOF - git add file && - test_tick && - git commit -m E && - git tag E -' - -test_expect_failure 'git detects conflict w/ criss-cross+contrived resolution' ' - git checkout D^0 && - - test_must_fail git merge -s recursive E^0 && - - test 3 -eq $(git ls-files -s | wc -l) && - test 3 -eq $(git ls-files -u | wc -l) && - test 0 -eq $(git ls-files -o | wc -l) && - - test $(git rev-parse :2:file) = $(git rev-parse D:file) && - test $(git rev-parse :3:file) = $(git rev-parse E:file) -' - -# # criss-cross + d/f conflict via add/add: # Commit A: Neither file 'a' nor directory 'a/' exists. # Commit B: Introduce 'a' diff --git a/t/t6041-bisect-submodule.sh b/t/t6041-bisect-submodule.sh index c6b7aa6977..62b8a2e7bb 100755 --- a/t/t6041-bisect-submodule.sh +++ b/t/t6041-bisect-submodule.sh @@ -8,7 +8,7 @@ test_description='bisect can handle submodules' git_bisect () { git status -su >expect && ls -1pR * >>expect && - tar czf "$TRASH_DIRECTORY/tmp.tgz" * && + tar cf "$TRASH_DIRECTORY/tmp.tar" * && GOOD=$(git rev-parse --verify HEAD) && git checkout "$1" && echo "foo" >bar && @@ -20,7 +20,7 @@ git_bisect () { git bisect start && git bisect good $GOOD && rm -rf * && - tar xzf "$TRASH_DIRECTORY/tmp.tgz" && + tar xf "$TRASH_DIRECTORY/tmp.tar" && git status -su >actual && ls -1pR * >>actual && test_cmp expect actual && diff --git a/t/t6044-merge-unrelated-index-changes.sh b/t/t6044-merge-unrelated-index-changes.sh new file mode 100755 index 0000000000..20a3ffed69 --- /dev/null +++ b/t/t6044-merge-unrelated-index-changes.sh @@ -0,0 +1,153 @@ +#!/bin/sh + +test_description="merges with unrelated index changes" + +. ./test-lib.sh + +# Testcase for some simple merges +# A +# o-----o B +# \ +# \---o C +# \ +# \-o D +# \ +# o E +# Commit A: some file a +# Commit B: adds file b, modifies end of a +# Commit C: adds file c +# Commit D: adds file d, modifies beginning of a +# Commit E: renames a->subdir/a, adds subdir/e + +test_expect_success 'setup trivial merges' ' + seq 1 10 >a && + git add a && + test_tick && git commit -m A && + + git branch A && + git branch B && + git branch C && + git branch D && + git branch E && + + git checkout B && + echo b >b && + echo 11 >>a && + git add a b && + test_tick && git commit -m B && + + git checkout C && + echo c >c && + git add c && + test_tick && git commit -m C && + + git checkout D && + seq 2 10 >a && + echo d >d && + git add a d && + test_tick && git commit -m D && + + git checkout E && + mkdir subdir && + git mv a subdir/a && + echo e >subdir/e && + git add subdir && + test_tick && git commit -m E +' + +test_expect_success 'ff update' ' + git reset --hard && + git checkout A^0 && + + touch random_file && git add random_file && + + git merge E^0 && + + test_must_fail git rev-parse HEAD:random_file && + test "$(git diff --name-only --cached E)" = "random_file" +' + +test_expect_success 'ff update, important file modified' ' + git reset --hard && + git checkout A^0 && + + mkdir subdir && + touch subdir/e && + git add subdir/e && + + test_must_fail git merge E^0 +' + +test_expect_success 'resolve, trivial' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge -s resolve C^0 +' + +test_expect_success 'resolve, non-trivial' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge -s resolve D^0 +' + +test_expect_success 'recursive' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge -s recursive C^0 +' + +test_expect_success 'octopus, unrelated file touched' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge C^0 D^0 +' + +test_expect_success 'octopus, related file removed' ' + git reset --hard && + git checkout B^0 && + + git rm b && + + test_must_fail git merge C^0 D^0 +' + +test_expect_success 'octopus, related file modified' ' + git reset --hard && + git checkout B^0 && + + echo 12 >>a && git add a && + + test_must_fail git merge C^0 D^0 +' + +test_expect_success 'ours' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge -s ours C^0 +' + +test_expect_success 'subtree' ' + git reset --hard && + git checkout B^0 && + + touch random_file && git add random_file && + + test_must_fail git merge -s subtree E^0 +' + +test_done diff --git a/t/t6302-for-each-ref-filter.sh b/t/t6302-for-each-ref-filter.sh index 70afb44271..d0ab09f4bd 100755 --- a/t/t6302-for-each-ref-filter.sh +++ b/t/t6302-for-each-ref-filter.sh @@ -5,15 +5,6 @@ test_description='test for-each-refs usage of ref-filter APIs' . ./test-lib.sh . "$TEST_DIRECTORY"/lib-gpg.sh -test_prepare_expect () { - if test_have_prereq GPG - then - cat - else - sed '/signed/d' - fi -} - test_expect_success 'setup some history and refs' ' test_commit one && test_commit two && @@ -22,11 +13,19 @@ test_expect_success 'setup some history and refs' ' test_commit four && git tag -m "An annotated tag" annotated-tag && git tag -m "Annonated doubly" doubly-annotated-tag annotated-tag && + + # Note that these "signed" tags might not actually be signed. + # Tests which care about the distinction should be marked + # with the GPG prereq. if test_have_prereq GPG then - git tag -s -m "A signed tag" signed-tag && - git tag -s -m "Signed doubly" doubly-signed-tag signed-tag + sign=-s + else + sign= fi && + git tag $sign -m "A signed tag" signed-tag && + git tag $sign -m "Signed doubly" doubly-signed-tag signed-tag && + git checkout master && git update-ref refs/odd/spot master ' @@ -42,7 +41,7 @@ test_expect_success 'filtering with --points-at' ' ' test_expect_success 'check signed tags with --points-at' ' - test_prepare_expect <<-\EOF | sed -e "s/Z$//" >expect && + sed -e "s/Z$//" >expect <<-\EOF && refs/heads/side Z refs/tags/annotated-tag four refs/tags/four Z @@ -65,7 +64,7 @@ test_expect_success 'filtering with --merged' ' ' test_expect_success 'filtering with --no-merged' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && refs/heads/side refs/tags/annotated-tag refs/tags/doubly-annotated-tag @@ -78,7 +77,7 @@ test_expect_success 'filtering with --no-merged' ' ' test_expect_success 'filtering with --contains' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && refs/heads/master refs/heads/side refs/odd/spot @@ -99,7 +98,7 @@ test_expect_success '%(color) must fail' ' ' test_expect_success 'left alignment is default' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && refname is refs/heads/master |refs/heads/master refname is refs/heads/side |refs/heads/side refname is refs/odd/spot |refs/odd/spot @@ -117,7 +116,7 @@ test_expect_success 'left alignment is default' ' ' test_expect_success 'middle alignment' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && | refname is refs/heads/master |refs/heads/master | refname is refs/heads/side |refs/heads/side | refname is refs/odd/spot |refs/odd/spot @@ -135,7 +134,7 @@ test_expect_success 'middle alignment' ' ' test_expect_success 'right alignment' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && | refname is refs/heads/master|refs/heads/master | refname is refs/heads/side|refs/heads/side | refname is refs/odd/spot|refs/odd/spot @@ -152,7 +151,7 @@ test_expect_success 'right alignment' ' test_cmp expect actual ' -test_prepare_expect >expect <<-\EOF +cat >expect <<-\EOF | refname is refs/heads/master |refs/heads/master | refname is refs/heads/side |refs/heads/side | refname is refs/odd/spot |refs/odd/spot @@ -199,7 +198,7 @@ EOF # Individual atoms inside %(align:...) and %(end) must not be quoted. test_expect_success 'alignment with format quote' " - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && |' '\''master| A U Thor'\'' '| |' '\''side| A U Thor'\'' '| |' '\''odd/spot| A U Thor'\'' '| @@ -217,7 +216,7 @@ test_expect_success 'alignment with format quote' " " test_expect_success 'nested alignment with quote formatting' " - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && |' master '| |' side '| |' odd/spot '| @@ -235,7 +234,7 @@ test_expect_success 'nested alignment with quote formatting' " " test_expect_success 'check `%(contents:lines=1)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master |three side |four odd/spot |three @@ -253,7 +252,7 @@ test_expect_success 'check `%(contents:lines=1)`' ' ' test_expect_success 'check `%(contents:lines=0)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master | side | odd/spot | @@ -271,7 +270,7 @@ test_expect_success 'check `%(contents:lines=0)`' ' ' test_expect_success 'check `%(contents:lines=99999)`' ' - test_prepare_expect >expect <<-\EOF && + cat >expect <<-\EOF && master |three side |four odd/spot |three diff --git a/t/t7001-mv.sh b/t/t7001-mv.sh index 4008faead8..4a2570ed95 100755 --- a/t/t7001-mv.sh +++ b/t/t7001-mv.sh @@ -292,6 +292,9 @@ test_expect_success 'setup submodule' ' echo content >file && git add file && git commit -m "added sub and file" && + mkdir -p deep/directory/hierachy && + git submodule add ./. deep/directory/hierachy/sub && + git commit -m "added another submodule" && git branch submodule ' @@ -475,4 +478,17 @@ test_expect_success 'mv -k does not accidentally destroy submodules' ' git checkout . ' +test_expect_success 'moving a submodule in nested directories' ' + ( + cd deep && + git mv directory ../ && + # git status would fail if the update of linking git dir to + # work dir of the submodule failed. + git status && + git config -f ../.gitmodules submodule.deep/directory/hierachy/sub.path >../actual && + echo "directory/hierachy/sub" >../expect + ) && + test_cmp actual expect +' + test_done diff --git a/t/t7030-verify-tag.sh b/t/t7030-verify-tag.sh index 4608e71343..07079a41c4 100755 --- a/t/t7030-verify-tag.sh +++ b/t/t7030-verify-tag.sh @@ -112,4 +112,17 @@ test_expect_success GPG 'verify signatures with --raw' ' ) ' +test_expect_success GPG 'verify multiple tags' ' + tags="fourth-signed sixth-signed seventh-signed" && + for i in $tags + do + git verify-tag -v --raw $i || return 1 + done >expect.stdout 2>expect.stderr.1 && + grep "^.GNUPG:." <expect.stderr.1 >expect.stderr && + git verify-tag -v --raw $tags >actual.stdout 2>actual.stderr.1 && + grep "^.GNUPG:." <actual.stderr.1 >actual.stderr && + test_cmp expect.stdout actual.stdout && + test_cmp expect.stderr actual.stderr +' + test_done diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index 86ceb38b01..b89fd2a6ad 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -495,7 +495,7 @@ test_expect_success 'should not clean submodules' ' test_path_is_missing to_clean ' -test_expect_success POSIXPERM 'should avoid cleaning possible submodules' ' +test_expect_success POSIXPERM,SANITY 'should avoid cleaning possible submodules' ' rm -fr to_clean possible_sub1 && mkdir to_clean possible_sub1 && test_when_finished "rm -rf possible_sub*" && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index f99f674ac7..3570f7bb8c 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -11,6 +11,10 @@ subcommands of git submodule. . ./test-lib.sh +test_expect_success 'submodule deinit works on empty repository' ' + git submodule deinit --all +' + test_expect_success 'setup - initial commit' ' >t && git add t && @@ -18,6 +22,22 @@ test_expect_success 'setup - initial commit' ' git branch initial ' +test_expect_success 'submodule init aborts on missing .gitmodules file' ' + test_when_finished "git update-index --remove sub" && + git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub && + # missing the .gitmodules file here + test_must_fail git submodule init 2>actual && + test_i18ngrep "No url found for submodule path" actual +' + +test_expect_success 'submodule update aborts on missing .gitmodules file' ' + test_when_finished "git update-index --remove sub" && + git update-index --add --cacheinfo 160000,$(git rev-parse HEAD),sub && + # missing the .gitmodules file here + git submodule update sub 2>actual && + test_i18ngrep "Submodule path .sub. not initialized" actual +' + test_expect_success 'configuration parsing' ' test_when_finished "rm -f .gitmodules" && cat >.gitmodules <<-\EOF && @@ -898,8 +918,9 @@ test_expect_success 'submodule deinit works on repository without submodules' ' git init && >file && git add file && - git commit -m "repo should not be empty" - git submodule deinit . + git commit -m "repo should not be empty" && + git submodule deinit . && + git submodule deinit --all ) ' @@ -941,6 +962,19 @@ test_expect_success 'submodule deinit . deinits all initialized submodules' ' rmdir init example2 ' +test_expect_success 'submodule deinit --all deinits all initialized submodules' ' + git submodule update --init && + git config submodule.example.foo bar && + git config submodule.example2.frotz nitfol && + test_must_fail git submodule deinit && + git submodule deinit --all >actual && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test -z "$(git config --get-regexp "submodule\.example2\.")" && + test_i18ngrep "Cleared directory .init" actual && + test_i18ngrep "Cleared directory .example2" actual && + rmdir init example2 +' + test_expect_success 'submodule deinit deinits a submodule when its work tree is missing or empty' ' git submodule update --init && rm -rf init example2/* example2/.git && @@ -1007,6 +1041,10 @@ test_expect_success 'submodule deinit is silent when used on an uninitialized su test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual && test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual && test_i18ngrep "Cleared directory .init" actual && + git submodule deinit --all >actual && + test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual && + test_i18ngrep ! "Submodule .example2. (.*) unregistered for path .example2" actual && + test_i18ngrep "Cleared directory .init" actual && rmdir init example2 ' diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 0791df75ac..5f278799d5 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -63,6 +63,10 @@ test_expect_success 'setup a submodule tree' ' git submodule add ../none none && test_tick && git commit -m "none" + ) && + git clone . recursivesuper && + ( cd recursivesuper + git submodule add ../super super ) ' @@ -95,6 +99,47 @@ test_expect_success 'submodule update from subdirectory' ' ) ' +supersha1=$(git -C super rev-parse HEAD) +mergingsha1=$(git -C super/merging rev-parse HEAD) +nonesha1=$(git -C super/none rev-parse HEAD) +rebasingsha1=$(git -C super/rebasing rev-parse HEAD) +submodulesha1=$(git -C super/submodule rev-parse HEAD) +pwd=$(pwd) + +cat <<EOF >expect +Submodule path '../super': checked out '$supersha1' +Submodule path '../super/merging': checked out '$mergingsha1' +Submodule path '../super/none': checked out '$nonesha1' +Submodule path '../super/rebasing': checked out '$rebasingsha1' +Submodule path '../super/submodule': checked out '$submodulesha1' +EOF + +cat <<EOF >expect2 +Submodule 'merging' ($pwd/merging) registered for path '../super/merging' +Submodule 'none' ($pwd/none) registered for path '../super/none' +Submodule 'rebasing' ($pwd/rebasing) registered for path '../super/rebasing' +Submodule 'submodule' ($pwd/submodule) registered for path '../super/submodule' +Cloning into '$pwd/recursivesuper/super/merging'... +done. +Cloning into '$pwd/recursivesuper/super/none'... +done. +Cloning into '$pwd/recursivesuper/super/rebasing'... +done. +Cloning into '$pwd/recursivesuper/super/submodule'... +done. +EOF + +test_expect_success 'submodule update --init --recursive from subdirectory' ' + git -C recursivesuper/super reset --hard HEAD^ && + (cd recursivesuper && + mkdir tmp && + cd tmp && + git submodule update --init --recursive ../super >../../actual 2>../../actual2 + ) && + test_cmp expect actual && + test_cmp expect2 actual2 +' + apos="'"; test_expect_success 'submodule update does not fetch already present commits' ' (cd submodule && @@ -311,16 +356,59 @@ test_expect_success 'submodule update - command in .git/config' ' ) ' +cat << EOF >expect +Execution of 'false $submodulesha1' failed in submodule path 'submodule' +EOF + test_expect_success 'submodule update - command in .git/config catches failure' ' (cd super && git config submodule.submodule.update "!false" ) && (cd super/submodule && - git reset --hard HEAD^ + git reset --hard $submodulesha1^ ) && (cd super && - test_must_fail git submodule update submodule - ) + test_must_fail git submodule update submodule 2>../actual + ) && + test_cmp actual expect +' + +cat << EOF >expect +Execution of 'false $submodulesha1' failed in submodule path '../submodule' +EOF + +test_expect_success 'submodule update - command in .git/config catches failure -- subdirectory' ' + (cd super && + git config submodule.submodule.update "!false" + ) && + (cd super/submodule && + git reset --hard $submodulesha1^ + ) && + (cd super && + mkdir tmp && cd tmp && + test_must_fail git submodule update ../submodule 2>../../actual + ) && + test_cmp actual expect +' + +cat << EOF >expect +Execution of 'false $submodulesha1' failed in submodule path '../super/submodule' +Failed to recurse into submodule path '../super' +EOF + +test_expect_success 'recursive submodule update - command in .git/config catches failure -- subdirectory' ' + (cd recursivesuper && + git submodule update --remote super && + git add super && + git commit -m "update to latest to have more than one commit in submodules" + ) && + git -C recursivesuper/super config submodule.submodule.update "!false" && + git -C recursivesuper/super/submodule reset --hard $submodulesha1^ && + (cd recursivesuper && + mkdir -p tmp && cd tmp && + test_must_fail git submodule update --recursive ../super 2>../../actual + ) && + test_cmp actual expect ' test_expect_success 'submodule init does not copy command into .git/config' ' diff --git a/t/t7407-submodule-foreach.sh b/t/t7407-submodule-foreach.sh index 7ca10b8606..6ba5daf42e 100755 --- a/t/t7407-submodule-foreach.sh +++ b/t/t7407-submodule-foreach.sh @@ -178,6 +178,26 @@ test_expect_success 'test messages from "foreach --recursive"' ' ' cat > expect <<EOF +Entering '../nested1' +Entering '../nested1/nested2' +Entering '../nested1/nested2/nested3' +Entering '../nested1/nested2/nested3/submodule' +Entering '../sub1' +Entering '../sub2' +Entering '../sub3' +EOF + +test_expect_success 'test messages from "foreach --recursive" from subdirectory' ' + ( + cd clone2 && + mkdir untracked && + cd untracked && + git submodule foreach --recursive >../../actual + ) && + test_i18ncmp expect actual +' + +cat > expect <<EOF nested1-nested1 nested2-nested2 nested3-nested3 @@ -242,8 +262,12 @@ test_expect_success 'test "status --recursive"' ' test_cmp expect actual ' -sed -e "/nested2 /s/.*/+$nested2sha1 nested1\/nested2 (file2~1)/;/sub[1-3]/d" < expect > expect2 -mv -f expect2 expect +cat > expect <<EOF + $nested1sha1 nested1 (heads/master) ++$nested2sha1 nested1/nested2 (file2~1) + $nested3sha1 nested1/nested2/nested3 (heads/master) + $submodulesha1 nested1/nested2/nested3/submodule (heads/master) +EOF test_expect_success 'ensure "status --cached --recursive" preserves the --cached flag' ' ( @@ -257,6 +281,27 @@ test_expect_success 'ensure "status --cached --recursive" preserves the --cached test_cmp expect actual ' +nested2sha1=$(git -C clone3/nested1/nested2 rev-parse HEAD) + +cat > expect <<EOF + $nested1sha1 ../nested1 (heads/master) ++$nested2sha1 ../nested1/nested2 (file2) + $nested3sha1 ../nested1/nested2/nested3 (heads/master) + $submodulesha1 ../nested1/nested2/nested3/submodule (heads/master) + $sub1sha1 ../sub1 ($sub1sha1_short) + $sub2sha1 ../sub2 ($sub2sha1_short) + $sub3sha1 ../sub3 (heads/master) +EOF + +test_expect_success 'test "status --recursive" from sub directory' ' + ( + cd clone3 && + mkdir tmp && cd tmp && + git submodule status --recursive > ../../actual + ) && + test_cmp expect actual +' + test_expect_success 'use "git clone --recursive" to checkout all submodules' ' git clone --recursive super clone4 && ( diff --git a/t/t7412-submodule--helper.sh b/t/t7412-submodule--helper.sh deleted file mode 100755 index 149d42864f..0000000000 --- a/t/t7412-submodule--helper.sh +++ /dev/null @@ -1,26 +0,0 @@ -#!/bin/sh -# -# Copyright (c) 2016 Jacob Keller -# - -test_description='Basic plumbing support of submodule--helper - -This test verifies the submodule--helper plumbing command used to implement -git-submodule. -' - -. ./test-lib.sh - -test_expect_success 'sanitize-config clears configuration' ' - git -c user.name="Some User" submodule--helper sanitize-config >actual && - test_must_be_empty actual -' - -sq="'" -test_expect_success 'sanitize-config keeps credential.helper' ' - git -c credential.helper=helper submodule--helper sanitize-config >actual && - echo "${sq}credential.helper=helper${sq}" >expect && - test_cmp expect actual -' - -test_done diff --git a/t/t7501-commit.sh b/t/t7501-commit.sh index 900f7de05a..d84897a67a 100755 --- a/t/t7501-commit.sh +++ b/t/t7501-commit.sh @@ -607,4 +607,24 @@ test_expect_success '--only works on to-be-born branch' ' test_cmp expected actual ' +test_expect_success '--dry-run with conflicts fixed from a merge' ' + # setup two branches with conflicting information + # in the same file, resolve the conflict, + # call commit with --dry-run + echo "Initial contents, unimportant" >test-file && + git add test-file && + git commit -m "Initial commit" && + echo "commit-1-state" >test-file && + git commit -m "commit 1" -i test-file && + git tag commit-1 && + git checkout -b branch-2 HEAD^1 && + echo "commit-2-state" >test-file && + git commit -m "commit 2" -i test-file && + ! $(git merge --no-commit commit-1) && + echo "commit-2-state" >test-file && + git add test-file && + git commit --dry-run && + git commit -m "conflicts fixed from merge." +' + test_done diff --git a/t/t7507-commit-verbose.sh b/t/t7507-commit-verbose.sh index 2ddf28c984..ed2653d46f 100755 --- a/t/t7507-commit-verbose.sh +++ b/t/t7507-commit-verbose.sh @@ -3,11 +3,10 @@ test_description='verbose commit template' . ./test-lib.sh -cat >check-for-diff <<EOF -#!$SHELL_PATH -exec grep '^diff --git' "\$1" +write_script "check-for-diff" <<\EOF && +grep '^diff --git' "$1" >out +exit 0 EOF -chmod +x check-for-diff test_set_editor "$PWD/check-for-diff" cat >message <<'EOF' @@ -23,7 +22,8 @@ test_expect_success 'setup' ' ' test_expect_success 'initial commit shows verbose diff' ' - git commit --amend -v + git commit --amend -v && + test_line_count = 1 out ' test_expect_success 'second commit' ' @@ -39,13 +39,15 @@ check_message() { test_expect_success 'verbose diff is stripped out' ' git commit --amend -v && - check_message message + check_message message && + test_line_count = 1 out ' test_expect_success 'verbose diff is stripped out (mnemonicprefix)' ' git config diff.mnemonicprefix true && git commit --amend -v && - check_message message + check_message message && + test_line_count = 1 out ' cat >diff <<'EOF' @@ -96,4 +98,60 @@ test_expect_success 'verbose diff is stripped out with set core.commentChar' ' test_i18ngrep "Aborting commit due to empty commit message." err ' +test_expect_success 'status does not verbose without --verbose' ' + git status >actual && + ! grep "^diff --git" actual +' + +test_expect_success 'setup -v -v' ' + echo dirty >file +' + +for i in true 1 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 1 out + " +done + +for i in false -2 -1 0 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 0 out + " +done + +for i in 2 3 +do + test_expect_success "commit.verbose=$i and --verbose omitted" " + git -c commit.verbose=$i commit --amend && + test_line_count = 2 out + " +done + +for i in true false -2 -1 0 1 2 3 +do + test_expect_success "commit.verbose=$i and --verbose" " + git -c commit.verbose=$i commit --amend --verbose && + test_line_count = 1 out + " + + test_expect_success "commit.verbose=$i and --no-verbose" " + git -c commit.verbose=$i commit --amend --no-verbose && + test_line_count = 0 out + " + + test_expect_success "commit.verbose=$i and -v -v" " + git -c commit.verbose=$i commit --amend -v -v && + test_line_count = 2 out + " +done + +test_expect_success "status ignores commit.verbose=true" ' + git -c commit.verbose=true status >actual && + ! grep "^diff --git actual" +' + test_done diff --git a/t/t7510-signed-commit.sh b/t/t7510-signed-commit.sh index 18e5cf0663..4177a8609a 100755 --- a/t/t7510-signed-commit.sh +++ b/t/t7510-signed-commit.sh @@ -45,12 +45,18 @@ test_expect_success GPG 'create signed commits' ' git tag seventh-signed && echo 8 >file && test_tick && git commit -a -m eighth -SB7227189 && - git tag eighth-signed-alt + git tag eighth-signed-alt && + + # commit.gpgsign is still on but this must not be signed + git tag ninth-unsigned $(echo 9 | git commit-tree HEAD^{tree}) && + # explicit -S of course must sign. + git tag tenth-signed $(echo 9 | git commit-tree -S HEAD^{tree}) ' test_expect_success GPG 'verify and show signatures' ' ( - for commit in initial second merge fourth-signed fifth-signed sixth-signed seventh-signed + for commit in initial second merge fourth-signed \ + fifth-signed sixth-signed seventh-signed tenth-signed do git verify-commit $commit && git show --pretty=short --show-signature $commit >actual && @@ -60,7 +66,8 @@ test_expect_success GPG 'verify and show signatures' ' done ) && ( - for commit in merge^2 fourth-unsigned sixth-unsigned seventh-unsigned + for commit in merge^2 fourth-unsigned sixth-unsigned \ + seventh-unsigned ninth-unsigned do test_must_fail git verify-commit $commit && git show --pretty=short --show-signature $commit >actual && diff --git a/t/t7605-merge-resolve.sh b/t/t7605-merge-resolve.sh index 0cb9d11f21..5d56c38546 100755 --- a/t/t7605-merge-resolve.sh +++ b/t/t7605-merge-resolve.sh @@ -27,7 +27,7 @@ test_expect_success 'setup' ' git tag c3 ' -test_expect_success 'merge c1 to c2' ' +merge_c1_to_c2_cmds=' git reset --hard c1 && git merge -s resolve c2 && test "$(git rev-parse c1)" != "$(git rev-parse HEAD)" && @@ -41,6 +41,10 @@ test_expect_success 'merge c1 to c2' ' test 3 = $(git ls-files | wc -l) ' +test_expect_success 'merge c1 to c2' "$merge_c1_to_c2_cmds" + +test_expect_success 'merge c1 to c2, again' "$merge_c1_to_c2_cmds" + test_expect_success 'merge c2 to c3 (fails)' ' git reset --hard c2 && test_must_fail git merge -s resolve c3 diff --git a/t/t7609-merge-co-error-msgs.sh b/t/t7609-merge-co-error-msgs.sh index 0e4a682c64..6729cb379f 100755 --- a/t/t7609-merge-co-error-msgs.sh +++ b/t/t7609-merge-co-error-msgs.sh @@ -37,14 +37,14 @@ EOF test_expect_success 'untracked files overwritten by merge (fast and non-fast forward)' ' test_must_fail git merge branch 2>out && - test_cmp out expect && + test_i18ncmp out expect && git commit --allow-empty -m empty && ( GIT_MERGE_VERBOSITY=0 && export GIT_MERGE_VERBOSITY && test_must_fail git merge branch 2>out2 ) && - test_cmp out2 expect && + test_i18ncmp out2 expect && git reset --hard HEAD^ ' @@ -53,7 +53,7 @@ error: Your local changes to the following files would be overwritten by merge: four three two -Please, commit your changes or stash them before you can merge. +Please commit your changes or stash them before you can merge. error: The following untracked working tree files would be overwritten by merge: five Please move or remove them before you can merge. @@ -65,14 +65,14 @@ test_expect_success 'untracked files or local changes ovewritten by merge' ' git add three && git add four && test_must_fail git merge branch 2>out && - test_cmp out expect + test_i18ncmp out expect ' cat >expect <<\EOF error: Your local changes to the following files would be overwritten by checkout: rep/one rep/two -Please, commit your changes or stash them before you can switch branches. +Please commit your changes or stash them before you can switch branches. Aborting EOF @@ -87,21 +87,21 @@ test_expect_success 'cannot switch branches because of local changes' ' echo uno >rep/one && echo dos >rep/two && test_must_fail git checkout branch 2>out && - test_cmp out expect + test_i18ncmp out expect ' cat >expect <<\EOF error: Your local changes to the following files would be overwritten by checkout: rep/one rep/two -Please, commit your changes or stash them before you can switch branches. +Please commit your changes or stash them before you can switch branches. Aborting EOF test_expect_success 'not uptodate file porcelain checkout error' ' git add rep/one rep/two && test_must_fail git checkout branch 2>out && - test_cmp out expect + test_i18ncmp out expect ' cat >expect <<\EOF @@ -132,7 +132,7 @@ test_expect_success 'not_uptodate_dir porcelain checkout error' ' >rep/untracked-file && >rep2/untracked-file && test_must_fail git checkout branch 2>out && - test_cmp out ../expect + test_i18ncmp out ../expect ' test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index 4e713f7aa5..7ce4cd753e 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -20,7 +20,7 @@ difftool_test_setup () prompt_given () { prompt="$1" - test "$prompt" = "Launch 'test-tool' [Y/n]: branch" + test "$prompt" = "Launch 'test-tool' [Y/n]? branch" } # Create a file on master and change it on branch @@ -419,6 +419,29 @@ run_dir_diff_test 'difftool --dir-diff when worktree file is missing' ' grep file2 output ' +run_dir_diff_test 'difftool --dir-diff with unmerged files' ' + test_when_finished git reset --hard && + test_config difftool.echo.cmd "echo ok" && + git checkout -B conflict-a && + git checkout -B conflict-b && + git checkout conflict-a && + echo a >>file && + git add file && + git commit -m conflict-a && + git checkout conflict-b && + echo b >>file && + git add file && + git commit -m conflict-b && + git checkout master && + git merge conflict-a && + test_must_fail git merge conflict-b && + cat >expect <<-EOF && + ok + EOF + git difftool --dir-diff $symlinks -t echo >actual && + test_cmp expect actual +' + write_script .git/CHECK_SYMLINKS <<\EOF for f in file file2 sub/sub do diff --git a/t/t9100-git-svn-basic.sh b/t/t9100-git-svn-basic.sh index 22d8367ff3..28082b134f 100755 --- a/t/t9100-git-svn-basic.sh +++ b/t/t9100-git-svn-basic.sh @@ -45,13 +45,13 @@ test_expect_success "checkout from svn" 'svn co "$svnrepo" "$SVN_TREE"' name='try a deep --rmdir with a commit' test_expect_success "$name" ' - git checkout -f -b mybranch ${remotes_git_svn} && + git checkout -f -b mybranch remotes/git-svn && mv dir/a/b/c/d/e/file dir/file && cp dir/file file && git update-index --add --remove dir/a/b/c/d/e/file dir/file file && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch && + remotes/git-svn..mybranch && svn_cmd up "$SVN_TREE" && test -d "$SVN_TREE"/dir && test ! -d "$SVN_TREE"/dir/a' @@ -65,14 +65,14 @@ test_expect_success "$name" " git update-index --add dir/file/file && git commit -m '$name' && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch + remotes/git-svn..mybranch " name='detect node change from directory to file #1' test_expect_success "$name" ' rm -rf dir "$GIT_DIR"/index && - git checkout -f -b mybranch2 ${remotes_git_svn} && + git checkout -f -b mybranch2 remotes/git-svn && mv bar/zzz zzz && rm -rf bar && mv zzz bar && @@ -80,14 +80,14 @@ test_expect_success "$name" ' git update-index --add -- bar && git commit -m "$name" && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch2 + remotes/git-svn..mybranch2 ' name='detect node change from file to directory #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch3 ${remotes_git_svn} && + git checkout -f -b mybranch3 remotes/git-svn && rm bar/zzz && git update-index --remove bar/zzz && mkdir bar/zzz && @@ -95,7 +95,7 @@ test_expect_success "$name" ' git update-index --add bar/zzz/yyy && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch3 && + remotes/git-svn..mybranch3 && svn_cmd up "$SVN_TREE" && test -d "$SVN_TREE"/bar/zzz && test -e "$SVN_TREE"/bar/zzz/yyy @@ -104,7 +104,7 @@ test_expect_success "$name" ' name='detect node change from directory to file #2' test_expect_success "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch4 ${remotes_git_svn} && + git checkout -f -b mybranch4 remotes/git-svn && rm -rf dir && git update-index --remove -- dir/file && touch dir && @@ -112,19 +112,19 @@ test_expect_success "$name" ' git update-index --add -- dir && git commit -m "$name" && test_must_fail git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch4 + remotes/git-svn..mybranch4 ' name='remove executable bit from a file' test_expect_success POSIXPERM "$name" ' rm -f "$GIT_DIR"/index && - git checkout -f -b mybranch5 ${remotes_git_svn} && + git checkout -f -b mybranch5 remotes/git-svn && chmod -x exec.sh && git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test ! -x "$SVN_TREE"/exec.sh' @@ -135,7 +135,7 @@ test_expect_success POSIXPERM "$name" ' git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -x "$SVN_TREE"/exec.sh' @@ -147,7 +147,7 @@ test_expect_success SYMLINKS "$name" ' git update-index exec.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -h "$SVN_TREE"/exec.sh' @@ -159,7 +159,7 @@ test_expect_success POSIXPERM,SYMLINKS "$name" ' git update-index --add file exec-2.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -x "$SVN_TREE"/file && test -h "$SVN_TREE"/exec-2.sh' @@ -172,7 +172,7 @@ test_expect_success POSIXPERM,SYMLINKS "$name" ' git update-index exec-2.sh && git commit -m "$name" && git svn set-tree --find-copies-harder --rmdir \ - ${remotes_git_svn}..mybranch5 && + remotes/git-svn..mybranch5 && svn_cmd up "$SVN_TREE" && test -f "$SVN_TREE"/exec-2.sh && test ! -h "$SVN_TREE"/exec-2.sh && @@ -194,7 +194,7 @@ GIT_SVN_ID=alt export GIT_SVN_ID test_expect_success "$name" \ 'git svn init "$svnrepo" && git svn fetch && - git rev-list --pretty=raw ${remotes_git_svn} | grep ^tree | uniq > a && + git rev-list --pretty=raw remotes/git-svn | grep ^tree | uniq > a && git rev-list --pretty=raw remotes/alt | grep ^tree | uniq > b && test_cmp a b' @@ -217,17 +217,17 @@ EOF test_expect_success POSIXPERM,SYMLINKS "$name" "test_cmp a expected" -test_expect_success 'exit if remote refs are ambigious' " +test_expect_success 'exit if remote refs are ambigious' ' git config --add svn-remote.svn.fetch \ - bar:refs/${remotes_git_svn} && + bar:refs/remotes/git-svn && test_must_fail git svn migrate -" +' test_expect_success 'exit if init-ing a would clobber a URL' ' svnadmin create "${PWD}/svnrepo2" && svn mkdir -m "mkdir bar" "${svnrepo}2/bar" && git config --unset svn-remote.svn.fetch \ - "^bar:refs/${remotes_git_svn}$" && + "^bar:refs/remotes/git-svn$" && test_must_fail git svn init "${svnrepo}2/bar" ' @@ -237,7 +237,7 @@ test_expect_success \ git config --get svn-remote.svn.fetch \ "^bar:refs/remotes/bar$" && git config --get svn-remote.svn.fetch \ - "^:refs/${remotes_git_svn}$" + "^:refs/remotes/git-svn$" ' test_expect_success 'dcommit $rev does not clobber current branch' ' @@ -259,26 +259,26 @@ test_expect_success 'dcommit $rev does not clobber current branch' ' git branch -D my-bar ' -test_expect_success 'able to dcommit to a subdirectory' " +test_expect_success 'able to dcommit to a subdirectory' ' git svn fetch -i bar && git checkout -b my-bar refs/remotes/bar && echo abc > d && git update-index --add d && - git commit -m '/bar/d should be in the log' && + git commit -m "/bar/d should be in the log" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" && + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" && mkdir newdir && echo new > newdir/dir && git update-index --add newdir/dir && - git commit -m 'add a new directory' && + git commit -m "add a new directory" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" && + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" && echo foo >> newdir/dir && git update-index newdir/dir && - git commit -m 'modify a file in new directory' && + git commit -m "modify a file in new directory" && git svn dcommit -i bar && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" - " + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" +' test_expect_success 'dcommit should not fail with a touched file' ' test_commit "commit-new-file-foo2" foo2 && @@ -291,13 +291,13 @@ test_expect_success 'rebase should not fail with a touched file' ' git svn rebase ' -test_expect_success 'able to set-tree to a subdirectory' " +test_expect_success 'able to set-tree to a subdirectory' ' echo cba > d && git update-index d && - git commit -m 'update /bar/d' && + git commit -m "update /bar/d" && git svn set-tree -i bar HEAD && - test -z \"\$(git diff refs/heads/my-bar refs/remotes/bar)\" - " + test -z "$(git diff refs/heads/my-bar refs/remotes/bar)" +' test_expect_success 'git-svn works in a bare repository' ' mkdir bare-repo && diff --git a/t/t9101-git-svn-props.sh b/t/t9101-git-svn-props.sh index e8173d5fef..07bfb63777 100755 --- a/t/t9101-git-svn-props.sh +++ b/t/t9101-git-svn-props.sh @@ -73,11 +73,11 @@ test_expect_success 'fetch revisions from svn' 'git svn fetch' name='test svn:keywords ignoring' test_expect_success "$name" \ - 'git checkout -b mybranch ${remotes_git_svn} && + 'git checkout -b mybranch remotes/git-svn && echo Hi again >> kw.c && git commit -a -m "test keywords ignoring" && - git svn set-tree ${remotes_git_svn}..mybranch && - git pull . ${remotes_git_svn}' + git svn set-tree remotes/git-svn..mybranch && + git pull . remotes/git-svn' expect='/* $Id$ */' got="$(sed -ne 2p kw.c)" @@ -95,7 +95,7 @@ test_expect_success "propset CR on crlf files" ' test_expect_success 'fetch and pull latest from svn and checkout a new wc' \ 'git svn fetch && - git pull . ${remotes_git_svn} && + git pull . remotes/git-svn && svn_cmd co "$svnrepo" new_wc' for i in crlf ne_crlf lf ne_lf cr ne_cr empty_cr empty_lf empty empty_crlf @@ -117,7 +117,7 @@ cd test_wc svn_cmd commit -m "propset CRLF on cr files"' cd .. test_expect_success 'fetch and pull latest from svn' \ - 'git svn fetch && git pull . ${remotes_git_svn}' + 'git svn fetch && git pull . remotes/git-svn' b_cr="$(git hash-object cr)" b_ne_cr="$(git hash-object ne_cr)" @@ -168,7 +168,7 @@ cat >create-ignore-index.expect <<\EOF EOF test_expect_success 'test create-ignore' " - git svn fetch && git pull . ${remotes_git_svn} && + git svn fetch && git pull . remotes/git-svn && git svn create-ignore && cmp ./.gitignore create-ignore.expect && cmp ./deeply/.gitignore create-ignore.expect && diff --git a/t/t9102-git-svn-deep-rmdir.sh b/t/t9102-git-svn-deep-rmdir.sh index eb70f4839c..66cd51102c 100755 --- a/t/t9102-git-svn-deep-rmdir.sh +++ b/t/t9102-git-svn-deep-rmdir.sh @@ -17,7 +17,7 @@ test_expect_success 'initialize repo' ' test_expect_success 'mirror via git svn' ' git svn init "$svnrepo" && git svn fetch && - git checkout -f -b test-rmdir ${remotes_git_svn} + git checkout -f -b test-rmdir remotes/git-svn ' test_expect_success 'Try a commit on rmdir' ' diff --git a/t/t9103-git-svn-tracked-directory-removed.sh b/t/t9103-git-svn-tracked-directory-removed.sh index 3413164cb1..b28271345c 100755 --- a/t/t9103-git-svn-tracked-directory-removed.sh +++ b/t/t9103-git-svn-tracked-directory-removed.sh @@ -23,17 +23,19 @@ test_expect_success 'make history for tracking' ' test_expect_success 'clone repo with git' ' git svn clone -s "$svnrepo" x && - test -f x/FOLLOWME && - test ! -f x/README + test_path_is_file x/FOLLOWME && + test_path_is_missing x/README ' -test_expect_success 'make sure r2 still has old file' " - cd x && - test -n \"\$(git svn find-rev r1)\" && - git reset --hard \$(git svn find-rev r1) && - test -f README && - test ! -f FOLLOWME && - test x\$(git svn find-rev r2) = x -" +test_expect_success 'make sure r2 still has old file' ' + ( + cd x && + test -n "$(git svn find-rev r1)" && + git reset --hard "$(git svn find-rev r1)" && + test_path_is_file README && + test_path_is_missing FOLLOWME && + test -z "$(git svn find-rev r2)" + ) +' test_done diff --git a/t/t9106-git-svn-commit-diff-clobber.sh b/t/t9106-git-svn-commit-diff-clobber.sh index f6d7ac7c5f..dbe8deac0d 100755 --- a/t/t9106-git-svn-commit-diff-clobber.sh +++ b/t/t9106-git-svn-commit-diff-clobber.sh @@ -44,7 +44,7 @@ test_expect_success 'commit complementing change from git' ' test_expect_success 'dcommit fails to commit because of conflict' ' git svn init "$svnrepo" && git svn fetch && - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && svn_cmd co "$svnrepo" t.svn && ( cd t.svn && @@ -59,7 +59,7 @@ test_expect_success 'dcommit fails to commit because of conflict' ' ' test_expect_success 'dcommit does the svn equivalent of an index merge' " - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && echo 'index merge' > file2 && git update-index --add file2 && git commit -a -m 'index merge' && @@ -81,7 +81,7 @@ test_expect_success 'commit another change from svn side' ' ' test_expect_success 'multiple dcommit from git svn will not clobber svn' " - git reset --hard refs/${remotes_git_svn} && + git reset --hard refs/remotes/git-svn && echo new file >> new-file && git update-index --add new-file && git commit -a -m 'new file' && diff --git a/t/t9107-git-svn-migrate.sh b/t/t9107-git-svn-migrate.sh index 9060198037..9f3ef8f2ef 100755 --- a/t/t9107-git-svn-migrate.sh +++ b/t/t9107-git-svn-migrate.sh @@ -19,13 +19,14 @@ test_expect_success 'setup old-looking metadata' ' git svn init "$svnrepo" && git svn fetch && rm -rf "$GIT_DIR"/svn && - git update-ref refs/heads/git-svn-HEAD refs/${remotes_git_svn} && - git update-ref refs/heads/svn-HEAD refs/${remotes_git_svn} && - git update-ref -d refs/${remotes_git_svn} refs/${remotes_git_svn} + git update-ref refs/heads/git-svn-HEAD refs/remotes/git-svn && + git update-ref refs/heads/svn-HEAD refs/remotes/git-svn && + git update-ref -d refs/remotes/git-svn refs/remotes/git-svn ' -head=$(git rev-parse --verify refs/heads/git-svn-HEAD^0) -test_expect_success 'git-svn-HEAD is a real HEAD' "test -n '$head'" +test_expect_success 'git-svn-HEAD is a real HEAD' ' + git rev-parse --verify refs/heads/git-svn-HEAD^0 +' svnrepo_escaped=$(echo $svnrepo | sed 's/ /%20/') @@ -35,11 +36,11 @@ test_expect_success 'initialize old-style (v0) git svn layout' ' echo "$svnrepo" > "$GIT_DIR"/svn/info/url && git svn migrate && ! test -d "$GIT_DIR"/git-svn && - git rev-parse --verify refs/${remotes_git_svn}^0 && + git rev-parse --verify refs/remotes/git-svn^0 && git rev-parse --verify refs/remotes/svn^0 && test "$(git config --get svn-remote.svn.url)" = "$svnrepo_escaped" && test $(git config --get svn-remote.svn.fetch) = \ - ":refs/${remotes_git_svn}" + ":refs/remotes/git-svn" ' test_expect_success 'initialize a multi-repository repo' ' @@ -56,9 +57,11 @@ test_expect_success 'initialize a multi-repository repo' ' "^tags/\*:refs/remotes/origin/tags/\*$" && git config --add svn-remote.svn.fetch "branches/a:refs/remotes/origin/a" && git config --add svn-remote.svn.fetch "branches/b:refs/remotes/origin/b" && - for i in tags/0.1 tags/0.2 tags/0.3; do + for i in tags/0.1 tags/0.2 tags/0.3 + do git config --add svn-remote.svn.fetch \ - $i:refs/remotes/origin/$i || exit 1; done && + $i:refs/remotes/origin/$i || return 1 + done && git config --get-all svn-remote.svn.fetch > fetch.out && grep "^trunk:refs/remotes/origin/trunk$" fetch.out && grep "^branches/a:refs/remotes/origin/a$" fetch.out && @@ -66,34 +69,42 @@ test_expect_success 'initialize a multi-repository repo' ' grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && - grep "^:refs/${remotes_git_svn}" fetch.out + grep "^:refs/remotes/git-svn" fetch.out ' # refs should all be different, but the trees should all be the same: -test_expect_success 'multi-fetch works on partial urls + paths' " +test_expect_success 'multi-fetch works on partial urls + paths' ' + refs="trunk a b tags/0.1 tags/0.2 tags/0.3" && git svn multi-fetch && - for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do - git rev-parse --verify refs/remotes/origin/\$i^0 >> refs.out || exit 1; - done && - test -z \"\$(sort < refs.out | uniq -d)\" && - for i in trunk a b tags/0.1 tags/0.2 tags/0.3; do - for j in trunk a b tags/0.1 tags/0.2 tags/0.3; do - if test \$j != \$i; then continue; fi - test -z \"\$(git diff refs/remotes/origin/\$i \ - refs/remotes/origin/\$j)\" ||exit 1; done; done - " + for i in $refs + do + git rev-parse --verify refs/remotes/origin/$i^0 || return 1; + done >refs.out && + test -z "$(sort <refs.out | uniq -d)" && + for i in $refs + do + for j in $refs + do + git diff --exit-code refs/remotes/origin/$i \ + refs/remotes/origin/$j || + return 1 + done + done +' test_expect_success 'migrate --minimize on old inited layout' ' git config --unset-all svn-remote.svn.fetch && git config --unset-all svn-remote.svn.url && rm -rf "$GIT_DIR"/svn && - for i in $(cat fetch.out); do + for i in $(cat fetch.out) + do path=$(expr $i : "\([^:]*\):.*$") ref=$(expr $i : "[^:]*:\(refs/remotes/.*\)$") if test -z "$ref"; then continue; fi if test -n "$path"; then path="/$path"; fi - ( mkdir -p "$GIT_DIR"/svn/$ref/info/ && - echo "$svnrepo"$path > "$GIT_DIR"/svn/$ref/info/url ) || exit 1; + mkdir -p "$GIT_DIR"/svn/$ref/info/ && + echo "$svnrepo"$path >"$GIT_DIR"/svn/$ref/info/url || + return 1 done && git svn migrate --minimize && test -z "$(git config -l | grep "^svn-remote\.git-svn\.")" && @@ -104,7 +115,7 @@ test_expect_success 'migrate --minimize on old inited layout' ' grep "^tags/0\.1:refs/remotes/origin/tags/0\.1$" fetch.out && grep "^tags/0\.2:refs/remotes/origin/tags/0\.2$" fetch.out && grep "^tags/0\.3:refs/remotes/origin/tags/0\.3$" fetch.out && - grep "^:refs/${remotes_git_svn}" fetch.out + grep "^:refs/remotes/git-svn" fetch.out ' test_expect_success ".rev_db auto-converted to .rev_map.UUID" ' diff --git a/t/t9110-git-svn-use-svm-props.sh b/t/t9110-git-svn-use-svm-props.sh index 29fbdfdd3f..dde0a3c222 100755 --- a/t/t9110-git-svn-use-svm-props.sh +++ b/t/t9110-git-svn-use-svm-props.sh @@ -22,31 +22,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^${git_svn_id}: $bar_url@12 $uuid$' && + grep '^git-svn-id: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^${git_svn_id}: $bar_url@11 $uuid$' && + grep '^git-svn-id: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^${git_svn_id}: $bar_url@10 $uuid$' && + grep '^git-svn-id: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^${git_svn_id}: $bar_url@9 $uuid$' && + grep '^git-svn-id: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^${git_svn_id}: $bar_url@6 $uuid$' && + grep '^git-svn-id: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^${git_svn_id}: $bar_url@1 $uuid$' + grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^${git_svn_id}: $e_url@1 $uuid$' + grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^${git_svn_id}: $dir_url@2 $uuid$' && + grep '^git-svn-id: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^${git_svn_id}: $dir_url@1 $uuid$' + grep '^git-svn-id: $dir_url@1 $uuid$' " test_expect_success 'find commit based on SVN revision number' " diff --git a/t/t9111-git-svn-use-svnsync-props.sh b/t/t9111-git-svn-use-svnsync-props.sh index bd081c2ec3..22b6e5ee7d 100755 --- a/t/t9111-git-svn-use-svnsync-props.sh +++ b/t/t9111-git-svn-use-svnsync-props.sh @@ -21,31 +21,31 @@ uuid=161ce429-a9dd-4828-af4a-52023f968c89 bar_url=http://mayonaise/svnrepo/bar test_expect_success 'verify metadata for /bar' " git cat-file commit refs/remotes/bar | \ - grep '^${git_svn_id}: $bar_url@12 $uuid$' && + grep '^git-svn-id: $bar_url@12 $uuid$' && git cat-file commit refs/remotes/bar~1 | \ - grep '^${git_svn_id}: $bar_url@11 $uuid$' && + grep '^git-svn-id: $bar_url@11 $uuid$' && git cat-file commit refs/remotes/bar~2 | \ - grep '^${git_svn_id}: $bar_url@10 $uuid$' && + grep '^git-svn-id: $bar_url@10 $uuid$' && git cat-file commit refs/remotes/bar~3 | \ - grep '^${git_svn_id}: $bar_url@9 $uuid$' && + grep '^git-svn-id: $bar_url@9 $uuid$' && git cat-file commit refs/remotes/bar~4 | \ - grep '^${git_svn_id}: $bar_url@6 $uuid$' && + grep '^git-svn-id: $bar_url@6 $uuid$' && git cat-file commit refs/remotes/bar~5 | \ - grep '^${git_svn_id}: $bar_url@1 $uuid$' + grep '^git-svn-id: $bar_url@1 $uuid$' " e_url=http://mayonaise/svnrepo/dir/a/b/c/d/e test_expect_success 'verify metadata for /dir/a/b/c/d/e' " git cat-file commit refs/remotes/e | \ - grep '^${git_svn_id}: $e_url@1 $uuid$' + grep '^git-svn-id: $e_url@1 $uuid$' " dir_url=http://mayonaise/svnrepo/dir test_expect_success 'verify metadata for /dir' " git cat-file commit refs/remotes/dir | \ - grep '^${git_svn_id}: $dir_url@2 $uuid$' && + grep '^git-svn-id: $dir_url@2 $uuid$' && git cat-file commit refs/remotes/dir~1 | \ - grep '^${git_svn_id}: $dir_url@1 $uuid$' + grep '^git-svn-id: $dir_url@1 $uuid$' " test_done diff --git a/t/t9120-git-svn-clone-with-percent-escapes.sh b/t/t9120-git-svn-clone-with-percent-escapes.sh index 1c84ce1023..59465b147e 100755 --- a/t/t9120-git-svn-clone-with-percent-escapes.sh +++ b/t/t9120-git-svn-clone-with-percent-escapes.sh @@ -22,7 +22,7 @@ test_expect_success 'test clone with percent escapes' ' git svn clone "$svnrepo/pr%20ject" clone && ( cd clone && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' @@ -42,7 +42,7 @@ test_expect_success 'test clone trunk with percent escapes and minimize-url' ' git svn clone --minimize-url "$svnrepo/pr%20ject/trunk" minimize && ( cd minimize && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' @@ -50,7 +50,7 @@ test_expect_success 'test clone trunk with percent escapes' ' git svn clone "$svnrepo/pr%20ject/trunk" trunk && ( cd trunk && - git rev-parse refs/${remotes_git_svn} + git rev-parse refs/remotes/git-svn ) ' diff --git a/t/t9123-git-svn-rebuild-with-rewriteroot.sh b/t/t9123-git-svn-rebuild-with-rewriteroot.sh index fd8184787f..ead404589e 100755 --- a/t/t9123-git-svn-rebuild-with-rewriteroot.sh +++ b/t/t9123-git-svn-rebuild-with-rewriteroot.sh @@ -17,7 +17,7 @@ rm -rf import test_expect_success 'init, fetch and checkout repository' ' git svn init --rewrite-root=http://invalid.invalid/ "$svnrepo" && git svn fetch && - git checkout -b mybranch ${remotes_git_svn} + git checkout -b mybranch remotes/git-svn ' test_expect_success 'remove rev_map' ' diff --git a/t/t9153-git-svn-rewrite-uuid.sh b/t/t9153-git-svn-rewrite-uuid.sh index 88a2cfa233..372ef15685 100755 --- a/t/t9153-git-svn-rewrite-uuid.sh +++ b/t/t9153-git-svn-rewrite-uuid.sh @@ -17,9 +17,9 @@ test_expect_success 'load svn repo' " test_expect_success 'verify uuid' " git cat-file commit refs/remotes/git-svn~0 | \ - grep '^${git_svn_id}: .*@2 $uuid$' && + grep '^git-svn-id: .*@2 $uuid$' && git cat-file commit refs/remotes/git-svn~1 | \ - grep '^${git_svn_id}: .*@1 $uuid$' + grep '^git-svn-id: .*@1 $uuid$' " test_done diff --git a/t/t9802-git-p4-filetype.sh b/t/t9802-git-p4-filetype.sh index 66d3fc91a7..eb9a8ed197 100755 --- a/t/t9802-git-p4-filetype.sh +++ b/t/t9802-git-p4-filetype.sh @@ -223,12 +223,12 @@ build_gendouble() { import sys import struct - s = struct.pack(">LL18s", + s = struct.pack(b">LL18s", 0x00051607, # AppleDouble 0x00020000, # version 2 - "" # pad to 26 bytes + b"" # pad to 26 bytes ) - sys.stdout.write(s) + getattr(sys.stdout, 'buffer', sys.stdout).write(s) EOF } diff --git a/t/t9824-git-p4-git-lfs.sh b/t/t9824-git-p4-git-lfs.sh index 0b664a377c..110a7e7924 100755 --- a/t/t9824-git-p4-git-lfs.sh +++ b/t/t9824-git-p4-git-lfs.sh @@ -13,6 +13,10 @@ test_file_in_lfs () { FILE="$1" && SIZE="$2" && EXPECTED_CONTENT="$3" && + sed -n '1,1 p' "$FILE" | grep "^version " && + sed -n '2,2 p' "$FILE" | grep "^oid " && + sed -n '3,3 p' "$FILE" | grep "^size " && + test_line_count = 3 "$FILE" && cat "$FILE" | grep "size $SIZE" && HASH=$(cat "$FILE" | grep "oid sha256:" | sed -e "s/oid sha256://g") && LFS_FILE=".git/lfs/objects/$(echo "$HASH" | cut -c1-2)/$(echo "$HASH" | cut -c3-4)/$HASH" && @@ -265,7 +269,7 @@ test_expect_success 'Add big files to repo and store files in LFS based on compr # We only import HEAD here ("@all" is missing!) git p4 clone --destination="$git" //depot && - test_file_in_lfs file6.bin 13 "content 6 bin 39 bytes XXXXXYYYYYZZZZZ" + test_file_in_lfs file6.bin 39 "content 6 bin 39 bytes XXXXXYYYYYZZZZZ" && test_file_count_in_dir ".git/lfs/objects" 1 && cat >expect <<-\EOF && diff --git a/t/t9826-git-p4-keep-empty-commits.sh b/t/t9826-git-p4-keep-empty-commits.sh index be12960d39..fa8b9daf1f 100755 --- a/t/t9826-git-p4-keep-empty-commits.sh +++ b/t/t9826-git-p4-keep-empty-commits.sh @@ -47,23 +47,23 @@ test_expect_success 'Clone repo root path with all history' ' git init . && git p4 clone --use-client-spec --destination="$git" //depot@all && cat >expect <<-\EOF && -Remove file 4 -[git-p4: depot-paths = "//depot/": change = 6] + Remove file 4 + [git-p4: depot-paths = "//depot/": change = 6] -Remove file 3 -[git-p4: depot-paths = "//depot/": change = 5] + Remove file 3 + [git-p4: depot-paths = "//depot/": change = 5] -Add file 4 -[git-p4: depot-paths = "//depot/": change = 4] + Add file 4 + [git-p4: depot-paths = "//depot/": change = 4] -Add file 3 -[git-p4: depot-paths = "//depot/": change = 3] + Add file 3 + [git-p4: depot-paths = "//depot/": change = 3] -Add file 2 -[git-p4: depot-paths = "//depot/": change = 2] + Add file 2 + [git-p4: depot-paths = "//depot/": change = 2] -Add file 1 -[git-p4: depot-paths = "//depot/": change = 1] + Add file 1 + [git-p4: depot-paths = "//depot/": change = 1] EOF git log --format=%B >actual && @@ -80,23 +80,23 @@ test_expect_success 'Clone repo subdir with all history but keep empty commits' git config git-p4.keepEmptyCommits true && git p4 clone --use-client-spec --destination="$git" //depot@all && cat >expect <<-\EOF && -Remove file 4 -[git-p4: depot-paths = "//depot/": change = 6] + Remove file 4 + [git-p4: depot-paths = "//depot/": change = 6] -Remove file 3 -[git-p4: depot-paths = "//depot/": change = 5] + Remove file 3 + [git-p4: depot-paths = "//depot/": change = 5] -Add file 4 -[git-p4: depot-paths = "//depot/": change = 4] + Add file 4 + [git-p4: depot-paths = "//depot/": change = 4] -Add file 3 -[git-p4: depot-paths = "//depot/": change = 3] + Add file 3 + [git-p4: depot-paths = "//depot/": change = 3] -Add file 2 -[git-p4: depot-paths = "//depot/": change = 2] + Add file 2 + [git-p4: depot-paths = "//depot/": change = 2] -Add file 1 -[git-p4: depot-paths = "//depot/": change = 1] + Add file 1 + [git-p4: depot-paths = "//depot/": change = 1] EOF git log --format=%B >actual && @@ -112,14 +112,14 @@ test_expect_success 'Clone repo subdir with all history' ' git init . && git p4 clone --use-client-spec --destination="$git" --verbose //depot@all && cat >expect <<-\EOF && -Remove file 3 -[git-p4: depot-paths = "//depot/": change = 5] + Remove file 3 + [git-p4: depot-paths = "//depot/": change = 5] -Add file 3 -[git-p4: depot-paths = "//depot/": change = 3] + Add file 3 + [git-p4: depot-paths = "//depot/": change = 3] -Add file 1 -[git-p4: depot-paths = "//depot/": change = 1] + Add file 1 + [git-p4: depot-paths = "//depot/": change = 1] EOF git log --format=%B >actual && diff --git a/t/t9829-git-p4-jobs.sh b/t/t9829-git-p4-jobs.sh new file mode 100755 index 0000000000..971aeeea1f --- /dev/null +++ b/t/t9829-git-p4-jobs.sh @@ -0,0 +1,99 @@ +#!/bin/sh + +test_description='git p4 retrieve job info' + +. ./lib-git-p4.sh + +test_expect_success 'start p4d' ' + start_p4d +' + +test_expect_success 'add p4 jobs' ' + ( + p4_add_job TESTJOB-A && + p4_add_job TESTJOB-B + ) +' + +test_expect_success 'add p4 files' ' + client_view "//depot/... //client/..." && + ( + cd "$cli" && + >file1 && + p4 add file1 && + p4 submit -d "Add file 1" + ) +' + +test_expect_success 'check log message of changelist with no jobs' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git p4 clone --use-client-spec --destination="$git" //depot@all && + cat >expect <<-\EOF && + Add file 1 + [git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'add TESTJOB-A to change 1' ' + ( + cd "$cli" && + p4 fix -c 1 TESTJOB-A + ) +' + +test_expect_success 'check log message of changelist with one job' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git p4 clone --use-client-spec --destination="$git" //depot@all && + cat >expect <<-\EOF && + Add file 1 + Jobs: TESTJOB-A + [git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'add TESTJOB-B to change 1' ' + ( + cd "$cli" && + p4 fix -c 1 TESTJOB-B + ) +' + +test_expect_success 'check log message of changelist with more jobs' ' + client_view "//depot/... //client/..." && + test_when_finished cleanup_git && + ( + cd "$git" && + git init . && + git p4 clone --use-client-spec --destination="$git" //depot@all && + cat >expect <<-\EOF && + Add file 1 + Jobs: TESTJOB-A TESTJOB-B + [git-p4: depot-paths = "//depot/": change = 1] + + EOF + git log --format=%B >actual && + test_cmp expect actual + ) +' + +test_expect_success 'kill p4d' ' + kill_p4d +' + +test_done diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index ffbfa0efb8..0db4469c89 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -107,7 +107,7 @@ test_expect_success 'prompt - describe detached head - contains' ' ' test_expect_success 'prompt - describe detached head - branch' ' - printf " ((b1~1))" >expected && + printf " ((tags/t2~1))" >expected && git checkout b1^ && test_when_finished "git checkout master" && ( diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 8d99eb303f..3978fc0b45 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -718,20 +718,13 @@ test_cmp_rev () { test_cmp expect.rev actual.rev } -# Print a sequence of numbers or letters in increasing order. This is -# similar to GNU seq(1), but the latter might not be available -# everywhere (and does not do letters). It may be used like: -# -# for i in $(test_seq 100) -# do -# for j in $(test_seq 10 20) -# do -# for k in $(test_seq a z) -# do -# echo $i-$j-$k -# done -# done -# done +# Print a sequence of integers in increasing order, either with +# two arguments (start and end): +# +# test_seq 1 5 -- outputs 1 2 3 4 5 one line at a time +# +# or with one argument (end), in which case it starts counting +# from 1. test_seq () { case $# in @@ -739,7 +732,12 @@ test_seq () { 2) ;; *) error "bug in the test script: not 1 or 2 parameters to test_seq" ;; esac - perl -le 'print for $ARGV[0]..$ARGV[1]' -- "$@" + test_seq_counter__=$1 + while test "$test_seq_counter__" -le "$2" + do + echo "$test_seq_counter__" + test_seq_counter__=$(( $test_seq_counter__ + 1 )) + done } # This function can be used to schedule some commands to be run diff --git a/t/test-lib.sh b/t/test-lib.sh index 0b47eb6bb2..0055ebba46 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -202,13 +202,13 @@ do } run_list=$1; shift ;; --run=*) - run_list=$(expr "z$1" : 'z[^=]*=\(.*\)'); shift ;; + run_list=${1#--*=}; shift ;; -h|--h|--he|--hel|--help) help=t; shift ;; -v|--v|--ve|--ver|--verb|--verbo|--verbos|--verbose) verbose=t; shift ;; --verbose-only=*) - verbose_only=$(expr "z$1" : 'z[^=]*=\(.*\)') + verbose_only=${1#--*=} shift ;; -q|--q|--qu|--qui|--quie|--quiet) # Ignore --quiet under a TAP::Harness. Saying how many tests @@ -222,15 +222,15 @@ do valgrind=memcheck shift ;; --valgrind=*) - valgrind=$(expr "z$1" : 'z[^=]*=\(.*\)') + valgrind=${1#--*=} shift ;; --valgrind-only=*) - valgrind_only=$(expr "z$1" : 'z[^=]*=\(.*\)') + valgrind_only=${1#--*=} shift ;; --tee) shift ;; # was handled already --root=*) - root=$(expr "z$1" : 'z[^=]*=\(.*\)') + root=${1#--*=} shift ;; --chain-lint) GIT_TEST_CHAIN_LINT=1 @@ -322,6 +322,19 @@ else exec 4>/dev/null 3>/dev/null fi +# Send any "-x" output directly to stderr to avoid polluting tests +# which capture stderr. We can do this unconditionally since it +# has no effect if tracing isn't turned on. +# +# Note that this sets up the trace fd as soon as we assign the variable, so it +# must come after the creation of descriptor 4 above. Likewise, we must never +# unset this, as it has the side effect of closing descriptor 4, which we +# use to show verbose tests to the user. +# +# Note also that we don't need or want to export it. The tracing is local to +# this shell, and we would not want to influence any shells we exec. +BASH_XTRACEFD=4 + test_failure=0 test_count=0 test_fixed=0 @@ -854,10 +867,10 @@ test -d "$GIT_BUILD_DIR"/templates/blt || { error "You haven't built things yet, have you?" } -if ! test -x "$GIT_BUILD_DIR"/test-chmtime +if ! test -x "$GIT_BUILD_DIR"/t/helper/test-chmtime then echo >&2 'You need to build test-chmtime:' - echo >&2 'Run "make test-chmtime" in the source (toplevel) directory' + echo >&2 'Run "make t/helper/test-chmtime" in the source (toplevel) directory' exit 1 fi @@ -6,6 +6,59 @@ const char *tag_type = "tag"; +static int run_gpg_verify(const char *buf, unsigned long size, unsigned flags) +{ + struct signature_check sigc; + size_t payload_size; + int ret; + + memset(&sigc, 0, sizeof(sigc)); + + payload_size = parse_signature(buf, size); + + if (size == payload_size) { + if (flags & GPG_VERIFY_VERBOSE) + write_in_full(1, buf, payload_size); + return error("no signature found"); + } + + ret = check_signature(buf, payload_size, buf + payload_size, + size - payload_size, &sigc); + print_signature_buffer(&sigc, flags); + + signature_check_clear(&sigc); + return ret; +} + +int gpg_verify_tag(const unsigned char *sha1, const char *name_to_report, + unsigned flags) +{ + enum object_type type; + char *buf; + unsigned long size; + int ret; + + type = sha1_object_info(sha1, NULL); + if (type != OBJ_TAG) + return error("%s: cannot verify a non-tag object of type %s.", + name_to_report ? + name_to_report : + find_unique_abbrev(sha1, DEFAULT_ABBREV), + typename(type)); + + buf = read_sha1_file(sha1, &type, &size); + if (!buf) + return error("%s: unable to read file.", + name_to_report ? + name_to_report : + find_unique_abbrev(sha1, DEFAULT_ABBREV)); + + ret = run_gpg_verify(buf, size, flags); + + free(buf); + return ret; +} + struct object *deref_tag(struct object *o, const char *warn, int warnlen) { while (o && o->type == OBJ_TAG) @@ -17,5 +17,7 @@ extern int parse_tag_buffer(struct tag *item, const void *data, unsigned long si extern int parse_tag(struct tag *item); extern struct object *deref_tag(struct object *, const char *, int); extern struct object *deref_tag_noverify(struct object *); +extern int gpg_verify_tag(const unsigned char *sha1, + const char *name_to_report, unsigned flags); #endif /* TAG_H */ diff --git a/transport-helper.c b/transport-helper.c index b934183236..bd666b29ec 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -1152,7 +1152,7 @@ static void udt_close_if_finished(struct unidirectional_transfer *t) } /* - * Tries to read read data from source into buffer. If buffer is full, + * Tries to read data from source into buffer. If buffer is full, * no data is read. Returns 0 on success, -1 on error. */ static int udt_do_read(struct unidirectional_transfer *t) @@ -1166,7 +1166,7 @@ static int udt_do_read(struct unidirectional_transfer *t) bytes = read(t->src, t->buf + t->bufuse, BUFFERSIZE - t->bufuse); if (bytes < 0 && errno != EWOULDBLOCK && errno != EAGAIN && errno != EINTR) { - error("read(%s) failed: %s", t->src_name, strerror(errno)); + error_errno("read(%s) failed", t->src_name); return -1; } else if (bytes == 0) { transfer_debug("%s EOF (with %i bytes in buffer)", @@ -1193,7 +1193,7 @@ static int udt_do_write(struct unidirectional_transfer *t) transfer_debug("%s is writable", t->dest_name); bytes = xwrite(t->dest, t->buf, t->bufuse); if (bytes < 0 && errno != EWOULDBLOCK) { - error("write(%s) failed: %s", t->dest_name, strerror(errno)); + error_errno("write(%s) failed", t->dest_name); return -1; } else if (bytes > 0) { t->bufuse -= bytes; @@ -1306,7 +1306,7 @@ static int tloop_join(pid_t pid, const char *name) { int tret; if (waitpid(pid, &tret, 0) < 0) { - error("%s process failed to wait: %s", name, strerror(errno)); + error_errno("%s process failed to wait", name); return 1; } if (!WIFEXITED(tret) || WEXITSTATUS(tret)) { diff --git a/tree-diff.c b/tree-diff.c index 4dda9a14ab..ff4e0d3cb6 100644 --- a/tree-diff.c +++ b/tree-diff.c @@ -183,7 +183,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, if (t) { /* path present in resulting tree */ - sha1 = tree_entry_extract(t, &path, &mode); + sha1 = tree_entry_extract(t, &path, &mode)->hash; pathlen = tree_entry_len(&t->entry); isdir = S_ISDIR(mode); } else { @@ -229,7 +229,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, DIFF_STATUS_ADDED; if (tpi_valid) { - sha1_i = tp[i].entry.sha1; + sha1_i = tp[i].entry.oid->hash; mode_i = tp[i].entry.mode; } else { @@ -270,7 +270,7 @@ static struct combine_diff_path *emit_path(struct combine_diff_path *p, /* same rule as in emitthis */ int tpi_valid = tp && !(tp[i].entry.mode & S_IFXMIN_NEQ); - parents_sha1[i] = tpi_valid ? tp[i].entry.sha1 + parents_sha1[i] = tpi_valid ? tp[i].entry.oid->hash : NULL; } @@ -482,7 +482,7 @@ static struct combine_diff_path *ll_diff_tree_paths( continue; /* diff(t,pi) != ΓΈ */ - if (hashcmp(t.entry.sha1, tp[i].entry.sha1) || + if (oidcmp(t.entry.oid, tp[i].entry.oid) || (t.entry.mode != tp[i].entry.mode)) continue; diff --git a/tree-walk.c b/tree-walk.c index cd4bb2c38b..ce27842439 100644 --- a/tree-walk.c +++ b/tree-walk.c @@ -38,7 +38,7 @@ static void decode_tree_entry(struct tree_desc *desc, const char *buf, unsigned /* Initialize the descriptor entry */ desc->entry.path = path; desc->entry.mode = canon_mode(mode); - desc->entry.sha1 = (const unsigned char *)(path + len); + desc->entry.oid = (const struct object_id *)(path + len); } void init_tree_desc(struct tree_desc *desc, const void *buffer, unsigned long size) @@ -76,7 +76,7 @@ static void entry_extract(struct tree_desc *t, struct name_entry *a) void update_tree_entry(struct tree_desc *desc) { const void *buf = desc->buffer; - const unsigned char *end = desc->entry.sha1 + 20; + const unsigned char *end = desc->entry.oid->hash + 20; unsigned long size = desc->size; unsigned long len = end - (const unsigned char *)buf; @@ -110,7 +110,7 @@ void setup_traverse_info(struct traverse_info *info, const char *base) pathlen--; info->pathlen = pathlen ? pathlen + 1 : 0; info->name.path = base; - info->name.sha1 = (void *)(base + pathlen + 1); + info->name.oid = (void *)(base + pathlen + 1); if (pathlen) info->prev = &dummy; } @@ -433,10 +433,10 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char int namelen = strlen(name); while (t->size) { const char *entry; - const unsigned char *sha1; + const struct object_id *oid; int entrylen, cmp; - sha1 = tree_entry_extract(t, &entry, mode); + oid = tree_entry_extract(t, &entry, mode); entrylen = tree_entry_len(&t->entry); update_tree_entry(t); if (entrylen > namelen) @@ -447,7 +447,7 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char if (cmp < 0) break; if (entrylen == namelen) { - hashcpy(result, sha1); + hashcpy(result, oid->hash); return 0; } if (name[entrylen] != '/') @@ -455,10 +455,10 @@ static int find_tree_entry(struct tree_desc *t, const char *name, unsigned char if (!S_ISDIR(*mode)) break; if (++entrylen == namelen) { - hashcpy(result, sha1); + hashcpy(result, oid->hash); return 0; } - return get_tree_entry(sha1, name + entrylen, result, mode); + return get_tree_entry(oid->hash, name + entrylen, result, mode); } return -1; } diff --git a/tree-walk.h b/tree-walk.h index 174eb617df..97a7d6957e 100644 --- a/tree-walk.h +++ b/tree-walk.h @@ -2,7 +2,7 @@ #define TREE_WALK_H struct name_entry { - const unsigned char *sha1; + const struct object_id *oid; const char *path; unsigned int mode; }; @@ -13,16 +13,16 @@ struct tree_desc { unsigned int size; }; -static inline const unsigned char *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep) +static inline const struct object_id *tree_entry_extract(struct tree_desc *desc, const char **pathp, unsigned int *modep) { *pathp = desc->entry.path; *modep = desc->entry.mode; - return desc->entry.sha1; + return desc->entry.oid; } static inline int tree_entry_len(const struct name_entry *ne) { - return (const char *)ne->sha1 - ne->path - 1; + return (const char *)ne->oid - ne->path - 1; } void update_tree_entry(struct tree_desc *); @@ -76,7 +76,7 @@ static int read_tree_1(struct tree *tree, struct strbuf *base, continue; } - switch (fn(entry.sha1, base, + switch (fn(entry.oid->hash, base, entry.path, entry.mode, stage, context)) { case 0: continue; @@ -87,19 +87,19 @@ static int read_tree_1(struct tree *tree, struct strbuf *base, } if (S_ISDIR(entry.mode)) - hashcpy(sha1, entry.sha1); + hashcpy(sha1, entry.oid->hash); else if (S_ISGITLINK(entry.mode)) { struct commit *commit; - commit = lookup_commit(entry.sha1); + commit = lookup_commit(entry.oid->hash); if (!commit) die("Commit %s in submodule path %s%s not found", - sha1_to_hex(entry.sha1), + oid_to_hex(entry.oid), base->buf, entry.path); if (parse_commit(commit)) die("Invalid commit %s in submodule path %s%s", - sha1_to_hex(entry.sha1), + oid_to_hex(entry.oid), base->buf, entry.path); hashcpy(sha1, commit->tree->object.oid.hash); diff --git a/unpack-trees.c b/unpack-trees.c index 9f55cc28b9..6bc9512a45 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -58,40 +58,74 @@ void setup_unpack_trees_porcelain(struct unpack_trees_options *opts, int i; const char **msgs = opts->msgs; const char *msg; - const char *cmd2 = strcmp(cmd, "checkout") ? cmd : "switch branches"; - if (advice_commit_before_merge) - msg = "Your local changes to the following files would be overwritten by %s:\n%%s" - "Please, commit your changes or stash them before you can %s."; + if (!strcmp(cmd, "checkout")) + msg = advice_commit_before_merge + ? _("Your local changes to the following files would be overwritten by checkout:\n%%s" + "Please commit your changes or stash them before you can switch branches.") + : _("Your local changes to the following files would be overwritten by checkout:\n%%s"); + else if (!strcmp(cmd, "merge")) + msg = advice_commit_before_merge + ? _("Your local changes to the following files would be overwritten by merge:\n%%s" + "Please commit your changes or stash them before you can merge.") + : _("Your local changes to the following files would be overwritten by merge:\n%%s"); else - msg = "Your local changes to the following files would be overwritten by %s:\n%%s"; + msg = advice_commit_before_merge + ? _("Your local changes to the following files would be overwritten by %s:\n%%s" + "Please commit your changes or stash them before you can %s.") + : _("Your local changes to the following files would be overwritten by %s:\n%%s"); msgs[ERROR_WOULD_OVERWRITE] = msgs[ERROR_NOT_UPTODATE_FILE] = - xstrfmt(msg, cmd, cmd2); + xstrfmt(msg, cmd, cmd); msgs[ERROR_NOT_UPTODATE_DIR] = - "Updating the following directories would lose untracked files in it:\n%s"; - - if (advice_commit_before_merge) - msg = "The following untracked working tree files would be %s by %s:\n%%s" - "Please move or remove them before you can %s."; + _("Updating the following directories would lose untracked files in it:\n%s"); + + if (!strcmp(cmd, "checkout")) + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be removed by checkout:\n%%s" + "Please move or remove them before you can switch branches.") + : _("The following untracked working tree files would be removed by checkout:\n%%s"); + else if (!strcmp(cmd, "merge")) + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be removed by merge:\n%%s" + "Please move or remove them before you can merge.") + : _("The following untracked working tree files would be removed by merge:\n%%s"); else - msg = "The following untracked working tree files would be %s by %s:\n%%s"; - - msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, "removed", cmd, cmd2); - msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, "overwritten", cmd, cmd2); + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be removed by %s:\n%%s" + "Please move or remove them before you can %s.") + : _("The following untracked working tree files would be removed by %s:\n%%s"); + msgs[ERROR_WOULD_LOSE_UNTRACKED_REMOVED] = xstrfmt(msg, cmd, cmd); + + if (!strcmp(cmd, "checkout")) + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be overwritten by checkout:\n%%s" + "Please move or remove them before you can switch branches.") + : _("The following untracked working tree files would be overwritten by checkout:\n%%s"); + else if (!strcmp(cmd, "merge")) + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be overwritten by merge:\n%%s" + "Please move or remove them before you can merge.") + : _("The following untracked working tree files would be overwritten by merge:\n%%s"); + else + msg = advice_commit_before_merge + ? _("The following untracked working tree files would be overwritten by %s:\n%%s" + "Please move or remove them before you can %s.") + : _("The following untracked working tree files would be overwritten by %s:\n%%s"); + msgs[ERROR_WOULD_LOSE_UNTRACKED_OVERWRITTEN] = xstrfmt(msg, cmd, cmd); /* * Special case: ERROR_BIND_OVERLAP refers to a pair of paths, we * cannot easily display it as a list. */ - msgs[ERROR_BIND_OVERLAP] = "Entry '%s' overlaps with '%s'. Cannot bind."; + msgs[ERROR_BIND_OVERLAP] = _("Entry '%s' overlaps with '%s'. Cannot bind."); msgs[ERROR_SPARSE_NOT_UPTODATE_FILE] = - "Cannot update sparse checkout: the following entries are not up-to-date:\n%s"; + _("Cannot update sparse checkout: the following entries are not up-to-date:\n%s"); msgs[ERROR_WOULD_LOSE_ORPHANED_OVERWRITTEN] = - "The following Working tree files would be overwritten by sparse checkout update:\n%s"; + _("The following Working tree files would be overwritten by sparse checkout update:\n%s"); msgs[ERROR_WOULD_LOSE_ORPHANED_REMOVED] = - "The following Working tree files would be removed by sparse checkout update:\n%s"; + _("The following Working tree files would be removed by sparse checkout update:\n%s"); opts->show_all_errors = 1; /* rejected paths may not have a static buffer */ @@ -168,7 +202,7 @@ static void display_error_msgs(struct unpack_trees_options *o) string_list_clear(rejects, 0); } if (something_displayed) - fprintf(stderr, "Aborting\n"); + fprintf(stderr, _("Aborting\n")); } /* @@ -475,7 +509,7 @@ static int traverse_trees_recursive(int n, unsigned long dirmask, for (i = 0; i < n; i++, dirmask >>= 1) { const unsigned char *sha1 = NULL; if (dirmask & 1) - sha1 = names[i].sha1; + sha1 = names[i].oid->hash; buf[i] = fill_tree_descriptor(t+i, sha1); } @@ -591,7 +625,7 @@ static struct cache_entry *create_ce_entry(const struct traverse_info *info, con ce->ce_mode = create_ce_mode(n->mode); ce->ce_flags = create_ce_flags(stage); ce->ce_namelen = len; - hashcpy(ce->sha1, n->sha1); + hashcpy(ce->sha1, n->oid->hash); make_traverse_path(ce->name, info, n); return ce; @@ -1499,8 +1533,7 @@ static int verify_absent_1(const struct cache_entry *ce, path = xmemdupz(ce->name, len); if (lstat(path, &st)) - ret = error("cannot stat '%s': %s", path, - strerror(errno)); + ret = error_errno("cannot stat '%s'", path); else ret = check_ok_to_remove(path, len, DT_UNKNOWN, NULL, &st, error_type, o); @@ -1508,8 +1541,7 @@ static int verify_absent_1(const struct cache_entry *ce, return ret; } else if (lstat(ce->name, &st)) { if (errno != ENOENT) - return error("cannot stat '%s': %s", ce->name, - strerror(errno)); + return error_errno("cannot stat '%s'", ce->name); return 0; } else { return check_ok_to_remove(ce->name, ce_namelen(ce), diff --git a/upload-pack.c b/upload-pack.c index dc802a07c2..f19444df7b 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -174,8 +174,7 @@ static void create_pack_file(void) if (ret < 0) { if (errno != EINTR) { - error("poll failed, resuming: %s", - strerror(errno)); + error_errno("poll failed, resuming"); sleep(1); } continue; @@ -109,19 +109,11 @@ void NORETURN die(const char *err, ...) va_end(params); } -void NORETURN die_errno(const char *fmt, ...) +static const char *fmt_with_err(char *buf, int n, const char *fmt) { - va_list params; - char fmt_with_err[1024]; char str_error[256], *err; int i, j; - if (die_is_recursing()) { - fputs("fatal: recursion detected in die_errno handler\n", - stderr); - exit(128); - } - err = strerror(errno); for (i = j = 0; err[i] && j < sizeof(str_error) - 1; ) { if ((str_error[j++] = err[i++]) != '%') @@ -136,13 +128,37 @@ void NORETURN die_errno(const char *fmt, ...) } } str_error[j] = 0; - snprintf(fmt_with_err, sizeof(fmt_with_err), "%s: %s", fmt, str_error); + snprintf(buf, n, "%s: %s", fmt, str_error); + return buf; +} + +void NORETURN die_errno(const char *fmt, ...) +{ + char buf[1024]; + va_list params; + + if (die_is_recursing()) { + fputs("fatal: recursion detected in die_errno handler\n", + stderr); + exit(128); + } va_start(params, fmt); - die_routine(fmt_with_err, params); + die_routine(fmt_with_err(buf, sizeof(buf), fmt), params); va_end(params); } +int error_errno(const char *fmt, ...) +{ + char buf[1024]; + va_list params; + + va_start(params, fmt); + error_routine(fmt_with_err(buf, sizeof(buf), fmt), params); + va_end(params); + return -1; +} + #undef error int error(const char *err, ...) { @@ -154,6 +170,16 @@ int error(const char *err, ...) return -1; } +void warning_errno(const char *warn, ...) +{ + char buf[1024]; + va_list params; + + va_start(params, warn); + warn_routine(fmt_with_err(buf, sizeof(buf), warn), params); + va_end(params); +} + void warning(const char *warn, ...) { va_list params; @@ -48,7 +48,7 @@ static inline char *reencode_string(const char *in, int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding); /* - * Returns true if the the path would match ".git" after HFS case-folding. + * Returns true if the path would match ".git" after HFS case-folding. * The path should be NUL-terminated, but we will match variants of both ".git\0" * and ".git/..." (but _not_ ".../.git"). This makes it suitable for both fsck * and verify_path(). diff --git a/vcs-svn/line_buffer.c b/vcs-svn/line_buffer.c index 57cc1cec03..e416caf8a4 100644 --- a/vcs-svn/line_buffer.c +++ b/vcs-svn/line_buffer.c @@ -53,9 +53,9 @@ long buffer_tmpfile_prepare_to_read(struct line_buffer *buf) { long pos = ftell(buf->infile); if (pos < 0) - return error("ftell error: %s", strerror(errno)); + return error_errno("ftell error"); if (fseek(buf->infile, 0, SEEK_SET)) - return error("seek error: %s", strerror(errno)); + return error_errno("seek error"); return pos; } diff --git a/vcs-svn/sliding_window.c b/vcs-svn/sliding_window.c index f11d490995..06d273c9e8 100644 --- a/vcs-svn/sliding_window.c +++ b/vcs-svn/sliding_window.c @@ -12,7 +12,7 @@ static int input_error(struct line_buffer *file) { if (!buffer_ferror(file)) return error("delta preimage ends early"); - return error("cannot read delta preimage: %s", strerror(errno)); + return error_errno("cannot read delta preimage"); } static int skip_or_whine(struct line_buffer *file, off_t gap) diff --git a/vcs-svn/svndiff.c b/vcs-svn/svndiff.c index 74c97c4543..75c753162a 100644 --- a/vcs-svn/svndiff.c +++ b/vcs-svn/svndiff.c @@ -64,13 +64,13 @@ static int write_strbuf(struct strbuf *sb, FILE *out) { if (fwrite(sb->buf, 1, sb->len, out) == sb->len) /* Success. */ return 0; - return error("cannot write delta postimage: %s", strerror(errno)); + return error_errno("cannot write delta postimage"); } static int error_short_read(struct line_buffer *input) { if (buffer_ferror(input)) - return error("error reading delta: %s", strerror(errno)); + return error_errno("error reading delta"); return error("invalid delta: unexpected end of file"); } diff --git a/vcs-svn/svndump.c b/vcs-svn/svndump.c index 31d1d83d45..e4b395963b 100644 --- a/vcs-svn/svndump.c +++ b/vcs-svn/svndump.c @@ -501,7 +501,7 @@ static void init(int report_fd) int svndump_init(const char *filename) { if (buffer_init(&input, filename)) - return error("cannot open %s: %s", filename ? filename : "NULL", strerror(errno)); + return error_errno("cannot open %s", filename ? filename : "NULL"); init(REPORT_FILENO); return 0; } @@ -509,7 +509,7 @@ int svndump_init(const char *filename) int svndump_init_fd(int in_fd, int back_fd) { if(buffer_fdinit(&input, xdup(in_fd))) - return error("cannot open fd %d: %s", in_fd, strerror(errno)); + return error_errno("cannot open fd %d", in_fd); init(xdup(back_fd)); return 0; } @@ -43,12 +43,12 @@ static int process_tree(struct walker *walker, struct tree *tree) if (S_ISGITLINK(entry.mode)) continue; if (S_ISDIR(entry.mode)) { - struct tree *tree = lookup_tree(entry.sha1); + struct tree *tree = lookup_tree(entry.oid->hash); if (tree) obj = &tree->object; } else { - struct blob *blob = lookup_blob(entry.sha1); + struct blob *blob = lookup_blob(entry.oid->hash); if (blob) obj = &blob->object; } diff --git a/wildmatch.c b/wildmatch.c index f91ba99f32..57c8765805 100644 --- a/wildmatch.c +++ b/wildmatch.c @@ -136,7 +136,7 @@ static int dowild(const uchar *p, const uchar *text, unsigned int flags) /* * Try to advance faster when an asterisk is * followed by a literal. We know in this case - * that the the string before the literal + * that the string before the literal * must belong to "*". * If match_slash is false, do not look past * the first slash as it cannot belong to '*'. diff --git a/worktree.c b/worktree.c index 6181a66f1e..199b1ef94b 100644 --- a/worktree.c +++ b/worktree.c @@ -2,6 +2,8 @@ #include "refs.h" #include "strbuf.h" #include "worktree.h" +#include "dir.h" +#include "wt-status.h" void free_worktrees(struct worktree **worktrees) { @@ -9,7 +11,7 @@ void free_worktrees(struct worktree **worktrees) for (i = 0; worktrees[i]; i++) { free(worktrees[i]->path); - free(worktrees[i]->git_dir); + free(worktrees[i]->id); free(worktrees[i]->head_ref); free(worktrees[i]); } @@ -18,7 +20,7 @@ void free_worktrees(struct worktree **worktrees) /* * read 'path_to_ref' into 'ref'. Also if is_detached is not NULL, - * set is_detached to 1 (0) if the ref is detatched (is not detached). + * set is_detached to 1 (0) if the ref is detached (is not detached). * * $GIT_COMMON_DIR/$symref (e.g. HEAD) is practically outside $GIT_DIR so * for linked worktrees, `resolve_ref_unsafe()` won't work (it uses @@ -74,13 +76,11 @@ static struct worktree *get_main_worktree(void) struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; - struct strbuf gitdir = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; int is_bare = 0; int is_detached = 0; - strbuf_addf(&gitdir, "%s", absolute_path(get_git_common_dir())); - strbuf_addbuf(&worktree_path, &gitdir); + strbuf_addstr(&worktree_path, absolute_path(get_git_common_dir())); is_bare = !strbuf_strip_suffix(&worktree_path, "/.git"); if (is_bare) strbuf_strip_suffix(&worktree_path, "/."); @@ -92,15 +92,15 @@ static struct worktree *get_main_worktree(void) worktree = xmalloc(sizeof(struct worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); - worktree->git_dir = strbuf_detach(&gitdir, NULL); + worktree->id = NULL; worktree->is_bare = is_bare; worktree->head_ref = NULL; worktree->is_detached = is_detached; + worktree->is_current = 0; add_head_info(&head_ref, worktree); done: strbuf_release(&path); - strbuf_release(&gitdir); strbuf_release(&worktree_path); strbuf_release(&head_ref); return worktree; @@ -111,16 +111,13 @@ static struct worktree *get_linked_worktree(const char *id) struct worktree *worktree = NULL; struct strbuf path = STRBUF_INIT; struct strbuf worktree_path = STRBUF_INIT; - struct strbuf gitdir = STRBUF_INIT; struct strbuf head_ref = STRBUF_INIT; int is_detached = 0; if (!id) die("Missing linked worktree name"); - strbuf_addf(&gitdir, "%s/worktrees/%s", - absolute_path(get_git_common_dir()), id); - strbuf_addf(&path, "%s/gitdir", gitdir.buf); + strbuf_git_common_path(&path, "worktrees/%s/gitdir", id); if (strbuf_read_file(&worktree_path, path.buf, 0) <= 0) /* invalid gitdir file */ goto done; @@ -140,20 +137,39 @@ static struct worktree *get_linked_worktree(const char *id) worktree = xmalloc(sizeof(struct worktree)); worktree->path = strbuf_detach(&worktree_path, NULL); - worktree->git_dir = strbuf_detach(&gitdir, NULL); + worktree->id = xstrdup(id); worktree->is_bare = 0; worktree->head_ref = NULL; worktree->is_detached = is_detached; + worktree->is_current = 0; add_head_info(&head_ref, worktree); done: strbuf_release(&path); - strbuf_release(&gitdir); strbuf_release(&worktree_path); strbuf_release(&head_ref); return worktree; } +static void mark_current_worktree(struct worktree **worktrees) +{ + struct strbuf git_dir = STRBUF_INIT; + struct strbuf path = STRBUF_INIT; + int i; + + strbuf_addstr(&git_dir, absolute_path(get_git_dir())); + for (i = 0; worktrees[i]; i++) { + struct worktree *wt = worktrees[i]; + strbuf_addstr(&path, absolute_path(get_worktree_git_dir(wt))); + wt->is_current = !fspathcmp(git_dir.buf, path.buf); + strbuf_reset(&path); + if (wt->is_current) + break; + } + strbuf_release(&git_dir); + strbuf_release(&path); +} + struct worktree **get_worktrees(void) { struct worktree **list = NULL; @@ -185,35 +201,105 @@ struct worktree **get_worktrees(void) } ALLOC_GROW(list, counter + 1, alloc); list[counter] = NULL; + + mark_current_worktree(list); return list; } -char *find_shared_symref(const char *symref, const char *target) +const char *get_worktree_git_dir(const struct worktree *wt) +{ + if (!wt) + return get_git_dir(); + else if (!wt->id) + return get_git_common_dir(); + else + return git_common_path("worktrees/%s", wt->id); +} + +int is_worktree_being_rebased(const struct worktree *wt, + const char *target) +{ + struct wt_status_state state; + int found_rebase; + + memset(&state, 0, sizeof(state)); + found_rebase = wt_status_check_rebase(wt, &state) && + ((state.rebase_in_progress || + state.rebase_interactive_in_progress) && + state.branch && + starts_with(target, "refs/heads/") && + !strcmp(state.branch, target + strlen("refs/heads/"))); + free(state.branch); + free(state.onto); + return found_rebase; +} + +int is_worktree_being_bisected(const struct worktree *wt, + const char *target) { - char *existing = NULL; + struct wt_status_state state; + int found_rebase; + + memset(&state, 0, sizeof(state)); + found_rebase = wt_status_check_bisect(wt, &state) && + state.branch && + starts_with(target, "refs/heads/") && + !strcmp(state.branch, target + strlen("refs/heads/")); + free(state.branch); + return found_rebase; +} + +/* + * note: this function should be able to detect shared symref even if + * HEAD is temporarily detached (e.g. in the middle of rebase or + * bisect). New commands that do similar things should update this + * function as well. + */ +const struct worktree *find_shared_symref(const char *symref, + const char *target) +{ + const struct worktree *existing = NULL; struct strbuf path = STRBUF_INIT; struct strbuf sb = STRBUF_INIT; - struct worktree **worktrees = get_worktrees(); + static struct worktree **worktrees; int i = 0; + if (worktrees) + free_worktrees(worktrees); + worktrees = get_worktrees(); + for (i = 0; worktrees[i]; i++) { + struct worktree *wt = worktrees[i]; + + if (wt->is_detached && !strcmp(symref, "HEAD")) { + if (is_worktree_being_rebased(wt, target)) { + existing = wt; + break; + } + if (is_worktree_being_bisected(wt, target)) { + existing = wt; + break; + } + } + strbuf_reset(&path); strbuf_reset(&sb); - strbuf_addf(&path, "%s/%s", worktrees[i]->git_dir, symref); + strbuf_addf(&path, "%s/%s", + get_worktree_git_dir(wt), + symref); if (parse_ref(path.buf, &sb, NULL)) { continue; } if (!strcmp(sb.buf, target)) { - existing = xstrdup(worktrees[i]->path); + existing = wt; break; } } strbuf_release(&path); strbuf_release(&sb); - free_worktrees(worktrees); return existing; } diff --git a/worktree.h b/worktree.h index b4b3dda792..13949093cc 100644 --- a/worktree.h +++ b/worktree.h @@ -3,11 +3,12 @@ struct worktree { char *path; - char *git_dir; + char *id; char *head_ref; unsigned char head_sha1[20]; int is_detached; int is_bare; + int is_current; }; /* Functions for acting on the information about worktrees. */ @@ -23,16 +24,33 @@ struct worktree { extern struct worktree **get_worktrees(void); /* + * Return git dir of the worktree. Note that the path may be relative. + * If wt is NULL, git dir of current worktree is returned. + */ +extern const char *get_worktree_git_dir(const struct worktree *wt); + +/* * Free up the memory for worktree(s) */ extern void free_worktrees(struct worktree **); /* * Check if a per-worktree symref points to a ref in the main worktree - * or any linked worktree, and return the path to the exising worktree - * if it is. Returns NULL if there is no existing ref. The caller is - * responsible for freeing the returned path. + * or any linked worktree, and return the worktree that holds the ref, + * or NULL otherwise. The result may be destroyed by the next call. + */ +extern const struct worktree *find_shared_symref(const char *symref, + const char *target); + +int is_worktree_being_rebased(const struct worktree *wt, const char *target); +int is_worktree_being_bisected(const struct worktree *wt, const char *target); + +/* + * Similar to git_path() but can produce paths for a specified + * worktree instead of current one */ -extern char *find_shared_symref(const char *symref, const char *target); +extern const char *worktree_git_path(const struct worktree *wt, + const char *fmt, ...) + __attribute__((format (printf, 2, 3))); #endif diff --git a/wrap-for-bin.sh b/wrap-for-bin.sh index db0ec6a737..22b6e4948f 100644 --- a/wrap-for-bin.sh +++ b/wrap-for-bin.sh @@ -17,6 +17,7 @@ fi GITPERLLIB='@@BUILD_DIR@@/perl/blib/lib'"${GITPERLLIB:+:$GITPERLLIB}" GIT_TEXTDOMAINDIR='@@BUILD_DIR@@/po/build/locale' PATH='@@BUILD_DIR@@/bin-wrappers:'"$PATH" + export GIT_EXEC_PATH GITPERLLIB PATH GIT_TEXTDOMAINDIR if test -n "$GIT_TEST_GDB" @@ -446,23 +446,6 @@ int git_mkstemp(char *path, size_t len, const char *template) return mkstemp(path); } -/* git_mkstemps() - create tmp file with suffix honoring TMPDIR variable. */ -int git_mkstemps(char *path, size_t len, const char *template, int suffix_len) -{ - const char *tmp; - size_t n; - - tmp = getenv("TMPDIR"); - if (!tmp) - tmp = "/tmp"; - n = snprintf(path, len, "%s/%s", tmp, template); - if (len <= n) { - errno = ENAMETOOLONG; - return -1; - } - return mkstemps(path, suffix_len); -} - /* Adapted from libiberty's mkstemp.c. */ #undef TMP_MAX @@ -572,7 +555,7 @@ static int warn_if_unremovable(const char *op, const char *file, int rc) if (!rc || errno == ENOENT) return 0; err = errno; - warning("unable to %s %s: %s", op, file, strerror(errno)); + warning_errno("unable to %s %s", op, file); errno = err; return rc; } @@ -608,7 +591,7 @@ int remove_or_warn(unsigned int mode, const char *file) void warn_on_inaccessible(const char *path) { - warning(_("unable to access '%s': %s"), path, strerror(errno)); + warning_errno(_("unable to access '%s'"), path); } static int access_error_is_ok(int err, unsigned flag) diff --git a/wt-status.c b/wt-status.c index 1ea2ebe4c0..4f27bd62af 100644 --- a/wt-status.c +++ b/wt-status.c @@ -15,6 +15,7 @@ #include "column.h" #include "strbuf.h" #include "utf8.h" +#include "worktree.h" static const char cut_line[] = "------------------------ >8 ------------------------\n"; @@ -950,6 +951,7 @@ static void show_merge_in_progress(struct wt_status *s, status_printf_ln(s, color, _(" (fix conflicts and run \"git commit\")")); } else { + s-> commitable = 1; status_printf_ln(s, color, _("All conflicts fixed but you are still merging.")); if (s->hints) @@ -1262,13 +1264,13 @@ static void show_bisect_in_progress(struct wt_status *s, /* * Extract branch information from rebase/bisect */ -static char *read_and_strip_branch(const char *path) +static char *get_branch(const struct worktree *wt, const char *path) { struct strbuf sb = STRBUF_INIT; unsigned char sha1[20]; const char *branch_name; - if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0) + if (strbuf_read_file(&sb, worktree_git_path(wt, "%s", path), 0) <= 0) goto got_nothing; while (sb.len && sb.buf[sb.len - 1] == '\n') @@ -1360,40 +1362,62 @@ static void wt_status_get_detached_from(struct wt_status_state *state) strbuf_release(&cb.buf); } -void wt_status_get_state(struct wt_status_state *state, - int get_detached_from) +int wt_status_check_rebase(const struct worktree *wt, + struct wt_status_state *state) { struct stat st; - unsigned char sha1[20]; - if (!stat(git_path_merge_head(), &st)) { - state->merge_in_progress = 1; - } else if (!stat(git_path("rebase-apply"), &st)) { - if (!stat(git_path("rebase-apply/applying"), &st)) { + if (!stat(worktree_git_path(wt, "rebase-apply"), &st)) { + if (!stat(worktree_git_path(wt, "rebase-apply/applying"), &st)) { state->am_in_progress = 1; - if (!stat(git_path("rebase-apply/patch"), &st) && !st.st_size) + if (!stat(worktree_git_path(wt, "rebase-apply/patch"), &st) && !st.st_size) state->am_empty_patch = 1; } else { state->rebase_in_progress = 1; - state->branch = read_and_strip_branch("rebase-apply/head-name"); - state->onto = read_and_strip_branch("rebase-apply/onto"); + state->branch = get_branch(wt, "rebase-apply/head-name"); + state->onto = get_branch(wt, "rebase-apply/onto"); } - } else if (!stat(git_path("rebase-merge"), &st)) { - if (!stat(git_path("rebase-merge/interactive"), &st)) + } else if (!stat(worktree_git_path(wt, "rebase-merge"), &st)) { + if (!stat(worktree_git_path(wt, "rebase-merge/interactive"), &st)) state->rebase_interactive_in_progress = 1; else state->rebase_in_progress = 1; - state->branch = read_and_strip_branch("rebase-merge/head-name"); - state->onto = read_and_strip_branch("rebase-merge/onto"); + state->branch = get_branch(wt, "rebase-merge/head-name"); + state->onto = get_branch(wt, "rebase-merge/onto"); + } else + return 0; + return 1; +} + +int wt_status_check_bisect(const struct worktree *wt, + struct wt_status_state *state) +{ + struct stat st; + + if (!stat(worktree_git_path(wt, "BISECT_LOG"), &st)) { + state->bisect_in_progress = 1; + state->branch = get_branch(wt, "BISECT_START"); + return 1; + } + return 0; +} + +void wt_status_get_state(struct wt_status_state *state, + int get_detached_from) +{ + struct stat st; + unsigned char sha1[20]; + + if (!stat(git_path_merge_head(), &st)) { + state->merge_in_progress = 1; + } else if (wt_status_check_rebase(NULL, state)) { + ; /* all set */ } else if (!stat(git_path_cherry_pick_head(), &st) && !get_sha1("CHERRY_PICK_HEAD", sha1)) { state->cherry_pick_in_progress = 1; hashcpy(state->cherry_pick_head_sha1, sha1); } - if (!stat(git_path("BISECT_LOG"), &st)) { - state->bisect_in_progress = 1; - state->branch = read_and_strip_branch("BISECT_START"); - } + wt_status_check_bisect(NULL, state); if (!stat(git_path_revert_head(), &st) && !get_sha1("REVERT_HEAD", sha1)) { state->revert_in_progress = 1; diff --git a/wt-status.h b/wt-status.h index c9b3b744e9..2ca93f6957 100644 --- a/wt-status.h +++ b/wt-status.h @@ -6,6 +6,8 @@ #include "color.h" #include "pathspec.h" +struct worktree; + enum color_wt_status { WT_STATUS_HEADER = 0, WT_STATUS_UPDATED, @@ -100,6 +102,10 @@ void wt_status_prepare(struct wt_status *s); void wt_status_print(struct wt_status *s); void wt_status_collect(struct wt_status *s); void wt_status_get_state(struct wt_status_state *state, int get_detached_from); +int wt_status_check_rebase(const struct worktree *wt, + struct wt_status_state *state); +int wt_status_check_bisect(const struct worktree *wt, + struct wt_status_state *state); void wt_shortstatus_print(struct wt_status *s); void wt_porcelain_print(struct wt_status *s); diff --git a/xdiff/xdiff.h b/xdiff/xdiff.h index 4fb7e79410..7423f77fc8 100644 --- a/xdiff/xdiff.h +++ b/xdiff/xdiff.h @@ -41,6 +41,8 @@ extern "C" { #define XDF_IGNORE_BLANK_LINES (1 << 7) +#define XDF_COMPACTION_HEURISTIC (1 << 8) + #define XDL_EMIT_FUNCNAMES (1 << 0) #define XDL_EMIT_FUNCCONTEXT (1 << 2) diff --git a/xdiff/xdiffi.c b/xdiff/xdiffi.c index 2358a2d632..b3c6848875 100644 --- a/xdiff/xdiffi.c +++ b/xdiff/xdiffi.c @@ -400,9 +400,23 @@ static xdchange_t *xdl_add_change(xdchange_t *xscr, long i1, long i2, long chg1, } +static int is_blank_line(xrecord_t **recs, long ix, long flags) +{ + return xdl_blankline(recs[ix]->ptr, recs[ix]->size, flags); +} + +static int recs_match(xrecord_t **recs, long ixs, long ix, long flags) +{ + return (recs[ixs]->ha == recs[ix]->ha && + xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, + recs[ix]->ptr, recs[ix]->size, + flags)); +} + int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { long ix, ixo, ixs, ixref, grpsiz, nrec = xdf->nrec; char *rchg = xdf->rchg, *rchgo = xdfo->rchg; + unsigned int blank_lines; xrecord_t **recs = xdf->recs; /* @@ -436,14 +450,14 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { do { grpsiz = ix - ixs; + blank_lines = 0; /* * If the line before the current change group, is equal to * the last line of the current change group, shift backward * the group. */ - while (ixs > 0 && recs[ixs - 1]->ha == recs[ix - 1]->ha && - xdl_recmatch(recs[ixs - 1]->ptr, recs[ixs - 1]->size, recs[ix - 1]->ptr, recs[ix - 1]->size, flags)) { + while (ixs > 0 && recs_match(recs, ixs - 1, ix - 1, flags)) { rchg[--ixs] = 1; rchg[--ix] = 0; @@ -470,8 +484,9 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { * the line next of the current change group, shift forward * the group. */ - while (ix < nrec && recs[ixs]->ha == recs[ix]->ha && - xdl_recmatch(recs[ixs]->ptr, recs[ixs]->size, recs[ix]->ptr, recs[ix]->size, flags)) { + while (ix < nrec && recs_match(recs, ixs, ix, flags)) { + blank_lines += is_blank_line(recs, ix, flags); + rchg[ixs++] = 0; rchg[ix++] = 1; @@ -498,6 +513,23 @@ int xdl_change_compact(xdfile_t *xdf, xdfile_t *xdfo, long flags) { rchg[--ix] = 0; while (rchgo[--ixo]); } + + /* + * If a group can be moved back and forth, see if there is a + * blank line in the moving space. If there is a blank line, + * make sure the last blank line is the end of the group. + * + * As we already shifted the group forward as far as possible + * in the earlier loop, we need to shift it back only if at all. + */ + if ((flags & XDF_COMPACTION_HEURISTIC) && blank_lines) { + while (ixs > 0 && + !is_blank_line(recs, ix - 1, flags) && + recs_match(recs, ixs - 1, ix - 1, flags)) { + rchg[--ixs] = 1; + rchg[--ix] = 0; + } + } } return 0; |