diff options
309 files changed, 18623 insertions, 9387 deletions
diff --git a/.gitignore b/.gitignore index 6669bf0c6c..10aee94760 100644 --- a/.gitignore +++ b/.gitignore @@ -125,6 +125,7 @@ /git-remote-ftps /git-remote-fd /git-remote-ext +/git-remote-testgit /git-remote-testpy /git-remote-testsvn /git-repack diff --git a/Documentation/CodingGuidelines b/Documentation/CodingGuidelines index 7e4d5716a6..559d5f9ebf 100644 --- a/Documentation/CodingGuidelines +++ b/Documentation/CodingGuidelines @@ -237,8 +237,10 @@ For Python scripts: Writing Documentation: - Most (if not all) of the documentation pages are written in AsciiDoc - and processed into HTML output and manpages. + Most (if not all) of the documentation pages are written in the + AsciiDoc format in *.txt files (e.g. Documentation/git.txt), and + processed into HTML and manpages (e.g. git.html and git.1 in the + same directory). Every user-visible change should be reflected in the documentation. The same general rule as for code applies -- imitate the existing diff --git a/Documentation/RelNotes/1.8.2.3.txt b/Documentation/RelNotes/1.8.2.3.txt new file mode 100644 index 0000000000..613948251a --- /dev/null +++ b/Documentation/RelNotes/1.8.2.3.txt @@ -0,0 +1,19 @@ +Git v1.8.2.3 Release Notes +========================== + +Fixes since v1.8.2.2 +-------------------- + + * "rev-list --stdin" and friends kept bogus pointers into the input + buffer around as human readable object names. This was not a + huge problem but was exposed by a new change that uses these + names in error output. + + * When "git difftool" drove "kdiff3", it mistakenly passed --auto + option that was meant while resolving merge conflicts. + + * "git remote add" command did not diagnose extra command line + arguments as an error and silently ignored them. + +Also contains a handful of trivial code clean-ups, documentation +updates, updates to the test suite, etc. diff --git a/Documentation/RelNotes/1.8.3.txt b/Documentation/RelNotes/1.8.3.txt new file mode 100644 index 0000000000..ead568e7f1 --- /dev/null +++ b/Documentation/RelNotes/1.8.3.txt @@ -0,0 +1,436 @@ +Git v1.8.3 Release Notes +======================== + +Backward compatibility notes (for Git 2.0) +------------------------------------------ + +When "git push [$there]" does not say what to push, we have used the +traditional "matching" semantics so far (all your branches were sent +to the remote as long as there already are branches of the same name +over there). In Git 2.0, the default will change to the "simple" +semantics that pushes only the current branch to the branch with the same +name, and only when the current branch is set to integrate with that +remote branch. Use the user preference configuration variable +"push.default" to change this. If you are an old-timer who is used +to the "matching" semantics, you can set the variable to "matching" +to keep the traditional behaviour. If you want to live in the future +early, you can set it to "simple" today without waiting for Git 2.0. + +When "git add -u" (and "git add -A") is run inside a subdirectory and +does not specify which paths to add on the command line, it +will operate on the entire tree in Git 2.0 for consistency +with "git commit -a" and other commands. There will be no +mechanism to make plain "git add -u" behave like "git add -u .". +Current users of "git add -u" (without a pathspec) should start +training their fingers to explicitly say "git add -u ." +before Git 2.0 comes. A warning is issued when these commands are +run without a pathspec and when you have local changes outside the +current directory, because the behaviour in Git 2.0 will be different +from today's version in such a situation. + +In Git 2.0, "git add <path>" will behave as "git add -A <path>", so +that "git add dir/" will notice paths you removed from the directory +and record the removal. Versions before Git 2.0, including this +release, will keep ignoring removals, but the users who rely on this +behaviour are encouraged to start using "git add --ignore-removal <path>" +now before 2.0 is released. + + +Updates since v1.8.2 +-------------------- + +Foreign interface + + * remote-hg and remote-bzr helpers (in contrib/ since v1.8.2) have + been updated; especially, the latter has been done in an + accelerated schedule (read: we may not have merged to this release + if we were following the usual "cook sufficiently in next before + unleashing it to the world" workflow) in order to help Emacs folks, + whose primary SCM seems to be stagnating. + + +UI, Workflows & Features + + * A handful of updates applied to gitk, including an addition of + "revert" action, showing dates in tags in a nicer way, making + colors configurable, and support for -G'pickaxe' search. + + * The prompt string generator (in contrib/completion/) learned to + show how many changes there are in total and how many have been + replayed during a "git rebase" session. + + * "git branch --vv" learned to paint the name of the branch it + integrates with in a different color (color.branch.upstream, + which defaults to blue). + + * In a sparsely populated working tree, "git checkout <pathspec>" no + longer unmarks paths that match the given pathspec that were + originally ignored with "--sparse" (use --ignore-skip-worktree-bits + option to resurrect these paths out of the index if you really want + to). + + * "git log --format" specifier learned %C(auto) token that tells Git + to use color when interpolating %d (decoration), %h (short commit + object name), etc. for terminal output. + + * "git bisect" leaves the final outcome as a comment in its bisect + log file. + + * "git clone --reference" can now refer to a gitfile "textual symlink" + that points at the real location of the repository. + + * "git count-objects" learned "--human-readable" aka "-H" option to + show various large numbers in Ki/Mi/GiB scaled as necessary. + + * "git cherry-pick $blob" and "git cherry-pick $tree" are nonsense, + and a more readable error message e.g. "can't cherry-pick a tree" + is given (we used to say "expected exactly one commit"). + + * The "--annotate" option to "git send-email" can be turned on (or + off) by default with sendemail.annotate configuration variable (you + can use --no-annotate from the command line to override it). + + * The "--cover-letter" option to "git format-patch" can be turned on + (or off) by default with format.coverLetter configuration + variable. By setting it to 'auto', you can turn it on only for a + series with two or more patches. + + * The bash completion support (in contrib/) learned that cherry-pick + takes a few more options than it already knew about. + + * "git help" learned "-g" option to show the list of guides just like + list of commands are given with "-a". + + * A triangular "pull from one place, push to another place" workflow + is supported better by new remote.pushdefault (overrides the + "origin" thing) and branch.*.pushremote (overrides the + branch.*.remote) configuration variables. + + * "git status" learned to report that you are in the middle of a + revert session, just like it does for a cherry-pick and a bisect + session. + + * The handling by "git branch --set-upstream-to" against various forms + of erroneous inputs was suboptimal and has been improved. + + * When the interactive access to git-shell is not enabled, it issues + a message meant to help the system administrator to enable it. An + explicit way has been added to issue custom messages to refuse an + access over the network to help the end users who connect to the + service expecting an interactive shell. + + * In addition to the case where the user edits the log message with + the "e)dit" option of "am -i", replace the "Applying: this patch" + message with the final log message contents after applymsg hook + munges it. + + * "git status" suggests users to look into using --untracked=no option + when it takes too long. + + * "git status" shows a bit more information during a rebase/bisect + session. + + * "git fetch" learned to fetch a commit at the tip of an unadvertised + ref by specifying a raw object name from the command line when the + server side supports this feature. + + * Output from "git log --graph" works better with submodule log + output now. + + * "git count-objects -v" learned to report leftover temporary + packfiles and other garbage in the object store. + + * A new read-only credential helper (in contrib/) to interact with + the .netrc/.authinfo files has been added. + + * "git send-email" can be used with the credential helper system. + + * There was no Porcelain way to say "I no longer am interested in + this submodule", once you express your interest in a submodule with + "submodule init". "submodule deinit" is the way to do so. + + * "git pull --rebase" learned to pass "-v/-q" options to underlying + "git rebase". + + * The new "--follow-tags" option tells "git push" to push relevant + annotated tags when pushing branches out. + + * "git merge" and "git pull" can optionally be told to inspect and + reject when merging a commit that does not carry a trusted GPG + signature. + + * "git mergetool" now feeds files to the "p4merge" backend in the + order that matches the p4 convention, where "theirs" is usually + shown on the left side, which is the opposite from what other backends + expect. + + * "show/log" now honors gpg.program configuration just like other + parts of the code that use GnuPG. + + * "git log" that shows the difference between the parent and the + child has been optimized somewhat. + + * "git difftool" allows the user to write into the temporary files + being shown; if the user makes changes to the working tree at the + same time, it now refrains from overwriting the copy in the working + tree and leaves the temporary file so that changes can be merged + manually. + + * There was no good way to ask "I have a random string that came from + outside world. I want to turn it into a 40-hex object name while + making sure such an object exists". A new peeling suffix ^{object} + can be used for that purpose, together with "rev-parse --verify". + + +Performance, Internal Implementation, etc. + + * Updates for building under msvc. + + * A handful of issues in the code that traverses the working tree to find + untracked and/or ignored files have been fixed, and the general + codepath involved in "status -u" and "clean" have been cleaned up + and optimized. + + * The stack footprint of some codepaths that access an object from a + pack has been shrunk. + + * The logic to coalesce the same lines removed from the parents in + the output from "diff -c/--cc" has been updated, but with O(n^2) + complexity, so this might turn out to be undesirable. + + * The code to enforce permission bits on files in $GIT_DIR/ for + shared repositories has been simplified. + + * A few codepaths know how much data they need to put in the + hashtables they use when they start, but still began with small tables + and repeatedly grew and rehashed them. + + * The API to walk reflog entries from the latest to older, which was + necessary for operations such as "git checkout -", was cumbersome + to use correctly and also inefficient. + + * Codepaths that inspect log-message-to-be and decide when to add a + new Signed-off-by line in various commands have been consolidated. + + * The pkt-line API, implementation and its callers have been cleaned + up to make them more robust. + + * The Cygwin port has a faster-but-lying lstat(2) emulation whose + incorrectness does not matter in practice except for a few + codepaths, and setting permission bits on directories is a codepath + that needs to use a more correct one. + + * "git checkout" had repeated pathspec matches on the same paths, + which have been consolidated. Also a bug in "git checkout dir/" + that is started from an unmerged index has been fixed. + + * A few bugfixes to "git rerere" working on corner case merge + conflicts have been applied. + + +Also contains various documentation updates and code clean-ups. + + +Fixes since v1.8.2 +------------------ + +Unless otherwise noted, all the fixes since v1.8.2 in the maintenance +track are contained in this release (see release notes to them for +details). + + * Recent versions of File::Temp (used by "git svn") started blowing + up when its tempfile sub is called as a class method; updated the + callsite to call it as a plain vanilla function to fix it. + (merge eafc2dd hb/git-pm-tempfile later to maint). + + * Various subcommands of "git remote" simply ignored extraneous + command line arguments instead of diagnosing them as errors. + + * When receive-pack detects an error in the pack header it received in + order to decide which of unpack-objects or index-pack to run, it + returned without closing the error stream, which led to a hung + sideband thread. + + * Zsh completion forgot that the '%' character used to signal untracked + files needs to be escaped with another '%'. + + * A commit object whose author or committer ident are malformed + crashed some code that trusted that a name, an email and a + timestamp can always be found in it. + + * When "upload-pack" fails while generating a pack in response to + "git fetch" (or "git clone"), the receiving side had + a programming error that triggered the die handler + recursively. + + * "rev-list --stdin" and friends kept bogus pointers into the input + buffer around as human readable object names. This was not a huge + problem but was exposed by a new change that uses these names in + error output. + + * Smart-capable HTTP servers were not restricted via the + GIT_NAMESPACE mechanism when talking with commit-walking clients, + like they are when talking with smart HTTP clients. + (merge 6130f86 jk/http-dumb-namespaces later to maint). + + * "git merge-tree" did not omit a merge result that is identical to + the "our" side in certain cases. + (merge aacecc3 jk/merge-tree-added-identically later to maint). + + * Perl scripts like "git-svn" closed (instead of redirecting to /dev/null) + the standard error stream, which is not a very smart thing to do. + A later open may return file descriptor #2 for an unrelated purpose, and + error reporting code may write into it. + + * "git show-branch" was not prepared to show a very long run of + ancestor operators e.g. foobar^2~2^2^2^2...^2~4 correctly. + + * "git diff --diff-algorithm algo" is also understood as "git diff + --diff-algorithm=algo". + + * The new core.commentchar configuration was not applied in a few + places. + + * "git bundle" erroneously bailed out when parsing a valid bundle + containing a prerequisite commit without a commit message. + + * "git log -S/-G" started paying attention to textconv filter, but + there was no way to disable this. Make it honor the --no-textconv + option. + + * When used with the "-d temporary-directory" option, "git filter-branch" + failed to come back to the original working tree to perform the + final clean-up procedure. + + * "git merge $(git rev-parse v1.8.2)" behaved quite differently from + "git merge v1.8.2", as if v1.8.2 were written as v1.8.2^0 and did + not pay much attention to the annotated tag payload. Make the code + notice the type of the tag object, in addition to the dwim_ref() + based classification the current code uses (i.e. the name appears + in refs/tags/) to decide when to special-case tag merging. + + * Fix a 1.8.1.x regression that stopped matching "dir" (without a + trailing slash) to a directory "dir". + + * "git apply --whitespace=fix" was not prepared to see a line getting + longer after fixing whitespaces (e.g. tab-in-indent aka Python). + + * The prompt string generator (in contrib/completion/) did not notice + when we are in a middle of a "git revert" session. + + * "submodule summary --summary-limit" option did not support the + "--option=value" form. + + * "index-pack --fix-thin" used an uninitialized value to compute + the delta depths of objects it appends to the resulting pack. + + * "index-pack --verify-stat" used a few counters outside the protection + of a mutex, possibly showing incorrect numbers. + + * The code to keep track of what directory names are known to Git on + platforms with case insensitive filesystems could get confused upon a + hash collision between these pathnames and would loop forever. + + * Annotated tags outside the refs/tags/ hierarchy were not advertised + correctly to ls-remote and fetch with recent versions of Git. + + * Recent optimizations broke shallow clones. + + * "git cmd -- ':(top'" was not diagnosed as an invalid syntax, and + instead the parser kept reading beyond the end of the string. + + * "git tag -f <tag>" always said "Updated tag '<tag>'" even when + creating a new tag (i.e. neither overwriting nor updating). + + * "git p4" did not behave well when the path to the root of the P4 + client was not its real path. + (merge bbd8486 pw/p4-symlinked-root later to maint). + + * "git archive" reported a failure when asked to create an archive out + of an empty tree. It is more intuitive to give an empty + archive back in such a case. + + * When "format-patch" quoted a non-ascii string in header files, + it incorrectly applied rfc2047 and chopped a single character in + the middle of the string. + + * An aliased command spawned from a bare repository that does not say + it is bare with "core.bare = yes" was treated as non-bare by mistake. + + * In "git reflog expire", the REACHABLE bit was not cleared from the + correct objects. + + * The logic used by "git diff -M --stat" to shorten the names of + files before and after a rename did not work correctly when the + common prefix and suffix between the two filenames overlapped. + + * The "--match=<pattern>" option of "git describe", when used with + "--all" to allow refs that are not annotated tags to be a + base of description, did not restrict the output from the command + to those refs that match the given pattern. + + * Clarify in the documentation "what" gets pushed to "where" when the + command line to "git push" does not say these explicitly. + + * The "--color=<when>" argument to the commands in the diff family + was described poorly. + + * The arguments given to the pre-rebase hook were not documented. + + * The v4 index format was not documented. + + * The "--match=<pattern>" argument "git describe" takes uses glob + pattern but it wasn't obvious from the documentation. + + * Some sources failed to compile on systems that lack NI_MAXHOST in + their system header (e.g. z/OS). + + * Add an example use of "--env-filter" in "filter-branch" + documentation. + + * "git bundle verify" did not say "records a complete history" for a + bundle that does not have any prerequisites. + + * In the v1.8.0 era, we changed symbols that do not have to be global + to file scope static, but a few functions in graph.c were used by + CGit sideways, bypassing the entry points of the API the + in-tree users use. + + * "git update-index -h" did not do the usual "-h(elp)" thing. + + * "git index-pack" had a buffer-overflow while preparing an + informational message when the translated version of it was too + long. + + * 'git commit -m "$msg"' used to add an extra newline even when + $msg already ended with one. + + * The SSL peer verification done by "git imap-send" did not ask for + Server Name Indication (RFC 4366), failing to connect to SSL/TLS + sites that serve multiple hostnames on a single IP. + + * perl/Git.pm::cat_blob slurped everything in core only to write it + out to a file descriptor, which was not a very smart thing to do. + + * "git branch" did not bother to check nonsense command line + parameters. It now issues errors in many cases. + + * Verification of signed tags was not done correctly when not in C + or en/US locale. + + * Some platforms and users spell UTF-8 differently; retry with the + most official "UTF-8" when the system does not understand the + user-supplied encoding name that is a common alternative + spelling of UTF-8. + + * When export-subst is used, "zip" output recorded an incorrect + size of the file. + + * "git am $maildir/" applied messages in an unexpected order; sort + filenames read from the maildir/ in a way that is more likely to + sort the messages in the order the writing MUA meant to, by sorting + numeric segments in numeric order and non-numeric segments in + alphabetical order. + + * "git submodule update", when recursed into sub-submodules, did not + accumulate the prefix paths. diff --git a/Documentation/config.txt b/Documentation/config.txt index e97faccb7d..6e53fc5074 100644 --- a/Documentation/config.txt +++ b/Documentation/config.txt @@ -727,9 +727,22 @@ branch.autosetuprebase:: This option defaults to never. branch.<name>.remote:: - When in branch <name>, it tells 'git fetch' and 'git push' which - remote to fetch from/push to. It defaults to `origin` if no remote is - configured. `origin` is also used if you are not on any branch. + When on branch <name>, it tells 'git fetch' and 'git push' + which remote to fetch from/push to. The remote to push to + may be overridden with `remote.pushdefault` (for all branches). + The remote to push to, for the current branch, may be further + overridden by `branch.<name>.pushremote`. If no remote is + configured, or if you are not on any branch, it defaults to + `origin` for fetching and `remote.pushdefault` for pushing. + +branch.<name>.pushremote:: + When on branch <name>, it overrides `branch.<name>.remote` for + pushing. It also overrides `remote.pushdefault` for pushing + from branch <name>. When you pull from one place (e.g. your + upstream) and push to another place (e.g. your own publishing + repository), you would want to set `remote.pushdefault` to + specify the remote to push to for all branches, and use this + option to override it for a specific branch. branch.<name>.merge:: Defines, together with branch.<name>.remote, the upstream branch @@ -794,7 +807,8 @@ color.branch:: color.branch.<slot>:: Use customized color for branch coloration. `<slot>` is one of `current` (the current branch), `local` (a local branch), - `remote` (a remote-tracking branch in refs/remotes/), `plain` (other + `remote` (a remote-tracking branch in refs/remotes/), + `upstream` (upstream tracking branch), `plain` (other refs). + The value for these configuration variables is a list of colors (at most @@ -1096,6 +1110,11 @@ format.signoff:: the rights to submit this work under the same open source license. Please see the 'SubmittingPatches' document for further discussion. +format.coverLetter:: + A boolean that controls whether to generate a cover-letter when + format-patch is invoked, but in addition can be set to "auto", to + generate a cover-letter only when there's more than one patch. + 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 @@ -1447,6 +1466,14 @@ http.sslCAPath:: with when fetching or pushing over HTTPS. Can be overridden by the 'GIT_SSL_CAPATH' environment variable. +http.sslTry:: + Attempt to use AUTH SSL/TLS and encrypted data transfers + when connecting via regular FTP protocol. This might be needed + if the FTP server requires it for security reasons or you wish + to connect securely whenever remote FTP server supports it. + Default is false since it might trigger certificate verification + errors on misconfigured servers. + http.maxRequests:: How many HTTP requests to launch in parallel. Can be overridden by the 'GIT_HTTP_MAX_REQUESTS' environment variable. Default is 5. @@ -1898,6 +1925,11 @@ receive.updateserverinfo:: If set to true, git-receive-pack will run git-update-server-info after receiving data from git-push and updating refs. +remote.pushdefault:: + The remote to push to by default. Overrides + `branch.<name>.remote` for all branches, and is overridden by + `branch.<name>.pushremote` for specific branches. + remote.<name>.url:: The URL of a remote repository. See linkgit:git-fetch[1] or linkgit:git-push[1]. @@ -1998,6 +2030,7 @@ sendemail.<identity>.*:: sendemail.aliasesfile:: sendemail.aliasfiletype:: +sendemail.annotate:: sendemail.bcc:: sendemail.cc:: sendemail.cccmd:: @@ -2123,7 +2156,13 @@ uploadpack.hiderefs:: are under the hierarchies listed on the value of this variable is excluded, and is hidden from `git ls-remote`, `git fetch`, etc. An attempt to fetch a hidden ref by `git - fetch` will fail. + fetch` will fail. See also `uploadpack.allowtipsha1inwant`. + +uploadpack.allowtipsha1inwant:: + When `uploadpack.hiderefs` is in effect, allow `upload-pack` + to accept a fetch request that asks for an object at the tip + of a hidden ref (by default, such a request is rejected). + see also `uploadpack.hiderefs`. url.<base>.insteadOf:: Any URL that starts with this value will be rewritten to diff --git a/Documentation/git-add.txt b/Documentation/git-add.txt index b0944e57d5..48754cbc67 100644 --- a/Documentation/git-add.txt +++ b/Documentation/git-add.txt @@ -9,9 +9,9 @@ SYNOPSIS -------- [verse] 'git add' [-n] [-v] [--force | -f] [--interactive | -i] [--patch | -p] - [--edit | -e] [--all | [--update | -u]] [--intent-to-add | -N] - [--refresh] [--ignore-errors] [--ignore-missing] [--] - [<pathspec>...] + [--edit | -e] [--[no-]all | --[no-]ignore-removal | [--update | -u]] + [--intent-to-add | -N] [--refresh] [--ignore-errors] [--ignore-missing] + [--] [<pathspec>...] DESCRIPTION ----------- @@ -111,6 +111,7 @@ of Git, hence the form without <pathspec> should not be used. -A:: --all:: +--no-ignore-removal:: Update the index not only where the working tree has a file matching <pathspec> but also where the index already has an entry. This adds, modifies, and removes index entries to @@ -121,6 +122,19 @@ If no <pathspec> is given, the current version of Git defaults to and its subdirectories. This default will change in a future version of Git, hence the form without <pathspec> should not be used. +--no-all:: +--ignore-removal:: + Update the index by adding new files that are unknown to the + index and files modified in the working tree, but ignore + files that have been removed from the working tree. This + option is a no-op when no <pathspec> is used. ++ +This option is primarily to help the current users of Git, whose +"git add <pathspec>..." ignores removed files. In future versions +of Git, "git add <pathspec>..." will be a synonym to "git add -A +<pathspec>..." and "git add --ignore-removal <pathspec>..." will behave like +today's "git add <pathspec>...", ignoring removed files. + -N:: --intent-to-add:: Record only the fact that the path will be added later. An entry diff --git a/Documentation/git-am.txt b/Documentation/git-am.txt index 19d57a80f5..5bbe7b6d10 100644 --- a/Documentation/git-am.txt +++ b/Documentation/git-am.txt @@ -9,12 +9,12 @@ git-am - Apply a series of patches from a mailbox SYNOPSIS -------- [verse] -'git am' [--signoff] [--keep] [--keep-cr | --no-keep-cr] [--utf8 | --no-utf8] +'git am' [--signoff] [--keep] [--[no-]keep-cr] [--[no-]utf8] [--3way] [--interactive] [--committer-date-is-author-date] [--ignore-date] [--ignore-space-change | --ignore-whitespace] [--whitespace=<option>] [-C<n>] [-p<n>] [--directory=<dir>] [--exclude=<path>] [--include=<path>] [--reject] [-q | --quiet] - [--scissors | --no-scissors] + [--[no-]scissors] [(<mbox> | <Maildir>)...] 'git am' (--continue | --skip | --abort) @@ -43,8 +43,7 @@ OPTIONS --keep-non-patch:: Pass `-b` flag to 'git mailinfo' (see linkgit:git-mailinfo[1]). ---keep-cr:: ---no-keep-cr:: +--[no-]keep-cr:: With `--keep-cr`, call 'git mailsplit' (see linkgit:git-mailsplit[1]) with the same option, to prevent it from stripping CR at the end of lines. `am.keepcr` configuration variable can be used to specify the diff --git a/Documentation/git-archive.txt b/Documentation/git-archive.txt index 250e5228a3..b97aaab4ed 100644 --- a/Documentation/git-archive.txt +++ b/Documentation/git-archive.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git archive' [--format=<fmt>] [--list] [--prefix=<prefix>/] [<extra>] - [-o | --output=<file>] [--worktree-attributes] + [-o <file> | --output=<file>] [--worktree-attributes] [--remote=<repo> [--exec=<git-upload-archive>]] <tree-ish> [<path>...] diff --git a/Documentation/git-check-attr.txt b/Documentation/git-check-attr.txt index 5abdbaa51c..a7be80d48b 100644 --- a/Documentation/git-check-attr.txt +++ b/Documentation/git-check-attr.txt @@ -56,6 +56,11 @@ being queried and <info> can be either: 'set';; when the attribute is defined as true. <value>;; when a value has been assigned to the attribute. +Buffering happens as documented under the `GIT_FLUSH` option in +linkgit:git[1]. The caller is responsible for avoiding deadlocks +caused by overfilling an input buffer or reading from an empty output +buffer. + EXAMPLES -------- diff --git a/Documentation/git-check-ignore.txt b/Documentation/git-check-ignore.txt index 854e4d0c42..8e1f7ab7ea 100644 --- a/Documentation/git-check-ignore.txt +++ b/Documentation/git-check-ignore.txt @@ -39,6 +39,12 @@ OPTIONS below). If `--stdin` is also given, input paths are separated with a NUL character instead of a linefeed character. +-n, --non-matching:: + Show given paths which don't match any pattern. This only + makes sense when `--verbose` is enabled, otherwise it would + not be possible to distinguish between paths which match a + pattern and those which don't. + OUTPUT ------ @@ -65,6 +71,20 @@ are also used instead of colons and hard tabs: <source> <NULL> <linenum> <NULL> <pattern> <NULL> <pathname> <NULL> +If `-n` or `--non-matching` are specified, non-matching pathnames will +also be output, in which case all fields in each output record except +for <pathname> will be empty. This can be useful when running +non-interactively, so that files can be incrementally streamed to +STDIN of a long-running check-ignore process, and for each of these +files, STDOUT will indicate whether that file matched a pattern or +not. (Without this option, it would be impossible to tell whether the +absence of output for a given file meant that it didn't match any +pattern, or that the output hadn't been generated yet.) + +Buffering happens as documented under the `GIT_FLUSH` option in +linkgit:git[1]. The caller is responsible for avoiding deadlocks +caused by overfilling an input buffer or reading from an empty output +buffer. EXIT STATUS ----------- diff --git a/Documentation/git-check-ref-format.txt b/Documentation/git-check-ref-format.txt index ec1739a896..a49be1bab4 100644 --- a/Documentation/git-check-ref-format.txt +++ b/Documentation/git-check-ref-format.txt @@ -83,8 +83,7 @@ typed the branch name. OPTIONS ------- ---allow-onelevel:: ---no-allow-onelevel:: +--[no-]allow-onelevel:: Controls whether one-level refnames are accepted (i.e., refnames that do not contain multiple `/`-separated components). The default is `--no-allow-onelevel`. diff --git a/Documentation/git-checkout.txt b/Documentation/git-checkout.txt index 8edcdcae9d..ca118ac6bf 100644 --- a/Documentation/git-checkout.txt +++ b/Documentation/git-checkout.txt @@ -131,9 +131,9 @@ entries; instead, unmerged entries are ignored. "--track" in linkgit:git-branch[1] for details. + If no '-b' option is given, the name of the new branch will be -derived from the remote-tracking branch. If "remotes/" or "refs/remotes/" -is prefixed it is stripped away, and then the part up to the -next slash (which would be the nickname of the remote) is removed. +derived from the remote-tracking branch, by looking at the local part of +the refspec configured for the corresponding remote, and then stripping +the initial part up to the "*". This would tell us to use "hack" as the local branch when branching off of "origin/hack" (or "remotes/origin/hack", or even "refs/remotes/origin/hack"). If the given name has no slash, or the above @@ -180,6 +180,12 @@ branch by running "git rm -rf ." from the top level of the working tree. Afterwards you will be ready to prepare your new files, repopulating the working tree, by copying them from elsewhere, extracting a tarball, etc. +--ignore-skip-worktree-bits:: + In sparse checkout mode, `git checkout -- <paths>` would + update only entries matched by <paths> and sparse patterns + in $GIT_DIR/info/sparse-checkout. This option ignores + the sparse patterns and adds back any files in <paths>. + -m:: --merge:: When switching branches, diff --git a/Documentation/git-clone.txt b/Documentation/git-clone.txt index 5c16e317f6..a0727d7759 100644 --- a/Documentation/git-clone.txt +++ b/Documentation/git-clone.txt @@ -14,7 +14,7 @@ SYNOPSIS [-o <name>] [-b <name>] [-u <upload-pack>] [--reference <repository>] [--separate-git-dir <git dir>] [--depth <depth>] [--[no-]single-branch] - [--recursive|--recurse-submodules] [--] <repository> + [--recursive | --recurse-submodules] [--] <repository> [<directory>] DESCRIPTION @@ -188,7 +188,7 @@ objects from the source repository into a pack in the cloned repository. with a long history, and would want to send in fixes as patches. ---single-branch:: +--[no-]single-branch:: Clone only the history leading to the tip of a single branch, either specified by the `--branch` option or the primary branch remote's `HEAD` points at. When creating a shallow diff --git a/Documentation/git-commit-tree.txt b/Documentation/git-commit-tree.txt index 86ef56e7c8..cafdc9642d 100644 --- a/Documentation/git-commit-tree.txt +++ b/Documentation/git-commit-tree.txt @@ -10,7 +10,9 @@ SYNOPSIS -------- [verse] 'git commit-tree' <tree> [(-p <parent>)...] < changelog -'git commit-tree' [(-p <parent>)...] [(-m <message>)...] [(-F <file>)...] <tree> +'git commit-tree' [(-p <parent>)...] [-S[<keyid>]] [(-m <message>)...] + [(-F <file>)...] <tree> + DESCRIPTION ----------- @@ -52,6 +54,9 @@ OPTIONS Read the commit log message from the given file. Use `-` to read from the standard input. +-S[<keyid>]:: + GPG-sign commit. + Commit Information ------------------ diff --git a/Documentation/git-commit.txt b/Documentation/git-commit.txt index 9b1be5581d..1a7616c73a 100644 --- a/Documentation/git-commit.txt +++ b/Documentation/git-commit.txt @@ -12,7 +12,7 @@ SYNOPSIS [--dry-run] [(-c | -C | --fixup | --squash) <commit>] [-F <file> | -m <msg>] [--reset-author] [--allow-empty] [--allow-empty-message] [--no-verify] [-e] [--author=<author>] - [--date=<date>] [--cleanup=<mode>] [--status | --no-status] + [--date=<date>] [--cleanup=<mode>] [--[no-]status] [-i | -o] [-S[<keyid>]] [--] [<file>...] DESCRIPTION @@ -197,8 +197,8 @@ variable (see linkgit:git-config[1]). -e:: --edit:: The message taken from file with `-F`, command line with - `-m`, and from file with `-C` are usually used as the - commit log message unmodified. This option lets you + `-m`, and from commit object with `-C` are usually used as + the commit log message unmodified. This option lets you further edit the message taken from these sources. --no-edit:: diff --git a/Documentation/git-config.txt b/Documentation/git-config.txt index 9ae2508f3f..d88a6fcb29 100644 --- a/Documentation/git-config.txt +++ b/Documentation/git-config.txt @@ -186,8 +186,7 @@ See also <<FILES>>. Opens an editor to modify the specified config file; either '--system', '--global', or repository (default). ---includes:: ---no-includes:: +--[no-]includes:: Respect `include.*` directives in config files when looking up values. Defaults to on. diff --git a/Documentation/git-count-objects.txt b/Documentation/git-count-objects.txt index 23c80cea64..b300e846f1 100644 --- a/Documentation/git-count-objects.txt +++ b/Documentation/git-count-objects.txt @@ -8,7 +8,7 @@ git-count-objects - Count unpacked number of objects and their disk consumption SYNOPSIS -------- [verse] -'git count-objects' [-v] +'git count-objects' [-v] [-H | --human-readable] DESCRIPTION ----------- @@ -20,11 +20,29 @@ OPTIONS ------- -v:: --verbose:: - In addition to the number of loose objects and disk - space consumed, it reports the number of in-pack - objects, number of packs, disk space consumed by those packs, - and number of objects that can be removed by running - `git prune-packed`. + Report in more detail: ++ +count: the number of loose objects ++ +size: disk space consumed by loose objects, in KiB (unless -H is specified) ++ +in-pack: the number of in-pack objects ++ +size-pack: disk space consumed by the packs, in KiB (unless -H is specified) ++ +prune-packable: the number of loose objects that are also present in +the packs. These objects could be pruned using `git prune-packed`. ++ +garbage: the number of files in object database that are not valid +loose objects nor valid packs ++ +size-garbage: disk space consumed by garbage files, in KiB (unless -H is +specified) + +-H:: +--human-readable:: + +Print sizes in human readable format GIT --- diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index bfb106cccd..223f731523 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -16,8 +16,10 @@ SYNOPSIS [--reuseaddr] [--detach] [--pid-file=<file>] [--enable=<service>] [--disable=<service>] [--allow-override=<service>] [--forbid-override=<service>] - [--access-hook=<path>] - [--inetd | [--listen=<host_or_ipaddr>] [--port=<n>] [--user=<user> [--group=<group>]] + [--access-hook=<path>] [--[no-]informative-errors] + [--inetd | + [--listen=<host_or_ipaddr>] [--port=<n>] + [--user=<user> [--group=<group>]]] [<directory>...] DESCRIPTION @@ -169,8 +171,7 @@ Git configuration files in that directory are readable by `<user>`. repository configuration. By default, all the services are overridable. ---informative-errors:: ---no-informative-errors:: +--[no-]informative-errors:: When informative errors are turned on, git-daemon will report more verbose errors to the client, differentiating conditions like "no such repository" from "repository not exported". This diff --git a/Documentation/git-difftool.txt b/Documentation/git-difftool.txt index e0e12e9470..11887e63a0 100644 --- a/Documentation/git-difftool.txt +++ b/Documentation/git-difftool.txt @@ -69,13 +69,14 @@ with custom merge tool commands and has the same value as `$MERGED`. --tool-help:: Print a list of diff tools that may be used with `--tool`. ---symlinks:: ---no-symlinks:: +--[no-]symlinks:: 'git difftool''s default behavior is create symlinks to the - working tree when run in `--dir-diff` mode. + working tree when run in `--dir-diff` mode and the right-hand + side of the comparison yields the same content as the file in + the working tree. + - Specifying `--no-symlinks` instructs 'git difftool' to create - copies instead. `--no-symlinks` is the default on Windows. +Specifying `--no-symlinks` instructs 'git difftool' to create copies +instead. `--no-symlinks` is the default on Windows. -x <command>:: --extcmd=<command>:: diff --git a/Documentation/git-fast-export.txt b/Documentation/git-fast-export.txt index d6487e1ce0..efb03806f5 100644 --- a/Documentation/git-fast-export.txt +++ b/Documentation/git-fast-export.txt @@ -27,15 +27,17 @@ OPTIONS Insert 'progress' statements every <n> objects, to be shown by 'git fast-import' during import. ---signed-tags=(verbatim|warn|strip|abort):: +--signed-tags=(verbatim|warn|warn-strip|strip|abort):: Specify how to handle signed tags. Since any transformation after the export can change the tag names (which can also happen when excluding revisions) the signatures will not match. + When asking to 'abort' (which is the default), this program will die -when encountering a signed tag. With 'strip', the tags will be made -unsigned, with 'verbatim', they will be silently exported -and with 'warn', they will be exported, but you will see a warning. +when encountering a signed tag. With 'strip', the tags will silently +be made unsigned, with 'warn-strip' they will be made unsigned but a +warning will be displayed, with 'verbatim', they will be silently +exported and with 'warn', they will be exported, but you will see a +warning. --tag-of-filtered-object=(abort|drop|rewrite):: Specify how to handle tags whose tagged object is filtered out. @@ -66,6 +68,8 @@ produced incorrect results if you gave these options. incremental runs. As <file> is only opened and truncated at completion, the same path can also be safely given to \--import-marks. + The file will not be written if no new object has been + marked/exported. --import-marks=<file>:: Before processing any input, load the marks specified in @@ -102,11 +106,11 @@ marks the same across runs. different from the commit's first parent). [<git-rev-list-args>...]:: - A list of arguments, acceptable to 'git rev-parse' and - 'git rev-list', that specifies the specific objects and references - to export. For example, `master~10..master` causes the - current master reference to be exported along with all objects - added since its 10th ancestor commit. + A list of arguments, acceptable to 'git rev-parse' and + 'git rev-list', that specifies the specific objects and references + to export. For example, `master~10..master` causes the + current master reference to be exported along with all objects + added since its 10th ancestor commit. EXAMPLES -------- diff --git a/Documentation/git-fetch-pack.txt b/Documentation/git-fetch-pack.txt index b81e90d8e7..1e71754347 100644 --- a/Documentation/git-fetch-pack.txt +++ b/Documentation/git-fetch-pack.txt @@ -10,9 +10,9 @@ SYNOPSIS -------- [verse] 'git fetch-pack' [--all] [--quiet|-q] [--keep|-k] [--thin] [--include-tag] - [--upload-pack=<git-upload-pack>] - [--depth=<n>] [--no-progress] - [-v] [<host>:]<directory> [<refs>...] + [--upload-pack=<git-upload-pack>] + [--depth=<n>] [--no-progress] + [-v] [<host>:]<directory> [<refs>...] DESCRIPTION ----------- diff --git a/Documentation/git-fmt-merge-msg.txt b/Documentation/git-fmt-merge-msg.txt index 3a0f55ec8e..bb1232a52c 100644 --- a/Documentation/git-fmt-merge-msg.txt +++ b/Documentation/git-fmt-merge-msg.txt @@ -35,8 +35,7 @@ OPTIONS Do not list one-line descriptions from the actual commits being merged. ---summary:: ---no-summary:: +--[no-]summary:: Synonyms to --log and --no-log; these are deprecated and will be removed in the future. diff --git a/Documentation/git-format-patch.txt b/Documentation/git-format-patch.txt index 3a62f50eda..39118774af 100644 --- a/Documentation/git-format-patch.txt +++ b/Documentation/git-format-patch.txt @@ -20,7 +20,7 @@ SYNOPSIS [--ignore-if-in-upstream] [--subject-prefix=Subject-Prefix] [(--reroll-count|-v) <n>] [--to=<email>] [--cc=<email>] - [--cover-letter] [--quiet] [--notes[=<ref>]] + [--[no-]cover-letter] [--quiet] [--notes[=<ref>]] [<common diff options>] [ <since> | <revision range> ] @@ -195,7 +195,7 @@ will want to ensure that threading is disabled for `git send-email`. `Cc:`, and custom) headers added so far from config or command line. ---cover-letter:: +--[no-]cover-letter:: In addition to the patches, generate a cover letter file containing the shortlog and the overall diffstat. You can fill in a description in the file before sending it out. @@ -260,6 +260,7 @@ attachments, and sign off patches with configuration variables. cc = <email> attach [ = mime-boundary-string ] signoff = true + coverletter = auto ------------ diff --git a/Documentation/git-fsck.txt b/Documentation/git-fsck.txt index e5878bd97b..25c431d3c5 100644 --- a/Documentation/git-fsck.txt +++ b/Documentation/git-fsck.txt @@ -30,8 +30,7 @@ index file, all SHA-1 references in `refs` namespace, and all reflogs Print out objects that exist but that aren't reachable from any of the reference nodes. ---dangling:: ---no-dangling:: +--[no-]dangling:: Print objects that exist but that are never 'directly' used (default). `--no-dangling` can be used to omit this information from the output. @@ -78,8 +77,7 @@ index file, all SHA-1 references in `refs` namespace, and all reflogs a blob, the contents are written into the file, rather than its object name. ---progress:: ---no-progress:: +--[no-]progress:: Progress status is reported on the standard error stream by default when it is attached to a terminal, unless --no-progress or --verbose is specified. --progress forces diff --git a/Documentation/git-gc.txt b/Documentation/git-gc.txt index b370b025b8..2402ed6828 100644 --- a/Documentation/git-gc.txt +++ b/Documentation/git-gc.txt @@ -62,8 +62,9 @@ automatic consolidation of packs. --prune=<date>:: Prune loose objects older than date (default is 2 weeks ago, - overridable by the config variable `gc.pruneExpire`). This - option is on by default. + overridable by the config variable `gc.pruneExpire`). + --prune=all prunes loose objects regardless of their age. + --prune is on by default. --no-prune:: Do not prune any loose objects. diff --git a/Documentation/git-grep.txt b/Documentation/git-grep.txt index 50d46e1a7b..8497aa4494 100644 --- a/Documentation/git-grep.txt +++ b/Documentation/git-grep.txt @@ -25,7 +25,7 @@ SYNOPSIS [-W | --function-context] [-f <file>] [-e] <pattern> [--and|--or|--not|(|)|-e <pattern>...] - [ [--exclude-standard] [--cached | --no-index | --untracked] | <tree>...] + [ [--[no-]exclude-standard] [--cached | --no-index | --untracked] | <tree>...] [--] [<pathspec>...] DESCRIPTION diff --git a/Documentation/git-help.txt b/Documentation/git-help.txt index e07b6dc19a..b21e9d79be 100644 --- a/Documentation/git-help.txt +++ b/Documentation/git-help.txt @@ -8,31 +8,45 @@ git-help - Display help information about Git SYNOPSIS -------- [verse] -'git help' [-a|--all|-i|--info|-m|--man|-w|--web] [COMMAND] +'git help' [-a|--all] [-g|--guide] + [-i|--info|-m|--man|-w|--web] [COMMAND|GUIDE] DESCRIPTION ----------- -With no options and no COMMAND given, the synopsis of the 'git' +With no options and no COMMAND or GUIDE given, the synopsis of the 'git' command and a list of the most commonly used Git commands are printed on the standard output. -If the option '--all' or '-a' is given, then all available commands are +If the option '--all' or '-a' is given, all available commands are printed on the standard output. -If a Git subcommand is named, a manual page for that subcommand is brought -up. The 'man' program is used by default for this purpose, but this -can be overridden by other options or configuration variables. +If the option '--guide' or '-g' is given, a list of the useful +Git guides is also printed on the standard output. + +If a command, or a guide, is given, a manual page for that command or +guide is brought up. The 'man' program is used by default for this +purpose, but this can be overridden by other options or configuration +variables. Note that `git --help ...` is identical to `git help ...` because the former is internally converted into the latter. +To display the linkgit:git[1] man page, use `git help git`. + +This page can be displayed with 'git help help' or `git help --help` + OPTIONS ------- -a:: --all:: Prints all the available commands on the standard output. This - option supersedes any other option. + option overrides any given command or guide name. + +-g:: +--guides:: + Prints a list of useful guides on the standard output. This + option overrides any given command or guide name. -i:: --info:: diff --git a/Documentation/git-log.txt b/Documentation/git-log.txt index 69db5783ce..a976534ab8 100644 --- a/Documentation/git-log.txt +++ b/Documentation/git-log.txt @@ -9,7 +9,7 @@ git-log - Show commit logs SYNOPSIS -------- [verse] -'git log' [<options>] [<since>..<until>] [[\--] <path>...] +'git log' [<options>] [<revision range>] [[\--] <path>...] DESCRIPTION ----------- @@ -24,13 +24,6 @@ each commit introduces are shown. OPTIONS ------- -<since>..<until>:: - Show only commits between the named two commits. When - either <since> or <until> is omitted, it defaults to - `HEAD`, i.e. the tip of the current branch. - For a more complete list of ways to spell <since> - and <until>, see linkgit:gitrevisions[7]. - --follow:: Continue listing the history of a file beyond renames (works only for a single file). @@ -69,14 +62,23 @@ produced by --stat etc. Note that only message is considered, if also a diff is shown its size is not included. +<revision range>:: + Show only commits in the specified revision range. When no + <revision range> is specified, it defaults to `HEAD` (i.e. the + whole history leading to the current commit). `origin..HEAD` + specifies all the commits reachable from the current commit + (i.e. `HEAD`), but not from `origin`. For a complete list of + ways to spell <revision range>, see the "Specifying Ranges" + section of linkgit:gitrevisions[7]. + [\--] <path>...:: Show only commits that are enough to explain how the files that match the specified paths came to be. See "History Simplification" below for details and other simplification modes. + -To prevent confusion with options and branch names, paths may need to -be prefixed with "\-- " to separate them from options or refnames. +Paths may need to be prefixed with "\-- " to separate them from +options or the revision range, when confusion arises. include::rev-list-options.txt[] diff --git a/Documentation/git-mailinfo.txt b/Documentation/git-mailinfo.txt index 97e7a8e9e7..164a3c6ede 100644 --- a/Documentation/git-mailinfo.txt +++ b/Documentation/git-mailinfo.txt @@ -9,7 +9,7 @@ git-mailinfo - Extracts patch and authorship from a single e-mail message SYNOPSIS -------- [verse] -'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--scissors] <msg> <patch> +'git mailinfo' [-k|-b] [-u | --encoding=<encoding> | -n] [--[no-]scissors] <msg> <patch> DESCRIPTION diff --git a/Documentation/git-merge.txt b/Documentation/git-merge.txt index 42391f2ae7..67ca99cd92 100644 --- a/Documentation/git-merge.txt +++ b/Documentation/git-merge.txt @@ -76,8 +76,7 @@ The 'git fmt-merge-msg' command can be used to give a good default for automated 'git merge' invocations. ---rerere-autoupdate:: ---no-rerere-autoupdate:: +--[no-]rerere-autoupdate:: Allow the rerere mechanism to update the index with the result of auto-conflict resolution if possible. diff --git a/Documentation/git-mergetool.txt b/Documentation/git-mergetool.txt index 6b563c500f..07137f252b 100644 --- a/Documentation/git-mergetool.txt +++ b/Documentation/git-mergetool.txt @@ -8,7 +8,7 @@ git-mergetool - Run merge conflict resolution tools to resolve merge conflicts SYNOPSIS -------- [verse] -'git mergetool' [--tool=<tool>] [-y|--no-prompt|--prompt] [<file>...] +'git mergetool' [--tool=<tool>] [-y | --[no-]prompt] [<file>...] DESCRIPTION ----------- diff --git a/Documentation/git-push.txt b/Documentation/git-push.txt index 577d201c00..d51481394c 100644 --- a/Documentation/git-push.txt +++ b/Documentation/git-push.txt @@ -9,7 +9,7 @@ git-push - Update remote refs along with associated objects SYNOPSIS -------- [verse] -'git push' [--all | --mirror | --tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>] +'git push' [--all | --mirror | --tags] [--follow-tags] [-n | --dry-run] [--receive-pack=<git-receive-pack>] [--repo=<repository>] [-f | --force] [--prune] [-v | --verbose] [-u | --set-upstream] [<repository> [<refspec>...]] @@ -117,6 +117,12 @@ already exists on the remote side. addition to refspecs explicitly listed on the command line. +--follow-tags:: + Push all the refs that would be pushed without this option, + and also push annotated tags in `refs/tags` that are missing + from the remote but are pointing at committish that are + reachable from the refs being pushed. + --receive-pack=<git-receive-pack>:: --exec=<git-receive-pack>:: Path to the 'git-receive-pack' program on the remote @@ -156,8 +162,7 @@ useful if you write an alias or script around 'git push'. linkgit:git-pull[1] and other commands. For more information, see 'branch.<name>.merge' in linkgit:git-config[1]. ---thin:: ---no-thin:: +--[no-]thin:: These options are passed to linkgit:git-send-pack[1]. A thin transfer significantly reduces the amount of sent data when the sender and receiver share many of the same objects in common. The default is diff --git a/Documentation/git-reflog.txt b/Documentation/git-reflog.txt index fb8697ea4c..70791b9fd8 100644 --- a/Documentation/git-reflog.txt +++ b/Documentation/git-reflog.txt @@ -67,14 +67,19 @@ them. --expire=<time>:: Entries older than this time are pruned. Without the option it is taken from configuration `gc.reflogExpire`, - which in turn defaults to 90 days. + which in turn defaults to 90 days. --expire=all prunes + entries regardless of their age; --expire=never turns off + pruning of reachable entries (but see --expire-unreachable). --expire-unreachable=<time>:: Entries older than this time and not reachable from the current tip of the branch are pruned. Without the option it is taken from configuration `gc.reflogExpireUnreachable`, which in turn defaults to - 30 days. + 30 days. --expire-unreachable=all prunes unreachable + entries regardless of their age; --expire-unreachable=never + turns off early pruning of unreachable entries (but see + --expire). --all:: Instead of listing <refs> explicitly, prune all refs. diff --git a/Documentation/git-remote.txt b/Documentation/git-remote.txt index e8c396b5f9..581bb4c413 100644 --- a/Documentation/git-remote.txt +++ b/Documentation/git-remote.txt @@ -10,7 +10,7 @@ SYNOPSIS -------- [verse] 'git remote' [-v | --verbose] -'git remote add' [-t <branch>] [-m <master>] [-f] [--tags|--no-tags] [--mirror=<fetch|push>] <name> <url> +'git remote add' [-t <branch>] [-m <master>] [-f] [--[no-]tags] [--mirror=<fetch|push>] <name> <url> 'git remote rename' <old> <new> 'git remote remove' <name> 'git remote set-head' <name> (-a | -d | <branch>) @@ -18,8 +18,8 @@ SYNOPSIS 'git remote set-url' [--push] <name> <newurl> [<oldurl>] 'git remote set-url --add' [--push] <name> <newurl> 'git remote set-url --delete' [--push] <name> <url> -'git remote' [-v | --verbose] 'show' [-n] <name> -'git remote prune' [-n | --dry-run] <name> +'git remote' [-v | --verbose] 'show' [-n] <name>... +'git remote prune' [-n | --dry-run] <name>... 'git remote' [-v | --verbose] 'update' [-p | --prune] [(<group> | <remote>)...] DESCRIPTION diff --git a/Documentation/git-rev-parse.txt b/Documentation/git-rev-parse.txt index f2537bb837..947d62fd25 100644 --- a/Documentation/git-rev-parse.txt +++ b/Documentation/git-rev-parse.txt @@ -60,8 +60,19 @@ OPTIONS instead. --verify:: - The parameter given must be usable as a single, valid - object name. Otherwise barf and abort. + Verify that exactly one parameter is provided, and that it + can be turned into a raw 20-byte SHA-1 that can be used to + access the object database. If so, emit it to the standard + output; otherwise, error out. ++ +If you want to make sure that the output actually names an object in +your object database and/or can be used as a specific type of object +you require, you can add "^{type}" peeling operator to the parmeter. +For example, `git rev-parse "$VAR^{commit}"` will make sure `$VAR` +names an existing object that is a commit-ish (i.e. a commit, or an +annotated tag that points at a commit). To make sure that `$VAR` +names an existing object of any type, `git rev-parse "$VAR^{object}"` +can be used. -q:: --quiet:: @@ -308,12 +319,12 @@ $ git rev-parse --verify HEAD * Print the commit object name from the revision in the $REV shell variable: + ------------ -$ git rev-parse --verify $REV +$ git rev-parse --verify $REV^{commit} ------------ + This will error out if $REV is empty or not a valid revision. -* Same as above: +* Similar to above: + ------------ $ git rev-parse --default master --verify $REV diff --git a/Documentation/git-revert.txt b/Documentation/git-revert.txt index 70152e8b1e..f79c9d8583 100644 --- a/Documentation/git-revert.txt +++ b/Documentation/git-revert.txt @@ -8,7 +8,7 @@ git-revert - Revert some existing commits SYNOPSIS -------- [verse] -'git revert' [--edit | --no-edit] [-n] [-m parent-number] [-s] <commit>... +'git revert' [--[no-]edit] [-n] [-m parent-number] [-s] <commit>... 'git revert' --continue 'git revert' --quit 'git revert' --abort diff --git a/Documentation/git-rm.txt b/Documentation/git-rm.txt index 92bac27e05..1d876c2619 100644 --- a/Documentation/git-rm.txt +++ b/Documentation/git-rm.txt @@ -149,6 +149,10 @@ files that aren't ignored are present in the submodules work tree. Ignored files are deemed expendable and won't stop a submodule's work tree from being removed. +If you only want to remove the local checkout of a submodule from your +work tree without committing the removal, +use linkgit:git-submodule[1] `deinit` instead. + EXAMPLES -------- `git rm Documentation/\*.txt`:: diff --git a/Documentation/git-send-email.txt b/Documentation/git-send-email.txt index 44a1f7c4e8..40a9a9abc1 100644 --- a/Documentation/git-send-email.txt +++ b/Documentation/git-send-email.txt @@ -45,8 +45,9 @@ Composing ~~~~~~~~~ --annotate:: - Review and edit each patch you're about to send. See the - CONFIGURATION section for 'sendemail.multiedit'. + Review and edit each patch you're about to send. Default is the value + of 'sendemail.annotate'. See the CONFIGURATION section for + 'sendemail.multiedit'. --bcc=<address>:: Specify a "Bcc:" value for each email. Default is the value of @@ -164,8 +165,8 @@ Sending Furthermore, passwords need not be specified in configuration files or on the command line. If a username has been specified (with '--smtp-user' or a 'sendemail.smtpuser'), but no password has been -specified (with '--smtp-pass' or 'sendemail.smtppass'), then the -user is prompted for a password while the input is masked for privacy. +specified (with '--smtp-pass' or 'sendemail.smtppass'), then +a password is obtained using 'git-credential'. --smtp-server=<host>:: If set, specifies the outgoing SMTP server to use (e.g. diff --git a/Documentation/git-sh-setup.txt b/Documentation/git-sh-setup.txt index 6a9f66d1d9..5d709d02c3 100644 --- a/Documentation/git-sh-setup.txt +++ b/Documentation/git-sh-setup.txt @@ -82,6 +82,12 @@ get_author_ident_from_commit:: outputs code for use with eval to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL and GIT_AUTHOR_DATE variables for a given commit. +create_virtual_base:: + modifies the first file so only lines in common with the + second file remain. If there is insufficient common material, + then the first file is left empty. The result is suitable + as a virtual base input for a 3-way merge. + GIT --- Part of the linkgit:git[1] suite diff --git a/Documentation/git-shell.txt b/Documentation/git-shell.txt index 9b9250600f..c35051ba58 100644 --- a/Documentation/git-shell.txt +++ b/Documentation/git-shell.txt @@ -9,25 +9,81 @@ git-shell - Restricted login shell for Git-only SSH access SYNOPSIS -------- [verse] -'git shell' [-c <command> <argument>] +'chsh' -s $(command -v git-shell) <user> +'git clone' <user>`@localhost:/path/to/repo.git` +'ssh' <user>`@localhost` DESCRIPTION ----------- -A login shell for SSH accounts to provide restricted Git access. When -'-c' is given, the program executes <command> non-interactively; -<command> can be one of 'git receive-pack', 'git upload-pack', 'git -upload-archive', 'cvs server', or a command in COMMAND_DIR. The shell -is started in interactive mode when no arguments are given; in this -case, COMMAND_DIR must exist, and any of the executables in it can be -invoked. +This is a login shell for SSH accounts to provide restricted Git access. +It permits execution only of server-side Git commands implementing the +pull/push functionality, plus custom commands present in a subdirectory +named `git-shell-commands` in the user's home directory. -'cvs server' is a special command which executes git-cvsserver. +COMMANDS +-------- + +'git shell' accepts the following commands after the '-c' option: + +'git receive-pack <argument>':: +'git upload-pack <argument>':: +'git upload-archive <argument>':: + Call the corresponding server-side command to support + the client's 'git push', 'git fetch', or 'git archive --remote' + request. +'cvs server':: + Imitate a CVS server. See linkgit:git-cvsserver[1]. + +If a `~/git-shell-commands` directory is present, 'git shell' will +also handle other, custom commands by running +"`git-shell-commands/<command> <arguments>`" from the user's home +directory. + +INTERACTIVE USE +--------------- + +By default, the commands above can be executed only with the '-c' +option; the shell is not interactive. -COMMAND_DIR is the path "$HOME/git-shell-commands". The user must have -read and execute permissions to the directory in order to execute the -programs in it. The programs are executed with a cwd of $HOME, and -<argument> is parsed as a command-line string. +If a `~/git-shell-commands` directory is present, 'git shell' +can also be run interactively (with no arguments). If a `help` +command is present in the `git-shell-commands` directory, it is +run to provide the user with an overview of allowed actions. Then a +"git> " prompt is presented at which one can enter any of the +commands from the `git-shell-commands` directory, or `exit` to close +the connection. + +Generally this mode is used as an administrative interface to allow +users to list repositories they have access to, create, delete, or +rename repositories, or change repository descriptions and +permissions. + +If a `no-interactive-login` command exists, then it is run and the +interactive shell is aborted. + +EXAMPLE +------- + +To disable interactive logins, displaying a greeting instead: ++ +---------------- +$ chsh -s /usr/bin/git-shell +$ mkdir $HOME/git-shell-commands +$ cat >$HOME/git-shell-commands/no-interactive-login <<\EOF +#!/bin/sh +printf '%s\n' "Hi $USER! You've successfully authenticated, but I do not" +printf '%s\n' "provide interactive shell access." +exit 128 +EOF +$ chmod +x $HOME/git-shell-commands/no-interactive-login +---------------- + +SEE ALSO +-------- +ssh(1), +linkgit:git-daemon[1], +contrib/git-shell-commands/README GIT --- diff --git a/Documentation/git-shortlog.txt b/Documentation/git-shortlog.txt index c308e91537..31af7f2736 100644 --- a/Documentation/git-shortlog.txt +++ b/Documentation/git-shortlog.txt @@ -8,8 +8,8 @@ git-shortlog - Summarize 'git log' output SYNOPSIS -------- [verse] -git log --pretty=short | 'git shortlog' [-h] [-n] [-s] [-e] [-w] -'git shortlog' [-n|--numbered] [-s|--summary] [-e|--email] [-w[<width>[,<indent1>[,<indent2>]]]] <commit>... +git log --pretty=short | 'git shortlog' [<options>] +'git shortlog' [<options>] [<revision range>] [[\--] <path>...] DESCRIPTION ----------- @@ -26,10 +26,6 @@ reference to the current repository. OPTIONS ------- --h:: ---help:: - Print a short usage message and exit. - -n:: --numbered:: Sort output according to the number of commits per author instead @@ -60,6 +56,21 @@ OPTIONS If width is `0` (zero) then indent the lines of the output without wrapping them. +<revision range>:: + Show only commits in the specified revision range. When no + <revision range> is specified, it defaults to `HEAD` (i.e. the + whole history leading to the current commit). `origin..HEAD` + specifies all the commits reachable from the current commit + (i.e. `HEAD`), but not from `origin`. For a complete list of + ways to spell <revision range>, see the "Specifying Ranges" + section of linkgit:gitrevisions[7]. + +[\--] <path>...:: + Consider only commits that are enough to explain how the files + that match the specified paths came to be. ++ +Paths may need to be prefixed with "\-- " to separate them from +options or the revision range, when confusion arises. MAPPING AUTHORS --------------- diff --git a/Documentation/git-submodule.txt b/Documentation/git-submodule.txt index c99d795618..e5767134b1 100644 --- a/Documentation/git-submodule.txt +++ b/Documentation/git-submodule.txt @@ -13,6 +13,7 @@ SYNOPSIS [--reference <repository>] [--] <repository> [<path>] 'git submodule' [--quiet] status [--cached] [--recursive] [--] [<path>...] 'git submodule' [--quiet] init [--] [<path>...] +'git submodule' [--quiet] deinit [-f|--force] [--] <path>... 'git submodule' [--quiet] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] @@ -76,6 +77,8 @@ argument <path> is the relative location for the cloned submodule to exist in the superproject. If <path> is not given, the "humanish" part of the source repository is used ("repo" for "/path/to/repo.git" and "foo" for "host.xz:foo/.git"). +The <path> is also used as the submodule's logical name in its +configuration entries unless `--name` is used to specify a logical name. + <repository> is the URL of the new submodule's origin repository. This may be either an absolute URL, or (if it begins with ./ @@ -123,8 +126,10 @@ linkgit:git-status[1] and linkgit:git-diff[1] will provide that information too (and can also report changes to a submodule's work tree). init:: - Initialize the submodules, i.e. register each submodule name - and url found in .gitmodules into .git/config. + Initialize the submodules recorded in the index (which were + added and committed elsewhere) by copying submodule + names and urls from .gitmodules to .git/config. + Optional <path> arguments limit which submodules will be initialized. It will also copy the value of `submodule.$name.update` into .git/config. The key used in .git/config is `submodule.$name.url`. @@ -135,6 +140,19 @@ init:: the explicit 'init' step if you do not intend to customize any submodule locations. +deinit:: + Unregister the given submodules, i.e. remove the whole + `submodule.$name` section from .git/config together with their work + 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 + 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. + update:: Update the registered submodules, i.e. clone missing submodules and checkout the commit specified in the index of the containing repository. @@ -214,8 +232,10 @@ OPTIONS -f:: --force:: - This option is only valid for add and update commands. + 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 update, throw away local changes in submodules when switching to a different commit; and always run a checkout operation in the submodule, even if the commit listed in the index of the diff --git a/Documentation/git-svn.txt b/Documentation/git-svn.txt index 7706d41c87..aad452f169 100644 --- a/Documentation/git-svn.txt +++ b/Documentation/git-svn.txt @@ -85,6 +85,10 @@ COMMANDS When passed to 'init' or 'clone' this regular expression will be preserved as a config key. See 'fetch' for a description of '--ignore-paths'. +--include-paths=<regex>;; + When passed to 'init' or 'clone' this regular expression will + be preserved as a config key. See 'fetch' for a description + of '--include-paths'. --no-minimize-url;; When tracking multiple directories (using --stdlayout, --branches, or --tags options), git svn will attempt to connect @@ -146,6 +150,14 @@ Skip "branches" and "tags" of first level directories;; ------------------------------------------------------------------------ -- +--include-paths=<regex>;; + This allows one to specify a Perl regular expression that will + cause the inclusion of only matching paths from checkout from SVN. + The '--include-paths' option should match for every 'fetch' + (including automatic fetches due to 'clone', 'dcommit', + 'rebase', etc) on a given repository. '--ignore-paths' takes + precedence over '--include-paths'. + --log-window-size=<n>;; Fetch <n> log entries per request when scanning Subversion history. The default is 100. For very large Subversion repositories, larger @@ -259,13 +271,15 @@ first have already been pushed into SVN. Create a tag by using the tags_subdir instead of the branches_subdir specified during git svn init. --d;; ---destination;; +-d<path>;; +--destination=<path>;; + If more than one --branches (or --tags) option was given to the 'init' or 'clone' command, you must provide the location of the branch (or - tag) you wish to create in the SVN repository. The value of this - option must match one of the paths specified by a --branches (or - --tags) option. You can see these paths with the commands + tag) you wish to create in the SVN repository. <path> specifies which + path to use to create the branch or tag and should match the pattern + on the left-hand side of one of the configured branches or tags + refspecs. You can see these refspecs with the commands + git config --get-all svn-remote.<name>.branches git config --get-all svn-remote.<name>.tags @@ -286,6 +300,11 @@ where <name> is the name of the SVN repository as specified by the -R option to git config --get-all svn-remote.<name>.commiturl + +--parents;; + Create parent folders. This parameter is equivalent to the parameter + --parents on svn cp commands and is useful for non-standard repository + layouts. + 'tag':: Create a tag in the SVN repository. This is a shorthand for 'branch -t'. @@ -1020,6 +1039,25 @@ comma-separated list of names within braces. For example: tags = tags/{1.0,2.0}/src:refs/remotes/tags/* ------------------------------------------------------------------------ +Multiple fetch, branches, and tags keys are supported: + +------------------------------------------------------------------------ +[svn-remote "messy-repo"] + url = http://server.org/svn + fetch = trunk/project-a:refs/remotes/project-a/trunk + fetch = branches/demos/june-project-a-demo:refs/remotes/project-a/demos/june-demo + branches = branches/server/*:refs/remotes/project-a/branches/* + branches = branches/demos/2011/*:refs/remotes/project-a/2011-demos/* + tags = tags/server/*:refs/remotes/project-a/tags/* +------------------------------------------------------------------------ + +Creating a branch in such a configuration requires disambiguating which +location to use using the -d or --destination flag: + +------------------------------------------------------------------------ +$ git svn branch -d branches/server release-2-3-0 +------------------------------------------------------------------------ + Note that git-svn keeps track of the highest revision in which a branch or tag has appeared. If the subset of branches or tags is changed after fetching, then .git/svn/.metadata must be manually edited to remove (or diff --git a/Documentation/git-update-index.txt b/Documentation/git-update-index.txt index 670e9fb2c2..e0a87029cd 100644 --- a/Documentation/git-update-index.txt +++ b/Documentation/git-update-index.txt @@ -14,8 +14,8 @@ SYNOPSIS [--refresh] [-q] [--unmerged] [--ignore-missing] [(--cacheinfo <mode> <object> <file>)...] [--chmod=(+|-)x] - [--assume-unchanged | --no-assume-unchanged] - [--skip-worktree | --no-skip-worktree] + [--[no-]assume-unchanged] + [--[no-]skip-worktree] [--ignore-submodules] [--really-refresh] [--unresolve] [--again | -g] [--info-only] [--index-info] @@ -77,8 +77,7 @@ OPTIONS --chmod=(+|-)x:: Set the execute permissions on the updated files. ---assume-unchanged:: ---no-assume-unchanged:: +--[no-]assume-unchanged:: When these flags are specified, the object names recorded for the paths are not updated. Instead, these options set and unset the "assume unchanged" bit for the @@ -102,8 +101,7 @@ you will need to handle the situation manually. Like '--refresh', but checks stat information unconditionally, without regard to the "assume unchanged" setting. ---skip-worktree:: ---no-skip-worktree:: +--[no-]skip-worktree:: When one of these flags is specified, the object name recorded for the paths are not updated. Instead, these options set and unset the "skip-worktree" bit for the paths. See diff --git a/Documentation/git.txt b/Documentation/git.txt index 8438c076c3..65de534e43 100644 --- a/Documentation/git.txt +++ b/Documentation/git.txt @@ -43,9 +43,10 @@ unreleased) version of Git, that is available from 'master' branch of the `git.git` repository. Documentation for older releases are available here: -* link:v1.8.2.2/git.html[documentation for release 1.8.2.2] +* link:v1.8.2.3/git.html[documentation for release 1.8.2.3] * release notes for + link:RelNotes/1.8.2.3.txt[1.8.2.3]. link:RelNotes/1.8.2.2.txt[1.8.2.2]. link:RelNotes/1.8.2.1.txt[1.8.2.1]. link:RelNotes/1.8.2.txt[1.8.2]. @@ -810,8 +811,9 @@ for further details. 'GIT_FLUSH':: If this environment variable is set to "1", then commands such as 'git blame' (in incremental mode), 'git rev-list', 'git log', - and 'git whatchanged' will force a flush of the output stream - after each commit-oriented record have been flushed. If this + 'git check-attr', 'git check-ignore', and 'git whatchanged' will + force a flush of the output stream after each record have been + flushed. If this variable is set to "0", the output of these commands will be done using completely buffered I/O. If this environment variable is not set, Git will choose buffered or record-oriented flushing diff --git a/Documentation/gitremote-helpers.txt b/Documentation/gitremote-helpers.txt index 0c91aba861..0827f69139 100644 --- a/Documentation/gitremote-helpers.txt +++ b/Documentation/gitremote-helpers.txt @@ -159,11 +159,11 @@ Miscellaneous capabilities carried out. 'refspec' <refspec>:: - This modifies the 'import' capability, allowing the produced - fast-import stream to modify refs in a private namespace - instead of writing to refs/heads or refs/remotes directly. + For remote helpers that implement 'import' or 'export', this capability + allows the refs to be constrained to a private namespace, instead of + writing to refs/heads or refs/remotes directly. It is recommended that all importers providing the 'import' - capability use this. + capability use this. It's mandatory for 'export'. + A helper advertising the capability `refspec refs/heads/*:refs/svn/origin/branches/*` @@ -202,6 +202,10 @@ there is an implied `refspec *:*`. marks specified in <file> before processing any input. For details, read up on '--import-marks=<file>' in linkgit:git-fast-export[1]. +'signed-tags':: + This modifies the 'export' capability, instructing Git to pass + '--signed-tags=verbatim' to linkgit:git-fast-export[1]. In the + absence of this capability, Git will use '--signed-tags=warn-strip'. diff --git a/Documentation/gitrepository-layout.txt b/Documentation/gitrepository-layout.txt index 2ad09f4baf..d6f3393c5f 100644 --- a/Documentation/gitrepository-layout.txt +++ b/Documentation/gitrepository-layout.txt @@ -184,6 +184,10 @@ info/exclude:: 'git clean' look at it but the core Git commands do not look at it. See also: linkgit:gitignore[5]. +info/sparse-checkout:: + This file stores sparse checkout patterns. + See also: linkgit:git-read-tree[1]. + remotes:: Stores shorthands for URL and default refnames for use when interacting with remote repositories via 'git fetch', diff --git a/Documentation/glossary-content.txt b/Documentation/glossary-content.txt index ce3e4fae73..db2a74df93 100644 --- a/Documentation/glossary-content.txt +++ b/Documentation/glossary-content.txt @@ -400,12 +400,13 @@ should not be combined with other pathspec. <<def_ref,ref>> and local ref. [[def_remote_tracking_branch]]remote-tracking branch:: - A regular Git <<def_branch,branch>> that is used to follow changes from - another <<def_repository,repository>>. A remote-tracking - branch should not contain direct modifications or have local commits - made to it. A remote-tracking branch can usually be - identified as the right-hand-side <<def_ref,ref>> in a Pull: - <<def_refspec,refspec>>. + A <<def_ref,ref>> that is used to follow changes from another + <<def_repository,repository>>. It typically looks like + 'refs/remotes/foo/bar' (indicating that it tracks a branch named + 'bar' in a remote named 'foo'), and matches the right-hand-side of + a configured fetch <<def_refspec,refspec>>. A remote-tracking + branch should not contain direct modifications or have local + commits made to it. [[def_repository]]repository:: A collection of <<def_ref,refs>> together with an @@ -420,9 +421,7 @@ should not be combined with other pathspec. <<def_merge,merge>> left behind. [[def_revision]]revision:: - A particular state of files and directories which was stored in the - <<def_object_database,object database>>. It is referenced by a - <<def_commit_object,commit object>>. + Synonym for <<def_commit,commit>> (the noun). [[def_rewind]]rewind:: To throw away part of the development, i.e. to assign the diff --git a/Documentation/merge-options.txt b/Documentation/merge-options.txt index 34a8445828..2adccf8fec 100644 --- a/Documentation/merge-options.txt +++ b/Documentation/merge-options.txt @@ -84,6 +84,11 @@ option can be used to override --squash. Pass merge strategy specific option through to the merge strategy. +--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. + --summary:: --no-summary:: Synonyms to --stat and --no-stat; these are deprecated and will be diff --git a/Documentation/pretty-formats.txt b/Documentation/pretty-formats.txt index 342965d4f6..1d174fd0b6 100644 --- a/Documentation/pretty-formats.txt +++ b/Documentation/pretty-formats.txt @@ -106,18 +106,22 @@ The placeholders are: - '%P': parent hashes - '%p': abbreviated parent hashes - '%an': author name -- '%aN': author name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%aN': author name (respecting .mailmap, see linkgit:git-shortlog[1] + or linkgit:git-blame[1]) - '%ae': author email -- '%aE': author email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%aE': author email (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) - '%ad': author date (format respects --date= option) - '%aD': author date, RFC2822 style - '%ar': author date, relative - '%at': author date, UNIX timestamp - '%ai': author date, ISO 8601 format - '%cn': committer name -- '%cN': committer name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%cN': committer name (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) - '%ce': committer email -- '%cE': committer email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%cE': committer email (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) - '%cd': committer date - '%cD': committer date, RFC2822 style - '%cr': committer date, relative @@ -131,15 +135,18 @@ The placeholders are: - '%B': raw body (unwrapped subject and body) - '%N': commit notes - '%GG': raw verification message from GPG for a signed commit -- '%G?': show either "G" for Good or "B" for Bad 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 - '%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}` - '%gd': shortened reflog selector, e.g., `stash@{1}` - '%gn': reflog identity name -- '%gN': reflog identity name (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%gN': reflog identity name (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) - '%ge': reflog identity email -- '%gE': reflog identity email (respecting .mailmap, see linkgit:git-shortlog[1] or linkgit:git-blame[1]) +- '%gE': reflog identity email (respecting .mailmap, see + linkgit:git-shortlog[1] or linkgit:git-blame[1]) - '%gs': reflog subject - '%Cred': switch color to red - '%Cgreen': switch color to green @@ -149,13 +156,28 @@ The placeholders are: adding `auto,` at the beginning will emit color only when colors are enabled for log output (by `color.diff`, `color.ui`, or `--color`, and respecting the `auto` settings of the former if we are going to a - terminal) + terminal). `auto` alone (i.e. `%C(auto)`) will turn on auto coloring + on the next placeholders until the color is switched again. - '%m': left, right or boundary mark - '%n': newline - '%%': a raw '%' - '%x00': print a byte from a hex code - '%w([<w>[,<i1>[,<i2>]]])': switch line wrapping, like the -w option of linkgit:git-shortlog[1]. +- '%<(<N>[,trunc|ltrunc|mtrunc])': make the next placeholder take at + least N columns, padding spaces on the right if necessary. + Optionally truncate at the beginning (ltrunc), the middle (mtrunc) + or the end (trunc) if the output is longer than N columns. + Note that truncating only works correctly with N >= 2. +- '%<|(<N>)': make the next placeholder take at least until Nth + columns, padding spaces on the right if necessary +- '%>(<N>)', '%>|(<N>)': similar to '%<(<N>)', '%<|(<N>)' + respectively, but padding spaces on the left +- '%>>(<N>)', '%>>|(<N>)': similar to '%>(<N>)', '%>|(<N>)' + respectively, except that if the next placeholder takes more spaces + than given and there are spaces on its left, use those spaces +- '%><(<N>)', '%><|(<N>)': similar to '% <(<N>)', '%<|(<N>)' + respectively, but padding both sides (i.e. the text is centered) NOTE: Some placeholders may depend on other options given to the revision traversal engine. For example, the `%g*` reflog options will diff --git a/Documentation/revisions.txt b/Documentation/revisions.txt index c5822634fc..d477b3f6bc 100644 --- a/Documentation/revisions.txt +++ b/Documentation/revisions.txt @@ -116,6 +116,11 @@ some output processing may assume ref names in UTF-8. object of that type is found or the object cannot be dereferenced anymore (in which case, barf). '<rev>{caret}0' is a short-hand for '<rev>{caret}\{commit\}'. ++ +'rev{caret}\{object\}' can be used to make sure 'rev' names an +object that exists, without requiring 'rev' to be a tag, and +without dereferencing 'rev'; because a tag is already an object, +it does not have to be dereferenced even once to get to an object. '<rev>{caret}\{\}', e.g. 'v0.99.8{caret}\{\}':: A suffix '{caret}' followed by an empty brace pair @@ -239,11 +244,13 @@ To summarize: '<rev1>..<rev2>':: Include commits that are reachable from <rev2> but exclude - those that are reachable from <rev1>. + those that are reachable from <rev1>. When either <rev1> or + <rev2> is omitted, it defaults to 'HEAD'. '<rev1>\...<rev2>':: Include commits that are reachable from either <rev1> or - <rev2> but exclude those that are reachable from both. + <rev2> but exclude those that are reachable from both. When + either <rev1> or <rev2> is omitted, it defaults to 'HEAD'. '<rev>{caret}@', e.g. 'HEAD{caret}@':: A suffix '{caret}' followed by an at sign is the same as listing diff --git a/Documentation/technical/api-directory-listing.txt b/Documentation/technical/api-directory-listing.txt index 1f349b28ae..7f8e78d916 100644 --- a/Documentation/technical/api-directory-listing.txt +++ b/Documentation/technical/api-directory-listing.txt @@ -22,12 +22,23 @@ The notable options are: `flags`:: - A bit-field of options: + A bit-field of options (the `*IGNORED*` flags are mutually exclusive): `DIR_SHOW_IGNORED`::: - The traversal is for finding just ignored files, not unignored - files. + Return just ignored files in `entries[]`, not untracked files. + +`DIR_SHOW_IGNORED_TOO`::: + + Similar to `DIR_SHOW_IGNORED`, but return ignored files in `ignored[]` + in addition to untracked files in `entries[]`. + +`DIR_COLLECT_IGNORED`::: + + Special mode for git-add. Return ignored files in `ignored[]` and + untracked files in `entries[]`. Only returns ignored files that match + pathspec exactly (no wildcards). Does not recurse into ignored + directories. `DIR_SHOW_OTHER_DIRECTORIES`::: @@ -57,6 +68,14 @@ The result of the enumeration is left in these fields: Internal use; keeps track of allocation of `entries[]` array. +`ignored[]`:: + + An array of `struct dir_entry`, used for ignored paths with the + `DIR_SHOW_IGNORED_TOO` and `DIR_COLLECT_IGNORED` flags. + +`ignored_nr`:: + + The number of members in `ignored[]` array. Calling sequence ---------------- diff --git a/Documentation/technical/api-parse-options.txt b/Documentation/technical/api-parse-options.txt index 32ddc1cf13..1317db4d6c 100644 --- a/Documentation/technical/api-parse-options.txt +++ b/Documentation/technical/api-parse-options.txt @@ -41,6 +41,8 @@ The parse-options API allows: * Boolean long options can be 'negated' (or 'unset') by prepending `no-`, e.g. `--no-abbrev` instead of `--abbrev`. Conversely, options that begin with `no-` can be 'negated' by removing it. + Other long options can be unset (e.g., set string to NULL, set + integer to 0) by prepending `no-`. * Options and non-option arguments can clearly be separated using the `--` option, e.g. `-a -b --option -- --this-is-a-file` indicates that @@ -174,6 +176,10 @@ There are some macros to easily define options: Introduce an option with date argument, see `approxidate()`. The timestamp is put into `int_var`. +`OPT_EXPIRY_DATE(short, long, &int_var, description)`:: + Introduce an option with expiry date argument, see `parse_expiry_date()`. + The timestamp is put into `int_var`. + `OPT_CALLBACK(short, long, &var, arg_str, description, func_ptr)`:: Introduce an option with argument. The argument will be fed into the function given by `func_ptr` diff --git a/Documentation/technical/api-strbuf.txt b/Documentation/technical/api-strbuf.txt index 2c59cb2259..3350d97dda 100644 --- a/Documentation/technical/api-strbuf.txt +++ b/Documentation/technical/api-strbuf.txt @@ -230,6 +230,11 @@ which can be used by the programmer of the callback as she sees fit. destination. This is useful for literal data to be fed to either strbuf_expand or to the *printf family of functions. +`strbuf_humanise_bytes`:: + + Append the given byte size as a human-readable string (i.e. 12.23 KiB, + 3.50 MiB). + `strbuf_addf`:: Add a formatted string to the buffer. diff --git a/Documentation/technical/pack-protocol.txt b/Documentation/technical/pack-protocol.txt index f1a51edf47..b898e97988 100644 --- a/Documentation/technical/pack-protocol.txt +++ b/Documentation/technical/pack-protocol.txt @@ -228,8 +228,7 @@ obtained through ref discovery. The client MUST write all obj-ids which it only has shallow copies of (meaning that it does not have the parents of a commit) as 'shallow' lines so that the server is aware of the limitations of -the client's history. Clients MUST NOT mention an obj-id which -it does not know exists on the server. +the client's history. The client now sends the maximum commit history depth it wants for this transaction, which is the number of commits it wants from the diff --git a/GIT-VERSION-GEN b/GIT-VERSION-GEN index 7186e774a8..aa87dbfd53 100755 --- a/GIT-VERSION-GEN +++ b/GIT-VERSION-GEN @@ -1,7 +1,7 @@ #!/bin/sh GVF=GIT-VERSION-FILE -DEF_VER=v1.8.2.2 +DEF_VER=v1.8.3-rc3 LF=' ' @@ -358,33 +358,39 @@ STRIP ?= strip # Among the variables below, these: # gitexecdir # template_dir -# mandir -# infodir -# htmldir # sysconfdir # can be specified as a relative path some/where/else; # this is interpreted as relative to $(prefix) and "git" at # runtime figures out where they are based on the path to the executable. +# Additionally, the following will be treated as relative by "git" if they +# begin with "$(prefix)/": +# mandir +# infodir +# htmldir # This can help installing the suite in a relocatable way. prefix = $(HOME) bindir_relative = bin bindir = $(prefix)/$(bindir_relative) -mandir = share/man -infodir = share/info +mandir = $(prefix)/share/man +infodir = $(prefix)/share/info gitexecdir = libexec/git-core mergetoolsdir = $(gitexecdir)/mergetools sharedir = $(prefix)/share gitwebdir = $(sharedir)/gitweb localedir = $(sharedir)/locale template_dir = share/git-core/templates -htmldir = share/doc/git-doc +htmldir = $(prefix)/share/doc/git-doc ETC_GITCONFIG = $(sysconfdir)/gitconfig ETC_GITATTRIBUTES = $(sysconfdir)/gitattributes lib = lib # DESTDIR = pathsep = : +mandir_relative = $(patsubst $(prefix)/%,%,$(mandir)) +infodir_relative = $(patsubst $(prefix)/%,%,$(infodir)) +htmldir_relative = $(patsubst $(prefix)/%,%,$(htmldir)) + export prefix bindir sharedir sysconfdir gitwebdir localedir CC = cc @@ -454,6 +460,7 @@ SCRIPT_SH += git-mergetool.sh SCRIPT_SH += git-pull.sh SCRIPT_SH += git-quiltimport.sh SCRIPT_SH += git-rebase.sh +SCRIPT_SH += git-remote-testgit.sh SCRIPT_SH += git-repack.sh SCRIPT_SH += git-request-pull.sh SCRIPT_SH += git-stash.sh @@ -678,7 +685,6 @@ LIB_H += notes-cache.h LIB_H += notes-merge.h LIB_H += notes.h LIB_H += object.h -LIB_H += pack-refs.h LIB_H += pack-revindex.h LIB_H += pack.h LIB_H += parse-options.h @@ -811,7 +817,6 @@ LIB_OBJS += notes-cache.o LIB_OBJS += notes-merge.o LIB_OBJS += object.o LIB_OBJS += pack-check.o -LIB_OBJS += pack-refs.o LIB_OBJS += pack-revindex.o LIB_OBJS += pack-write.o LIB_OBJS += pager.o @@ -1539,12 +1544,12 @@ ETC_GITATTRIBUTES_SQ = $(subst ','\'',$(ETC_GITATTRIBUTES)) DESTDIR_SQ = $(subst ','\'',$(DESTDIR)) bindir_SQ = $(subst ','\'',$(bindir)) bindir_relative_SQ = $(subst ','\'',$(bindir_relative)) -mandir_SQ = $(subst ','\'',$(mandir)) -infodir_SQ = $(subst ','\'',$(infodir)) +mandir_relative_SQ = $(subst ','\'',$(mandir_relative)) +infodir_relative_SQ = $(subst ','\'',$(infodir_relative)) localedir_SQ = $(subst ','\'',$(localedir)) gitexecdir_SQ = $(subst ','\'',$(gitexecdir)) template_dir_SQ = $(subst ','\'',$(template_dir)) -htmldir_SQ = $(subst ','\'',$(htmldir)) +htmldir_relative_SQ = $(subst ','\'',$(htmldir_relative)) prefix_SQ = $(subst ','\'',$(prefix)) gitwebdir_SQ = $(subst ','\'',$(gitwebdir)) @@ -1676,9 +1681,9 @@ strip: $(PROGRAMS) git$X git.sp git.s git.o: GIT-PREFIX git.sp git.s git.o: EXTRA_CPPFLAGS = \ - '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ - '-DGIT_MAN_PATH="$(mandir_SQ)"' \ - '-DGIT_INFO_PATH="$(infodir_SQ)"' + '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ + '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \ + '-DGIT_INFO_PATH="$(infodir_relative_SQ)"' git$X: git.o GIT-LDFLAGS $(BUILTIN_OBJS) $(GITLIBS) $(QUIET_LINK)$(CC) $(ALL_CFLAGS) -o $@ git.o \ @@ -1688,9 +1693,9 @@ help.sp help.s help.o: common-cmds.h builtin/help.sp builtin/help.s builtin/help.o: common-cmds.h GIT-PREFIX builtin/help.sp builtin/help.s builtin/help.o: EXTRA_CPPFLAGS = \ - '-DGIT_HTML_PATH="$(htmldir_SQ)"' \ - '-DGIT_MAN_PATH="$(mandir_SQ)"' \ - '-DGIT_INFO_PATH="$(infodir_SQ)"' + '-DGIT_HTML_PATH="$(htmldir_relative_SQ)"' \ + '-DGIT_MAN_PATH="$(mandir_relative_SQ)"' \ + '-DGIT_INFO_PATH="$(infodir_relative_SQ)"' version.sp version.s version.o: GIT-VERSION-FILE GIT-USER-AGENT version.sp version.s version.o: EXTRA_CPPFLAGS = \ @@ -1998,6 +2003,7 @@ endif ifdef USE_NED_ALLOCATOR compat/nedmalloc/nedmalloc.sp compat/nedmalloc/nedmalloc.o: EXTRA_CPPFLAGS = \ -DNDEBUG -DOVERRIDE_STRDUP -DREPLACE_SYSTEM_ALLOCATOR +compat/nedmalloc/nedmalloc.sp: SPARSE_FLAGS += -Wno-non-pointer-null endif git-%$X: %.o GIT-LDFLAGS $(GITLIBS) @@ -2153,6 +2159,9 @@ GIT-BUILD-OPTIONS: FORCE @echo NO_PERL=\''$(subst ','\'',$(subst ','\'',$(NO_PERL)))'\' >>$@ @echo NO_PYTHON=\''$(subst ','\'',$(subst ','\'',$(NO_PYTHON)))'\' >>$@ @echo NO_UNIX_SOCKETS=\''$(subst ','\'',$(subst ','\'',$(NO_UNIX_SOCKETS)))'\' >>$@ +ifdef TEST_OUTPUT_DIRECTORY + @echo TEST_OUTPUT_DIRECTORY=\''$(subst ','\'',$(subst ','\'',$(TEST_OUTPUT_DIRECTORY)))'\' >>$@ +endif ifdef GIT_TEST_OPTS @echo GIT_TEST_OPTS=\''$(subst ','\'',$(subst ','\'',$(GIT_TEST_OPTS)))'\' >>$@ endif @@ -1 +1 @@ -Documentation/RelNotes/1.8.2.2.txt
\ No newline at end of file +Documentation/RelNotes/1.8.3.txt
\ No newline at end of file @@ -13,6 +13,7 @@ int advice_commit_before_merge = 1; int advice_resolve_conflict = 1; int advice_implicit_identity = 1; int advice_detached_head = 1; +int advice_set_upstream_failure = 1; static struct { const char *name; @@ -31,6 +32,7 @@ static struct { { "resolveconflict", &advice_resolve_conflict }, { "implicitidentity", &advice_implicit_identity }, { "detachedhead", &advice_detached_head }, + { "setupstreamfailure", &advice_set_upstream_failure }, /* make this an alias for backward compatibility */ { "pushnonfastforward", &advice_push_update_rejected } @@ -16,6 +16,7 @@ extern int advice_commit_before_merge; extern int advice_resolve_conflict; extern int advice_implicit_identity; extern int advice_detached_head; +extern int advice_set_upstream_failure; int git_default_advice_config(const char *var, const char *value); void advise(const char *advice, ...); diff --git a/archive-zip.c b/archive-zip.c index a8d119305f..b2c4fe0e9f 100644 --- a/archive-zip.c +++ b/archive-zip.c @@ -111,8 +111,9 @@ static void copy_le32(unsigned char *dest, unsigned int n) dest[3] = 0xff & (n >> 030); } -static void *zlib_deflate(void *data, unsigned long size, - int compression_level, unsigned long *compressed_size) +static void *zlib_deflate_raw(void *data, unsigned long size, + int compression_level, + unsigned long *compressed_size) { git_zstream stream; unsigned long maxsize; @@ -120,7 +121,7 @@ static void *zlib_deflate(void *data, unsigned long size, int result; memset(&stream, 0, sizeof(stream)); - git_deflate_init(&stream, compression_level); + git_deflate_init_raw(&stream, compression_level); maxsize = git_deflate_bound(&stream, size); buffer = xmalloc(maxsize); @@ -265,14 +266,11 @@ static int write_zip_entry(struct archiver_args *args, } if (buffer && method == 8) { - deflated = zlib_deflate(buffer, size, args->compression_level, - &compressed_size); - if (deflated && compressed_size - 6 < size) { - /* ZLIB --> raw compressed data (see RFC 1950) */ - /* CMF and FLG ... */ - out = (unsigned char *)deflated + 2; - compressed_size -= 6; /* ... and ADLER32 */ - } else { + out = deflated = zlib_deflate_raw(buffer, size, + args->compression_level, + &compressed_size); + if (!out || compressed_size >= size) { + out = buffer; method = 0; compressed_size = size; } @@ -353,7 +351,7 @@ static int write_zip_entry(struct archiver_args *args, unsigned char compressed[STREAM_BUFFER_SIZE * 2]; memset(&zstream, 0, sizeof(zstream)); - git_deflate_init(&zstream, args->compression_level); + git_deflate_init_raw(&zstream, args->compression_level); compressed_size = 0; zstream.next_out = compressed; @@ -370,13 +368,10 @@ static int write_zip_entry(struct archiver_args *args, result = git_deflate(&zstream, 0); if (result != Z_OK) die("deflate error (%d)", result); - out = compressed; - if (!compressed_size) - out += 2; - out_len = zstream.next_out - out; + out_len = zstream.next_out - compressed; if (out_len > 0) { - write_or_die(1, out, out_len); + write_or_die(1, compressed, out_len); compressed_size += out_len; zstream.next_out = compressed; zstream.avail_out = sizeof(compressed); @@ -394,11 +389,8 @@ static int write_zip_entry(struct archiver_args *args, die("deflate error (%d)", result); git_deflate_end(&zstream); - out = compressed; - if (!compressed_size) - out += 2; - out_len = zstream.next_out - out - 4; - write_or_die(1, out, out_len); + out_len = zstream.next_out - compressed; + write_or_die(1, compressed, out_len); compressed_size += out_len; zip_offset += compressed_size; @@ -381,46 +381,13 @@ static struct attr_stack *read_attr_from_file(const char *path, int macro_ok) return res; } -static void *read_index_data(const char *path) -{ - int pos, len; - unsigned long sz; - enum object_type type; - void *data; - struct index_state *istate = use_index ? use_index : &the_index; - - len = strlen(path); - pos = index_name_pos(istate, path, len); - if (pos < 0) { - /* - * We might be in the middle of a merge, in which - * case we would read stage #2 (ours). - */ - int i; - for (i = -pos - 1; - (pos < 0 && i < istate->cache_nr && - !strcmp(istate->cache[i]->name, path)); - i++) - if (ce_stage(istate->cache[i]) == 2) - pos = i; - } - if (pos < 0) - return NULL; - data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz); - if (!data || type != OBJ_BLOB) { - free(data); - return NULL; - } - return data; -} - static struct attr_stack *read_attr_from_index(const char *path, int macro_ok) { struct attr_stack *res; char *buf, *sp; int lineno = 0; - buf = read_index_data(path); + buf = read_blob_data_from_index(use_index ? use_index : &the_index, path, NULL); if (!buf) return NULL; @@ -57,7 +57,7 @@ void install_branch_config(int flag, const char *local, const char *origin, cons if (remote_is_branch && !strcmp(local, shortname) && !origin) { - warning("Not setting branch %s as its own upstream.", + warning(_("Not setting branch %s as its own upstream."), local); return; } @@ -78,25 +78,25 @@ void install_branch_config(int flag, const char *local, const char *origin, cons if (flag & BRANCH_CONFIG_VERBOSE) { if (remote_is_branch && origin) - printf(rebasing ? - "Branch %s set up to track remote branch %s from %s by rebasing.\n" : - "Branch %s set up to track remote branch %s from %s.\n", - local, shortname, origin); + printf_ln(rebasing ? + _("Branch %s set up to track remote branch %s from %s by rebasing.") : + _("Branch %s set up to track remote branch %s from %s."), + local, shortname, origin); else if (remote_is_branch && !origin) - printf(rebasing ? - "Branch %s set up to track local branch %s by rebasing.\n" : - "Branch %s set up to track local branch %s.\n", - local, shortname); + printf_ln(rebasing ? + _("Branch %s set up to track local branch %s by rebasing.") : + _("Branch %s set up to track local branch %s."), + local, shortname); else if (!remote_is_branch && origin) - printf(rebasing ? - "Branch %s set up to track remote ref %s by rebasing.\n" : - "Branch %s set up to track remote ref %s.\n", - local, remote); + printf_ln(rebasing ? + _("Branch %s set up to track remote ref %s by rebasing.") : + _("Branch %s set up to track remote ref %s."), + local, remote); else if (!remote_is_branch && !origin) - printf(rebasing ? - "Branch %s set up to track local ref %s by rebasing.\n" : - "Branch %s set up to track local ref %s.\n", - local, remote); + printf_ln(rebasing ? + _("Branch %s set up to track local ref %s by rebasing.") : + _("Branch %s set up to track local ref %s."), + local, remote); else die("BUG: impossible combination of %d and %p", remote_is_branch, origin); @@ -115,7 +115,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref, int config_flags = quiet ? 0 : BRANCH_CONFIG_VERBOSE; if (strlen(new_ref) > 1024 - 7 - 7 - 1) - return error("Tracking not set up: name too long: %s", + return error(_("Tracking not set up: name too long: %s"), new_ref); memset(&tracking, 0, sizeof(tracking)); @@ -134,7 +134,7 @@ static int setup_tracking(const char *new_ref, const char *orig_ref, } if (tracking.matches > 1) - return error("Not tracking: ambiguous information for ref %s", + return error(_("Not tracking: ambiguous information for ref %s"), orig_ref); install_branch_config(config_flags, new_ref, tracking.remote, @@ -179,12 +179,12 @@ int validate_new_branchname(const char *name, struct strbuf *ref, int force, int attr_only) { if (strbuf_check_branch_ref(ref, name)) - die("'%s' is not a valid branch name.", name); + die(_("'%s' is not a valid branch name."), name); if (!ref_exists(ref->buf)) return 0; else if (!force && !attr_only) - die("A branch named '%s' already exists.", ref->buf + strlen("refs/heads/")); + die(_("A branch named '%s' already exists."), ref->buf + strlen("refs/heads/")); if (!attr_only) { const char *head; @@ -192,11 +192,40 @@ int validate_new_branchname(const char *name, struct strbuf *ref, head = resolve_ref_unsafe("HEAD", sha1, 0, NULL); if (!is_bare_repository() && head && !strcmp(head, ref->buf)) - die("Cannot force update the current branch."); + die(_("Cannot force update the current branch.")); } return 1; } +static int check_tracking_branch(struct remote *remote, void *cb_data) +{ + char *tracking_branch = cb_data; + struct refspec query; + memset(&query, 0, sizeof(struct refspec)); + query.dst = tracking_branch; + return !(remote_find_tracking(remote, &query) || + prefixcmp(query.src, "refs/heads/")); +} + +static int validate_remote_tracking_branch(char *ref) +{ + return !for_each_remote(check_tracking_branch, ref); +} + +static const char upstream_not_branch[] = +N_("Cannot setup tracking information; starting point '%s' is not a branch."); +static const char upstream_missing[] = +N_("the requested upstream branch '%s' does not exist"); +static const char upstream_advice[] = +N_("\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push."); + void create_branch(const char *head, const char *name, const char *start_name, int force, int reflog, int clobber_head, @@ -224,38 +253,47 @@ void create_branch(const char *head, } real_ref = NULL; - if (get_sha1(start_name, sha1)) - die("Not a valid object name: '%s'.", start_name); + if (get_sha1(start_name, sha1)) { + if (explicit_tracking) { + if (advice_set_upstream_failure) { + error(_(upstream_missing), start_name); + advise(_(upstream_advice)); + exit(1); + } + die(_(upstream_missing), start_name); + } + die(_("Not a valid object name: '%s'."), start_name); + } switch (dwim_ref(start_name, strlen(start_name), sha1, &real_ref)) { case 0: /* Not branching from any existing branch */ if (explicit_tracking) - die("Cannot setup tracking information; starting point is not a branch."); + die(_(upstream_not_branch), start_name); break; case 1: /* Unique completion -- good, only if it is a real branch */ if (prefixcmp(real_ref, "refs/heads/") && - prefixcmp(real_ref, "refs/remotes/")) { + validate_remote_tracking_branch(real_ref)) { if (explicit_tracking) - die("Cannot setup tracking information; starting point is not a branch."); + die(_(upstream_not_branch), start_name); else real_ref = NULL; } break; default: - die("Ambiguous object name: '%s'.", start_name); + die(_("Ambiguous object name: '%s'."), start_name); break; } if ((commit = lookup_commit_reference(sha1)) == NULL) - die("Not a valid branch point: '%s'.", start_name); + die(_("Not a valid branch point: '%s'."), start_name); hashcpy(sha1, commit->object.sha1); if (!dont_change_ref) { lock = lock_any_ref_for_update(ref.buf, NULL, 0); if (!lock) - die_errno("Failed to lock ref for update"); + die_errno(_("Failed to lock ref for update")); } if (reflog) @@ -273,7 +311,7 @@ void create_branch(const char *head, if (!dont_change_ref) if (write_ref_sha1(lock, sha1, msg) < 0) - die_errno("Failed to write ref"); + die_errno(_("Failed to write ref")); strbuf_release(&ref); free(real_ref); diff --git a/builtin/add.c b/builtin/add.c index ab1c9e8fb7..f45d9d4865 100644 --- a/builtin/add.c +++ b/builtin/add.c @@ -26,8 +26,55 @@ static int take_worktree_changes; struct update_callback_data { int flags; int add_errors; + const char *implicit_dot; + size_t implicit_dot_len; + + /* only needed for 2.0 transition preparation */ + int warn_add_would_remove; }; +static const char *option_with_implicit_dot; +static const char *short_option_with_implicit_dot; + +static void warn_pathless_add(void) +{ + static int shown; + assert(option_with_implicit_dot && short_option_with_implicit_dot); + + if (shown) + return; + shown = 1; + + /* + * To be consistent with "git add -p" and most Git + * commands, we should default to being tree-wide, but + * this is not the original behavior and can't be + * changed until users trained themselves not to type + * "git add -u" or "git add -A". For now, we warn and + * keep the old behavior. Later, the behavior can be changed + * to tree-wide, keeping the warning for a while, and + * eventually we can drop the warning. + */ + warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n" + "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n" + "To add content for the whole tree, run:\n" + "\n" + " git add %s :/\n" + " (or git add %s :/)\n" + "\n" + "To restrict the command to the current directory, run:\n" + "\n" + " git add %s .\n" + " (or git add %s .)\n" + "\n" + "With the current Git version, the command is restricted to " + "the current directory.\n" + ""), + option_with_implicit_dot, short_option_with_implicit_dot, + option_with_implicit_dot, short_option_with_implicit_dot, + option_with_implicit_dot, short_option_with_implicit_dot); +} + static int fix_unmerged_status(struct diff_filepair *p, struct update_callback_data *data) { @@ -49,15 +96,49 @@ static int fix_unmerged_status(struct diff_filepair *p, return DIFF_STATUS_MODIFIED; } +static const char *add_would_remove_warning = N_( + "You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n"); + +static void warn_add_would_remove(const char *path) +{ + warning(_(add_would_remove_warning), path); +} + static void update_callback(struct diff_queue_struct *q, struct diff_options *opt, void *cbdata) { int i; struct update_callback_data *data = cbdata; + const char *implicit_dot = data->implicit_dot; + size_t implicit_dot_len = data->implicit_dot_len; for (i = 0; i < q->nr; i++) { struct diff_filepair *p = q->queue[i]; const char *path = p->one->path; + /* + * Check if "git add -A" or "git add -u" was run from a + * subdirectory with a modified file outside that directory, + * and warn if so. + * + * "git add -u" will behave like "git add -u :/" instead of + * "git add -u ." in the future. This warning prepares for + * that change. + */ + if (implicit_dot && + strncmp_icase(path, implicit_dot, implicit_dot_len)) { + warn_pathless_add(); + continue; + } switch (fix_unmerged_status(p, data)) { default: die(_("unexpected diff status %c"), p->status); @@ -70,6 +151,10 @@ static void update_callback(struct diff_queue_struct *q, } break; case DIFF_STATUS_DELETED: + if (data->warn_add_would_remove) { + warn_add_would_remove(path); + data->warn_add_would_remove = 0; + } if (data->flags & ADD_CACHE_IGNORE_REMOVAL) break; if (!(data->flags & ADD_CACHE_PRETEND)) @@ -81,24 +166,34 @@ static void update_callback(struct diff_queue_struct *q, } } -int add_files_to_cache(const char *prefix, const char **pathspec, int flags) +static void update_files_in_cache(const char *prefix, const char **pathspec, + struct update_callback_data *data) { - struct update_callback_data data; struct rev_info rev; + init_revisions(&rev, prefix); setup_revisions(0, NULL, &rev, NULL); init_pathspec(&rev.prune_data, pathspec); rev.diffopt.output_format = DIFF_FORMAT_CALLBACK; rev.diffopt.format_callback = update_callback; - data.flags = flags; - data.add_errors = 0; - rev.diffopt.format_callback_data = &data; + rev.diffopt.format_callback_data = data; rev.max_count = 0; /* do not compare unmerged paths with stage #2 */ run_diff_files(&rev, DIFF_RACY_IS_MODIFIED); +} + +int add_files_to_cache(const char *prefix, const char **pathspec, int flags) +{ + struct update_callback_data data; + + memset(&data, 0, sizeof(data)); + data.flags = flags; + update_files_in_cache(prefix, pathspec, &data); return !!data.add_errors; } -static char *prune_directory(struct dir_struct *dir, const char **pathspec, int prefix) +#define WARN_IMPLICIT_DOT (1u << 0) +static char *prune_directory(struct dir_struct *dir, const char **pathspec, + int prefix, unsigned flag) { char *seen; int i, specs; @@ -115,6 +210,16 @@ static char *prune_directory(struct dir_struct *dir, const char **pathspec, int if (match_pathspec(pathspec, entry->name, entry->len, prefix, seen)) *dst++ = entry; + else if (flag & WARN_IMPLICIT_DOT) + /* + * "git add -A" was run from a subdirectory with a + * new file outside that directory. + * + * "git add -A" will behave like "git add -A :/" + * instead of "git add -A ." in the future. + * Warn about the coming behavior change. + */ + warn_pathless_add(); } dir->nr = dst - dir->entries; add_pathspec_matches_against_index(pathspec, seen, specs); @@ -270,23 +375,38 @@ static struct lock_file lock_file; static const char ignore_error[] = N_("The following paths are ignored by one of your .gitignore files:\n"); -static int verbose = 0, show_only = 0, ignored_too = 0, refresh_only = 0; -static int ignore_add_errors, addremove, intent_to_add, ignore_missing = 0; +static int verbose, show_only, ignored_too, refresh_only; +static int ignore_add_errors, intent_to_add, ignore_missing; + +#define ADDREMOVE_DEFAULT 0 /* Change to 1 in Git 2.0 */ +static int addremove = ADDREMOVE_DEFAULT; +static int addremove_explicit = -1; /* unspecified */ + +static int ignore_removal_cb(const struct option *opt, const char *arg, int unset) +{ + /* if we are told to ignore, we are not adding removals */ + *(int *)opt->value = !unset ? 0 : 1; + return 0; +} static struct option builtin_add_options[] = { OPT__DRY_RUN(&show_only, N_("dry run")), OPT__VERBOSE(&verbose, N_("be verbose")), OPT_GROUP(""), - OPT_BOOLEAN('i', "interactive", &add_interactive, N_("interactive picking")), - OPT_BOOLEAN('p', "patch", &patch_interactive, N_("select hunks interactively")), - OPT_BOOLEAN('e', "edit", &edit_interactive, N_("edit current diff and apply")), + OPT_BOOL('i', "interactive", &add_interactive, N_("interactive picking")), + OPT_BOOL('p', "patch", &patch_interactive, N_("select hunks interactively")), + OPT_BOOL('e', "edit", &edit_interactive, N_("edit current diff and apply")), OPT__FORCE(&ignored_too, N_("allow adding otherwise ignored files")), - OPT_BOOLEAN('u', "update", &take_worktree_changes, N_("update tracked files")), - OPT_BOOLEAN('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")), - OPT_BOOLEAN('A', "all", &addremove, N_("add changes from all tracked and untracked files")), - OPT_BOOLEAN( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")), - OPT_BOOLEAN( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")), - OPT_BOOLEAN( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")), + OPT_BOOL('u', "update", &take_worktree_changes, N_("update tracked files")), + OPT_BOOL('N', "intent-to-add", &intent_to_add, N_("record only the fact that the path will be added later")), + OPT_BOOL('A', "all", &addremove_explicit, N_("add changes from all tracked and untracked files")), + { OPTION_CALLBACK, 0, "ignore-removal", &addremove_explicit, + NULL /* takes no arguments */, + N_("ignore paths removed in the working tree (same as --no-all)"), + PARSE_OPT_NOARG, ignore_removal_cb }, + OPT_BOOL( 0 , "refresh", &refresh_only, N_("don't add, only refresh the index")), + OPT_BOOL( 0 , "ignore-errors", &ignore_add_errors, N_("just skip files which cannot be added because of errors")), + OPT_BOOL( 0 , "ignore-missing", &ignore_missing, N_("check if - even missing - files are ignored in dry run")), OPT_END(), }; @@ -321,35 +441,6 @@ static int add_files(struct dir_struct *dir, int flags) return exit_status; } -static void warn_pathless_add(const char *option_name, const char *short_name) { - /* - * To be consistent with "git add -p" and most Git - * commands, we should default to being tree-wide, but - * this is not the original behavior and can't be - * changed until users trained themselves not to type - * "git add -u" or "git add -A". For now, we warn and - * keep the old behavior. Later, the behavior can be changed - * to tree-wide, keeping the warning for a while, and - * eventually we can drop the warning. - */ - warning(_("The behavior of 'git add %s (or %s)' with no path argument from a\n" - "subdirectory of the tree will change in Git 2.0 and should not be used anymore.\n" - "To add content for the whole tree, run:\n" - "\n" - " git add %s :/\n" - " (or git add %s :/)\n" - "\n" - "To restrict the command to the current directory, run:\n" - "\n" - " git add %s .\n" - " (or git add %s .)\n" - "\n" - "With the current Git version, the command is restricted to the current directory."), - option_name, short_name, - option_name, short_name, - option_name, short_name); -} - int cmd_add(int argc, const char **argv, const char *prefix) { int exit_status = 0; @@ -360,8 +451,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) int add_new_files; int require_pathspec; char *seen = NULL; - const char *option_with_implicit_dot = NULL; - const char *short_option_with_implicit_dot = NULL; + int implicit_dot = 0; + struct update_callback_data update_data; git_config(add_config, NULL); @@ -377,8 +468,29 @@ int cmd_add(int argc, const char **argv, const char *prefix) argc--; argv++; + if (0 <= addremove_explicit) + addremove = addremove_explicit; + else if (take_worktree_changes && ADDREMOVE_DEFAULT) + addremove = 0; /* "-u" was given but not "-A" */ + if (addremove && take_worktree_changes) die(_("-A and -u are mutually incompatible")); + + /* + * Warn when "git add pathspec..." was given without "-u" or "-A" + * and pathspec... covers a removed path. + */ + memset(&update_data, 0, sizeof(update_data)); + if (!take_worktree_changes && addremove_explicit < 0) + update_data.warn_add_would_remove = 1; + + if (!take_worktree_changes && addremove_explicit < 0 && argc) + /* + * Turn "git add pathspec..." to "git add -A pathspec..." + * in Git 2.0 but not yet + */ + ; /* addremove = 1; */ + if (!show_only && ignore_missing) die(_("Option --ignore-missing can only be used together with --dry-run")); if (addremove) { @@ -391,11 +503,9 @@ int cmd_add(int argc, const char **argv, const char *prefix) } if (option_with_implicit_dot && !argc) { static const char *here[2] = { ".", NULL }; - if (prefix) - warn_pathless_add(option_with_implicit_dot, - short_option_with_implicit_dot); argc = 1; argv = here; + implicit_dot = 1; } add_new_files = !take_worktree_changes && !refresh_only; @@ -408,7 +518,8 @@ int cmd_add(int argc, const char **argv, const char *prefix) (intent_to_add ? ADD_CACHE_INTENT : 0) | (ignore_add_errors ? ADD_CACHE_IGNORE_ERRORS : 0) | (!(addremove || take_worktree_changes) - ? ADD_CACHE_IGNORE_REMOVAL : 0)); + ? ADD_CACHE_IGNORE_REMOVAL : 0)) | + (implicit_dot ? ADD_CACHE_IMPLICIT_DOT : 0); if (require_pathspec && argc == 0) { fprintf(stderr, _("Nothing specified, nothing added.\n")); @@ -432,21 +543,22 @@ int cmd_add(int argc, const char **argv, const char *prefix) } /* This picks up the paths that are not tracked */ - baselen = fill_directory(&dir, pathspec); + baselen = fill_directory(&dir, implicit_dot ? NULL : pathspec); if (pathspec) - seen = prune_directory(&dir, pathspec, baselen); + seen = prune_directory(&dir, pathspec, baselen, + implicit_dot ? WARN_IMPLICIT_DOT : 0); } if (refresh_only) { refresh(verbose, pathspec); goto finish; } + if (implicit_dot && prefix) + refresh_cache(REFRESH_QUIET); if (pathspec) { int i; - struct path_exclude_check check; - path_exclude_check_init(&check, &dir); if (!seen) seen = find_pathspecs_matching_against_index(pathspec); for (i = 0; pathspec[i]; i++) { @@ -454,7 +566,7 @@ int cmd_add(int argc, const char **argv, const char *prefix) && !file_exists(pathspec[i])) { if (ignore_missing) { int dtype = DT_UNKNOWN; - if (is_path_excluded(&check, pathspec[i], -1, &dtype)) + if (is_excluded(&dir, pathspec[i], &dtype)) dir_add_ignored(&dir, pathspec[i], strlen(pathspec[i])); } else die(_("pathspec '%s' did not match any files"), @@ -462,13 +574,24 @@ int cmd_add(int argc, const char **argv, const char *prefix) } } free(seen); - path_exclude_check_clear(&check); } plug_bulk_checkin(); - exit_status |= add_files_to_cache(prefix, pathspec, flags); + if ((flags & ADD_CACHE_IMPLICIT_DOT) && prefix) { + /* + * Check for modified files throughout the worktree so + * update_callback has a chance to warn about changes + * outside the cwd. + */ + update_data.implicit_dot = prefix; + update_data.implicit_dot_len = strlen(prefix); + pathspec = NULL; + } + update_data.flags = flags & ~ADD_CACHE_IMPLICIT_DOT; + update_files_in_cache(prefix, pathspec, &update_data); + exit_status |= !!update_data.add_errors; if (add_new_files) exit_status |= add_files(&dir, flags); diff --git a/builtin/archive.c b/builtin/archive.c index 9a1cfd3dac..49178f159e 100644 --- a/builtin/archive.c +++ b/builtin/archive.c @@ -27,8 +27,8 @@ static int run_remote_archiver(int argc, const char **argv, const char *remote, const char *exec, const char *name_hint) { - char buf[LARGE_PACKET_MAX]; - int fd[2], i, len, rv; + char *buf; + int fd[2], i, rv; struct transport *transport; struct remote *_remote; @@ -53,21 +53,18 @@ static int run_remote_archiver(int argc, const char **argv, packet_write(fd[1], "argument %s\n", argv[i]); packet_flush(fd[1]); - len = packet_read_line(fd[0], buf, sizeof(buf)); - if (!len) + buf = packet_read_line(fd[0], NULL); + if (!buf) die(_("git archive: expected ACK/NAK, got EOF")); - if (buf[len-1] == '\n') - buf[--len] = 0; if (strcmp(buf, "ACK")) { - if (len > 5 && !prefixcmp(buf, "NACK ")) + if (!prefixcmp(buf, "NACK ")) die(_("git archive: NACK %s"), buf + 5); - if (len > 4 && !prefixcmp(buf, "ERR ")) + if (!prefixcmp(buf, "ERR ")) die(_("remote error: %s"), buf + 4); die(_("git archive: protocol error")); } - len = packet_read_line(fd[0], buf, sizeof(buf)); - if (len) + if (packet_read_line(fd[0], NULL)) die(_("git archive: expected a flush")); /* Now, start reading from fd[0] and spit it out to stdout */ diff --git a/builtin/blame.c b/builtin/blame.c index 77707819af..57a487e052 100644 --- a/builtin/blame.c +++ b/builtin/blame.c @@ -1430,7 +1430,7 @@ static void get_commit_info(struct commit *commit, commit_info_init(ret); encoding = get_log_output_encoding(); - message = logmsg_reencode(commit, encoding); + message = logmsg_reencode(commit, NULL, encoding); get_ac_line(message, "\nauthor ", &ret->author, &ret->author_mail, &ret->author_time, &ret->author_tz); diff --git a/builtin/branch.c b/builtin/branch.c index 00d17d25d1..083689063f 100644 --- a/builtin/branch.c +++ b/builtin/branch.c @@ -18,6 +18,7 @@ #include "string-list.h" #include "column.h" #include "utf8.h" +#include "wt-status.h" static const char * const builtin_branch_usage[] = { N_("git branch [options] [-r | -a] [--merged | --no-merged]"), @@ -40,13 +41,15 @@ static char branch_colors[][COLOR_MAXLEN] = { GIT_COLOR_RED, /* REMOTE */ GIT_COLOR_NORMAL, /* LOCAL */ GIT_COLOR_GREEN, /* CURRENT */ + GIT_COLOR_BLUE, /* UPSTREAM */ }; enum color_branch { BRANCH_COLOR_RESET = 0, BRANCH_COLOR_PLAIN = 1, BRANCH_COLOR_REMOTE = 2, BRANCH_COLOR_LOCAL = 3, - BRANCH_COLOR_CURRENT = 4 + BRANCH_COLOR_CURRENT = 4, + BRANCH_COLOR_UPSTREAM = 5 }; static enum merge_filter { @@ -71,6 +74,8 @@ static int parse_branch_color_slot(const char *var, int ofs) return BRANCH_COLOR_LOCAL; if (!strcasecmp(var+ofs, "current")) return BRANCH_COLOR_CURRENT; + if (!strcasecmp(var+ofs, "upstream")) + return BRANCH_COLOR_UPSTREAM; return -1; } @@ -417,36 +422,52 @@ static void fill_tracking_info(struct strbuf *stat, const char *branch_name, int ours, theirs; char *ref = NULL; struct branch *branch = branch_get(branch_name); + struct strbuf fancy = STRBUF_INIT; if (!stat_tracking_info(branch, &ours, &theirs)) { if (branch && branch->merge && branch->merge[0]->dst && - show_upstream_ref) - strbuf_addf(stat, "[%s] ", - shorten_unambiguous_ref(branch->merge[0]->dst, 0)); + show_upstream_ref) { + ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0); + if (want_color(branch_use_color)) + strbuf_addf(stat, "[%s%s%s] ", + branch_get_color(BRANCH_COLOR_UPSTREAM), + ref, branch_get_color(BRANCH_COLOR_RESET)); + else + strbuf_addf(stat, "[%s] ", ref); + } return; } - if (show_upstream_ref) + if (show_upstream_ref) { ref = shorten_unambiguous_ref(branch->merge[0]->dst, 0); + if (want_color(branch_use_color)) + strbuf_addf(&fancy, "%s%s%s", + branch_get_color(BRANCH_COLOR_UPSTREAM), + ref, branch_get_color(BRANCH_COLOR_RESET)); + else + strbuf_addstr(&fancy, ref); + } + if (!ours) { if (ref) - strbuf_addf(stat, _("[%s: behind %d]"), ref, theirs); + strbuf_addf(stat, _("[%s: behind %d]"), fancy.buf, theirs); else strbuf_addf(stat, _("[behind %d]"), theirs); } else if (!theirs) { if (ref) - strbuf_addf(stat, _("[%s: ahead %d]"), ref, ours); + strbuf_addf(stat, _("[%s: ahead %d]"), fancy.buf, ours); else strbuf_addf(stat, _("[ahead %d]"), ours); } else { if (ref) strbuf_addf(stat, _("[%s: ahead %d, behind %d]"), - ref, ours, theirs); + fancy.buf, ours, theirs); else strbuf_addf(stat, _("[ahead %d, behind %d]"), ours, theirs); } + strbuf_release(&fancy); strbuf_addch(stat, ' '); free(ref); } @@ -550,6 +571,29 @@ static int calc_maxwidth(struct ref_list *refs) return w; } +static char *get_head_description(void) +{ + struct strbuf desc = STRBUF_INIT; + struct wt_status_state state; + memset(&state, 0, sizeof(state)); + wt_status_get_state(&state, 1); + if (state.rebase_in_progress || + state.rebase_interactive_in_progress) + strbuf_addf(&desc, _("(no branch, rebasing %s)"), + state.branch); + else if (state.bisect_in_progress) + strbuf_addf(&desc, _("(no branch, bisect started on %s)"), + state.branch); + else if (state.detached_from) + strbuf_addf(&desc, _("(detached from %s)"), + state.detached_from); + else + strbuf_addstr(&desc, _("(no branch)")); + free(state.branch); + free(state.onto); + free(state.detached_from); + return strbuf_detach(&desc, NULL); +} static void show_detached(struct ref_list *ref_list) { @@ -557,7 +601,7 @@ static void show_detached(struct ref_list *ref_list) if (head_commit && is_descendant_of(head_commit, ref_list->with_commit)) { struct ref_item item; - item.name = xstrdup(_("(no branch)")); + item.name = get_head_description(); item.width = utf8_strwidth(item.name); item.kind = REF_LOCAL_BRANCH; item.dest = NULL; @@ -880,7 +924,9 @@ int cmd_branch(int argc, const char **argv, const char *prefix) if (edit_branch_description(branch_name)) return 1; } else if (rename) { - if (argc == 1) + if (!argc) + die(_("branch name required")); + else if (argc == 1) rename_branch(head, argv[0], rename > 1); else if (argc == 2) rename_branch(argv[0], argv[1], rename > 1); diff --git a/builtin/check-ignore.c b/builtin/check-ignore.c index 0240f99b57..4a8fc707c7 100644 --- a/builtin/check-ignore.c +++ b/builtin/check-ignore.c @@ -5,7 +5,7 @@ #include "pathspec.h" #include "parse-options.h" -static int quiet, verbose, stdin_paths; +static int quiet, verbose, stdin_paths, show_non_matching; static const char * const check_ignore_usage[] = { "git check-ignore [options] pathname...", "git check-ignore [options] --stdin < <list-of-paths>", @@ -22,21 +22,28 @@ static const struct option check_ignore_options[] = { N_("read file names from stdin")), OPT_BOOLEAN('z', NULL, &null_term_line, N_("input paths are terminated by a null character")), + OPT_BOOLEAN('n', "non-matching", &show_non_matching, + N_("show non-matching input paths")), OPT_END() }; static void output_exclude(const char *path, struct exclude *exclude) { - char *bang = exclude->flags & EXC_FLAG_NEGATIVE ? "!" : ""; - char *slash = exclude->flags & EXC_FLAG_MUSTBEDIR ? "/" : ""; + char *bang = (exclude && exclude->flags & EXC_FLAG_NEGATIVE) ? "!" : ""; + char *slash = (exclude && exclude->flags & EXC_FLAG_MUSTBEDIR) ? "/" : ""; if (!null_term_line) { if (!verbose) { write_name_quoted(path, stdout, '\n'); } else { - quote_c_style(exclude->el->src, NULL, stdout, 0); - printf(":%d:%s%s%s\t", - exclude->srcpos, - bang, exclude->pattern, slash); + if (exclude) { + quote_c_style(exclude->el->src, NULL, stdout, 0); + printf(":%d:%s%s%s\t", + exclude->srcpos, + bang, exclude->pattern, slash); + } + else { + printf("::\t"); + } quote_c_style(path, NULL, stdout, 0); fputc('\n', stdout); } @@ -44,39 +51,32 @@ static void output_exclude(const char *path, struct exclude *exclude) if (!verbose) { printf("%s%c", path, '\0'); } else { - printf("%s%c%d%c%s%s%s%c%s%c", - exclude->el->src, '\0', - exclude->srcpos, '\0', - bang, exclude->pattern, slash, '\0', - path, '\0'); + if (exclude) + printf("%s%c%d%c%s%s%s%c%s%c", + exclude->el->src, '\0', + exclude->srcpos, '\0', + bang, exclude->pattern, slash, '\0', + path, '\0'); + else + printf("%c%c%c%s%c", '\0', '\0', '\0', path, '\0'); } } } -static int check_ignore(const char *prefix, const char **pathspec) +static int check_ignore(struct dir_struct *dir, + const char *prefix, const char **pathspec) { - struct dir_struct dir; const char *path, *full_path; char *seen; int num_ignored = 0, dtype = DT_UNKNOWN, i; - struct path_exclude_check check; struct exclude *exclude; - /* read_cache() is only necessary so we can watch out for submodules. */ - if (read_cache() < 0) - die(_("index file corrupt")); - - memset(&dir, 0, sizeof(dir)); - dir.flags |= DIR_COLLECT_IGNORED; - setup_standard_excludes(&dir); - if (!pathspec || !*pathspec) { if (!quiet) fprintf(stderr, "no pathspec given.\n"); return 0; } - path_exclude_check_init(&check, &dir); /* * look for pathspecs matching entries in the index, since these * should not be ignored, in order to be consistent with @@ -89,30 +89,26 @@ static int check_ignore(const char *prefix, const char **pathspec) ? strlen(prefix) : 0, path); full_path = check_path_for_gitlink(full_path); die_if_path_beyond_symlink(full_path, prefix); + exclude = NULL; if (!seen[i]) { - exclude = last_exclude_matching_path(&check, full_path, - -1, &dtype); - if (exclude) { - if (!quiet) - output_exclude(path, exclude); - num_ignored++; - } + exclude = last_exclude_matching(dir, full_path, &dtype); } + if (!quiet && (exclude || show_non_matching)) + output_exclude(path, exclude); + if (exclude) + num_ignored++; } free(seen); - clear_directory(&dir); - path_exclude_check_clear(&check); return num_ignored; } -static int check_ignore_stdin_paths(const char *prefix) +static int check_ignore_stdin_paths(struct dir_struct *dir, const char *prefix) { struct strbuf buf, nbuf; - char **pathspec = NULL; - size_t nr = 0, alloc = 0; + char *pathspec[2] = { NULL, NULL }; int line_termination = null_term_line ? 0 : '\n'; - int num_ignored; + int num_ignored = 0; strbuf_init(&buf, 0); strbuf_init(&nbuf, 0); @@ -123,23 +119,19 @@ static int check_ignore_stdin_paths(const char *prefix) die("line is badly quoted"); strbuf_swap(&buf, &nbuf); } - ALLOC_GROW(pathspec, nr + 1, alloc); - pathspec[nr] = xcalloc(strlen(buf.buf) + 1, sizeof(*buf.buf)); - strcpy(pathspec[nr++], buf.buf); + pathspec[0] = buf.buf; + num_ignored += check_ignore(dir, prefix, (const char **)pathspec); + maybe_flush_or_die(stdout, "check-ignore to stdout"); } - ALLOC_GROW(pathspec, nr + 1, alloc); - pathspec[nr] = NULL; - num_ignored = check_ignore(prefix, (const char **)pathspec); - maybe_flush_or_die(stdout, "attribute to stdout"); strbuf_release(&buf); strbuf_release(&nbuf); - free(pathspec); return num_ignored; } int cmd_check_ignore(int argc, const char **argv, const char *prefix) { int num_ignored; + struct dir_struct dir; git_config(git_default_config, NULL); @@ -161,13 +153,24 @@ int cmd_check_ignore(int argc, const char **argv, const char *prefix) if (verbose) die(_("cannot have both --quiet and --verbose")); } + if (show_non_matching && !verbose) + die(_("--non-matching is only valid with --verbose")); + + /* read_cache() is only necessary so we can watch out for submodules. */ + if (read_cache() < 0) + die(_("index file corrupt")); + + memset(&dir, 0, sizeof(dir)); + setup_standard_excludes(&dir); if (stdin_paths) { - num_ignored = check_ignore_stdin_paths(prefix); + num_ignored = check_ignore_stdin_paths(&dir, prefix); } else { - num_ignored = check_ignore(prefix, argv); + num_ignored = check_ignore(&dir, prefix, argv); maybe_flush_or_die(stdout, "ignore to stdout"); } + clear_directory(&dir); + return !num_ignored; } diff --git a/builtin/checkout.c b/builtin/checkout.c index a9c1b5a95f..f5b50e520f 100644 --- a/builtin/checkout.c +++ b/builtin/checkout.c @@ -35,6 +35,7 @@ struct checkout_opts { int force_detach; int writeout_stage; int overwrite_ignore; + int ignore_skipworktree; const char *new_branch; const char *new_branch_force; @@ -271,24 +272,57 @@ static int checkout_paths(const struct checkout_opts *opts, ; ps_matched = xcalloc(1, pos); + /* + * Make sure all pathspecs participated in locating the paths + * to be checked out. + */ for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; + ce->ce_flags &= ~CE_MATCHED; + if (!opts->ignore_skipworktree && ce_skip_worktree(ce)) + continue; if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) + /* + * "git checkout tree-ish -- path", but this entry + * is in the original index; it will not be checked + * out to the working tree and it does not matter + * if pathspec matched this entry. We will not do + * anything to this entry at all. + */ continue; - match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, ps_matched); + /* + * Either this entry came from the tree-ish we are + * checking the paths out of, or we are checking out + * of the index. + * + * If it comes from the tree-ish, we already know it + * matches the pathspec and could just stamp + * CE_MATCHED to it from update_some(). But we still + * need ps_matched and read_tree_recursive (and + * eventually tree_entry_interesting) cannot fill + * ps_matched yet. Once it can, we can avoid calling + * match_pathspec() for _all_ entries when + * opts->source_tree != NULL. + */ + if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), + 0, ps_matched)) + ce->ce_flags |= CE_MATCHED; } - if (report_path_error(ps_matched, opts->pathspec, opts->prefix)) + if (report_path_error(ps_matched, opts->pathspec, opts->prefix)) { + free(ps_matched); return 1; + } + free(ps_matched); /* "checkout -m path" to recreate conflicted state */ if (opts->merge) - unmerge_cache(opts->pathspec); + unmerge_marked_index(&the_index); /* Any unmerged paths? */ for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; - if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) { + if (ce->ce_flags & CE_MATCHED) { if (!ce_stage(ce)) continue; if (opts->force) { @@ -313,9 +347,7 @@ static int checkout_paths(const struct checkout_opts *opts, state.refresh_cache = 1; for (pos = 0; pos < active_nr; pos++) { struct cache_entry *ce = active_cache[pos]; - if (opts->source_tree && !(ce->ce_flags & CE_UPDATE)) - continue; - if (match_pathspec(opts->pathspec, ce->name, ce_namelen(ce), 0, NULL)) { + if (ce->ce_flags & CE_MATCHED) { if (!ce_stage(ce)) { errs |= checkout_entry(ce, &state, NULL); continue; @@ -700,7 +732,7 @@ static void suggest_reattach(struct commit *commit, struct rev_info *revs) "If you want to keep them by creating a new branch, " "this may be a good time\nto do so with:\n\n" " git branch new_branch_name %s\n\n"), - sha1_to_hex(commit->object.sha1)); + find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV)); } /* @@ -793,38 +825,40 @@ static int git_checkout_config(const char *var, const char *value, void *cb) } struct tracking_name_data { - const char *name; - char *remote; + /* const */ char *src_ref; + char *dst_ref; + unsigned char *dst_sha1; int unique; }; -static int check_tracking_name(const char *refname, const unsigned char *sha1, - int flags, void *cb_data) +static int check_tracking_name(struct remote *remote, void *cb_data) { struct tracking_name_data *cb = cb_data; - const char *slash; - - if (prefixcmp(refname, "refs/remotes/")) - return 0; - slash = strchr(refname + 13, '/'); - if (!slash || strcmp(slash + 1, cb->name)) + struct refspec query; + memset(&query, 0, sizeof(struct refspec)); + query.src = cb->src_ref; + if (remote_find_tracking(remote, &query) || + get_sha1(query.dst, cb->dst_sha1)) return 0; - if (cb->remote) { + if (cb->dst_ref) { cb->unique = 0; return 0; } - cb->remote = xstrdup(refname); + cb->dst_ref = xstrdup(query.dst); return 0; } -static const char *unique_tracking_name(const char *name) +static const char *unique_tracking_name(const char *name, unsigned char *sha1) { - struct tracking_name_data cb_data = { NULL, NULL, 1 }; - cb_data.name = name; - for_each_ref(check_tracking_name, &cb_data); + struct tracking_name_data cb_data = { NULL, NULL, NULL, 1 }; + char src_ref[PATH_MAX]; + snprintf(src_ref, PATH_MAX, "refs/heads/%s", name); + cb_data.src_ref = src_ref; + cb_data.dst_sha1 = sha1; + for_each_remote(check_tracking_name, &cb_data); if (cb_data.unique) - return cb_data.remote; - free(cb_data.remote); + return cb_data.dst_ref; + free(cb_data.dst_ref); return NULL; } @@ -887,8 +921,8 @@ static int parse_branchname_arg(int argc, const char **argv, if (dwim_new_local_branch_ok && !check_filename(NULL, arg) && argc == 1) { - const char *remote = unique_tracking_name(arg); - if (!remote || get_sha1(remote, rev)) + const char *remote = unique_tracking_name(arg, rev); + if (!remote) return argcount; *new_branch = arg; arg = remote; @@ -1029,6 +1063,8 @@ int cmd_checkout(int argc, const char **argv, const char *prefix) OPT_STRING(0, "conflict", &conflict_style, N_("style"), N_("conflict style (merge or diff3)")), OPT_BOOLEAN('p', "patch", &opts.patch_mode, N_("select hunks interactively")), + OPT_BOOL(0, "ignore-skip-worktree-bits", &opts.ignore_skipworktree, + N_("do not limit pathspecs to sparse entries only")), { OPTION_BOOLEAN, 0, "guess", &dwim_new_local_branch, NULL, N_("second guess 'git checkout no-such-branch'"), PARSE_OPT_NOARG | PARSE_OPT_HIDDEN }, diff --git a/builtin/clone.c b/builtin/clone.c index e0aaf13583..5e70696d84 100644 --- a/builtin/clone.c +++ b/builtin/clone.c @@ -18,11 +18,11 @@ #include "transport.h" #include "strbuf.h" #include "dir.h" -#include "pack-refs.h" #include "sigchain.h" #include "branch.h" #include "remote.h" #include "run-command.h" +#include "connected.h" /* * Overall FIXMEs: @@ -231,16 +231,26 @@ static void strip_trailing_slashes(char *dir) static int add_one_reference(struct string_list_item *item, void *cb_data) { char *ref_git; + const char *repo; struct strbuf alternate = STRBUF_INIT; - /* Beware: real_path() and mkpath() return static buffer */ + /* Beware: read_gitfile(), real_path() and mkpath() return static buffer */ ref_git = xstrdup(real_path(item->string)); - if (is_directory(mkpath("%s/.git/objects", ref_git))) { + + repo = read_gitfile(ref_git); + if (!repo) + repo = read_gitfile(mkpath("%s/.git", ref_git)); + if (repo) { + free(ref_git); + ref_git = xstrdup(repo); + } + + if (!repo && is_directory(mkpath("%s/.git/objects", ref_git))) { char *ref_git_git = mkpathdup("%s/.git", ref_git); free(ref_git); ref_git = ref_git_git; } else if (!is_directory(mkpath("%s/objects", ref_git))) - die(_("reference repository '%s' is not a local directory."), + die(_("reference repository '%s' is not a local repository."), item->string); strbuf_addf(&alternate, "%s/objects", ref_git); @@ -376,10 +386,32 @@ static void clone_local(const char *src_repo, const char *dest_repo) static const char *junk_work_tree; static const char *junk_git_dir; static pid_t junk_pid; +static enum { + JUNK_LEAVE_NONE, + JUNK_LEAVE_REPO, + JUNK_LEAVE_ALL +} junk_mode = JUNK_LEAVE_NONE; + +static const char junk_leave_repo_msg[] = +N_("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"); static void remove_junk(void) { struct strbuf sb = STRBUF_INIT; + + switch (junk_mode) { + case JUNK_LEAVE_REPO: + warning("%s", _(junk_leave_repo_msg)); + /* fall-through */ + case JUNK_LEAVE_ALL: + return; + default: + /* proceed to removal */ + break; + } + if (getpid() != junk_pid) return; if (junk_git_dir) { @@ -485,12 +517,37 @@ static void write_followtags(const struct ref *refs, const char *msg) } } +static int iterate_ref_map(void *cb_data, unsigned char sha1[20]) +{ + struct ref **rm = cb_data; + struct ref *ref = *rm; + + /* + * Skip anything missing a peer_ref, which we are not + * actually going to write a ref for. + */ + while (ref && !ref->peer_ref) + ref = ref->next; + /* Returning -1 notes "end of list" to the caller. */ + if (!ref) + return -1; + + hashcpy(sha1, ref->old_sha1); + *rm = ref->next; + return 0; +} + static void update_remote_refs(const struct ref *refs, const struct ref *mapped_refs, const struct ref *remote_head_points_at, const char *branch_top, const char *msg) { + const struct ref *rm = mapped_refs; + + if (check_everything_connected(iterate_ref_map, 0, &rm)) + die(_("remote did not send all necessary objects")); + if (refs) { write_remote_refs(mapped_refs); if (option_single_branch) @@ -579,7 +636,8 @@ static int checkout(void) tree = parse_tree_indirect(sha1); parse_tree(tree); init_tree_desc(&t, tree->buffer, tree->size); - unpack_trees(1, &t, &opts); + if (unpack_trees(1, &t, &opts) < 0) + die(_("unable to checkout working tree")); if (write_cache(fd, active_cache, active_nr) || commit_locked_index(lock_file)) @@ -898,12 +956,13 @@ int cmd_clone(int argc, const char **argv, const char *prefix) transport_unlock_pack(transport); transport_disconnect(transport); + junk_mode = JUNK_LEAVE_REPO; err = checkout(); strbuf_release(&reflog_msg); strbuf_release(&branch_top); strbuf_release(&key); strbuf_release(&value); - junk_pid = 0; + junk_mode = JUNK_LEAVE_ALL; return err; } diff --git a/builtin/commit-tree.c b/builtin/commit-tree.c index eac901a0ee..f641ff2a89 100644 --- a/builtin/commit-tree.c +++ b/builtin/commit-tree.c @@ -10,7 +10,7 @@ #include "utf8.h" #include "gpg-interface.h" -static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-S<signer>] [-m <message>] [-F <file>] <sha1> <changelog"; +static const char commit_tree_usage[] = "git commit-tree [(-p <sha1>)...] [-S[<keyid>]] [-m <message>] [-F <file>] <sha1> <changelog"; static void new_parent(struct commit *parent, struct commit_list **parents_p) { diff --git a/builtin/commit.c b/builtin/commit.c index d21d07a1a8..d2f30d960a 100644 --- a/builtin/commit.c +++ b/builtin/commit.c @@ -702,7 +702,7 @@ static int prepare_to_commit(const char *index_file, const char *prefix, previous = eol; } - append_signoff(&sb, ignore_footer); + append_signoff(&sb, ignore_footer, 0); } if (fwrite(sb.buf, 1, sb.len, s->fp) < sb.len) @@ -955,7 +955,7 @@ static const char *read_commit_message(const char *name) if (!commit) die(_("could not lookup commit %s"), name); out_enc = get_commit_output_encoding(); - return logmsg_reencode(commit, out_enc); + return logmsg_reencode(commit, NULL, out_enc); } static int parse_and_validate_options(int argc, const char *argv[], diff --git a/builtin/count-objects.c b/builtin/count-objects.c index 9afaa88f77..a7f70cb858 100644 --- a/builtin/count-objects.c +++ b/builtin/count-objects.c @@ -9,11 +9,22 @@ #include "builtin.h" #include "parse-options.h" +static unsigned long garbage; +static off_t size_garbage; + +static void real_report_garbage(const char *desc, const char *path) +{ + struct stat st; + if (!stat(path, &st)) + size_garbage += st.st_size; + warning("%s: %s", desc, path); + garbage++; +} + static void count_objects(DIR *d, char *path, int len, int verbose, unsigned long *loose, off_t *loose_size, - unsigned long *packed_loose, - unsigned long *garbage) + unsigned long *packed_loose) { struct dirent *ent; while ((ent = readdir(d)) != NULL) { @@ -46,9 +57,11 @@ static void count_objects(DIR *d, char *path, int len, int verbose, } if (bad) { if (verbose) { - error("garbage found: %.*s/%s", - len + 2, path, ent->d_name); - (*garbage)++; + struct strbuf sb = STRBUF_INIT; + strbuf_addf(&sb, "%.*s/%s", + len + 2, path, ent->d_name); + report_garbage("garbage found", sb.buf); + strbuf_release(&sb); } continue; } @@ -66,20 +79,22 @@ static void count_objects(DIR *d, char *path, int len, int verbose, } static char const * const count_objects_usage[] = { - N_("git count-objects [-v]"), + N_("git count-objects [-v] [-H | --human-readable]"), NULL }; int cmd_count_objects(int argc, const char **argv, const char *prefix) { - int i, verbose = 0; + int i, verbose = 0, human_readable = 0; const char *objdir = get_object_directory(); int len = strlen(objdir); char *path = xmalloc(len + 50); - unsigned long loose = 0, packed = 0, packed_loose = 0, garbage = 0; + unsigned long loose = 0, packed = 0, packed_loose = 0; off_t loose_size = 0; struct option opts[] = { OPT__VERBOSE(&verbose, N_("be verbose")), + OPT_BOOL('H', "human-readable", &human_readable, + N_("print sizes in human readable format")), OPT_END(), }; @@ -87,6 +102,8 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) /* we do not take arguments other than flags for now */ if (argc) usage_with_options(count_objects_usage, opts); + if (verbose) + report_garbage = real_report_garbage; memcpy(path, objdir, len); if (len && objdir[len-1] != '/') path[len++] = '/'; @@ -97,13 +114,16 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) if (!d) continue; count_objects(d, path, len, verbose, - &loose, &loose_size, &packed_loose, &garbage); + &loose, &loose_size, &packed_loose); closedir(d); } if (verbose) { struct packed_git *p; unsigned long num_pack = 0; off_t size_pack = 0; + struct strbuf loose_buf = STRBUF_INIT; + struct strbuf pack_buf = STRBUF_INIT; + struct strbuf garbage_buf = STRBUF_INIT; if (!packed_git) prepare_packed_git(); for (p = packed_git; p; p = p->next) { @@ -115,16 +135,40 @@ int cmd_count_objects(int argc, const char **argv, const char *prefix) size_pack += p->pack_size + p->index_size; num_pack++; } + + if (human_readable) { + strbuf_humanise_bytes(&loose_buf, loose_size); + strbuf_humanise_bytes(&pack_buf, size_pack); + strbuf_humanise_bytes(&garbage_buf, size_garbage); + } else { + strbuf_addf(&loose_buf, "%lu", + (unsigned long)(loose_size / 1024)); + strbuf_addf(&pack_buf, "%lu", + (unsigned long)(size_pack / 1024)); + strbuf_addf(&garbage_buf, "%lu", + (unsigned long)(size_garbage / 1024)); + } + printf("count: %lu\n", loose); - printf("size: %lu\n", (unsigned long) (loose_size / 1024)); + printf("size: %s\n", loose_buf.buf); printf("in-pack: %lu\n", packed); printf("packs: %lu\n", num_pack); - printf("size-pack: %lu\n", (unsigned long) (size_pack / 1024)); + printf("size-pack: %s\n", pack_buf.buf); printf("prune-packable: %lu\n", packed_loose); printf("garbage: %lu\n", garbage); + printf("size-garbage: %s\n", garbage_buf.buf); + strbuf_release(&loose_buf); + strbuf_release(&pack_buf); + strbuf_release(&garbage_buf); + } else { + struct strbuf buf = STRBUF_INIT; + if (human_readable) + strbuf_humanise_bytes(&buf, loose_size); + else + strbuf_addf(&buf, "%lu kilobytes", + (unsigned long)(loose_size / 1024)); + printf("%lu objects, %s\n", loose, buf.buf); + strbuf_release(&buf); } - else - printf("%lu objects, %lu kilobytes\n", - loose, (unsigned long) (loose_size / 1024)); return 0; } diff --git a/builtin/fast-export.c b/builtin/fast-export.c index ad9d0c46e8..d60d675f6f 100644 --- a/builtin/fast-export.c +++ b/builtin/fast-export.c @@ -24,7 +24,7 @@ static const char *fast_export_usage[] = { }; static int progress; -static enum { ABORT, VERBATIM, WARN, STRIP } signed_tag_mode = ABORT; +static enum { ABORT, VERBATIM, WARN, WARN_STRIP, STRIP } signed_tag_mode = ABORT; static enum { ERROR, DROP, REWRITE } tag_of_filtered_mode = ERROR; static int fake_missing_tagger; static int use_done_feature; @@ -40,6 +40,8 @@ static int parse_opt_signed_tag_mode(const struct option *opt, signed_tag_mode = VERBATIM; else if (!strcmp(arg, "warn")) signed_tag_mode = WARN; + else if (!strcmp(arg, "warn-strip")) + signed_tag_mode = WARN_STRIP; else if (!strcmp(arg, "strip")) signed_tag_mode = STRIP; else @@ -113,12 +115,13 @@ static void show_progress(void) printf("progress %d objects\n", counter); } -static void handle_object(const unsigned char *sha1) +static void export_blob(const unsigned char *sha1) { unsigned long size; enum object_type type; char *buf; struct object *object; + int eaten; if (no_data) return; @@ -126,16 +129,18 @@ static void handle_object(const unsigned char *sha1) if (is_null_sha1(sha1)) return; - object = parse_object(sha1); - if (!object) - die ("Could not read blob %s", sha1_to_hex(sha1)); - - if (object->flags & SHOWN) + object = lookup_object(sha1); + if (object && object->flags & SHOWN) return; buf = read_sha1_file(sha1, &type, &size); if (!buf) die ("Could not read blob %s", sha1_to_hex(sha1)); + if (check_sha1_signature(sha1, buf, size, typename(type)) < 0) + die("sha1 mismatch in blob %s", sha1_to_hex(sha1)); + object = parse_object_buffer(sha1, type, size, buf, &eaten); + if (!object) + die("Could not read blob %s", sha1_to_hex(sha1)); mark_next_object(object); @@ -147,7 +152,8 @@ static void handle_object(const unsigned char *sha1) show_progress(); object->flags |= SHOWN; - free(buf); + if (!eaten) + free(buf); } static int depth_first(const void *a_, const void *b_) @@ -312,7 +318,7 @@ static void handle_commit(struct commit *commit, struct rev_info *rev) /* Export the referenced blobs, and remember the marks. */ for (i = 0; i < diff_queued_diff.nr; i++) if (!S_ISGITLINK(diff_queued_diff.queue[i]->two->mode)) - handle_object(diff_queued_diff.queue[i]->two->sha1); + export_blob(diff_queued_diff.queue[i]->two->sha1); mark_next_object(&commit->object); if (!is_encoding_utf8(encoding)) @@ -424,6 +430,10 @@ static void handle_tag(const char *name, struct tag *tag) /* fallthru */ case VERBATIM: break; + case WARN_STRIP: + warning ("Stripping signature from tag %s", + sha1_to_hex(tag->object.sha1)); + /* fallthru */ case STRIP: message_size = signature + 1 - message; break; @@ -512,7 +522,7 @@ static void get_tags_and_duplicates(struct rev_cmdline_info *info, commit = (struct commit *)tag; break; case OBJ_BLOB: - handle_object(tag->object.sha1); + export_blob(tag->object.sha1); continue; default: /* OBJ_TAG (nested tags) is already handled */ warning("Tag points to object of unexpected type %s, skipping.", @@ -614,9 +624,12 @@ static void import_marks(char *input_file) || *mark_end != ' ' || get_sha1(mark_end + 1, sha1)) die("corrupt mark line: %s", line); + if (last_idnum < mark) + last_idnum = mark; + object = parse_object(sha1); if (!object) - die ("Could not read blob %s", sha1_to_hex(sha1)); + continue; if (object->flags & SHOWN) error("Object %s already has a mark", sha1_to_hex(sha1)); @@ -626,8 +639,6 @@ static void import_marks(char *input_file) continue; mark_object(object, mark); - if (last_idnum < mark) - last_idnum = mark; object->flags |= SHOWN; } @@ -641,6 +652,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) struct string_list extra_refs = STRING_LIST_INIT_NODUP; struct commit *commit; char *export_filename = NULL, *import_filename = NULL; + uint32_t lastimportid; struct option options[] = { OPT_INTEGER(0, "progress", &progress, N_("show progress after <n> objects")), @@ -684,6 +696,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) if (import_filename) import_marks(import_filename); + lastimportid = last_idnum; if (import_filename && revs.prune_data.nr) full_tree = 1; @@ -706,7 +719,7 @@ int cmd_fast_export(int argc, const char **argv, const char *prefix) handle_tags_and_duplicates(&extra_refs); - if (export_filename) + if (export_filename && lastimportid != last_idnum) export_marks(export_filename); if (use_done_feature) diff --git a/builtin/fetch-pack.c b/builtin/fetch-pack.c index 940ae35dc2..aba4465552 100644 --- a/builtin/fetch-pack.c +++ b/builtin/fetch-pack.c @@ -7,12 +7,31 @@ static const char fetch_pack_usage[] = "[--include-tag] [--upload-pack=<git-upload-pack>] [--depth=<n>] " "[--no-progress] [-v] [<host>:]<directory> [<refs>...]"; +static void add_sought_entry_mem(struct ref ***sought, int *nr, int *alloc, + const char *name, int namelen) +{ + struct ref *ref = xcalloc(1, sizeof(*ref) + namelen + 1); + + memcpy(ref->name, name, namelen); + ref->name[namelen] = '\0'; + (*nr)++; + ALLOC_GROW(*sought, *nr, *alloc); + (*sought)[*nr - 1] = ref; +} + +static void add_sought_entry(struct ref ***sought, int *nr, int *alloc, + const char *string) +{ + add_sought_entry_mem(sought, nr, alloc, string, strlen(string)); +} + int cmd_fetch_pack(int argc, const char **argv, const char *prefix) { int i, ret; struct ref *ref = NULL; const char *dest = NULL; - struct string_list sought = STRING_LIST_INIT_DUP; + struct ref **sought = NULL; + int nr_sought = 0, alloc_sought = 0; int fd[2]; char *pack_lockfile = NULL; char **pack_lockfile_ptr = NULL; @@ -94,27 +113,24 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) * refs from the standard input: */ for (; i < argc; i++) - string_list_append(&sought, xstrdup(argv[i])); + add_sought_entry(&sought, &nr_sought, &alloc_sought, argv[i]); if (args.stdin_refs) { if (args.stateless_rpc) { /* in stateless RPC mode we use pkt-line to read * from stdin, until we get a flush packet */ - static char line[1000]; for (;;) { - int n = packet_read_line(0, line, sizeof(line)); - if (!n) + char *line = packet_read_line(0, NULL); + if (!line) break; - if (line[n-1] == '\n') - n--; - string_list_append(&sought, xmemdupz(line, n)); + add_sought_entry(&sought, &nr_sought, &alloc_sought, line); } } else { /* read from stdin one ref per line, until EOF */ struct strbuf line = STRBUF_INIT; while (strbuf_getline(&line, stdin, '\n') != EOF) - string_list_append(&sought, strbuf_detach(&line, NULL)); + add_sought_entry(&sought, &nr_sought, &alloc_sought, line.buf); strbuf_release(&line); } } @@ -128,10 +144,10 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) args.verbose ? CONNECT_VERBOSE : 0); } - get_remote_heads(fd[0], &ref, 0, NULL); + get_remote_heads(fd[0], NULL, 0, &ref, 0, NULL); ref = fetch_pack(&args, fd, conn, ref, dest, - &sought, pack_lockfile_ptr); + sought, nr_sought, pack_lockfile_ptr); if (pack_lockfile) { printf("lock %s\n", pack_lockfile); fflush(stdout); @@ -141,7 +157,7 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) if (finish_connect(conn)) return 1; - ret = !ref || sought.nr; + ret = !ref; /* * If the heads to pull were given, we should have consumed @@ -149,8 +165,13 @@ int cmd_fetch_pack(int argc, const char **argv, const char *prefix) * remote no-such-ref' would silently succeed without issuing * an error. */ - for (i = 0; i < sought.nr; i++) - error("no such remote ref %s", sought.items[i].string); + for (i = 0; i < nr_sought; i++) { + if (!sought[i] || sought[i]->matched) + continue; + error("no such remote ref %s", sought[i]->name); + ret = 1; + } + while (ref) { printf("%s %s\n", sha1_to_hex(ref->old_sha1), ref->name); diff --git a/builtin/help.c b/builtin/help.c index d1d71816a9..062957f629 100644 --- a/builtin/help.c +++ b/builtin/help.c @@ -36,10 +36,12 @@ enum help_format { static const char *html_path; static int show_all = 0; +static int show_guides = 0; static unsigned int colopts; static enum help_format help_format = HELP_FORMAT_NONE; static struct option builtin_help_options[] = { - OPT_BOOLEAN('a', "all", &show_all, N_("print all available commands")), + OPT_BOOL('a', "all", &show_all, N_("print all available commands")), + OPT_BOOL('g', "guides", &show_guides, N_("print list of useful guides")), OPT_SET_INT('m', "man", &help_format, N_("show man page"), HELP_FORMAT_MAN), OPT_SET_INT('w', "web", &help_format, N_("show manual in web browser"), HELP_FORMAT_WEB), @@ -49,7 +51,7 @@ static struct option builtin_help_options[] = { }; static const char * const builtin_help_usage[] = { - N_("git help [--all] [--man|--web|--info] [command]"), + N_("git help [--all] [--guides] [--man|--web|--info] [command]"), NULL }; @@ -413,6 +415,37 @@ static void show_html_page(const char *git_cmd) open_html(page_path.buf); } +static struct { + const char *name; + const char *help; +} common_guides[] = { + { "attributes", N_("Defining attributes per path") }, + { "glossary", N_("A Git glossary") }, + { "ignore", N_("Specifies intentionally untracked files to ignore") }, + { "modules", N_("Defining submodule properties") }, + { "revisions", N_("Specifying revisions and ranges for Git") }, + { "tutorial", N_("A tutorial introduction to Git (for version 1.5.1 or newer)") }, + { "workflows", N_("An overview of recommended workflows with Git") }, +}; + +static void list_common_guides_help(void) +{ + int i, longest = 0; + + for (i = 0; i < ARRAY_SIZE(common_guides); i++) { + if (longest < strlen(common_guides[i].name)) + longest = strlen(common_guides[i].name); + } + + puts(_("The common Git guides are:\n")); + for (i = 0; i < ARRAY_SIZE(common_guides); i++) { + printf(" %s ", common_guides[i].name); + mput_char(' ', longest - strlen(common_guides[i].name)); + puts(_(common_guides[i].help)); + } + putchar('\n'); +} + int cmd_help(int argc, const char **argv, const char *prefix) { int nongit; @@ -428,7 +461,16 @@ int cmd_help(int argc, const char **argv, const char *prefix) git_config(git_help_config, NULL); printf(_("usage: %s%s"), _(git_usage_string), "\n\n"); list_commands(colopts, &main_cmds, &other_cmds); + } + + if (show_guides) + list_common_guides_help(); + + if (show_all || show_guides) { printf("%s\n", _(git_more_info_string)); + /* + * We're done. Ignore any remaining args + */ return 0; } diff --git a/builtin/log.c b/builtin/log.c index 8f0b2e84fe..6e56a50002 100644 --- a/builtin/log.c +++ b/builtin/log.c @@ -23,6 +23,7 @@ #include "streaming.h" #include "version.h" #include "mailmap.h" +#include "gpg-interface.h" /* Set a default date-time format for git log ("log.date" config variable) */ static const char *default_date_mode = NULL; @@ -36,7 +37,7 @@ static const char *fmt_patch_subject_prefix = "PATCH"; static const char *fmt_pretty; static const char * const builtin_log_usage[] = { - N_("git log [<options>] [<since>..<until>] [[--] <path>...]\n") + N_("git log [<options>] [<revision range>] [[--] <path>...]\n") N_(" or: git show [options] <object>..."), NULL }; @@ -99,9 +100,9 @@ static void cmd_log_init_finish(int argc, const char **argv, const char *prefix, int quiet = 0, source = 0, mailmap = 0; const struct option builtin_log_options[] = { - OPT_BOOLEAN(0, "quiet", &quiet, N_("suppress diff output")), - OPT_BOOLEAN(0, "source", &source, N_("show source")), - OPT_BOOLEAN(0, "use-mailmap", &mailmap, N_("Use mail map file")), + OPT_BOOL(0, "quiet", &quiet, N_("suppress diff output")), + OPT_BOOL(0, "source", &source, N_("show source")), + OPT_BOOL(0, "use-mailmap", &mailmap, N_("Use mail map file")), { OPTION_CALLBACK, 0, "decorate", NULL, NULL, N_("decorate options"), PARSE_OPT_OPTARG, decorate_callback}, OPT_END() @@ -367,6 +368,8 @@ static int git_log_config(const char *var, const char *value, void *cb) if (grep_config(var, value, cb) < 0) return -1; + if (git_gpg_config(var, value, cb) < 0) + return -1; return git_diff_ui_config(var, value, cb); } @@ -619,6 +622,14 @@ static void add_header(const char *value) static int thread; static int do_signoff; static const char *signature = git_version_string; +static int config_cover_letter; + +enum { + COVER_UNSET, + COVER_OFF, + COVER_ON, + COVER_AUTO +}; static int git_format_config(const char *var, const char *value, void *cb) { @@ -680,6 +691,14 @@ static int git_format_config(const char *var, const char *value, void *cb) } if (!strcmp(var, "format.signature")) return git_config_string(&signature, var, value); + if (!strcmp(var, "format.coverletter")) { + if (value && !strcasecmp(value, "auto")) { + config_cover_letter = COVER_AUTO; + return 0; + } + config_cover_letter = git_config_bool(var, value) ? COVER_ON : COVER_OFF; + return 0; + } return git_log_config(var, value, cb); } @@ -791,9 +810,37 @@ static void add_branch_description(struct strbuf *buf, const char *branch_name) } } +static char *find_branch_name(struct rev_info *rev) +{ + int i, positive = -1; + unsigned char branch_sha1[20]; + const unsigned char *tip_sha1; + const char *ref; + char *full_ref, *branch = NULL; + + for (i = 0; i < rev->cmdline.nr; i++) { + if (rev->cmdline.rev[i].flags & UNINTERESTING) + continue; + if (positive < 0) + positive = i; + else + return NULL; + } + if (positive < 0) + return NULL; + ref = rev->cmdline.rev[positive].name; + tip_sha1 = rev->cmdline.rev[positive].item->sha1; + if (dwim_ref(ref, strlen(ref), branch_sha1, &full_ref) && + !prefixcmp(full_ref, "refs/heads/") && + !hashcmp(tip_sha1, branch_sha1)) + branch = xstrdup(full_ref + strlen("refs/heads/")); + free(full_ref); + return branch; +} + static void make_cover_letter(struct rev_info *rev, int use_stdout, struct commit *origin, - int nr, struct commit **list, struct commit *head, + int nr, struct commit **list, const char *branch_name, int quiet) { @@ -807,6 +854,7 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, struct diff_options opts; int need_8bit_cte = 0; struct pretty_print_context pp = {0}; + struct commit *head = list[0]; if (rev->commit_format != CMIT_FMT_EMAIL) die(_("Cover letter needs email format")); @@ -824,6 +872,9 @@ static void make_cover_letter(struct rev_info *rev, int use_stdout, if (has_non_ascii(list[i]->buffer)) need_8bit_cte = 1; + if (!branch_name) + branch_name = find_branch_name(rev); + msg = body; pp.fmt = CMIT_FMT_EMAIL; pp.date_mode = DATE_RFC2822; @@ -1030,45 +1081,6 @@ static int cc_callback(const struct option *opt, const char *arg, int unset) return 0; } -static char *find_branch_name(struct rev_info *rev) -{ - int i, positive = -1; - unsigned char branch_sha1[20]; - const unsigned char *tip_sha1; - const char *ref; - char *full_ref, *branch = NULL; - - for (i = 0; i < rev->cmdline.nr; i++) { - if (rev->cmdline.rev[i].flags & UNINTERESTING) - continue; - if (positive < 0) - positive = i; - else - return NULL; - } - if (0 <= positive) { - ref = rev->cmdline.rev[positive].name; - tip_sha1 = rev->cmdline.rev[positive].item->sha1; - } else if (!rev->cmdline.nr && rev->pending.nr == 1 && - !strcmp(rev->pending.objects[0].name, "HEAD")) { - /* - * No actual ref from command line, but "HEAD" from - * rev->def was added in setup_revisions() - * e.g. format-patch --cover-letter -12 - */ - ref = "HEAD"; - tip_sha1 = rev->pending.objects[0].item->sha1; - } else { - return NULL; - } - if (dwim_ref(ref, strlen(ref), branch_sha1, &full_ref) && - !prefixcmp(full_ref, "refs/heads/") && - !hashcmp(tip_sha1, branch_sha1)) - branch = xstrdup(full_ref + strlen("refs/heads/")); - free(full_ref); - return branch; -} - int cmd_format_patch(int argc, const char **argv, const char *prefix) { struct commit *commit; @@ -1080,13 +1092,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) int start_number = -1; int just_numbers = 0; int ignore_if_in_upstream = 0; - int cover_letter = 0; + int cover_letter = -1; int boundary_count = 0; int no_binary_diff = 0; - struct commit *origin = NULL, *head = NULL; + struct commit *origin = NULL; const char *in_reply_to = NULL; struct patch_ids ids; - char *add_signoff = NULL; struct strbuf buf = STRBUF_INIT; int use_patch_format = 0; int quiet = 0; @@ -1099,12 +1110,12 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) { OPTION_CALLBACK, 'N', "no-numbered", &numbered, NULL, N_("use [PATCH] even with multiple patches"), PARSE_OPT_NOARG, no_numbered_callback }, - OPT_BOOLEAN('s', "signoff", &do_signoff, N_("add Signed-off-by:")), - OPT_BOOLEAN(0, "stdout", &use_stdout, + OPT_BOOL('s', "signoff", &do_signoff, N_("add Signed-off-by:")), + OPT_BOOL(0, "stdout", &use_stdout, N_("print patches to standard out")), - OPT_BOOLEAN(0, "cover-letter", &cover_letter, + OPT_BOOL(0, "cover-letter", &cover_letter, N_("generate a cover letter")), - OPT_BOOLEAN(0, "numbered-files", &just_numbers, + OPT_BOOL(0, "numbered-files", &just_numbers, N_("use simple number sequence for output file names")), OPT_STRING(0, "suffix", &fmt_patch_suffix, N_("sfx"), N_("use <sfx> instead of '.patch'")), @@ -1193,16 +1204,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) rev.subject_prefix = strbuf_detach(&sprefix, NULL); } - if (do_signoff) { - const char *committer; - const char *endpos; - committer = git_committer_info(IDENT_STRICT); - endpos = strchr(committer, '>'); - if (!endpos) - die(_("bogus committer info %s"), committer); - add_signoff = xmemdupz(committer, endpos - committer + 1); - } - for (i = 0; i < extra_hdr.nr; i++) { strbuf_addstr(&buf, extra_hdr.items[i].string); strbuf_addch(&buf, '\n'); @@ -1288,28 +1289,36 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) } if (rev.pending.nr == 1) { + int check_head = 0; + if (rev.max_count < 0 && !rev.show_root_diff) { /* * This is traditional behaviour of "git format-patch * origin" that prepares what the origin side still * does not have. */ - unsigned char sha1[20]; - const char *ref; - rev.pending.objects[0].item->flags |= UNINTERESTING; add_head_to_pending(&rev); - ref = resolve_ref_unsafe("HEAD", sha1, 1, NULL); - if (ref && !prefixcmp(ref, "refs/heads/")) - branch_name = xstrdup(ref + strlen("refs/heads/")); - else - branch_name = xstrdup(""); /* no branch */ + check_head = 1; } /* * Otherwise, it is "format-patch -22 HEAD", and/or * "format-patch --root HEAD". The user wants * get_revision() to do the usual traversal. */ + + if (!strcmp(rev.pending.objects[0].name, "HEAD")) + check_head = 1; + + if (check_head) { + unsigned char sha1[20]; + const char *ref; + ref = resolve_ref_unsafe("HEAD", sha1, 1, NULL); + if (ref && !prefixcmp(ref, "refs/heads/")) + branch_name = xstrdup(ref + strlen("refs/heads/")); + else + branch_name = xstrdup(""); /* no branch */ + } } /* @@ -1318,29 +1327,6 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) */ rev.show_root_diff = 1; - if (cover_letter) { - /* - * NEEDSWORK:randomly pick one positive commit to show - * diffstat; this is often the tip and the command - * happens to do the right thing in most cases, but a - * complex command like "--cover-letter a b c ^bottom" - * picks "c" and shows diffstat between bottom..c - * which may not match what the series represents at - * all and totally broken. - */ - int i; - for (i = 0; i < rev.pending.nr; i++) { - struct object *o = rev.pending.objects[i].item; - if (!(o->flags & UNINTERESTING)) - head = (struct commit *)o; - } - /* There is nothing to show; it is not an error, though. */ - if (!head) - return 0; - if (!branch_name) - branch_name = find_branch_name(&rev); - } - if (ignore_if_in_upstream) { /* Don't say anything if head and upstream are the same. */ if (rev.pending.nr == 2) { @@ -1372,11 +1358,21 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) list = xrealloc(list, nr * sizeof(list[0])); list[nr - 1] = commit; } + if (nr == 0) + /* nothing to do */ + return 0; total = nr; if (!keep_subject && auto_number && total > 1) numbered = 1; if (numbered) rev.total = total + start_number - 1; + if (cover_letter == -1) { + if (config_cover_letter == COVER_AUTO) + cover_letter = (total > 1); + else + cover_letter = (config_cover_letter == COVER_ON); + } + if (in_reply_to || thread || cover_letter) rev.ref_message_ids = xcalloc(1, sizeof(struct string_list)); if (in_reply_to) { @@ -1389,11 +1385,11 @@ int cmd_format_patch(int argc, const char **argv, const char *prefix) if (thread) gen_message_id(&rev, "cover"); make_cover_letter(&rev, use_stdout, - origin, nr, list, head, branch_name, quiet); + origin, nr, list, branch_name, quiet); total++; start_number--; } - rev.add_signoff = add_signoff; + rev.add_signoff = do_signoff; while (0 <= --nr) { int shown; commit = list[nr]; diff --git a/builtin/ls-files.c b/builtin/ls-files.c index 175e6e3e72..22020729cb 100644 --- a/builtin/ls-files.c +++ b/builtin/ls-files.c @@ -201,19 +201,15 @@ static void show_ru_info(void) } } -static int ce_excluded(struct path_exclude_check *check, struct cache_entry *ce) +static int ce_excluded(struct dir_struct *dir, struct cache_entry *ce) { int dtype = ce_to_dtype(ce); - return is_path_excluded(check, ce->name, ce_namelen(ce), &dtype); + return is_excluded(dir, ce->name, &dtype); } static void show_files(struct dir_struct *dir) { int i; - struct path_exclude_check check; - - if ((dir->flags & DIR_SHOW_IGNORED)) - path_exclude_check_init(&check, dir); /* For cached/deleted files we don't need to even do the readdir */ if (show_others || show_killed) { @@ -227,7 +223,7 @@ static void show_files(struct dir_struct *dir) for (i = 0; i < active_nr; i++) { struct cache_entry *ce = active_cache[i]; if ((dir->flags & DIR_SHOW_IGNORED) && - !ce_excluded(&check, ce)) + !ce_excluded(dir, ce)) continue; if (show_unmerged && !ce_stage(ce)) continue; @@ -243,7 +239,7 @@ static void show_files(struct dir_struct *dir) struct stat st; int err; if ((dir->flags & DIR_SHOW_IGNORED) && - !ce_excluded(&check, ce)) + !ce_excluded(dir, ce)) continue; if (ce->ce_flags & CE_UPDATE) continue; @@ -256,9 +252,6 @@ static void show_files(struct dir_struct *dir) show_ce_entry(tag_modified, ce); } } - - if ((dir->flags & DIR_SHOW_IGNORED)) - path_exclude_check_clear(&check); } /* diff --git a/builtin/merge-tree.c b/builtin/merge-tree.c index bc912e399e..61cbde4094 100644 --- a/builtin/merge-tree.c +++ b/builtin/merge-tree.c @@ -155,6 +155,11 @@ static int same_entry(struct name_entry *a, struct name_entry *b) a->mode == b->mode; } +static int both_empty(struct name_entry *a, struct name_entry *b) +{ + return !(a->sha1 || b->sha1); +} + static struct merge_list *create_entry(unsigned stage, unsigned mode, const unsigned char *sha1, const char *path) { struct merge_list *res = xcalloc(1, sizeof(*res)); @@ -246,7 +251,11 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3]) for (i = 0; i < 3; i++) { mask |= (1 << i); - if (n[i].mode && S_ISDIR(n[i].mode)) + /* + * Treat missing entries as directories so that we return + * after unresolved_directory has handled this. + */ + if (!n[i].mode || S_ISDIR(n[i].mode)) dirmask |= (1 << i); } @@ -297,13 +306,10 @@ static void unresolved(const struct traverse_info *info, struct name_entry n[3]) static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, struct name_entry *entry, struct traverse_info *info) { /* Same in both? */ - if (same_entry(entry+1, entry+2)) { - if (entry[0].sha1) { - /* Modified identically */ - resolve(info, NULL, entry+1); - return mask; - } - /* "Both added the same" is left unresolved */ + if (same_entry(entry+1, entry+2) || both_empty(entry+1, entry+2)) { + /* Modified, added or removed identically */ + resolve(info, NULL, entry+1); + return mask; } if (same_entry(entry+0, entry+1)) { @@ -319,12 +325,10 @@ static int threeway_callback(int n, unsigned long mask, unsigned long dirmask, s */ } - if (same_entry(entry+0, entry+2)) { - if (entry[1].sha1 && !S_ISDIR(entry[1].mode)) { - /* We modified, they did not touch -- take ours */ - resolve(info, NULL, entry+1); - return mask; - } + if (same_entry(entry+0, entry+2) || both_empty(entry+0, entry+2)) { + /* We added, modified or removed, they did not touch -- take ours */ + resolve(info, NULL, entry+1); + return mask; } unresolved(info, entry); diff --git a/builtin/merge.c b/builtin/merge.c index 0d94d89e74..3e2daa37c3 100644 --- a/builtin/merge.c +++ b/builtin/merge.c @@ -49,7 +49,7 @@ static const char * const builtin_merge_usage[] = { static int show_diffstat = 1, shortlog_len = -1, squash; static int option_commit = 1, allow_fast_forward = 1; static int fast_forward_only, option_edit = -1; -static int allow_trivial = 1, have_message; +static int allow_trivial = 1, have_message, verify_signatures; static int overwrite_ignore = 1; static struct strbuf merge_msg = STRBUF_INIT; static struct strategy **use_strategies; @@ -199,6 +199,8 @@ static struct option builtin_merge_options[] = { OPT_BOOLEAN(0, "ff-only", &fast_forward_only, N_("abort if fast-forward is not possible")), OPT_RERERE_AUTOUPDATE(&allow_rerere_auto), + OPT_BOOL(0, "verify-signatures", &verify_signatures, + N_("Verify that the named commit has a valid GPG signature")), OPT_CALLBACK('s', "strategy", &use_strategies, N_("strategy"), N_("merge strategy to use"), option_parse_strategy), OPT_CALLBACK('X', "strategy-option", &xopts, N_("option=value"), @@ -1246,6 +1248,39 @@ int cmd_merge(int argc, const char **argv, const char *prefix) usage_with_options(builtin_merge_usage, builtin_merge_options); + if (verify_signatures) { + for (p = remoteheads; p; p = p->next) { + struct commit *commit = p->item; + char hex[41]; + struct signature_check signature_check; + memset(&signature_check, 0, sizeof(signature_check)); + + check_commit_signature(commit, &signature_check); + + strcpy(hex, find_unique_abbrev(commit->object.sha1, DEFAULT_ABBREV)); + switch (signature_check.result) { + case 'G': + break; + case 'U': + die(_("Commit %s has an untrusted GPG signature, " + "allegedly by %s."), hex, signature_check.signer); + case 'B': + die(_("Commit %s has a bad GPG signature " + "allegedly by %s."), hex, signature_check.signer); + default: /* 'N' */ + die(_("Commit %s does not have a GPG signature."), hex); + } + if (verbosity >= 0 && signature_check.result == 'G') + printf(_("Commit %s has a good GPG signature by %s\n"), + hex, signature_check.signer); + + free(signature_check.gpg_output); + free(signature_check.gpg_status); + free(signature_check.signer); + free(signature_check.key); + } + } + strbuf_addstr(&buf, "merge"); for (p = remoteheads; p; p = p->next) strbuf_addf(&buf, " %s", merge_remote_util(p->item)->name); diff --git a/builtin/pack-refs.c b/builtin/pack-refs.c index b5a0f88eb8..b20b1ec4c1 100644 --- a/builtin/pack-refs.c +++ b/builtin/pack-refs.c @@ -1,6 +1,6 @@ #include "builtin.h" #include "parse-options.h" -#include "pack-refs.h" +#include "refs.h" static char const * const pack_refs_usage[] = { N_("git pack-refs [options]"), diff --git a/builtin/prune.c b/builtin/prune.c index 85843d4f17..b90e5cc361 100644 --- a/builtin/prune.c +++ b/builtin/prune.c @@ -132,8 +132,8 @@ int cmd_prune(int argc, const char **argv, const char *prefix) OPT__DRY_RUN(&show_only, N_("do not remove, show only")), OPT__VERBOSE(&verbose, N_("report pruned objects")), OPT_BOOL(0, "progress", &show_progress, N_("show progress")), - OPT_DATE(0, "expire", &expire, - N_("expire objects older than <time>")), + OPT_EXPIRY_DATE(0, "expire", &expire, + N_("expire objects older than <time>")), OPT_END() }; char *s; diff --git a/builtin/push.c b/builtin/push.c index 42b129d36c..909c34dfda 100644 --- a/builtin/push.c +++ b/builtin/push.c @@ -322,7 +322,7 @@ static int push_with_options(struct transport *transport, int flags) static int do_push(const char *repo, int flags) { int i, errs; - struct remote *remote = remote_get(repo); + struct remote *remote = pushremote_get(repo); const char **url; int url_nr; @@ -437,6 +437,8 @@ int cmd_push(int argc, const char **argv, const char *prefix) OPT_BIT(0, "prune", &flags, N_("prune locally removed refs"), TRANSPORT_PUSH_PRUNE), OPT_BIT(0, "no-verify", &flags, N_("bypass pre-push hook"), TRANSPORT_PUSH_NO_HOOK), + OPT_BIT(0, "follow-tags", &flags, N_("push missing but relevant tags"), + TRANSPORT_PUSH_FOLLOW_TAGS), OPT_END() }; diff --git a/builtin/receive-pack.c b/builtin/receive-pack.c index 89792b0a33..e3eb5fc058 100644 --- a/builtin/receive-pack.c +++ b/builtin/receive-pack.c @@ -754,17 +754,15 @@ static struct command *read_head_info(void) struct command *commands = NULL; struct command **p = &commands; for (;;) { - static char line[1000]; + char *line; unsigned char old_sha1[20], new_sha1[20]; struct command *cmd; char *refname; int len, reflen; - len = packet_read_line(0, line, sizeof(line)); - if (!len) + line = packet_read_line(0, &len); + if (!line) break; - if (line[len-1] == '\n') - line[--len] = 0; if (len < 83 || line[40] != ' ' || line[81] != ' ' || @@ -935,7 +933,7 @@ static void report(struct command *commands, const char *unpack_status) if (use_sideband) send_sideband(1, 1, buf.buf, buf.len, use_sideband); else - safe_write(1, buf.buf, buf.len); + write_or_die(1, buf.buf, buf.len); strbuf_release(&buf); } diff --git a/builtin/reflog.c b/builtin/reflog.c index 72a0af70c3..54184b3d13 100644 --- a/builtin/reflog.c +++ b/builtin/reflog.c @@ -496,11 +496,9 @@ static int parse_expire_cfg_value(const char *var, const char *value, unsigned l { if (!value) return config_error_nonbool(var); - if (!strcmp(value, "never") || !strcmp(value, "false")) { - *expire = 0; - return 0; - } - *expire = approxidate(value); + if (parse_expiry_date(value, expire)) + return error(_("%s' for '%s' is not a valid timestamp"), + value, var); return 0; } @@ -614,11 +612,13 @@ static int cmd_reflog_expire(int argc, const char **argv, const char *prefix) if (!strcmp(arg, "--dry-run") || !strcmp(arg, "-n")) cb.dry_run = 1; else if (!prefixcmp(arg, "--expire=")) { - cb.expire_total = approxidate(arg + 9); + if (parse_expiry_date(arg + 9, &cb.expire_total)) + die(_("'%s' is not a valid timestamp"), arg); explicit_expiry |= EXPIRE_TOTAL; } else if (!prefixcmp(arg, "--expire-unreachable=")) { - cb.expire_unreachable = approxidate(arg + 21); + if (parse_expiry_date(arg + 21, &cb.expire_unreachable)) + die(_("'%s' is not a valid timestamp"), arg); explicit_expiry |= EXPIRE_UNREACH; } else if (!strcmp(arg, "--stale-fix")) diff --git a/builtin/remote.c b/builtin/remote.c index 937484d7c7..5e54d367b8 100644 --- a/builtin/remote.c +++ b/builtin/remote.c @@ -178,7 +178,7 @@ static int add(int argc, const char **argv) argc = parse_options(argc, argv, NULL, options, builtin_remote_add_usage, 0); - if (argc < 2) + if (argc != 2) usage_with_options(builtin_remote_add_usage, options); if (mirror && master) diff --git a/builtin/rm.c b/builtin/rm.c index dabfcf6890..7b91d52f39 100644 --- a/builtin/rm.c +++ b/builtin/rm.c @@ -110,7 +110,7 @@ static int check_local_mod(unsigned char *head, int index_only) ce = active_cache[pos]; if (lstat(ce->name, &st) < 0) { - if (errno != ENOENT) + if (errno != ENOENT && errno != ENOTDIR) warning("'%s': %s", ce->name, strerror(errno)); /* It already vanished from the working tree */ continue; diff --git a/builtin/send-pack.c b/builtin/send-pack.c index 57a46b2654..152c4ea092 100644 --- a/builtin/send-pack.c +++ b/builtin/send-pack.c @@ -79,7 +79,7 @@ static void print_helper_status(struct ref *ref) } strbuf_addch(&buf, '\n'); - safe_write(1, buf.buf, buf.len); + write_or_die(1, buf.buf, buf.len); } strbuf_release(&buf); } @@ -207,7 +207,7 @@ int cmd_send_pack(int argc, const char **argv, const char *prefix) memset(&extra_have, 0, sizeof(extra_have)); - get_remote_heads(fd[0], &remote_refs, REF_NORMAL, &extra_have); + get_remote_heads(fd[0], NULL, 0, &remote_refs, REF_NORMAL, &extra_have); transport_verify_remote_names(nr_refspecs, refspecs); diff --git a/builtin/shortlog.c b/builtin/shortlog.c index 240bff3efa..1fd6f8ac59 100644 --- a/builtin/shortlog.c +++ b/builtin/shortlog.c @@ -10,9 +10,7 @@ #include "parse-options.h" static char const * const shortlog_usage[] = { - N_("git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]"), - "", - N_("[rev-opts] are documented in git-rev-list(1)"), + N_("git shortlog [<options>] [<revision range>] [[--] [<path>...]]"), NULL }; diff --git a/builtin/upload-archive.c b/builtin/upload-archive.c index b928beb8ed..af2da35e7d 100644 --- a/builtin/upload-archive.c +++ b/builtin/upload-archive.c @@ -7,6 +7,7 @@ #include "pkt-line.h" #include "sideband.h" #include "run-command.h" +#include "argv-array.h" static const char upload_archive_usage[] = "git upload-archive <repo>"; @@ -18,51 +19,31 @@ static const char deadchild[] = int cmd_upload_archive_writer(int argc, const char **argv, const char *prefix) { - const char *sent_argv[MAX_ARGS]; + struct argv_array sent_argv = ARGV_ARRAY_INIT; const char *arg_cmd = "argument "; - char *p, buf[4096]; - int sent_argc; - int len; if (argc != 2) usage(upload_archive_usage); - if (strlen(argv[1]) + 1 > sizeof(buf)) - die("insanely long repository name"); - - strcpy(buf, argv[1]); /* enter-repo smudges its argument */ - - if (!enter_repo(buf, 0)) - die("'%s' does not appear to be a git repository", buf); + if (!enter_repo(argv[1], 0)) + die("'%s' does not appear to be a git repository", argv[1]); /* put received options in sent_argv[] */ - sent_argc = 1; - sent_argv[0] = "git-upload-archive"; - for (p = buf;;) { - /* This will die if not enough free space in buf */ - len = packet_read_line(0, p, (buf + sizeof buf) - p); - if (len == 0) + argv_array_push(&sent_argv, "git-upload-archive"); + for (;;) { + char *buf = packet_read_line(0, NULL); + if (!buf) break; /* got a flush */ - if (sent_argc > MAX_ARGS - 2) - die("Too many options (>%d)", MAX_ARGS - 2); + if (sent_argv.argc > MAX_ARGS) + die("Too many options (>%d)", MAX_ARGS - 1); - if (p[len-1] == '\n') { - p[--len] = 0; - } - if (len < strlen(arg_cmd) || - strncmp(arg_cmd, p, strlen(arg_cmd))) + if (prefixcmp(buf, arg_cmd)) die("'argument' token or flush expected"); - - len -= strlen(arg_cmd); - memmove(p, p + strlen(arg_cmd), len); - sent_argv[sent_argc++] = p; - p += len; - *p++ = 0; + argv_array_push(&sent_argv, buf + strlen(arg_cmd)); } - sent_argv[sent_argc] = NULL; /* parse all options sent by the client */ - return write_archive(sent_argc, sent_argv, prefix, 0, NULL, 1); + return write_archive(sent_argv.argc, sent_argv.argv, prefix, 0, NULL, 1); } __attribute__((format (printf, 1, 2))) @@ -34,6 +34,7 @@ int git_inflate(git_zstream *, int flush); void git_deflate_init(git_zstream *, int level); void git_deflate_init_gzip(git_zstream *, int level); +void git_deflate_init_raw(git_zstream *, int level); void git_deflate_end(git_zstream *); int git_deflate_abort(git_zstream *); int git_deflate_end_gently(git_zstream *); @@ -161,6 +162,9 @@ struct cache_entry { #define CE_UNPACKED (1 << 24) #define CE_NEW_SKIP_WORKTREE (1 << 25) +/* used to temporarily mark paths matched by pathspecs */ +#define CE_MATCHED (1 << 26) + /* * Extended on-disk flags */ @@ -307,6 +311,7 @@ extern void free_name_hash(struct index_state *istate); #define resolve_undo_clear() resolve_undo_clear_index(&the_index) #define unmerge_cache_entry_at(at) unmerge_index_entry_at(&the_index, at) #define unmerge_cache(pathspec) unmerge_index(&the_index, pathspec) +#define read_blob_data_from_cache(path, sz) read_blob_data_from_index(&the_index, (path), (sz)) #endif enum object_type { @@ -461,11 +466,13 @@ extern int remove_file_from_index(struct index_state *, const char *path); #define ADD_CACHE_IGNORE_ERRORS 4 #define ADD_CACHE_IGNORE_REMOVAL 8 #define ADD_CACHE_INTENT 16 +#define ADD_CACHE_IMPLICIT_DOT 32 /* internal to "git add -u/-A" */ extern int add_to_index(struct index_state *, const char *path, struct stat *, int flags); extern int add_file_to_index(struct index_state *, const char *path, int flags); extern struct cache_entry *make_cache_entry(unsigned int mode, const unsigned char *sha1, const char *path, int stage, int refresh); extern int ce_same_name(struct cache_entry *a, struct cache_entry *b); extern int index_name_is_other(const struct index_state *, const char *, int); +extern void *read_blob_data_from_index(struct index_state *, const char *, unsigned long *); /* do stat comparison even if CE_VALID is true */ #define CE_MATCH_IGNORE_VALID 01 @@ -715,8 +722,7 @@ enum sharedrepo { PERM_EVERYBODY = 0664 }; int git_config_perm(const char *var, const char *value); -int set_shared_perm(const char *path, int mode); -#define adjust_shared_perm(path) set_shared_perm((path), 0) +int adjust_shared_perm(const char *path); int safe_create_leading_directories(char *path); int safe_create_leading_directories_const(const char *path); int mkdir_in_gitdir(const char *path); @@ -904,6 +910,7 @@ void show_date_relative(unsigned long time, int tz, const struct timeval *now, struct strbuf *timebuf); int parse_date(const char *date, char *buf, int bufsize); int parse_date_basic(const char *date, unsigned long *timestamp, int *offset); +int parse_expiry_date(const char *date, unsigned long *timestamp); void datestamp(char *buf, int bufsize); #define approxidate(s) approxidate_careful((s), NULL) unsigned long approxidate_careful(const char *, int *); @@ -1019,7 +1026,8 @@ struct ref { force:1, forced_update:1, merge:1, - deletion:1; + deletion:1, + matched:1; enum { REF_STATUS_NONE = 0, REF_STATUS_OK, @@ -1051,7 +1059,9 @@ struct extra_have_objects { int nr, alloc; unsigned char (*array)[20]; }; -extern struct ref **get_remote_heads(int in, struct ref **list, unsigned int flags, struct extra_have_objects *); +extern struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, + struct ref **list, unsigned int flags, + struct extra_have_objects *); extern int server_supports(const char *feature); extern int parse_feature_request(const char *features, const char *feature); extern const char *server_feature_value(const char *feature, int *len_ret); @@ -1059,6 +1069,9 @@ extern const char *parse_feature_value(const char *feature_list, const char *fea extern struct packed_git *parse_pack_index(unsigned char *sha1, const char *idx_path); +/* A hook for count-objects to report invalid files in pack directory */ +extern void (*report_garbage)(const char *desc, const char *path); + extern void prepare_packed_git(void); extern void reprepare_packed_git(void); extern void install_packed_git(struct packed_git *pack); diff --git a/combine-diff.c b/combine-diff.c index 6288485965..77d7872aaf 100644 --- a/combine-diff.c +++ b/combine-diff.c @@ -74,16 +74,24 @@ static struct combine_diff_path *intersect_paths(struct combine_diff_path *curr, /* Lines lost from parent */ struct lline { - struct lline *next; + struct lline *next, *prev; int len; unsigned long parent_map; char line[FLEX_ARRAY]; }; +/* Lines lost from current parent (before coalescing) */ +struct plost { + struct lline *lost_head, *lost_tail; + int len; +}; + /* Lines surviving in the merge result */ struct sline { - struct lline *lost_head, **lost_tail; - struct lline *next_lost; + /* Accumulated and coalesced lost lines */ + struct lline *lost; + int lenlost; + struct plost plost; char *bol; int len; /* bit 0 up to (N-1) are on if the parent has this line (i.e. @@ -95,34 +103,6 @@ struct sline { unsigned long *p_lno; }; -static char *grab_blob(const unsigned char *sha1, unsigned int mode, - unsigned long *size, struct userdiff_driver *textconv, - const char *path) -{ - char *blob; - enum object_type type; - - if (S_ISGITLINK(mode)) { - blob = xmalloc(100); - *size = snprintf(blob, 100, - "Subproject commit %s\n", sha1_to_hex(sha1)); - } else if (is_null_sha1(sha1)) { - /* deleted blob */ - *size = 0; - return xcalloc(1, 1); - } else if (textconv) { - struct diff_filespec *df = alloc_filespec(path); - fill_filespec(df, sha1, 1, mode); - *size = fill_textconv(textconv, df, &blob); - free_filespec(df); - } else { - blob = read_sha1_file(sha1, &type, size); - if (type != OBJ_BLOB) - die("object '%s' is not a blob!", sha1_to_hex(sha1)); - } - return blob; -} - static int match_string_spaces(const char *line1, int len1, const char *line2, int len2, long flags) @@ -163,36 +143,180 @@ static int match_string_spaces(const char *line1, int len1, return 0; } -static void append_lost(struct sline *sline, int n, const char *line, int len, long flags) +enum coalesce_direction { MATCH, BASE, NEW }; + +/* Coalesce new lines into base by finding LCS */ +static struct lline *coalesce_lines(struct lline *base, int *lenbase, + struct lline *new, int lennew, + unsigned long parent, long flags) { - struct lline *lline; - unsigned long this_mask = (1UL<<n); - if (line[len-1] == '\n') - len--; + int **lcs; + enum coalesce_direction **directions; + struct lline *baseend, *newend = NULL; + int i, j, origbaselen = *lenbase; - /* Check to see if we can squash things */ - if (sline->lost_head) { - lline = sline->next_lost; - while (lline) { - if (match_string_spaces(lline->line, lline->len, - line, len, flags)) { - lline->parent_map |= this_mask; - sline->next_lost = lline->next; - return; + if (new == NULL) + return base; + + if (base == NULL) { + *lenbase = lennew; + return new; + } + + /* + * Coalesce new lines into base by finding the LCS + * - Create the table to run dynamic programing + * - Compute the LCS + * - Then reverse read the direction structure: + * - If we have MATCH, assign parent to base flag, and consume + * both baseend and newend + * - Else if we have BASE, consume baseend + * - Else if we have NEW, insert newend lline into base and + * consume newend + */ + lcs = xcalloc(origbaselen + 1, sizeof(int*)); + directions = xcalloc(origbaselen + 1, sizeof(enum coalesce_direction*)); + for (i = 0; i < origbaselen + 1; i++) { + lcs[i] = xcalloc(lennew + 1, sizeof(int)); + directions[i] = xcalloc(lennew + 1, sizeof(enum coalesce_direction)); + directions[i][0] = BASE; + } + for (j = 1; j < lennew + 1; j++) + directions[0][j] = NEW; + + for (i = 1, baseend = base; i < origbaselen + 1; i++) { + for (j = 1, newend = new; j < lennew + 1; j++) { + if (match_string_spaces(baseend->line, baseend->len, + newend->line, newend->len, flags)) { + lcs[i][j] = lcs[i - 1][j - 1] + 1; + directions[i][j] = MATCH; + } else if (lcs[i][j - 1] >= lcs[i - 1][j]) { + lcs[i][j] = lcs[i][j - 1]; + directions[i][j] = NEW; + } else { + lcs[i][j] = lcs[i - 1][j]; + directions[i][j] = BASE; + } + if (newend->next) + newend = newend->next; + } + if (baseend->next) + baseend = baseend->next; + } + + for (i = 0; i < origbaselen + 1; i++) + free(lcs[i]); + free(lcs); + + /* At this point, baseend and newend point to the end of each lists */ + i--; + j--; + while (i != 0 || j != 0) { + if (directions[i][j] == MATCH) { + baseend->parent_map |= 1<<parent; + baseend = baseend->prev; + newend = newend->prev; + i--; + j--; + } else if (directions[i][j] == NEW) { + struct lline *lline; + + lline = newend; + /* Remove lline from new list and update newend */ + if (lline->prev) + lline->prev->next = lline->next; + else + new = lline->next; + if (lline->next) + lline->next->prev = lline->prev; + + newend = lline->prev; + j--; + + /* Add lline to base list */ + if (baseend) { + lline->next = baseend->next; + lline->prev = baseend; + if (lline->prev) + lline->prev->next = lline; } - lline = lline->next; + else { + lline->next = base; + base = lline; + } + (*lenbase)++; + + if (lline->next) + lline->next->prev = lline; + + } else { + baseend = baseend->prev; + i--; } } + newend = new; + while (newend) { + struct lline *lline = newend; + newend = newend->next; + free(lline); + } + + for (i = 0; i < origbaselen + 1; i++) + free(directions[i]); + free(directions); + + return base; +} + +static char *grab_blob(const unsigned char *sha1, unsigned int mode, + unsigned long *size, struct userdiff_driver *textconv, + const char *path) +{ + char *blob; + enum object_type type; + + if (S_ISGITLINK(mode)) { + blob = xmalloc(100); + *size = snprintf(blob, 100, + "Subproject commit %s\n", sha1_to_hex(sha1)); + } else if (is_null_sha1(sha1)) { + /* deleted blob */ + *size = 0; + return xcalloc(1, 1); + } else if (textconv) { + struct diff_filespec *df = alloc_filespec(path); + fill_filespec(df, sha1, 1, mode); + *size = fill_textconv(textconv, df, &blob); + free_filespec(df); + } else { + blob = read_sha1_file(sha1, &type, size); + if (type != OBJ_BLOB) + die("object '%s' is not a blob!", sha1_to_hex(sha1)); + } + return blob; +} + +static void append_lost(struct sline *sline, int n, const char *line, int len) +{ + struct lline *lline; + unsigned long this_mask = (1UL<<n); + if (line[len-1] == '\n') + len--; + lline = xmalloc(sizeof(*lline) + len + 1); lline->len = len; lline->next = NULL; + lline->prev = sline->plost.lost_tail; + if (lline->prev) + lline->prev->next = lline; + else + sline->plost.lost_head = lline; + sline->plost.lost_tail = lline; + sline->plost.len++; lline->parent_map = this_mask; memcpy(lline->line, line, len); lline->line[len] = 0; - *sline->lost_tail = lline; - sline->lost_tail = &lline->next; - sline->next_lost = NULL; } struct combine_diff_state { @@ -203,7 +327,6 @@ struct combine_diff_state { int n; struct sline *sline; struct sline *lost_bucket; - long flags; }; static void consume_line(void *state_, char *line, unsigned long len) @@ -236,14 +359,13 @@ static void consume_line(void *state_, char *line, unsigned long len) xcalloc(state->num_parent, sizeof(unsigned long)); state->sline[state->nb-1].p_lno[state->n] = state->ob; - state->lost_bucket->next_lost = state->lost_bucket->lost_head; return; } if (!state->lost_bucket) return; /* not in any hunk yet */ switch (line[0]) { case '-': - append_lost(state->lost_bucket, state->n, line+1, len-1, state->flags); + append_lost(state->lost_bucket, state->n, line+1, len-1); break; case '+': state->sline[state->lno-1].flag |= state->nmask; @@ -276,7 +398,6 @@ static void combine_diff(const unsigned char *parent, unsigned int mode, xpp.flags = flags; memset(&xecfg, 0, sizeof(xecfg)); memset(&state, 0, sizeof(state)); - state.flags = flags; state.nmask = nmask; state.sline = sline; state.lno = 1; @@ -298,8 +419,18 @@ static void combine_diff(const unsigned char *parent, unsigned int mode, struct lline *ll; sline[lno].p_lno[n] = p_lno; + /* Coalesce new lines */ + if (sline[lno].plost.lost_head) { + struct sline *sl = &sline[lno]; + sl->lost = coalesce_lines(sl->lost, &sl->lenlost, + sl->plost.lost_head, + sl->plost.len, n, flags); + sl->plost.lost_head = sl->plost.lost_tail = NULL; + sl->plost.len = 0; + } + /* How many lines would this sline advance the p_lno? */ - ll = sline[lno].lost_head; + ll = sline[lno].lost; while (ll) { if (ll->parent_map & nmask) p_lno++; /* '-' means parent had it */ @@ -319,7 +450,7 @@ static int interesting(struct sline *sline, unsigned long all_mask) /* If some parents lost lines here, or if we have added to * some parent, it is interesting. */ - return ((sline->flag & all_mask) || sline->lost_head); + return ((sline->flag & all_mask) || sline->lost); } static unsigned long adjust_hunk_tail(struct sline *sline, @@ -502,7 +633,7 @@ static int make_hunks(struct sline *sline, unsigned long cnt, has_interesting = 0; for (j = i; j < hunk_end && !has_interesting; j++) { unsigned long this_diff = sline[j].flag & all_mask; - struct lline *ll = sline[j].lost_head; + struct lline *ll = sline[j].lost; if (this_diff) { /* This has some changes. Is it the * same as others? @@ -656,7 +787,7 @@ static void dump_sline(struct sline *sline, const char *line_prefix, int j; unsigned long p_mask; struct sline *sl = &sline[lno++]; - ll = (sl->flag & no_pre_delete) ? NULL : sl->lost_head; + ll = (sl->flag & no_pre_delete) ? NULL : sl->lost; while (ll) { printf("%s%s", line_prefix, c_old); for (j = 0; j < num_parent; j++) { @@ -707,7 +838,7 @@ static void reuse_combine_diff(struct sline *sline, unsigned long cnt, jmask = (1UL<<j); for (lno = 0; lno <= cnt; lno++) { - struct lline *ll = sline->lost_head; + struct lline *ll = sline->lost; sline->p_lno[i] = sline->p_lno[j]; while (ll) { if (ll->parent_map & jmask) @@ -966,10 +1097,6 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, sline = xcalloc(cnt+2, sizeof(*sline)); sline[0].bol = result; - for (lno = 0; lno <= cnt + 1; lno++) { - sline[lno].lost_tail = &sline[lno].lost_head; - sline[lno].flag = 0; - } for (lno = 0, cp = result; cp < result + result_size; cp++) { if (*cp == '\n') { sline[lno].len = cp - sline[lno].bol; @@ -1019,8 +1146,8 @@ static void show_patch_diff(struct combine_diff_path *elem, int num_parent, free(result); for (lno = 0; lno < cnt; lno++) { - if (sline[lno].lost_head) { - struct lline *ll = sline[lno].lost_head; + if (sline[lno].lost) { + struct lline *ll = sline[lno].lost; while (ll) { struct lline *tmp = ll; ll = ll->next; @@ -463,14 +463,23 @@ static void clear_commit_marks_1(struct commit_list **plist, } } -void clear_commit_marks(struct commit *commit, unsigned int mark) +void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark) { struct commit_list *list = NULL; - commit_list_insert(commit, &list); + + while (nr--) { + commit_list_insert(*commit, &list); + commit++; + } while (list) clear_commit_marks_1(&list, pop_commit(&list), mark); } +void clear_commit_marks(struct commit *commit, unsigned int mark) +{ + clear_commit_marks_many(1, &commit, mark); +} + void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark) { struct object *object; @@ -797,8 +806,7 @@ struct commit_list *get_merge_bases_many(struct commit *one, if (!result || !result->next) { if (cleanup) { clear_commit_marks(one, all_flags); - for (i = 0; i < n; i++) - clear_commit_marks(twos[i], all_flags); + clear_commit_marks_many(n, twos, all_flags); } return result; } @@ -816,8 +824,7 @@ struct commit_list *get_merge_bases_many(struct commit *one, free_commit_list(result); clear_commit_marks(one, all_flags); - for (i = 0; i < n; i++) - clear_commit_marks(twos[i], all_flags); + clear_commit_marks_many(n, twos, all_flags); cnt = remove_redundant(rslt, cnt); result = NULL; @@ -852,25 +859,36 @@ int is_descendant_of(struct commit *commit, struct commit_list *with_commit) } /* - * Is "commit" an ancestor of (i.e. reachable from) the "reference"? + * Is "commit" an ancestor of one of the "references"? */ -int in_merge_bases(struct commit *commit, struct commit *reference) +int in_merge_bases_many(struct commit *commit, int nr_reference, struct commit **reference) { struct commit_list *bases; - int ret = 0; + int ret = 0, i; - if (parse_commit(commit) || parse_commit(reference)) + if (parse_commit(commit)) return ret; + for (i = 0; i < nr_reference; i++) + if (parse_commit(reference[i])) + return ret; - bases = paint_down_to_common(commit, 1, &reference); + bases = paint_down_to_common(commit, nr_reference, reference); if (commit->object.flags & PARENT2) ret = 1; clear_commit_marks(commit, all_flags); - clear_commit_marks(reference, all_flags); + clear_commit_marks_many(nr_reference, reference, all_flags); free_commit_list(bases); return ret; } +/* + * Is "commit" an ancestor of (i.e. reachable from) the "reference"? + */ +int in_merge_bases(struct commit *commit, struct commit *reference) +{ + return in_merge_bases_many(commit, 1, &reference); +} + struct commit_list *reduce_heads(struct commit_list *heads) { struct commit_list *p; @@ -1023,6 +1041,76 @@ free_return: free(buf); } +static struct { + char result; + const char *check; +} sigcheck_gpg_status[] = { + { 'G', "\n[GNUPG:] GOODSIG " }, + { 'B', "\n[GNUPG:] BADSIG " }, + { 'U', "\n[GNUPG:] TRUST_NEVER" }, + { 'U', "\n[GNUPG:] TRUST_UNDEFINED" }, +}; + +static void parse_gpg_output(struct signature_check *sigc) +{ + const char *buf = sigc->gpg_status; + int i; + + /* Iterate over all search strings */ + for (i = 0; i < ARRAY_SIZE(sigcheck_gpg_status); i++) { + const char *found, *next; + + if (!prefixcmp(buf, sigcheck_gpg_status[i].check + 1)) { + /* At the very beginning of the buffer */ + found = buf + strlen(sigcheck_gpg_status[i].check + 1); + } else { + found = strstr(buf, sigcheck_gpg_status[i].check); + if (!found) + continue; + found += strlen(sigcheck_gpg_status[i].check); + } + sigc->result = sigcheck_gpg_status[i].result; + /* The trust messages are not followed by key/signer information */ + if (sigc->result != 'U') { + sigc->key = xmemdupz(found, 16); + found += 17; + next = strchrnul(found, '\n'); + sigc->signer = xmemdupz(found, next - found); + } + } +} + +void check_commit_signature(const struct commit* commit, struct signature_check *sigc) +{ + struct strbuf payload = STRBUF_INIT; + struct strbuf signature = STRBUF_INIT; + struct strbuf gpg_output = STRBUF_INIT; + struct strbuf gpg_status = STRBUF_INIT; + int status; + + sigc->result = 'N'; + + if (parse_signed_commit(commit->object.sha1, + &payload, &signature) <= 0) + goto out; + status = verify_signed_buffer(payload.buf, payload.len, + signature.buf, signature.len, + &gpg_output, &gpg_status); + if (status && !gpg_output.len) + goto out; + sigc->gpg_output = strbuf_detach(&gpg_output, NULL); + sigc->gpg_status = strbuf_detach(&gpg_status, NULL); + parse_gpg_output(sigc); + + out: + strbuf_release(&gpg_status); + strbuf_release(&gpg_output); + strbuf_release(&payload); + strbuf_release(&signature); +} + + + void append_merge_tag_headers(struct commit_list *parents, struct commit_extra_header ***tail) { @@ -5,6 +5,7 @@ #include "tree.h" #include "strbuf.h" #include "decorate.h" +#include "gpg-interface.h" struct commit_list { struct commit *item; @@ -100,6 +101,7 @@ struct userformat_want { extern int has_non_ascii(const char *text); struct rev_info; /* in revision.h, it circularly uses enum cmit_fmt */ extern char *logmsg_reencode(const struct commit *commit, + char **commit_encoding, const char *output_encoding); extern void logmsg_free(char *msg, const struct commit *commit); extern void get_commit_format(const char *arg, struct rev_info *); @@ -137,6 +139,7 @@ struct commit *pop_most_recent_commit(struct commit_list **list, struct commit *pop_commit(struct commit_list **stack); void clear_commit_marks(struct commit *commit, unsigned int mark); +void clear_commit_marks_many(int nr, struct commit **commit, unsigned int mark); void clear_commit_marks_for_object_array(struct object_array *a, unsigned mark); /* @@ -176,6 +179,7 @@ extern struct commit_list *get_shallow_commits(struct object_array *heads, int is_descendant_of(struct commit *, struct commit_list *); int in_merge_bases(struct commit *, struct commit *); +int in_merge_bases_many(struct commit *, int, struct commit **); extern int interactive_add(int argc, const char **argv, const char *prefix, int patch); extern int run_add_interactive(const char *revision, const char *patch_mode, @@ -230,4 +234,13 @@ extern void print_commit_list(struct commit_list *list, const char *format_cur, const char *format_last); +/* + * Check the signature of the given commit. The result of the check is stored + * in sig->check_result, 'G' for a good signature, 'U' for a good signature + * from an untrusted signer, 'B' for a bad signature and 'N' for no signature + * at all. This may allocate memory for sig->gpg_output, sig->gpg_status, + * sig->signer and sig->key. + */ +extern void check_commit_signature(const struct commit* commit, struct signature_check *sigc); + #endif /* COMMIT_H */ diff --git a/compat/cygwin.c b/compat/cygwin.c index 5428858875..871b41d23a 100644 --- a/compat/cygwin.c +++ b/compat/cygwin.c @@ -1,3 +1,4 @@ +#define CYGWIN_C #define WIN32_LEAN_AND_MEAN #ifdef CYGWIN_V15_WIN32API #include "../git-compat-util.h" @@ -10,6 +11,18 @@ #endif #include "../cache.h" /* to read configuration */ +/* + * Return POSIX permission bits, regardless of core.ignorecygwinfstricks + */ +int cygwin_get_st_mode_bits(const char *path, int *mode) +{ + struct stat st; + if (lstat(path, &st) < 0) + return -1; + *mode = st.st_mode; + return 0; +} + static inline void filetime_to_timespec(const FILETIME *ft, struct timespec *ts) { long long winTime = ((long long)ft->dwHighDateTime << 32) + diff --git a/compat/cygwin.h b/compat/cygwin.h index a3229f5b4f..c04965a2e0 100644 --- a/compat/cygwin.h +++ b/compat/cygwin.h @@ -4,6 +4,11 @@ typedef int (*stat_fn_t)(const char*, struct stat*); extern stat_fn_t cygwin_stat_fn; extern stat_fn_t cygwin_lstat_fn; +int cygwin_get_st_mode_bits(const char *path, int *mode); +#define get_st_mode_bits(p,m) cygwin_get_st_mode_bits((p),(m)) +#ifndef CYGWIN_C +/* cygwin.c needs the original lstat() */ #define stat(path, buf) (*cygwin_stat_fn)(path, buf) #define lstat(path, buf) (*cygwin_lstat_fn)(path, buf) +#endif diff --git a/compat/fnmatch/fnmatch.c b/compat/fnmatch/fnmatch.c index 5ef0685135..378c467401 100644 --- a/compat/fnmatch/fnmatch.c +++ b/compat/fnmatch/fnmatch.c @@ -25,6 +25,7 @@ # define _GNU_SOURCE 1 #endif +#include <stddef.h> #include <errno.h> #include <fnmatch.h> #include <ctype.h> @@ -121,7 +122,7 @@ whose names are inconsistent. */ # if !defined _LIBC && !defined getenv -extern char *getenv (); +extern char *getenv (const char *name); # endif # ifndef errno diff --git a/compat/mingw.c b/compat/mingw.c index b673625580..b295e2f6a9 100644 --- a/compat/mingw.c +++ b/compat/mingw.c @@ -841,8 +841,8 @@ struct pinfo_t { struct pinfo_t *next; pid_t pid; HANDLE proc; -} pinfo_t; -struct pinfo_t *pinfo = NULL; +}; +static struct pinfo_t *pinfo = NULL; CRITICAL_SECTION pinfo_cs; static pid_t mingw_spawnve_fd(const char *cmd, const char **argv, char **env, @@ -1253,7 +1253,7 @@ static int WSAAPI getaddrinfo_stub(const char *node, const char *service, else sin->sin_addr.s_addr = INADDR_LOOPBACK; ai->ai_addr = (struct sockaddr *)sin; - ai->ai_next = 0; + ai->ai_next = NULL; return 0; } diff --git a/compat/mingw.h b/compat/mingw.h index 685cd2c3d4..bd0a88bc1d 100644 --- a/compat/mingw.h +++ b/compat/mingw.h @@ -334,13 +334,20 @@ char **make_augmented_environ(const char *const *vars); void free_environ(char **env); /* + * A critical section used in the implementation of the spawn + * functions (mingw_spawnv[p]e()) and waitpid(). Intialised in + * the replacement main() macro below. + */ +extern CRITICAL_SECTION pinfo_cs; + +/* * A replacement of main() that ensures that argv[0] has a path * and that default fmode and std(in|out|err) are in binary mode */ #define main(c,v) dummy_decl_mingw_main(); \ -static int mingw_main(); \ -int main(int argc, const char **argv) \ +static int mingw_main(c,v); \ +int main(int argc, char **argv) \ { \ extern CRITICAL_SECTION pinfo_cs; \ _fmode = _O_BINARY; \ diff --git a/compat/msvc.h b/compat/msvc.h index aa4b56315a..96b6d605da 100644 --- a/compat/msvc.h +++ b/compat/msvc.h @@ -12,6 +12,8 @@ #define __attribute__(x) #define strncasecmp _strnicmp #define ftruncate _chsize +#define strtoull _strtoui64 +#define strtoll _strtoi64 static __inline int strcasecmp (const char *s1, const char *s2) { diff --git a/compat/nedmalloc/malloc.c.h b/compat/nedmalloc/malloc.c.h index 1401a67274..5a44dead9d 100644 --- a/compat/nedmalloc/malloc.c.h +++ b/compat/nedmalloc/malloc.c.h @@ -484,6 +484,10 @@ MAX_RELEASE_CHECK_RATE default: 4095 unless not HAVE_MMAP #define DLMALLOC_VERSION 20804 #endif /* DLMALLOC_VERSION */ +#if defined(linux) +#define _GNU_SOURCE 1 +#endif + #ifndef WIN32 #ifdef _WIN32 #define WIN32 1 @@ -1802,7 +1806,7 @@ struct win32_mlock_t static MLOCK_T malloc_global_mutex = { 0, 0, 0}; -static FORCEINLINE long win32_getcurrentthreadid() { +static FORCEINLINE long win32_getcurrentthreadid(void) { #ifdef _MSC_VER #if defined(_M_IX86) long *threadstruct=(long *)__readfsdword(0x18); diff --git a/compat/nedmalloc/nedmalloc.c b/compat/nedmalloc/nedmalloc.c index 91c4e7f27b..609ebba125 100644 --- a/compat/nedmalloc/nedmalloc.c +++ b/compat/nedmalloc/nedmalloc.c @@ -159,8 +159,8 @@ struct mallinfo nedmallinfo(void) THROWSPEC { return nedpmallinfo(0); } #endif int nedmallopt(int parno, int value) THROWSPEC { return nedpmallopt(0, parno, value); } int nedmalloc_trim(size_t pad) THROWSPEC { return nedpmalloc_trim(0, pad); } -void nedmalloc_stats() THROWSPEC { nedpmalloc_stats(0); } -size_t nedmalloc_footprint() THROWSPEC { return nedpmalloc_footprint(0); } +void nedmalloc_stats(void) THROWSPEC { nedpmalloc_stats(0); } +size_t nedmalloc_footprint(void) THROWSPEC { return nedpmalloc_footprint(0); } void **nedindependent_calloc(size_t elemsno, size_t elemsize, void **chunks) THROWSPEC { return nedpindependent_calloc(0, elemsno, elemsize, chunks); } void **nedindependent_comalloc(size_t elems, size_t *sizes, void **chunks) THROWSPEC { return nedpindependent_comalloc(0, elems, sizes, chunks); } diff --git a/compat/poll/poll.c b/compat/poll/poll.c index 7d226ecb29..44103103a4 100644 --- a/compat/poll/poll.c +++ b/compat/poll/poll.c @@ -576,7 +576,7 @@ restart: { /* It's a socket. */ WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev); - WSAEventSelect ((SOCKET) h, 0, 0); + WSAEventSelect ((SOCKET) h, NULL, 0); /* If we're lucky, WSAEnumNetworkEvents already provided a way to distinguish FD_READ and FD_ACCEPT; this saves a recv later. */ diff --git a/compat/precompose_utf8.c b/compat/precompose_utf8.c index 030174db51..7980abd1a7 100644 --- a/compat/precompose_utf8.c +++ b/compat/precompose_utf8.c @@ -78,7 +78,7 @@ void precompose_argv(int argc, const char **argv) size_t namelen; oldarg = argv[i]; if (has_non_ascii(oldarg, (size_t)-1, &namelen)) { - newarg = reencode_string_iconv(oldarg, namelen, ic_precompose); + newarg = reencode_string_iconv(oldarg, namelen, ic_precompose, NULL); if (newarg) argv[i] = newarg; } diff --git a/compat/regex/regexec.c b/compat/regex/regexec.c index 0194965c5d..0cd6e0ef98 100644 --- a/compat/regex/regexec.c +++ b/compat/regex/regexec.c @@ -2313,7 +2313,7 @@ transit_state (reg_errcode_t *err, re_match_context_t *mctx, } /* Update the state_log if we need */ -re_dfastate_t * +static re_dfastate_t * internal_function merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, re_dfastate_t *next_state) @@ -2326,7 +2326,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, mctx->state_log[cur_idx] = next_state; mctx->state_log_top = cur_idx; } - else if (mctx->state_log[cur_idx] == 0) + else if (mctx->state_log[cur_idx] == NULL) { mctx->state_log[cur_idx] = next_state; } @@ -2392,7 +2392,7 @@ merge_state_with_log (reg_errcode_t *err, re_match_context_t *mctx, /* Skip bytes in the input that correspond to part of a multi-byte match, then look in the log for a state from which to restart matching. */ -re_dfastate_t * +static re_dfastate_t * internal_function find_recover_state (reg_errcode_t *err, re_match_context_t *mctx) { diff --git a/compat/unsetenv.c b/compat/unsetenv.c index eb29f5e084..4ea18569c2 100644 --- a/compat/unsetenv.c +++ b/compat/unsetenv.c @@ -2,7 +2,6 @@ void gitunsetenv (const char *name) { - extern char **environ; int src, dst; size_t nmln; diff --git a/compat/vcbuild/include/sys/poll.h b/compat/vcbuild/include/sys/poll.h deleted file mode 100644 index 0d8552a2c6..0000000000 --- a/compat/vcbuild/include/sys/poll.h +++ /dev/null @@ -1 +0,0 @@ -/* Intentionally empty file to support building git with MSVC */ diff --git a/compat/vcbuild/include/unistd.h b/compat/vcbuild/include/unistd.h index b14fcf94da..c65c2cd566 100644 --- a/compat/vcbuild/include/unistd.h +++ b/compat/vcbuild/include/unistd.h @@ -49,6 +49,9 @@ typedef int64_t off64_t; #define INTMAX_MAX _I64_MAX #define UINTMAX_MAX _UI64_MAX +#define UINT32_MAX 0xffffffff /* 4294967295U */ + +#define STDIN_FILENO 0 #define STDOUT_FILENO 1 #define STDERR_FILENO 2 diff --git a/compat/win32/pthread.c b/compat/win32/pthread.c index 010e875ec4..e18f5c6e2e 100644 --- a/compat/win32/pthread.c +++ b/compat/win32/pthread.c @@ -52,7 +52,7 @@ int win32_pthread_join(pthread_t *thread, void **value_ptr) pthread_t pthread_self(void) { - pthread_t t = { 0 }; + pthread_t t = { NULL }; t.tid = GetCurrentThreadId(); return t; } diff --git a/compat/win32mmap.c b/compat/win32mmap.c index 61d2ef8e46..80a8c9af4f 100644 --- a/compat/win32mmap.c +++ b/compat/win32mmap.c @@ -21,8 +21,8 @@ void *git_mmap(void *start, size_t length, int prot, int flags, int fd, off_t of if (!(flags & MAP_PRIVATE)) die("Invalid usage of mmap when built with USE_WIN32_MMAP"); - hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), 0, PAGE_WRITECOPY, - 0, 0, 0); + hmap = CreateFileMapping((HANDLE)_get_osfhandle(fd), NULL, + PAGE_WRITECOPY, 0, 0, NULL); if (!hmap) return MAP_FAILED; diff --git a/config.mak.in b/config.mak.in index fa02bdd82a..e6a6d0f941 100644 --- a/config.mak.in +++ b/config.mak.in @@ -22,9 +22,3 @@ docdir = @docdir@ mandir = @mandir@ htmldir = @htmldir@ - -srcdir = @srcdir@ -VPATH = @srcdir@ - -export exec_prefix mandir -export srcdir VPATH diff --git a/config.mak.uname b/config.mak.uname index e09af8fc13..d78fd3df5b 100644 --- a/config.mak.uname +++ b/config.mak.uname @@ -326,7 +326,6 @@ ifeq ($(uname_S),Windows) # NEEDS_LIBICONV = YesPlease NO_ICONV = YesPlease NO_STRTOUMAX = YesPlease - NO_STRTOULL = YesPlease NO_MKDTEMP = YesPlease NO_MKSTEMPS = YesPlease SNPRINTF_RETURNS_BOGUS = YesPlease @@ -343,6 +342,9 @@ ifeq ($(uname_S),Windows) NO_CURL = YesPlease NO_PYTHON = YesPlease BLK_SHA1 = YesPlease + ETAGS_TARGET = ETAGS + NO_INET_PTON = YesPlease + NO_INET_NTOP = YesPlease NO_POSIX_GOODIES = UnfortunatelyYes NATIVE_CRLF = YesPlease DEFAULT_HELP_FORMAT = html @@ -505,6 +507,7 @@ ifneq (,$(findstring MINGW,$(uname_S))) compat/win32/dirent.o EXTLIBS += -lws2_32 PTHREAD_LIBS = + NATIVE_CRLF = YesPlease X = .exe SPARSE_FLAGS = -Wno-one-bit-signed-bitfield ifneq (,$(wildcard ../THIS_IS_MSYSGIT)) @@ -62,8 +62,8 @@ static void die_initial_contact(int got_at_least_one_head) /* * Read all the refs from the other end */ -struct ref **get_remote_heads(int in, struct ref **list, - unsigned int flags, +struct ref **get_remote_heads(int in, char *src_buf, size_t src_len, + struct ref **list, unsigned int flags, struct extra_have_objects *extra_have) { int got_at_least_one_head = 0; @@ -72,18 +72,19 @@ struct ref **get_remote_heads(int in, struct ref **list, for (;;) { struct ref *ref; unsigned char old_sha1[20]; - static char buffer[1000]; char *name; int len, name_len; + char *buffer = packet_buffer; - len = packet_read(in, buffer, sizeof(buffer)); + len = packet_read(in, &src_buf, &src_len, + packet_buffer, sizeof(packet_buffer), + PACKET_READ_GENTLE_ON_EOF | + PACKET_READ_CHOMP_NEWLINE); if (len < 0) die_initial_contact(got_at_least_one_head); if (!len) break; - if (buffer[len-1] == '\n') - buffer[--len] = 0; if (len > 4 && !prefixcmp(buffer, "ERR ")) die("remote error: %s", buffer + 4); diff --git a/contrib/completion/git-completion.bash b/contrib/completion/git-completion.bash index e769800393..1c35eef56a 100644 --- a/contrib/completion/git-completion.bash +++ b/contrib/completion/git-completion.bash @@ -53,19 +53,6 @@ __gitdir () fi } -__gitcomp_1 () -{ - local c IFS=$' \t\n' - for c in $1; do - c="$c$2" - case $c in - --*=*|*.) ;; - *) c="$c " ;; - esac - printf '%s\n' "$c" - done -} - # The following function is based on code from: # # bash_completion - programmable completion functions for bash 3.2+ @@ -195,8 +182,18 @@ _get_comp_words_by_ref () } fi -# Generates completion reply with compgen, appending a space to possible -# completion words, if necessary. +__gitcompadd () +{ + local i=0 + for x in $1; do + if [[ "$x" == "$3"* ]]; then + COMPREPLY[i++]="$2$x$4" + fi + done +} + +# Generates completion reply, appending a space to possible completion words, +# if necessary. # It accepts 1 to 4 arguments: # 1: List of possible completion words. # 2: A prefix to be added to each possible completion word (optional). @@ -208,19 +205,25 @@ __gitcomp () case "$cur_" in --*=) - COMPREPLY=() ;; *) - local IFS=$'\n' - COMPREPLY=($(compgen -P "${2-}" \ - -W "$(__gitcomp_1 "${1-}" "${4-}")" \ - -- "$cur_")) + local c i=0 IFS=$' \t\n' + for c in $1; do + c="$c${4-}" + if [[ $c == "$cur_"* ]]; then + case $c in + --*=*|*.) ;; + *) c="$c " ;; + esac + COMPREPLY[i++]="${2-}$c" + fi + done ;; esac } -# Generates completion reply with compgen from newline-separated possible -# completion words by appending a space to all of them. +# Generates completion reply from newline-separated possible completion words +# by appending a space to all of them. # It accepts 1 to 4 arguments: # 1: List of possible completion words, separated by a single newline. # 2: A prefix to be added to each possible completion word (optional). @@ -231,7 +234,7 @@ __gitcomp () __gitcomp_nl () { local IFS=$'\n' - COMPREPLY=($(compgen -P "${2-}" -S "${4- }" -W "$1" -- "${3-$cur}")) + __gitcompadd "$1" "${2-}" "${3-$cur}" "${4- }" } # Generates completion reply with compgen from newline-separated possible @@ -614,7 +617,6 @@ __git_complete_remote_or_refspec () case "$cmd" in push) no_complete_refspec=1 ;; fetch) - COMPREPLY=() return ;; *) ;; @@ -630,7 +632,6 @@ __git_complete_remote_or_refspec () return fi if [ $no_complete_refspec = 1 ]; then - COMPREPLY=() return fi [ "$remote" = "." ] && remote= @@ -951,7 +952,6 @@ _git_am () " return esac - COMPREPLY=() } _git_apply () @@ -971,7 +971,6 @@ _git_apply () " return esac - COMPREPLY=() } _git_add () @@ -1031,7 +1030,6 @@ _git_bisect () __gitcomp_nl "$(__git_refs)" ;; *) - COMPREPLY=() ;; esac } @@ -1124,9 +1122,14 @@ _git_cherry () _git_cherry_pick () { + local dir="$(__gitdir)" + if [ -f "$dir"/CHERRY_PICK_HEAD ]; then + __gitcomp "--continue --quit --abort" + return + fi case "$cur" in --*) - __gitcomp "--edit --no-commit" + __gitcomp "--edit --no-commit --signoff --strategy= --mainline" ;; *) __gitcomp_nl "$(__git_refs)" @@ -1170,7 +1173,6 @@ _git_clone () return ;; esac - COMPREPLY=() } _git_commit () @@ -1312,11 +1314,12 @@ _git_fetch () } __git_format_patch_options=" - --stdout --attach --no-attach --thread --thread= --output-directory + --stdout --attach --no-attach --thread --thread= --no-thread --numbered --start-number --numbered-files --keep-subject --signoff --signature --no-signature --in-reply-to= --cc= --full-index --binary --not --all --cover-letter --no-prefix --src-prefix= --dst-prefix= --inline --suffix= --ignore-if-in-upstream --subject-prefix= + --output-directory --reroll-count --to= --quiet --notes " _git_format_patch () @@ -1347,7 +1350,6 @@ _git_fsck () return ;; esac - COMPREPLY=() } _git_gc () @@ -1358,7 +1360,6 @@ _git_gc () return ;; esac - COMPREPLY=() } _git_gitk () @@ -1435,7 +1436,6 @@ _git_init () return ;; esac - COMPREPLY=() } _git_ls_files () @@ -1571,7 +1571,6 @@ _git_mergetool () return ;; esac - COMPREPLY=() } _git_merge_base () @@ -1812,7 +1811,7 @@ __git_config_get_set_variables () _git_config () { case "$prev" in - branch.*.remote) + branch.*.remote|branch.*.pushremote) __gitcomp_nl "$(__git_remotes)" return ;; @@ -1824,11 +1823,15 @@ _git_config () __gitcomp "false true" return ;; + remote.pushdefault) + __gitcomp_nl "$(__git_remotes)" + return + ;; remote.*.fetch) local remote="${prev#remote.}" remote="${remote%.fetch}" if [ -z "$cur" ]; then - COMPREPLY=("refs/heads/") + __gitcomp_nl "refs/heads/" "" "" "" return fi __gitcomp_nl "$(__git_refs_remotes "$remote")" @@ -1892,7 +1895,6 @@ _git_config () return ;; *.*) - COMPREPLY=() return ;; esac @@ -1909,7 +1911,7 @@ _git_config () ;; branch.*.*) local pfx="${cur%.*}." cur_="${cur##*.}" - __gitcomp "remote merge mergeoptions rebase" "$pfx" "$cur_" + __gitcomp "remote pushremote merge mergeoptions rebase" "$pfx" "$cur_" return ;; branch.*) @@ -2204,6 +2206,7 @@ _git_config () receive.fsckObjects receive.unpackLimit receive.updateserverinfo + remote.pushdefault remotes. repack.usedeltabaseoffset rerere.autoupdate @@ -2274,7 +2277,6 @@ _git_remote () __gitcomp "$c" ;; *) - COMPREPLY=() ;; esac } @@ -2390,8 +2392,6 @@ _git_stash () *) if [ -z "$(__git_find_on_cmdline "$save_opts")" ]; then __gitcomp "$subcommands" - else - COMPREPLY=() fi ;; esac @@ -2404,14 +2404,12 @@ _git_stash () __gitcomp "--index --quiet" ;; show,--*|drop,--*|branch,--*) - COMPREPLY=() ;; show,*|apply,*|drop,*|pop,*|branch,*) __gitcomp_nl "$(git --git-dir="$(__gitdir)" stash list \ | sed -n -e 's/:.*//p')" ;; *) - COMPREPLY=() ;; esac fi @@ -2421,7 +2419,7 @@ _git_submodule () { __git_has_doubledash && return - local subcommands="add status init update summary foreach sync" + local subcommands="add status init deinit update summary foreach sync" if [ -z "$(__git_find_on_cmdline "$subcommands")" ]; then case "$cur" in --*) @@ -2453,7 +2451,7 @@ _git_svn () --no-metadata --use-svm-props --use-svnsync-props --log-window-size= --no-checkout --quiet --repack-flags --use-log-author --localtime - --ignore-paths= $remote_opts + --ignore-paths= --include-paths= $remote_opts " local init_opts=" --template= --shared= --trunk= --tags= @@ -2528,7 +2526,6 @@ _git_svn () __gitcomp "--revision= --parent" ;; *) - COMPREPLY=() ;; esac fi @@ -2553,13 +2550,10 @@ _git_tag () case "$prev" in -m|-F) - COMPREPLY=() ;; -*|tag) if [ $f = 1 ]; then __gitcomp_nl "$(__git_tags)" - else - COMPREPLY=() fi ;; *) diff --git a/contrib/completion/git-completion.zsh b/contrib/completion/git-completion.zsh index 49f0cb8f69..2565d2eef4 100644 --- a/contrib/completion/git-completion.zsh +++ b/contrib/completion/git-completion.zsh @@ -198,7 +198,7 @@ _git () emulate ksh -c __${service}_main fi - let _ret && _default -S '' && _ret=0 + let _ret && _default && _ret=0 return _ret } diff --git a/contrib/completion/git-prompt.sh b/contrib/completion/git-prompt.sh index 054c52e90a..eaf5c369aa 100644 --- a/contrib/completion/git-prompt.sh +++ b/contrib/completion/git-prompt.sh @@ -263,14 +263,21 @@ __git_ps1 () else local r="" local b="" - if [ -f "$g/rebase-merge/interactive" ]; then - r="|REBASE-i" - b="$(cat "$g/rebase-merge/head-name")" - elif [ -d "$g/rebase-merge" ]; then - r="|REBASE-m" + local step="" + local total="" + if [ -d "$g/rebase-merge" ]; then b="$(cat "$g/rebase-merge/head-name")" + step=$(cat "$g/rebase-merge/msgnum") + total=$(cat "$g/rebase-merge/end") + if [ -f "$g/rebase-merge/interactive" ]; then + r="|REBASE-i" + else + r="|REBASE-m" + fi else if [ -d "$g/rebase-apply" ]; then + step=$(cat "$g/rebase-apply/next") + total=$(cat "$g/rebase-apply/last") if [ -f "$g/rebase-apply/rebasing" ]; then r="|REBASE" elif [ -f "$g/rebase-apply/applying" ]; then @@ -308,6 +315,10 @@ __git_ps1 () } fi + if [ -n "$step" ] && [ -n "$total" ]; then + r="$r $step/$total" + fi + local w="" local i="" local s="" diff --git a/contrib/credential/netrc/Makefile b/contrib/credential/netrc/Makefile new file mode 100644 index 0000000000..51b76138a5 --- /dev/null +++ b/contrib/credential/netrc/Makefile @@ -0,0 +1,5 @@ +test: + ./test.pl + +testverbose: + ./test.pl -d -v diff --git a/contrib/credential/netrc/git-credential-netrc b/contrib/credential/netrc/git-credential-netrc new file mode 100755 index 0000000000..6c51c43885 --- /dev/null +++ b/contrib/credential/netrc/git-credential-netrc @@ -0,0 +1,421 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +use Getopt::Long; +use File::Basename; + +my $VERSION = "0.1"; + +my %options = ( + help => 0, + debug => 0, + verbose => 0, + insecure => 0, + file => [], + + # identical token maps, e.g. host -> host, will be inserted later + tmap => { + port => 'protocol', + machine => 'host', + path => 'path', + login => 'username', + user => 'username', + password => 'password', + } + ); + +# Map each credential protocol token to itself on the netrc side. +foreach (values %{$options{tmap}}) { + $options{tmap}->{$_} = $_; +} + +# Now, $options{tmap} has a mapping from the netrc format to the Git credential +# helper protocol. + +# Next, we build the reverse token map. + +# When $rmap{foo} contains 'bar', that means that what the Git credential helper +# protocol calls 'bar' is found as 'foo' in the netrc/authinfo file. Keys in +# %rmap are what we expect to read from the netrc/authinfo file. + +my %rmap; +foreach my $k (keys %{$options{tmap}}) { + push @{$rmap{$options{tmap}->{$k}}}, $k; +} + +Getopt::Long::Configure("bundling"); + +# TODO: maybe allow the token map $options{tmap} to be configurable. +GetOptions(\%options, + "help|h", + "debug|d", + "insecure|k", + "verbose|v", + "file|f=s@", + ); + +if ($options{help}) { + my $shortname = basename($0); + $shortname =~ s/git-credential-//; + + print <<EOHIPPUS; + +$0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] [-v] [-k] get + +Version $VERSION by tzz\@lifelogs.com. License: BSD. + +Options: + + -f|--file AUTHFILE : specify netrc-style files. Files with the .gpg extension + will be decrypted by GPG before parsing. Multiple -f + arguments are OK. They are processed in order, and the + first matching entry found is returned via the credential + helper protocol (see below). + + When no -f option is given, .authinfo.gpg, .netrc.gpg, + .authinfo, and .netrc files in your home directory are used + in this order. + + -k|--insecure : ignore bad file ownership or permissions + + -d|--debug : turn on debugging (developer info) + + -v|--verbose : be more verbose (show files and information found) + +To enable this credential helper: + + git config credential.helper '$shortname -f AUTHFILE1 -f AUTHFILE2' + +(Note that Git will prepend "git-credential-" to the helper name and look for it +in the path.) + +...and if you want lots of debugging info: + + git config credential.helper '$shortname -f AUTHFILE -d' + +...or to see the files opened and data found: + + git config credential.helper '$shortname -f AUTHFILE -v' + +Only "get" mode is supported by this credential helper. It opens every AUTHFILE +and looks for the first entry that matches the requested search criteria: + + 'port|protocol': + The protocol that will be used (e.g., https). (protocol=X) + + 'machine|host': + The remote hostname for a network credential. (host=X) + + 'path': + The path with which the credential will be used. (path=X) + + 'login|user|username': + The credential’s username, if we already have one. (username=X) + +Thus, when we get this query on STDIN: + +host=github.com +protocol=https +username=tzz + +this credential helper will look for the first entry in every AUTHFILE that +matches + +machine github.com port https login tzz + +OR + +machine github.com protocol https login tzz + +OR... etc. acceptable tokens as listed above. Any unknown tokens are +simply ignored. + +Then, the helper will print out whatever tokens it got from the entry, including +"password" tokens, mapping back to Git's helper protocol; e.g. "port" is mapped +back to "protocol". Any redundant entry tokens (part of the original query) are +skipped. + +Again, note that only the first matching entry from all the AUTHFILEs, processed +in the sequence given on the command line, is used. + +Netrc/authinfo tokens can be quoted as 'STRING' or "STRING". + +No caching is performed by this credential helper. + +EOHIPPUS + + exit 0; +} + +my $mode = shift @ARGV; + +# Credentials must get a parameter, so die if it's missing. +die "Syntax: $0 [-f AUTHFILE1] [-f AUTHFILEN] [-d] get" unless defined $mode; + +# Only support 'get' mode; with any other unsupported ones we just exit. +exit 0 unless $mode eq 'get'; + +my $files = $options{file}; + +# if no files were given, use a predefined list. +# note that .gpg files come first +unless (scalar @$files) { + my @candidates = qw[ + ~/.authinfo.gpg + ~/.netrc.gpg + ~/.authinfo + ~/.netrc + ]; + + $files = $options{file} = [ map { glob $_ } @candidates ]; +} + +my $query = read_credential_data_from_stdin(); + +FILE: +foreach my $file (@$files) { + my $gpgmode = $file =~ m/\.gpg$/; + unless (-r $file) { + log_verbose("Unable to read $file; skipping it"); + next FILE; + } + + # the following check is copied from Net::Netrc, for non-GPG files + # OS/2 and Win32 do not handle stat in a way compatible with this check :-( + unless ($gpgmode || $options{insecure} || + $^O eq 'os2' + || $^O eq 'MSWin32' + || $^O eq 'MacOS' + || $^O =~ /^cygwin/) { + my @stat = stat($file); + + if (@stat) { + if ($stat[2] & 077) { + log_verbose("Insecure $file (mode=%04o); skipping it", + $stat[2] & 07777); + next FILE; + } + + if ($stat[4] != $<) { + log_verbose("Not owner of $file; skipping it"); + next FILE; + } + } + } + + my @entries = load_netrc($file, $gpgmode); + + unless (scalar @entries) { + if ($!) { + log_verbose("Unable to open $file: $!"); + } else { + log_verbose("No netrc entries found in $file"); + } + + next FILE; + } + + my $entry = find_netrc_entry($query, @entries); + if ($entry) { + print_credential_data($entry, $query); + # we're done! + last FILE; + } +} + +exit 0; + +sub load_netrc { + my $file = shift @_; + my $gpgmode = shift @_; + + my $io; + if ($gpgmode) { + my @cmd = (qw(gpg --decrypt), $file); + log_verbose("Using GPG to open $file: [@cmd]"); + open $io, "-|", @cmd; + } else { + log_verbose("Opening $file..."); + open $io, '<', $file; + } + + # nothing to do if the open failed (we log the error later) + return unless $io; + + # Net::Netrc does this, but the functionality is merged with the file + # detection logic, so we have to extract just the part we need + my @netrc_entries = net_netrc_loader($io); + + # these entries will use the credential helper protocol token names + my @entries; + + foreach my $nentry (@netrc_entries) { + my %entry; + my $num_port; + + if (!defined $nentry->{machine}) { + next; + } + if (defined $nentry->{port} && $nentry->{port} =~ m/^\d+$/) { + $num_port = $nentry->{port}; + delete $nentry->{port}; + } + + # create the new entry for the credential helper protocol + $entry{$options{tmap}->{$_}} = $nentry->{$_} foreach keys %$nentry; + + # for "host X port Y" where Y is an integer (captured by + # $num_port above), set the host to "X:Y" + if (defined $entry{host} && defined $num_port) { + $entry{host} = join(':', $entry{host}, $num_port); + } + + push @entries, \%entry; + } + + return @entries; +} + +sub net_netrc_loader { + my $fh = shift @_; + my @entries; + my ($mach, $macdef, $tok, @tok); + + LINE: + while (<$fh>) { + undef $macdef if /\A\n\Z/; + + if ($macdef) { + next LINE; + } + + s/^\s*//; + chomp; + + while (length && s/^("((?:[^"]+|\\.)*)"|((?:[^\\\s]+|\\.)*))\s*//) { + (my $tok = $+) =~ s/\\(.)/$1/g; + push(@tok, $tok); + } + + TOKEN: + while (@tok) { + if ($tok[0] eq "default") { + shift(@tok); + $mach = { machine => undef }; + next TOKEN; + } + + $tok = shift(@tok); + + if ($tok eq "machine") { + my $host = shift @tok; + $mach = { machine => $host }; + push @entries, $mach; + } elsif (exists $options{tmap}->{$tok}) { + unless ($mach) { + log_debug("Skipping token $tok because no machine was given"); + next TOKEN; + } + + my $value = shift @tok; + unless (defined $value) { + log_debug("Token $tok had no value, skipping it."); + next TOKEN; + } + + # Following line added by rmerrell to remove '/' escape char in .netrc + $value =~ s/\/\\/\\/g; + $mach->{$tok} = $value; + } elsif ($tok eq "macdef") { # we ignore macros + next TOKEN unless $mach; + my $value = shift @tok; + $macdef = 1; + } + } + } + + return @entries; +} + +sub read_credential_data_from_stdin { + # the query: start with every token with no value + my %q = map { $_ => undef } values(%{$options{tmap}}); + + while (<STDIN>) { + next unless m/^([^=]+)=(.+)/; + + my ($token, $value) = ($1, $2); + die "Unknown search token $token" unless exists $q{$token}; + $q{$token} = $value; + log_debug("We were given search token $token and value $value"); + } + + foreach (sort keys %q) { + log_debug("Searching for %s = %s", $_, $q{$_} || '(any value)'); + } + + return \%q; +} + +# takes the search tokens and then a list of entries +# each entry is a hash reference +sub find_netrc_entry { + my $query = shift @_; + + ENTRY: + foreach my $entry (@_) + { + my $entry_text = join ', ', map { "$_=$entry->{$_}" } keys %$entry; + foreach my $check (sort keys %$query) { + if (defined $query->{$check}) { + log_debug("compare %s [%s] to [%s] (entry: %s)", + $check, + $entry->{$check}, + $query->{$check}, + $entry_text); + unless ($query->{$check} eq $entry->{$check}) { + next ENTRY; + } + } else { + log_debug("OK: any value satisfies check $check"); + } + } + + return $entry; + } + + # nothing was found + return; +} + +sub print_credential_data { + my $entry = shift @_; + my $query = shift @_; + + log_debug("entry has passed all the search checks"); + TOKEN: + foreach my $git_token (sort keys %$entry) { + log_debug("looking for useful token $git_token"); + # don't print unknown (to the credential helper protocol) tokens + next TOKEN unless exists $query->{$git_token}; + + # don't print things asked in the query (the entry matches them) + next TOKEN if defined $query->{$git_token}; + + log_debug("FOUND: $git_token=$entry->{$git_token}"); + printf "%s=%s\n", $git_token, $entry->{$git_token}; + } +} +sub log_verbose { + return unless $options{verbose}; + printf STDERR @_; + printf STDERR "\n"; +} + +sub log_debug { + return unless $options{debug}; + printf STDERR @_; + printf STDERR "\n"; +} diff --git a/contrib/credential/netrc/test.netrc b/contrib/credential/netrc/test.netrc new file mode 100644 index 0000000000..ba119a937f --- /dev/null +++ b/contrib/credential/netrc/test.netrc @@ -0,0 +1,13 @@ +machine imap login tzz@lifelogs.com port imaps password letmeknow +machine imap login bob port imaps password bobwillknow + +# comment test + +machine imap2 login tzz port 1099 password tzzknow +machine imap2 login bob password bobwillknow + +# another command + +machine github.com + multilinetoken anothervalue + login carol password carolknows diff --git a/contrib/credential/netrc/test.pl b/contrib/credential/netrc/test.pl new file mode 100755 index 0000000000..169b6463c3 --- /dev/null +++ b/contrib/credential/netrc/test.pl @@ -0,0 +1,106 @@ +#!/usr/bin/perl + +use warnings; +use strict; +use Test; +use IPC::Open2; + +BEGIN { plan tests => 15 } + +my @global_credential_args = @ARGV; +my $netrc = './test.netrc'; +print "# Testing insecure file, nothing should be found\n"; +chmod 0644, $netrc; +my $cred = run_credential(['-f', $netrc, 'get'], + { host => 'github.com' }); + +ok(scalar keys %$cred, 0, "Got 0 keys from insecure file"); + +print "# Testing missing file, nothing should be found\n"; +chmod 0644, $netrc; +$cred = run_credential(['-f', '///nosuchfile///', 'get'], + { host => 'github.com' }); + +ok(scalar keys %$cred, 0, "Got 0 keys from missing file"); + +chmod 0600, $netrc; + +print "# Testing with invalid data\n"; +$cred = run_credential(['-f', $netrc, 'get'], + "bad data"); +ok(scalar keys %$cred, 4, "Got first found keys with bad data"); + +print "# Testing netrc file for a missing corovamilkbar entry\n"; +$cred = run_credential(['-f', $netrc, 'get'], + { host => 'corovamilkbar' }); + +ok(scalar keys %$cred, 0, "Got no corovamilkbar keys"); + +print "# Testing netrc file for a github.com entry\n"; +$cred = run_credential(['-f', $netrc, 'get'], + { host => 'github.com' }); + +ok(scalar keys %$cred, 2, "Got 2 Github keys"); + +ok($cred->{password}, 'carolknows', "Got correct Github password"); +ok($cred->{username}, 'carol', "Got correct Github username"); + +print "# Testing netrc file for a username-specific entry\n"; +$cred = run_credential(['-f', $netrc, 'get'], + { host => 'imap', username => 'bob' }); + +ok(scalar keys %$cred, 2, "Got 2 username-specific keys"); + +ok($cred->{password}, 'bobwillknow', "Got correct user-specific password"); +ok($cred->{protocol}, 'imaps', "Got correct user-specific protocol"); + +print "# Testing netrc file for a host:port-specific entry\n"; +$cred = run_credential(['-f', $netrc, 'get'], + { host => 'imap2:1099' }); + +ok(scalar keys %$cred, 2, "Got 2 host:port-specific keys"); + +ok($cred->{password}, 'tzzknow', "Got correct host:port-specific password"); +ok($cred->{username}, 'tzz', "Got correct host:port-specific username"); + +print "# Testing netrc file that 'host:port kills host' entry\n"; +$cred = run_credential(['-f', $netrc, 'get'], + { host => 'imap2' }); + +ok(scalar keys %$cred, 2, "Got 2 'host:port kills host' keys"); + +ok($cred->{password}, 'bobwillknow', "Got correct 'host:port kills host' password"); +ok($cred->{username}, 'bob', "Got correct 'host:port kills host' username"); + +sub run_credential +{ + my $args = shift @_; + my $data = shift @_; + my $pid = open2(my $chld_out, my $chld_in, + './git-credential-netrc', @global_credential_args, + @$args); + + die "Couldn't open pipe to netrc credential helper: $!" unless $pid; + + if (ref $data eq 'HASH') + { + print $chld_in "$_=$data->{$_}\n" foreach sort keys %$data; + } + else + { + print $chld_in "$data\n"; + } + + close $chld_in; + my %ret; + + while (<$chld_out>) + { + chomp; + next unless m/^([^=]+)=(.+)/; + + $ret{$1} = $2; + } + + return \%ret; +} diff --git a/contrib/remote-helpers/Makefile b/contrib/remote-helpers/Makefile index 9a76575f78..239161de33 100644 --- a/contrib/remote-helpers/Makefile +++ b/contrib/remote-helpers/Makefile @@ -3,6 +3,7 @@ TESTS := $(wildcard test*.sh) export T := $(addprefix $(CURDIR)/,$(TESTS)) export MAKE := $(MAKE) -e export PATH := $(CURDIR):$(PATH) +export TEST_LINT := test-lint-executable test-lint-shell-syntax test: $(MAKE) -C ../../t $@ diff --git a/contrib/remote-helpers/git-remote-bzr b/contrib/remote-helpers/git-remote-bzr index c5822e4ac9..10300c63d1 100755 --- a/contrib/remote-helpers/git-remote-bzr +++ b/contrib/remote-helpers/git-remote-bzr @@ -13,6 +13,9 @@ # or # % git clone bzr::lp:myrepo # +# If you want to specify which branches you want track (per repo): +# git config remote-bzr.branches 'trunk, devel, test' +# import sys @@ -25,15 +28,21 @@ bzrlib.plugin.load_plugins() import bzrlib.generate_ids import bzrlib.transport +import bzrlib.errors +import bzrlib.ui +import bzrlib.urlutils +import bzrlib.branch import sys import os import json import re import StringIO +import atexit, shutil, hashlib, urlparse, subprocess NAME_RE = re.compile('^([^<>]+)') AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$') +EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)') RAW_AUTHOR_RE = re.compile('^(\w+) (.+)? <(.*)> (\d+) ([+-]\d+)') def die(msg, *args): @@ -46,6 +55,12 @@ def warn(msg, *args): def gittz(tz): return '%+03d%02d' % (tz / 3600, tz % 3600 / 60) +def get_config(config): + cmd = ['git', 'config', '--get', config] + process = subprocess.Popen(cmd, stdout=subprocess.PIPE) + output, _ = process.communicate() + return output + class Marks: def __init__(self, path): @@ -81,7 +96,7 @@ class Marks: return self.marks[rev] def to_rev(self, mark): - return self.rev_marks[mark] + return str(self.rev_marks[mark]) def next_mark(self): self.last_mark += 1 @@ -93,7 +108,7 @@ class Marks: return self.last_mark def is_marked(self, rev): - return self.marks.has_key(rev) + return rev in self.marks def new_mark(self, rev, mark): self.marks[rev] = mark @@ -171,9 +186,19 @@ def fixup_user(user): name = m.group(1) mail = m.group(2).strip() else: - m = NAME_RE.match(user) + m = EMAIL_RE.match(user) if m: - name = m.group(1).strip() + name = m.group(1) + mail = m.group(2) + else: + m = NAME_RE.match(user) + if m: + name = m.group(1).strip() + + if not name: + name = 'unknown' + if not mail: + mail = 'Unknown' return '%s <%s>' % (name, mail) @@ -183,15 +208,24 @@ def get_filechanges(cur, prev): changes = cur.changes_from(prev) + def u(s): + return s.encode('utf-8') + for path, fid, kind in changes.added: - modified[path] = fid + modified[u(path)] = fid for path, fid, kind in changes.removed: - removed[path] = None + removed[u(path)] = None for path, fid, kind, mod, _ in changes.modified: - modified[path] = fid + modified[u(path)] = fid for oldpath, newpath, fid, kind, mod, _ in changes.renamed: - removed[oldpath] = None - modified[newpath] = fid + removed[u(oldpath)] = None + if kind == 'directory': + lst = cur.list_files(from_dir=newpath, recursive=True) + for path, file_class, kind, fid, entry in lst: + if kind != 'directory': + modified[u(newpath + '/' + path)] = fid + else: + modified[u(newpath)] = fid return modified, removed @@ -214,7 +248,7 @@ def export_files(tree, files): else: mode = '100644' - # is the blog already exported? + # is the blob already exported? if h in filenodes: mark = filenodes[h] final.append((mode, mark, path)) @@ -238,29 +272,44 @@ def export_files(tree, files): return final -def export_branch(branch, name): - global prefix, dirname +def export_branch(repo, name): + global prefix ref = '%s/heads/%s' % (prefix, name) tip = marks.get_tip(name) + branch = bzrlib.branch.Branch.open(branches[name]) repo = branch.repository - repo.lock_read() + + branch.lock_read() revs = branch.iter_merge_sorted_revisions(None, tip, 'exclude', 'forward') - count = 0 + try: + tip_revno = branch.revision_id_to_revno(tip) + last_revno, _ = branch.last_revision_info() + total = last_revno - tip_revno + except bzrlib.errors.NoSuchRevision: + tip_revno = 0 + total = 0 - revs = [revid for revid, _, _, _ in revs if not marks.is_marked(revid)] + for revid, _, seq, _ in revs: - for revid in revs: + if marks.is_marked(revid): + continue rev = repo.get_revision(revid) + revno = seq[0] parents = rev.parent_ids time = rev.timestamp tz = rev.timezone committer = rev.committer.encode('utf-8') committer = "%s %u %s" % (fixup_user(committer), time, gittz(tz)) - author = committer + authors = rev.get_apparent_authors() + if authors: + author = authors[0].encode('utf-8') + author = "%s %u %s" % (fixup_user(author), time, gittz(tz)) + else: + author = committer msg = rev.message.encode('utf-8') msg += '\n' @@ -297,18 +346,24 @@ def export_branch(branch, name): else: print "merge :%s" % m + for f in removed: + print "D %s" % (f,) for f in modified_final: print "M %s :%u %s" % f - for f in removed: - print "D %s" % (f) print - count += 1 - if (count % 100 == 0): - print "progress revision %s (%d/%d)" % (revid, count, len(revs)) - print "#############################################################" + if len(seq) > 1: + # let's skip branch revisions from the progress report + continue + + progress = (revno - tip_revno) + if (progress % 100 == 0): + if total: + print "progress revision %d '%s' (%d/%d)" % (revno, name, progress, total) + else: + print "progress revision %d '%s' (%d)" % (revno, name, progress) - repo.unlock() + branch.unlock() revid = branch.last_revision() @@ -320,34 +375,34 @@ def export_branch(branch, name): marks.set_tip(name, revid) def export_tag(repo, name): - global tags - try: - print "reset refs/tags/%s" % name - print "from :%u" % rev_to_mark(tags[name]) - print - except KeyError: - warn("TODO: fetch tag '%s'" % name) + global tags, prefix + + ref = '%s/tags/%s' % (prefix, name) + print "reset %s" % ref + print "from :%u" % rev_to_mark(tags[name]) + print def do_import(parser): global dirname - branch = parser.repo + repo = parser.repo path = os.path.join(dirname, 'marks-git') print "feature done" if os.path.exists(path): print "feature import-marks=%s" % path print "feature export-marks=%s" % path + print "feature force" sys.stdout.flush() while parser.check('import'): ref = parser[1] if ref.startswith('refs/heads/'): name = ref[len('refs/heads/'):] - export_branch(branch, name) + export_branch(repo, name) if ref.startswith('refs/tags/'): name = ref[len('refs/tags/'):] - export_tag(branch, name) + export_tag(repo, name) parser.next() print 'done' @@ -366,23 +421,21 @@ def parse_blob(parser): class CustomTree(): - def __init__(self, repo, revid, parents, files): + def __init__(self, branch, revid, parents, files): global files_cache - self.repo = repo - self.revid = revid - self.parents = parents self.updates = {} + self.branch = branch def copy_tree(revid): files = files_cache[revid] = {} - tree = repo.repository.revision_tree(revid) - repo.lock_read() + branch.lock_read() + tree = branch.repository.revision_tree(revid) try: for path, entry in tree.iter_entries_by_dir(): - files[path] = entry.file_id + files[path] = [entry.file_id, None] finally: - repo.unlock() + branch.unlock() return files if len(parents) == 0: @@ -395,12 +448,18 @@ class CustomTree(): self.base_files = copy_tree(self.base_id) self.files = files_cache[revid] = self.base_files.copy() + self.rev_files = {} + + for path, data in self.files.iteritems(): + fid, mark = data + self.rev_files[fid] = [path, mark] for path, f in files.iteritems(): - fid = self.files.get(path, None) + fid, mark = self.files.get(path, [None, None]) if not fid: fid = bzrlib.generate_ids.gen_file_id(path) f['path'] = path + self.rev_files[fid] = [path, mark] self.updates[fid] = f def last_revision(self): @@ -410,16 +469,16 @@ class CustomTree(): changes = [] def get_parent(dirname, basename): - parent_fid = self.base_files.get(dirname, None) + parent_fid, mark = self.base_files.get(dirname, [None, None]) if parent_fid: return parent_fid - parent_fid = self.files.get(dirname, None) + parent_fid, mark = self.files.get(dirname, [None, None]) if parent_fid: return parent_fid if basename == '': return None fid = bzrlib.generate_ids.gen_file_id(path) - d = add_entry(fid, dirname, 'directory') + add_entry(fid, dirname, 'directory') return fid def add_entry(fid, path, kind, mode = None): @@ -440,9 +499,8 @@ class CustomTree(): (None, basename), (None, kind), (None, executable)) - self.files[path] = change[0] + self.files[path] = [change[0], None] changes.append(change) - return change def update_entry(fid, path, kind, mode = None): dirname, basename = os.path.split(path) @@ -462,9 +520,8 @@ class CustomTree(): (None, basename), (None, kind), (None, executable)) - self.files[path] = change[0] + self.files[path] = [change[0], None] changes.append(change) - return change def remove_entry(fid, path, kind): dirname, basename = os.path.split(path) @@ -479,7 +536,6 @@ class CustomTree(): (None, None)) del self.files[path] changes.append(change) - return change for fid, f in self.updates.iteritems(): path = f['path'] @@ -493,16 +549,38 @@ class CustomTree(): else: add_entry(fid, path, 'file', f['mode']) + self.files[path][1] = f['mark'] + self.rev_files[fid][1] = f['mark'] + return changes + def get_content(self, file_id): + path, mark = self.rev_files[file_id] + if mark: + return blob_marks[mark] + + # last resort + tree = self.branch.repository.revision_tree(self.base_id) + return tree.get_file_text(file_id) + def get_file_with_stat(self, file_id, path=None): - return (StringIO.StringIO(self.updates[file_id]['data']), None) + content = self.get_content(file_id) + return (StringIO.StringIO(content), None) def get_symlink_target(self, file_id): - return self.updates[file_id]['data'] + return self.get_content(file_id) + + def id2path(self, file_id): + path, mark = self.rev_files[file_id] + return path + +def c_style_unescape(string): + if string[0] == string[-1] == '"': + return string.decode('string-escape')[1:-1] + return string def parse_commit(parser): - global marks, blob_marks, bmarks, parsed_refs + global marks, blob_marks, parsed_refs global mode parents = [] @@ -510,8 +588,11 @@ def parse_commit(parser): ref = parser[1] parser.next() - if ref != 'refs/heads/master': - die("bzr doesn't support multiple branches; use 'master'") + if ref.startswith('refs/heads/'): + name = ref[len('refs/heads/'):] + branch = bzrlib.branch.Branch.open(branches[name]) + else: + die('unknown ref') commit_mark = parser.get_mark() parser.next() @@ -528,34 +609,37 @@ def parse_commit(parser): parents.append(parser.get_mark()) parser.next() + # fast-export adds an extra newline + if data[-1] == '\n': + data = data[:-1] + files = {} for line in parser: if parser.check('M'): t, m, mark_ref, path = line.split(' ', 3) mark = int(mark_ref[1:]) - f = { 'mode' : m, 'data' : blob_marks[mark] } + f = { 'mode' : m, 'mark' : mark } elif parser.check('D'): t, path = line.split(' ') f = { 'deleted' : True } else: die('Unknown file command: %s' % line) + path = c_style_unescape(path).decode('utf-8') files[path] = f - repo = parser.repo - committer, date, tz = committer - parents = [str(mark_to_rev(p)) for p in parents] + parents = [mark_to_rev(p) for p in parents] revid = bzrlib.generate_ids.gen_revision_id(committer, date) props = {} - props['branch-nick'] = repo.nick + props['branch-nick'] = branch.nick - mtree = CustomTree(repo, revid, parents, files) + mtree = CustomTree(branch, revid, parents, files) changes = mtree.iter_changes() - repo.lock_write() + branch.lock_write() try: - builder = repo.get_commit_builder(parents, None, date, tz, committer, props, revid) + builder = branch.get_commit_builder(parents, None, date, tz, committer, props, revid) try: list(builder.record_iter_changes(mtree, mtree.last_revision(), changes)) builder.finish_inventory() @@ -564,7 +648,7 @@ def parse_commit(parser): builder.abort() raise finally: - repo.unlock() + branch.unlock() parsed_refs[ref] = revid marks.new_mark(revid, commit_mark) @@ -575,9 +659,6 @@ def parse_reset(parser): ref = parser[1] parser.next() - if ref != 'refs/heads/master': - die("bzr doesn't support multiple branches; use 'master'") - # ugh if parser.check('commit'): parse_commit(parser) @@ -590,7 +671,7 @@ def parse_reset(parser): parsed_refs[ref] = mark_to_rev(from_mark) def do_export(parser): - global parsed_refs, dirname, peer + global parsed_refs, dirname parser.next() @@ -608,22 +689,35 @@ def do_export(parser): else: die('unhandled export command: %s' % line) - repo = parser.repo - for ref, revid in parsed_refs.iteritems(): - if ref == 'refs/heads/master': - repo.generate_revision_history(revid, marks.get_tip('master')) - revno, revid = repo.last_revision_info() - if peer: - if hasattr(peer, "import_last_revision_info_and_tags"): - peer.import_last_revision_info_and_tags(repo, revno, revid) - else: - peer.import_last_revision_info(repo.repository, revno, revid) - wt = peer.bzrdir.open_workingtree() - else: - wt = repo.bzrdir.open_workingtree() - wt.update() + if ref.startswith('refs/heads/'): + name = ref[len('refs/heads/'):] + branch = bzrlib.branch.Branch.open(branches[name]) + branch.generate_revision_history(revid, marks.get_tip(name)) + + if name in peers: + peer = bzrlib.branch.Branch.open(peers[name]) + try: + peer.bzrdir.push_branch(branch, revision_id=revid) + except bzrlib.errors.DivergedBranches: + print "error %s non-fast forward" % ref + continue + + try: + wt = branch.bzrdir.open_workingtree() + wt.update() + except bzrlib.errors.NoWorkingTree: + pass + elif ref.startswith('refs/tags/'): + # TODO: implement tag push + print "error %s pushing tags not supported" % ref + continue + else: + # transport-helper/fast-export bugs + continue + print "ok %s" % ref + print def do_capabilities(parser): @@ -632,6 +726,7 @@ def do_capabilities(parser): print "import" print "export" print "refspec refs/heads/*:%s/heads/*" % prefix + print "refspec refs/tags/*:%s/tags/*" % prefix path = os.path.join(dirname, 'marks-git') @@ -641,66 +736,198 @@ def do_capabilities(parser): print +def ref_is_valid(name): + return not True in [c in name for c in '~^: \\'] + def do_list(parser): global tags - print "? refs/heads/%s" % 'master' - for tag, revid in parser.repo.tags.get_tag_dict().items(): + + master_branch = None + + for name in branches: + if not master_branch: + master_branch = name + print "? refs/heads/%s" % name + + branch = bzrlib.branch.Branch.open(branches[master_branch]) + branch.lock_read() + for tag, revid in branch.tags.get_tag_dict().items(): + try: + branch.revision_id_to_dotted_revno(revid) + except bzrlib.errors.NoSuchRevision: + continue + if not ref_is_valid(tag): + continue print "? refs/tags/%s" % tag tags[tag] = revid - print "@refs/heads/%s HEAD" % 'master' + branch.unlock() + + print "@refs/heads/%s HEAD" % master_branch print +def get_remote_branch(origin, remote_branch, name): + global dirname, peers + + branch_path = os.path.join(dirname, 'clone', name) + if os.path.exists(branch_path): + # pull + d = bzrlib.bzrdir.BzrDir.open(branch_path) + branch = d.open_branch() + try: + branch.pull(remote_branch, [], None, False) + except bzrlib.errors.DivergedBranches: + # use remote branch for now + return remote_branch + else: + # clone + d = origin.sprout(branch_path, None, + hardlink=True, create_tree_if_local=False, + force_new_repo=False, + source_branch=remote_branch) + branch = d.open_branch() + + return branch + +def find_branches(repo, wanted): + transport = repo.bzrdir.root_transport + + for fn in transport.iter_files_recursive(): + if not fn.endswith('.bzr/branch-format'): + continue + + name = subdir = fn[:-len('/.bzr/branch-format')] + name = name if name != '' else 'master' + name = name.replace('/', '+') + + if wanted and not name in wanted: + continue + + try: + cur = transport.clone(subdir) + branch = bzrlib.branch.Branch.open_from_transport(cur) + except bzrlib.errors.NotBranchError: + continue + else: + yield name, branch + def get_repo(url, alias): - global dirname, peer + global dirname, peer, branches + normal_url = bzrlib.urlutils.normalize_url(url) origin = bzrlib.bzrdir.BzrDir.open(url) - branch = origin.open_branch() + is_local = isinstance(origin.transport, bzrlib.transport.local.LocalTransport) + + shared_path = os.path.join(gitdir, 'bzr') + try: + shared_dir = bzrlib.bzrdir.BzrDir.open(shared_path) + except bzrlib.errors.NotBranchError: + shared_dir = bzrlib.bzrdir.BzrDir.create(shared_path) + try: + shared_repo = shared_dir.open_repository() + except bzrlib.errors.NoRepositoryPresent: + shared_repo = shared_dir.create_repository(shared=True) - if not isinstance(origin.transport, bzrlib.transport.local.LocalTransport): + if not is_local: clone_path = os.path.join(dirname, 'clone') - remote_branch = branch - if os.path.exists(clone_path): - # pull - d = bzrlib.bzrdir.BzrDir.open(clone_path) - branch = d.open_branch() - result = branch.pull(remote_branch, [], None, False) + if not os.path.exists(clone_path): + os.mkdir(clone_path) + else: + # check and remove old organization + try: + bdir = bzrlib.bzrdir.BzrDir.open(clone_path) + bdir.destroy_repository() + except bzrlib.errors.NotBranchError: + pass + except bzrlib.errors.NoRepositoryPresent: + pass + + try: + repo = origin.open_repository() + if not repo.user_transport.listable(): + # this repository is not usable for us + raise bzrlib.errors.NoRepositoryPresent(repo.bzrdir) + except bzrlib.errors.NoRepositoryPresent: + # branch + + name = 'master' + remote_branch = origin.open_branch() + + if not is_local: + peers[name] = remote_branch.base + branch = get_remote_branch(origin, remote_branch, name) else: - # clone - d = origin.sprout(clone_path, None, - hardlink=True, create_tree_if_local=False, - source_branch=remote_branch) - branch = d.open_branch() - branch.bind(remote_branch) - - peer = remote_branch + branch = remote_branch + + branches[name] = branch.base + + return branch.repository else: - peer = None + # repository - return branch + wanted = get_config('remote-bzr.branches').rstrip().split(', ') + # stupid python + wanted = [e for e in wanted if e] + + for name, remote_branch in find_branches(repo, wanted): + + if not is_local: + peers[name] = remote_branch.base + branch = get_remote_branch(origin, remote_branch, name) + else: + branch = remote_branch + + branches[name] = branch.base + + return repo + +def fix_path(alias, orig_url): + url = urlparse.urlparse(orig_url, 'file') + if url.scheme != 'file' or os.path.isabs(url.path): + return + abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url) + cmd = ['git', 'config', 'remote.%s.url' % alias, "bzr::%s" % abs_url] + subprocess.call(cmd) def main(args): - global marks, prefix, dirname + global marks, prefix, gitdir, dirname global tags, filenodes global blob_marks global parsed_refs global files_cache + global is_tmp + global branches, peers alias = args[1] url = args[2] - prefix = 'refs/bzr/%s' % alias tags = {} filenodes = {} blob_marks = {} parsed_refs = {} files_cache = {} + marks = None + branches = {} + peers = {} + + if alias[5:] == url: + is_tmp = True + alias = hashlib.sha1(alias).hexdigest() + else: + is_tmp = False + prefix = 'refs/bzr/%s' % alias gitdir = os.environ['GIT_DIR'] dirname = os.path.join(gitdir, 'bzr', alias) + if not is_tmp: + fix_path(alias, url) + if not os.path.exists(dirname): os.makedirs(dirname) + if hasattr(bzrlib.ui.ui_factory, 'be_quiet'): + bzrlib.ui.ui_factory.be_quiet(True) + repo = get_repo(url, alias) marks_path = os.path.join(dirname, 'marks-int') @@ -720,6 +947,13 @@ def main(args): die('unhandled command: %s' % line) sys.stdout.flush() - marks.store() +def bye(): + if not marks: + return + if not is_tmp: + marks.store() + else: + shutil.rmtree(dirname) +atexit.register(bye) sys.exit(main(sys.argv)) diff --git a/contrib/remote-helpers/git-remote-hg b/contrib/remote-helpers/git-remote-hg index 45f6c80d45..1dd3d7030e 100755 --- a/contrib/remote-helpers/git-remote-hg +++ b/contrib/remote-helpers/git-remote-hg @@ -8,8 +8,11 @@ # Just copy to your ~/bin, or anywhere in your $PATH. # Then you can clone with: # git clone hg::/path/to/mercurial/repo/ +# +# For remote repositories a local clone is stored in +# "$GIT_DIR/hg/origin/clone/.hg/". -from mercurial import hg, ui, bookmarks, context, util, encoding +from mercurial import hg, ui, bookmarks, context, encoding, node, error, extensions import re import sys @@ -18,8 +21,20 @@ import json import shutil import subprocess import urllib +import atexit +import urlparse, hashlib # +# If you are not in hg-git-compat mode and want to disable the tracking of +# named branches: +# git config --global remote-hg.track-branches false +# +# If you don't want to force pushes (and thus risk creating new remote heads): +# git config --global remote-hg.force-push false +# +# If you want the equivalent of hg's clone/pull--insecure option: +# git config --global remote-hg.insecure true +# # If you want to switch to hg-git compatibility mode: # git config --global remote-hg.hg-git-compat true # @@ -36,6 +51,7 @@ import urllib NAME_RE = re.compile('^([^<>]+)') AUTHOR_RE = re.compile('^([^<>]+?)? ?<([^<>]*)>$') +EMAIL_RE = re.compile('^([^<>]+[^ \\\t<>])?\\b(?:[ \\t<>]*?)\\b([^ \\t<>]+@[^ \\t<>]+)') AUTHOR_HG_RE = re.compile('^(.*?) ?<(.*?)(?:>(.+)?)?$') RAW_AUTHOR_RE = re.compile('^(\w+) (?:(.+)? )?<(.*)> (\d+) ([+-]\d+)') @@ -56,12 +72,30 @@ def hgmode(mode): m = { '100755': 'x', '120000': 'l' } return m.get(mode, '') +def hghex(node): + return hg.node.hex(node) + +def hgref(ref): + return ref.replace('___', ' ') + +def gitref(ref): + return ref.replace(' ', '___') + def get_config(config): cmd = ['git', 'config', '--get', config] process = subprocess.Popen(cmd, stdout=subprocess.PIPE) output, _ = process.communicate() return output +def get_config_bool(config, default=False): + value = get_config(config).rstrip('\n') + if value == "true": + return True + elif value == "false": + return False + else: + return default + class Marks: def __init__(self, path): @@ -101,6 +135,10 @@ class Marks: def to_rev(self, mark): return self.rev_marks[mark] + def next_mark(self): + self.last_mark += 1 + return self.last_mark + def get_mark(self, rev): self.last_mark += 1 self.marks[str(rev)] = self.last_mark @@ -112,7 +150,7 @@ class Marks: self.last_mark = mark def is_marked(self, rev): - return self.marks.has_key(str(rev)) + return str(rev) in self.marks def get_tip(self, branch): return self.tips.get(branch, 0) @@ -188,19 +226,43 @@ class Parser: tz = ((tz / 100) * 3600) + ((tz % 100) * 60) return (user, int(date), -tz) -def export_file(fc): - d = fc.data() - print "M %s inline %s" % (gitmode(fc.flags()), fc.path()) - print "data %d" % len(d) - print d +def fix_file_path(path): + if not os.path.isabs(path): + return path + return os.path.relpath(path, '/') + +def export_files(files): + global marks, filenodes + + final = [] + for f in files: + fid = node.hex(f.filenode()) + + if fid in filenodes: + mark = filenodes[fid] + else: + mark = marks.next_mark() + filenodes[fid] = mark + d = f.data() + + print "blob" + print "mark :%u" % mark + print "data %d" % len(d) + print d + + path = fix_file_path(f.path()) + final.append((gitmode(f.flags()), mark, path)) + + return final def get_filechanges(repo, ctx, parent): modified = set() added = set() removed = set() - cur = ctx.manifest() + # load earliest manifest first for caching reasons prev = repo[parent].manifest().copy() + cur = ctx.manifest() for fn in cur: if fn in prev: @@ -221,9 +283,14 @@ def fixup_user_git(user): name = m.group(1) mail = m.group(2).strip() else: - m = NAME_RE.match(user) + m = EMAIL_RE.match(user) if m: - name = m.group(1).strip() + name = m.group(1) + mail = m.group(2) + else: + m = NAME_RE.match(user) + if m: + name = m.group(1).strip() return (name, mail) def fixup_user_hg(user): @@ -267,17 +334,33 @@ def get_repo(url, alias): myui = ui.ui() myui.setconfig('ui', 'interactive', 'off') + myui.fout = sys.stderr + + if get_config_bool('remote-hg.insecure'): + myui.setconfig('web', 'cacerts', '') + + try: + mod = extensions.load(myui, 'hgext.schemes', None) + mod.extsetup(myui) + except ImportError: + pass if hg.islocal(url): repo = hg.repository(myui, url) else: local_path = os.path.join(dirname, 'clone') if not os.path.exists(local_path): - peer, dstpeer = hg.clone(myui, {}, url, local_path, update=False, pull=True) + try: + peer, dstpeer = hg.clone(myui, {}, url, local_path, update=True, pull=True) + except: + die('Repository error') repo = dstpeer.local() else: repo = hg.repository(myui, local_path) - peer = hg.peer(myui, {}, url) + try: + peer = hg.peer(myui, {}, url) + except: + die('Repository error') repo.pull(peer, heads=None, force=True) return repo @@ -296,10 +379,6 @@ def export_ref(repo, name, kind, head): ename = '%s/%s' % (kind, name) tip = marks.get_tip(ename) - # mercurial takes too much time checking this - if tip and tip == head.rev(): - # nothing to do - return revs = xrange(tip, head.rev() + 1) count = 0 @@ -357,6 +436,8 @@ def export_ref(repo, name, kind, head): if len(parents) == 0 and rev: print 'reset %s/%s' % (prefix, ename) + modified_final = export_files(c.filectx(f) for f in modified) + print "commit %s/%s" % (prefix, ename) print "mark :%d" % (marks.get_mark(rev)) print "author %s" % (author) @@ -369,16 +450,15 @@ def export_ref(repo, name, kind, head): if len(parents) > 1: print "merge :%s" % (rev_to_mark(parents[1])) - for f in modified: - export_file(c.filectx(f)) + for f in modified_final: + print "M %s :%u %s" % f for f in removed: - print "D %s" % (f) + print "D %s" % (fix_file_path(f)) print count += 1 if (count % 100 == 0): print "progress revision %d '%s' (%d/%d)" % (rev, name, count, len(revs)) - print "#############################################################" # make sure the ref is updated print "reset %s/%s" % (prefix, ename) @@ -388,10 +468,10 @@ def export_ref(repo, name, kind, head): marks.set_tip(ename, rev) def export_tag(repo, tag): - export_ref(repo, tag, 'tags', repo[tag]) + export_ref(repo, tag, 'tags', repo[hgref(tag)]) def export_bookmark(repo, bmark): - head = bmarks[bmark] + head = bmarks[hgref(bmark)] export_ref(repo, bmark, 'bookmarks', head) def export_branch(repo, branch): @@ -420,19 +500,24 @@ def do_capabilities(parser): print +def branch_tip(repo, branch): + # older versions of mercurial don't have this + if hasattr(repo, 'branchtip'): + return repo.branchtip(branch) + else: + return repo.branchtags()[branch] + def get_branch_tip(repo, branch): global branches - heads = branches.get(branch, None) + heads = branches.get(hgref(branch), None) if not heads: return None # verify there's only one head if (len(heads) > 1): warn("Branch '%s' has more than one head, consider merging" % branch) - # older versions of mercurial don't have this - if hasattr(repo, "branchtip"): - return repo.branchtip(branch) + return branch_tip(repo, hgref(branch)) return heads[0] @@ -454,11 +539,12 @@ def list_head(repo, cur): head = 'master' bmarks[head] = node + head = gitref(head) print "@refs/heads/%s HEAD" % head g_head = (head, node) def do_list(parser): - global branches, bmarks, mode, track_branches + global branches, bmarks, track_branches repo = parser.repo for bmark, node in bookmarks.listbookmarks(repo).iteritems(): @@ -475,15 +561,15 @@ def do_list(parser): branches[branch] = heads for branch in branches: - print "? refs/heads/branches/%s" % branch + print "? refs/heads/branches/%s" % gitref(branch) for bmark in bmarks: - print "? refs/heads/%s" % bmark + print "? refs/heads/%s" % gitref(bmark) for tag, node in repo.tagslist(): if tag == 'tip': continue - print "? refs/tags/%s" % tag + print "? refs/tags/%s" % gitref(tag) print @@ -532,7 +618,6 @@ def parse_blob(parser): data = parser.get_data() blob_marks[mark] = data parser.next() - return def get_merge_files(repo, p1, p2, files): for e in repo[p1].files(): @@ -543,7 +628,7 @@ def get_merge_files(repo, p1, p2, files): files[e] = f def parse_commit(parser): - global marks, blob_marks, bmarks, parsed_refs + global marks, blob_marks, parsed_refs global mode from_mark = merge_mark = None @@ -568,6 +653,10 @@ def parse_commit(parser): if parser.check('merge'): die('octopus merges are not supported yet') + # fast-export adds an extra newline + if data[-1] == '\n': + data = data[:-1] + files = {} for line in parser: @@ -576,7 +665,7 @@ def parse_commit(parser): mark = int(mark_ref[1:]) f = { 'mode' : hgmode(m), 'data' : blob_marks[mark] } elif parser.check('D'): - t, path = line.split(' ') + t, path = line.split(' ', 1) f = { 'deleted' : True } else: die('Unknown file command: %s' % line) @@ -619,11 +708,16 @@ def parse_commit(parser): if merge_mark: get_merge_files(repo, p1, p2, files) + # Check if the ref is supposed to be a named branch + if ref.startswith('refs/heads/branches/'): + branch = ref[len('refs/heads/branches/'):] + extra['branch'] = hgref(branch) + if mode == 'hg': i = data.find('\n--HG--\n') if i >= 0: tmp = data[i + len('\n--HG--\n'):].strip() - for k, v in [e.split(' : ') for e in tmp.split('\n')]: + for k, v in [e.split(' : ', 1) for e in tmp.split('\n')]: if k == 'rename': old, new = v.split(' => ', 1) files[new]['rename'] = old @@ -648,10 +742,11 @@ def parse_commit(parser): rev = repo[node].rev() parsed_refs[ref] = node - marks.new_mark(rev, commit_mark) def parse_reset(parser): + global parsed_refs + ref = parser[1] parser.next() # ugh @@ -676,11 +771,46 @@ def parse_tag(parser): data = parser.get_data() parser.next() - # nothing to do + parsed_tags[name] = (tagger, data) + +def write_tag(repo, tag, node, msg, author): + branch = repo[node].branch() + tip = branch_tip(repo, branch) + tip = repo[tip] + + def getfilectx(repo, memctx, f): + try: + fctx = tip.filectx(f) + data = fctx.data() + except error.ManifestLookupError: + data = "" + content = data + "%s %s\n" % (hghex(node), tag) + return context.memfilectx(f, content, False, False, None) + + p1 = tip.hex() + p2 = '\0' * 20 + if not author: + author = (None, 0, 0) + user, date, tz = author + + ctx = context.memctx(repo, (p1, p2), msg, + ['.hgtags'], getfilectx, + user, (date, tz), {'branch' : branch}) + + tmp = encoding.encoding + encoding.encoding = 'utf-8' + + tagnode = repo.commitctx(ctx) + + encoding.encoding = tmp + + return tagnode def do_export(parser): global parsed_refs, bmarks, peer + p_bmarks = [] + parser.next() for line in parser.each_block('done'): @@ -699,56 +829,93 @@ def do_export(parser): for ref, node in parsed_refs.iteritems(): if ref.startswith('refs/heads/branches'): - pass + branch = ref[len('refs/heads/branches/'):] + if branch in branches and node in branches[branch]: + # up to date + continue + print "ok %s" % ref elif ref.startswith('refs/heads/'): bmark = ref[len('refs/heads/'):] - if bmark in bmarks: - old = bmarks[bmark].hex() - else: - old = '' - if not bookmarks.pushbookmark(parser.repo, bmark, old, node): - continue + p_bmarks.append((bmark, node)) + continue elif ref.startswith('refs/tags/'): tag = ref[len('refs/tags/'):] - parser.repo.tag([tag], node, None, True, None, {}) + tag = hgref(tag) + author, msg = parsed_tags.get(tag, (None, None)) + if mode == 'git': + if not msg: + msg = 'Added tag %s for changeset %s' % (tag, hghex(node[:6])); + write_tag(parser.repo, tag, node, msg, author) + else: + fp = parser.repo.opener('localtags', 'a') + fp.write('%s %s\n' % (hghex(node), tag)) + fp.close() + print "ok %s" % ref else: # transport-helper/fast-export bugs continue + + if peer: + parser.repo.push(peer, force=force_push, newbranch=True) + + # handle bookmarks + for bmark, node in p_bmarks: + ref = 'refs/heads/' + bmark + new = hghex(node) + + if bmark in bmarks: + old = bmarks[bmark].hex() + else: + old = '' + + if old == new: + continue + + if bmark == 'master' and 'master' not in parser.repo._bookmarks: + # fake bookmark + print "ok %s" % ref + continue + elif bookmarks.pushbookmark(parser.repo, bmark, old, new): + # updated locally + pass + else: + print "error %s" % ref + continue + + if peer: + rb = peer.listkeys('bookmarks') + old = rb.get(bmark, '') + if not peer.pushkey('bookmarks', bmark, old, new): + print "error %s" % ref + continue + print "ok %s" % ref print - if peer: - parser.repo.push(peer, force=False) - def fix_path(alias, repo, orig_url): - repo_url = util.url(repo.url()) - url = util.url(orig_url) - if str(url) == str(repo_url): + url = urlparse.urlparse(orig_url, 'file') + if url.scheme != 'file' or os.path.isabs(url.path): return - cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % repo_url] + abs_url = urlparse.urljoin("%s/" % os.getcwd(), orig_url) + cmd = ['git', 'config', 'remote.%s.url' % alias, "hg::%s" % abs_url] subprocess.call(cmd) def main(args): global prefix, dirname, branches, bmarks global marks, blob_marks, parsed_refs global peer, mode, bad_mail, bad_name - global track_branches + global track_branches, force_push, is_tmp + global parsed_tags + global filenodes alias = args[1] url = args[2] peer = None - hg_git_compat = False - track_branches = True - try: - if get_config('remote-hg.hg-git-compat') == 'true\n': - hg_git_compat = True - track_branches = False - if get_config('remote-hg.track-branches') == 'false\n': - track_branches = False - except subprocess.CalledProcessError: - pass + hg_git_compat = get_config_bool('remote-hg.hg-git-compat') + track_branches = get_config_bool('remote-hg.track-branches', True) + force_push = get_config_bool('remote-hg.force-push') if hg_git_compat: mode = 'hg' @@ -761,7 +928,7 @@ def main(args): if alias[4:] == url: is_tmp = True - alias = util.sha1(alias).hexdigest() + alias = hashlib.sha1(alias).hexdigest() else: is_tmp = False @@ -771,6 +938,9 @@ def main(args): bmarks = {} blob_marks = {} parsed_refs = {} + marks = None + parsed_tags = {} + filenodes = {} repo = get_repo(url, alias) prefix = 'refs/hg/%s' % alias @@ -784,6 +954,10 @@ def main(args): marks_path = os.path.join(dirname, 'marks-hg') marks = Marks(marks_path) + if sys.platform == 'win32': + import msvcrt + msvcrt.setmode(sys.stdout.fileno(), os.O_BINARY) + parser = Parser(repo) for line in parser: if parser.check('capabilities'): @@ -798,9 +972,13 @@ def main(args): die('unhandled command: %s' % line) sys.stdout.flush() +def bye(): + if not marks: + return if not is_tmp: marks.store() else: shutil.rmtree(dirname) +atexit.register(bye) sys.exit(main(sys.argv)) diff --git a/contrib/remote-helpers/test-bzr.sh b/contrib/remote-helpers/test-bzr.sh index 70aa8a010a..5dfa070b64 100755 --- a/contrib/remote-helpers/test-bzr.sh +++ b/contrib/remote-helpers/test-bzr.sh @@ -17,20 +17,6 @@ if ! "$PYTHON_PATH" -c 'import bzrlib'; then test_done fi -cmd=' -import bzrlib -bzrlib.initialize() -import bzrlib.plugin -bzrlib.plugin.load_plugins() -import bzrlib.plugins.fastimport -' - -if ! "$PYTHON_PATH" -c "$cmd"; then - echo "consider setting BZR_PLUGIN_PATH=$HOME/.bazaar/plugins" 1>&2 - skip_all='skipping remote-bzr tests; bzr-fastimport not available' - test_done -fi - check () { (cd $1 && git log --format='%s' -1 && @@ -136,7 +122,219 @@ test_expect_success 'special modes' ' (cd gitrepo && git cat-file -p HEAD:link > ../actual) && - echo -n content > expected && + printf content > expected && + test_cmp expected actual +' + +cat > expected <<EOF +100644 blob 54f9d6da5c91d556e6b54340b1327573073030af content +100755 blob 68769579c3eaadbe555379b9c3538e6628bae1eb executable +120000 blob 6b584e8ece562ebffc15d38808cd6b98fc3d97ea link +040000 tree 35c0caa46693cef62247ac89a680f0c5ce32b37b movedir-new +EOF + +test_expect_success 'moving directory' ' + (cd bzrrepo && + mkdir movedir && + echo one > movedir/one && + echo two > movedir/two && + bzr add movedir && + bzr commit -m movedir && + bzr mv movedir movedir-new && + bzr commit -m movedir-new) && + + (cd gitrepo && + git pull && + git ls-tree HEAD > ../actual) && + + test_cmp expected actual +' + +test_expect_success 'different authors' ' + (cd bzrrepo && + echo john >> content && + bzr commit -m john \ + --author "Jane Rey <jrey@example.com>" \ + --author "John Doe <jdoe@example.com>") && + + (cd gitrepo && + git pull && + git show --format="%an <%ae>, %cn <%ce>" --quiet > ../actual) && + + echo "Jane Rey <jrey@example.com>, A U Thor <author@example.com>" > expected && + test_cmp expected actual +' + +test_expect_success 'fetch utf-8 filenames' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp && LC_ALL=C" && + + LC_ALL=en_US.UTF-8 + export LC_ALL + ( + bzr init bzrrepo && + cd bzrrepo && + + echo test >> "ærø" && + bzr add "ærø" && + echo test >> "ø~?" && + bzr add "ø~?" && + bzr commit -m add-utf-8 && + echo test >> "ærø" && + bzr commit -m test-utf-8 && + bzr rm "ø~?" && + bzr mv "ærø" "ø~?" && + bzr commit -m bzr-mv-utf-8 + ) && + + ( + git clone "bzr::$PWD/bzrrepo" gitrepo && + cd gitrepo && + git -c core.quotepath=false ls-files > ../actual + ) && + echo "ø~?" > expected && + test_cmp expected actual +' + +test_expect_success 'push utf-8 filenames' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp && LC_ALL=C" && + + LC_ALL=en_US.UTF-8 + export LC_ALL + + ( + bzr init bzrrepo && + cd bzrrepo && + + echo one >> content && + bzr add content && + bzr commit -m one + ) && + + ( + git clone "bzr::$PWD/bzrrepo" gitrepo && + cd gitrepo && + + echo test >> "ærø" && + git add "ærø" && + git commit -m utf-8 && + + git push + ) && + + (cd bzrrepo && bzr ls > ../actual) && + printf "content\nærø\n" > expected && + test_cmp expected actual +' + +test_expect_success 'pushing a merge' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + bzr init bzrrepo && + cd bzrrepo && + echo one > content && + bzr add content && + bzr commit -m one + ) && + + git clone "bzr::$PWD/bzrrepo" gitrepo && + + ( + cd bzrrepo && + echo two > content && + bzr commit -m two + ) && + + ( + cd gitrepo && + echo three > content && + git commit -a -m three && + git fetch && + git merge origin/master || true && + echo three > content && + git commit -a --no-edit && + git push + ) && + + echo three > expected && + cat bzrrepo/content > actual && + test_cmp expected actual +' + +cat > expected <<EOF +origin/HEAD +origin/branch +origin/trunk +EOF + +test_expect_success 'proper bzr repo' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + bzr init-repo bzrrepo && + + bzr init bzrrepo/trunk && + ( + cd bzrrepo/trunk && + echo one >> content && + bzr add content && + bzr commit -m one + ) && + + bzr branch bzrrepo/trunk bzrrepo/branch && + ( + cd bzrrepo/branch && + echo two >> content && + bzr commit -m one + ) && + + git clone "bzr::$PWD/bzrrepo" gitrepo && + ( + cd gitrepo && + git for-each-ref --format "%(refname:short)" refs/remotes/origin > ../actual + ) && + + test_cmp ../expected actual +' + +test_expect_success 'strip' ' + # Do not imitate this style; always chdir inside a subshell instead + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + bzr init bzrrepo && + cd bzrrepo && + + echo one >> content && + bzr add content && + bzr commit -m one && + + echo two >> content && + bzr commit -m two + ) && + + git clone "bzr::$PWD/bzrrepo" gitrepo && + + ( + cd bzrrepo && + bzr uncommit --force && + + echo three >> content && + bzr commit -m three && + + echo four >> content && + bzr commit -m four && + bzr log --line | sed -e "s/^[0-9][0-9]*: //" > ../expected + ) && + + (cd gitrepo && + git fetch && + git log --format="%an %ad %s" --date=short origin/master > ../actual) && + test_cmp expected actual ' diff --git a/contrib/remote-helpers/test-hg-bidi.sh b/contrib/remote-helpers/test-hg-bidi.sh index 2a5d85dd72..f569697734 100755 --- a/contrib/remote-helpers/test-hg-bidi.sh +++ b/contrib/remote-helpers/test-hg-bidi.sh @@ -22,7 +22,6 @@ fi # clone to a git repo git_clone () { - hg -R $1 bookmark -f -r tip master && git clone -q "hg::$PWD/$1" $2 } @@ -30,6 +29,7 @@ git_clone () { hg_clone () { ( hg init $2 && + hg -R $2 bookmark -i master && cd $1 && git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' ) && @@ -50,7 +50,8 @@ hg_push () { } hg_log () { - hg -R $1 log --graph --debug | grep -v 'tag: *default/' + hg -R $1 log --graph --debug >log && + grep -v 'tag: *default/' log } setup () { @@ -62,6 +63,8 @@ setup () { echo "commit = -d \"0 0\"" echo "debugrawcommit = -d \"0 0\"" echo "tag = -d \"0 0\"" + echo "[extensions]" + echo "graphlog =" ) >> "$HOME"/.hgrc && git config --global remote-hg.hg-git-compat true @@ -201,8 +204,8 @@ test_expect_success 'hg branch' ' hg_push hgrepo gitrepo && hg_clone gitrepo hgrepo2 && - : TODO, avoid "master" bookmark && - (cd hgrepo2 && hg checkout gamma) && + : Back to the common revision && + (cd hgrepo && hg checkout default) && hg_log hgrepo > expected && hg_log hgrepo2 > actual && diff --git a/contrib/remote-helpers/test-hg-hg-git.sh b/contrib/remote-helpers/test-hg-hg-git.sh index 9aaf043669..7f579c8436 100755 --- a/contrib/remote-helpers/test-hg-hg-git.sh +++ b/contrib/remote-helpers/test-hg-hg-git.sh @@ -27,7 +27,6 @@ fi # clone to a git repo with git git_clone_git () { - hg -R $1 bookmark -f -r tip master && git clone -q "hg::$PWD/$1" $2 } @@ -35,6 +34,7 @@ git_clone_git () { hg_clone_git () { ( hg init $2 && + hg -R $2 bookmark -i master && cd $1 && git push -q "hg::$PWD/../$2" 'refs/tags/*:refs/tags/*' 'refs/heads/*:refs/heads/*' ) && @@ -47,7 +47,7 @@ git_clone_hg () { ( git init -q $2 && cd $1 && - hg bookmark -f -r tip master && + hg bookmark -i -f -r tip master && hg -q push -r master ../$2 || true ) } @@ -78,7 +78,8 @@ hg_push_hg () { } hg_log () { - hg -R $1 log --graph --debug | grep -v 'tag: *default/' + hg -R $1 log --graph --debug >log && + grep -v 'tag: *default/' log } git_log () { @@ -97,9 +98,11 @@ setup () { echo "[extensions]" echo "hgext.bookmarks =" echo "hggit =" + echo "graphlog =" ) >> "$HOME"/.hgrc && git config --global receive.denycurrentbranch warn git config --global remote-hg.hg-git-compat true + git config --global remote-hg.track-branches false HGEDITOR=/usr/bin/true @@ -141,7 +144,6 @@ test_expect_success 'executable bit' ' git_clone_$x hgrepo-$x gitrepo2-$x && git_log gitrepo2-$x > log-$x done && - cp -r log-* output-* /tmp/foo/ && test_cmp output-hg output-git && test_cmp log-hg log-git @@ -454,8 +456,6 @@ test_expect_success 'hg author' ' git_log gitrepo-$x > git-log-$x done && - test_cmp git-log-hg git-log-git && - test_cmp hg-log-hg hg-log-git && test_cmp git-log-hg git-log-git ' diff --git a/contrib/remote-helpers/test-hg.sh b/contrib/remote-helpers/test-hg.sh index 7bb81f2f8e..8de2aa7fec 100755 --- a/contrib/remote-helpers/test-hg.sh +++ b/contrib/remote-helpers/test-hg.sh @@ -118,4 +118,40 @@ test_expect_success 'update bookmark' ' hg -R hgrepo bookmarks | egrep "devel[ ]+3:" ' +author_test () { + echo $1 >> content && + hg commit -u "$2" -m "add $1" && + echo "$3" >> ../expected +} + +test_expect_success 'authors' ' + mkdir -p tmp && cd tmp && + test_when_finished "cd .. && rm -rf tmp" && + + ( + hg init hgrepo && + cd hgrepo && + + touch content && + hg add content && + + author_test alpha "" "H G Wells <wells@example.com>" && + author_test beta "test" "test <unknown>" && + author_test beta "test <test@example.com> (comment)" "test <test@example.com>" && + author_test gamma "<test@example.com>" "Unknown <test@example.com>" && + author_test delta "name<test@example.com>" "name <test@example.com>" && + author_test epsilon "name <test@example.com" "name <test@example.com>" && + author_test zeta " test " "test <unknown>" && + author_test eta "test < test@example.com >" "test <test@example.com>" && + author_test theta "test >test@example.com>" "test <test@example.com>" && + author_test iota "test < test <at> example <dot> com>" "test <unknown>" && + author_test kappa "test@example.com" "Unknown <test@example.com>" + ) && + + git clone "hg::$PWD/hgrepo" gitrepo && + git --git-dir=gitrepo/.git log --reverse --format="%an <%ae>" > actual && + + test_cmp expected actual +' + test_done @@ -153,36 +153,13 @@ static void check_safe_crlf(const char *path, enum crlf_action crlf_action, static int has_cr_in_index(const char *path) { - int pos, len; unsigned long sz; - enum object_type type; void *data; int has_cr; - struct index_state *istate = &the_index; - len = strlen(path); - pos = index_name_pos(istate, path, len); - if (pos < 0) { - /* - * We might be in the middle of a merge, in which - * case we would read stage #2 (ours). - */ - int i; - for (i = -pos - 1; - (pos < 0 && i < istate->cache_nr && - !strcmp(istate->cache[i]->name, path)); - i++) - if (ce_stage(istate->cache[i]) == 2) - pos = i; - } - if (pos < 0) + data = read_blob_data_from_cache(path, &sz); + if (!data) return 0; - data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz); - if (!data || type != OBJ_BLOB) { - free(data); - return 0; - } - has_cr = memchr(data, '\r', sz) != NULL; free(data); return has_cr; diff --git a/credential-store.c b/credential-store.c index 26f7589a60..f9146e576f 100644 --- a/credential-store.c +++ b/credential-store.c @@ -114,7 +114,7 @@ static int lookup_credential(const char *fn, struct credential *c) return c->username && c->password; } -int main(int argc, const char **argv) +int main(int argc, char **argv) { const char * const usage[] = { "git credential-store [options] <action>", @@ -131,7 +131,7 @@ int main(int argc, const char **argv) umask(077); - argc = parse_options(argc, argv, NULL, options, usage, 0); + argc = parse_options(argc, (const char **)argv, NULL, options, usage, 0); if (argc != 1) usage_with_options(usage, options); op = argv[0]; @@ -600,7 +600,7 @@ static void parse_host_arg(char *extra_args, int buflen) static int execute(void) { - static char line[1000]; + char *line = packet_buffer; int pktlen, len, i; char *addr = getenv("REMOTE_ADDR"), *port = getenv("REMOTE_PORT"); @@ -608,7 +608,7 @@ static int execute(void) loginfo("Connection from %s:%s", addr, port); alarm(init_timeout ? init_timeout : timeout); - pktlen = packet_read_line(0, line, sizeof(line)); + pktlen = packet_read(0, NULL, NULL, packet_buffer, sizeof(packet_buffer), 0); alarm(0); len = strlen(line); @@ -383,7 +383,7 @@ static int is_date(int year, int month, int day, struct tm *now_tm, time_t now, * sense to specify timestamp way into the future. Make * sure it is not later than ten days from now... */ - if (now + 10*24*3600 < specified) + if ((specified != -1) && (now + 10*24*3600 < specified)) return 0; tm->tm_mon = r->tm_mon; tm->tm_mday = r->tm_mday; @@ -694,8 +694,14 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset) /* mktime uses local timezone */ *timestamp = tm_to_time_t(&tm); - if (*offset == -1) - *offset = ((time_t)*timestamp - mktime(&tm)) / 60; + if (*offset == -1) { + time_t temp_time = mktime(&tm); + if ((time_t)*timestamp > temp_time) { + *offset = ((time_t)*timestamp - temp_time) / 60; + } else { + *offset = -(int)((temp_time - (time_t)*timestamp) / 60); + } + } if (*timestamp == -1) return -1; @@ -705,6 +711,28 @@ int parse_date_basic(const char *date, unsigned long *timestamp, int *offset) return 0; /* success */ } +int parse_expiry_date(const char *date, unsigned long *timestamp) +{ + int errors = 0; + + if (!strcmp(date, "never") || !strcmp(date, "false")) + *timestamp = 0; + else if (!strcmp(date, "all") || !strcmp(date, "now")) + /* + * We take over "now" here, which usually translates + * to the current timestamp. This is because the user + * really means to expire everything she has done in + * the past, and by definition reflogs are the record + * of the past, and there is nothing from the future + * to be kept. + */ + *timestamp = ULONG_MAX; + else + *timestamp = approxidate_careful(date, &errors); + + return errors; +} + int parse_date(const char *date, char *result, int maxlen) { unsigned long timestamp; @@ -2255,6 +2255,7 @@ static void builtin_diff(const char *name_a, const char *del = diff_get_color_opt(o, DIFF_FILE_OLD); const char *add = diff_get_color_opt(o, DIFF_FILE_NEW); show_submodule_summary(o->file, one ? one->path : two->path, + line_prefix, one->sha1, two->sha1, two->dirty_submodule, meta, del, add, reset); return; diff --git a/diffcore-rename.c b/diffcore-rename.c index 512d0ac5fd..6c7a72fbe7 100644 --- a/diffcore-rename.c +++ b/diffcore-rename.c @@ -389,6 +389,7 @@ static int find_exact_renames(struct diff_options *options) struct hash_table file_table; init_hash(&file_table); + preallocate_hash(&file_table, rename_src_nr + rename_dst_nr); for (i = 0; i < rename_src_nr; i++) insert_file_table(&file_table, -1, i, rename_src[i].p->one); @@ -17,7 +17,21 @@ struct path_simplify { const char *path; }; -static int read_directory_recursive(struct dir_struct *dir, const char *path, int len, +/* + * Tells read_directory_recursive how a file or directory should be treated. + * Values are ordered by significance, e.g. if a directory contains both + * excluded and untracked files, it is listed as untracked because + * path_untracked > path_excluded. + */ +enum path_treatment { + path_none = 0, + path_recurse, + path_excluded, + path_untracked +}; + +static enum path_treatment read_directory_recursive(struct dir_struct *dir, + const char *path, int len, int check_only, const struct path_simplify *simplify); static int get_dtype(struct dirent *de, const char *path, int len); @@ -578,78 +592,6 @@ void add_excludes_from_file(struct dir_struct *dir, const char *fname) die("cannot use %s as an exclude file", fname); } -/* - * Loads the per-directory exclude list for the substring of base - * which has a char length of baselen. - */ -static void prep_exclude(struct dir_struct *dir, const char *base, int baselen) -{ - struct exclude_list_group *group; - struct exclude_list *el; - struct exclude_stack *stk = NULL; - int current; - - if ((!dir->exclude_per_dir) || - (baselen + strlen(dir->exclude_per_dir) >= PATH_MAX)) - return; /* too long a path -- ignore */ - - group = &dir->exclude_list_group[EXC_DIRS]; - - /* Pop the exclude lists from the EXCL_DIRS exclude_list_group - * which originate from directories not in the prefix of the - * path being checked. */ - while ((stk = dir->exclude_stack) != NULL) { - if (stk->baselen <= baselen && - !strncmp(dir->basebuf, base, stk->baselen)) - break; - el = &group->el[dir->exclude_stack->exclude_ix]; - dir->exclude_stack = stk->prev; - free((char *)el->src); /* see strdup() below */ - clear_exclude_list(el); - free(stk); - group->nr--; - } - - /* Read from the parent directories and push them down. */ - current = stk ? stk->baselen : -1; - while (current < baselen) { - struct exclude_stack *stk = xcalloc(1, sizeof(*stk)); - const char *cp; - - if (current < 0) { - cp = base; - current = 0; - } - else { - cp = strchr(base + current + 1, '/'); - if (!cp) - die("oops in prep_exclude"); - cp++; - } - stk->prev = dir->exclude_stack; - stk->baselen = cp - base; - memcpy(dir->basebuf + current, base + current, - stk->baselen - current); - strcpy(dir->basebuf + stk->baselen, dir->exclude_per_dir); - /* - * dir->basebuf gets reused by the traversal, but we - * need fname to remain unchanged to ensure the src - * member of each struct exclude correctly - * back-references its source file. Other invocations - * of add_exclude_list provide stable strings, so we - * strdup() and free() here in the caller. - */ - el = add_exclude_list(dir, EXC_DIRS, strdup(dir->basebuf)); - stk->exclude_ix = group->nr - 1; - add_excludes_from_file_to_list(dir->basebuf, - dir->basebuf, stk->baselen, - el, 1); - dir->exclude_stack = stk; - current = stk->baselen; - } - dir->basebuf[baselen] = '\0'; -} - int match_basename(const char *basename, int basenamelen, const char *pattern, int prefix, int patternlen, int flags) @@ -795,25 +737,13 @@ int is_excluded_from_list(const char *pathname, return -1; /* undecided */ } -/* - * Loads the exclude lists for the directory containing pathname, then - * scans all exclude lists to determine whether pathname is excluded. - * Returns the exclude_list element which matched, or NULL for - * undecided. - */ -static struct exclude *last_exclude_matching(struct dir_struct *dir, - const char *pathname, - int *dtype_p) +static struct exclude *last_exclude_matching_from_lists(struct dir_struct *dir, + const char *pathname, int pathlen, const char *basename, + int *dtype_p) { - int pathlen = strlen(pathname); int i, j; struct exclude_list_group *group; struct exclude *exclude; - const char *basename = strrchr(pathname, '/'); - basename = (basename) ? basename+1 : pathname; - - prep_exclude(dir, pathname, basename-pathname); - for (i = EXC_CMDL; i <= EXC_FILE; i++) { group = &dir->exclude_list_group[i]; for (j = group->nr - 1; j >= 0; j--) { @@ -828,101 +758,131 @@ static struct exclude *last_exclude_matching(struct dir_struct *dir, } /* - * Loads the exclude lists for the directory containing pathname, then - * scans all exclude lists to determine whether pathname is excluded. - * Returns 1 if true, otherwise 0. + * Loads the per-directory exclude list for the substring of base + * which has a char length of baselen. */ -static int is_excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) -{ - struct exclude *exclude = - last_exclude_matching(dir, pathname, dtype_p); - if (exclude) - return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1; - return 0; -} - -void path_exclude_check_init(struct path_exclude_check *check, - struct dir_struct *dir) +static void prep_exclude(struct dir_struct *dir, const char *base, int baselen) { - check->dir = dir; - check->exclude = NULL; - strbuf_init(&check->path, 256); -} + struct exclude_list_group *group; + struct exclude_list *el; + struct exclude_stack *stk = NULL; + int current; -void path_exclude_check_clear(struct path_exclude_check *check) -{ - strbuf_release(&check->path); -} + group = &dir->exclude_list_group[EXC_DIRS]; -/* - * For each subdirectory in name, starting with the top-most, checks - * to see if that subdirectory is excluded, and if so, returns the - * corresponding exclude structure. Otherwise, checks whether name - * itself (which is presumably a file) is excluded. - * - * A path to a directory known to be excluded is left in check->path to - * optimize for repeated checks for files in the same excluded directory. - */ -struct exclude *last_exclude_matching_path(struct path_exclude_check *check, - const char *name, int namelen, - int *dtype) -{ - int i; - struct strbuf *path = &check->path; - struct exclude *exclude; + /* Pop the exclude lists from the EXCL_DIRS exclude_list_group + * which originate from directories not in the prefix of the + * path being checked. */ + while ((stk = dir->exclude_stack) != NULL) { + if (stk->baselen <= baselen && + !strncmp(dir->basebuf, base, stk->baselen)) + break; + el = &group->el[dir->exclude_stack->exclude_ix]; + dir->exclude_stack = stk->prev; + dir->exclude = NULL; + free((char *)el->src); /* see strdup() below */ + clear_exclude_list(el); + free(stk); + group->nr--; + } - /* - * we allow the caller to pass namelen as an optimization; it - * must match the length of the name, as we eventually call - * is_excluded() on the whole name string. - */ - if (namelen < 0) - namelen = strlen(name); + /* Skip traversing into sub directories if the parent is excluded */ + if (dir->exclude) + return; - /* - * If path is non-empty, and name is equal to path or a - * subdirectory of path, name should be excluded, because - * it's inside a directory which is already known to be - * excluded and was previously left in check->path. - */ - if (path->len && - path->len <= namelen && - !memcmp(name, path->buf, path->len) && - (!name[path->len] || name[path->len] == '/')) - return check->exclude; + /* Read from the parent directories and push them down. */ + current = stk ? stk->baselen : -1; + while (current < baselen) { + struct exclude_stack *stk = xcalloc(1, sizeof(*stk)); + const char *cp; - strbuf_setlen(path, 0); - for (i = 0; name[i]; i++) { - int ch = name[i]; + if (current < 0) { + cp = base; + current = 0; + } + else { + cp = strchr(base + current + 1, '/'); + if (!cp) + die("oops in prep_exclude"); + cp++; + } + stk->prev = dir->exclude_stack; + stk->baselen = cp - base; + stk->exclude_ix = group->nr; + el = add_exclude_list(dir, EXC_DIRS, NULL); + memcpy(dir->basebuf + current, base + current, + stk->baselen - current); - if (ch == '/') { + /* Abort if the directory is excluded */ + if (stk->baselen) { int dt = DT_DIR; - exclude = last_exclude_matching(check->dir, - path->buf, &dt); - if (exclude) { - check->exclude = exclude; - return exclude; + dir->basebuf[stk->baselen - 1] = 0; + dir->exclude = last_exclude_matching_from_lists(dir, + dir->basebuf, stk->baselen - 1, + dir->basebuf + current, &dt); + dir->basebuf[stk->baselen - 1] = '/'; + if (dir->exclude) { + dir->basebuf[stk->baselen] = 0; + dir->exclude_stack = stk; + return; } } - strbuf_addch(path, ch); + + /* Try to read per-directory file unless path is too long */ + if (dir->exclude_per_dir && + stk->baselen + strlen(dir->exclude_per_dir) < PATH_MAX) { + strcpy(dir->basebuf + stk->baselen, + dir->exclude_per_dir); + /* + * dir->basebuf gets reused by the traversal, but we + * need fname to remain unchanged to ensure the src + * member of each struct exclude correctly + * back-references its source file. Other invocations + * of add_exclude_list provide stable strings, so we + * strdup() and free() here in the caller. + */ + el->src = strdup(dir->basebuf); + add_excludes_from_file_to_list(dir->basebuf, + dir->basebuf, stk->baselen, el, 1); + } + dir->exclude_stack = stk; + current = stk->baselen; } + dir->basebuf[baselen] = '\0'; +} - /* An entry in the index; cannot be a directory with subentries */ - strbuf_setlen(path, 0); +/* + * Loads the exclude lists for the directory containing pathname, then + * scans all exclude lists to determine whether pathname is excluded. + * Returns the exclude_list element which matched, or NULL for + * undecided. + */ +struct exclude *last_exclude_matching(struct dir_struct *dir, + const char *pathname, + int *dtype_p) +{ + int pathlen = strlen(pathname); + const char *basename = strrchr(pathname, '/'); + basename = (basename) ? basename+1 : pathname; + + prep_exclude(dir, pathname, basename-pathname); - return last_exclude_matching(check->dir, name, dtype); + if (dir->exclude) + return dir->exclude; + + return last_exclude_matching_from_lists(dir, pathname, pathlen, + basename, dtype_p); } /* - * Is this name excluded? This is for a caller like show_files() that - * do not honor directory hierarchy and iterate through paths that are - * possibly in an ignored directory. + * Loads the exclude lists for the directory containing pathname, then + * scans all exclude lists to determine whether pathname is excluded. + * Returns 1 if true, otherwise 0. */ -int is_path_excluded(struct path_exclude_check *check, - const char *name, int namelen, int *dtype) +int is_excluded(struct dir_struct *dir, const char *pathname, int *dtype_p) { struct exclude *exclude = - last_exclude_matching_path(check, name, namelen, dtype); + last_exclude_matching(dir, pathname, dtype_p); if (exclude) return exclude->flags & EXC_FLAG_NEGATIVE ? 0 : 1; return 0; @@ -941,8 +901,7 @@ static struct dir_entry *dir_entry_new(const char *pathname, int len) static struct dir_entry *dir_add_name(struct dir_struct *dir, const char *pathname, int len) { - if (!(dir->flags & DIR_SHOW_IGNORED) && - cache_name_exists(pathname, len, ignore_case)) + if (cache_name_exists(pathname, len, ignore_case)) return NULL; ALLOC_GROW(dir->entries, dir->nr+1, dir->alloc); @@ -1044,9 +1003,8 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len) * traversal routine. * * Case 1: If we *already* have entries in the index under that - * directory name, we recurse into the directory to see all the files, - * unless the directory is excluded and we want to show ignored - * directories + * directory name, we always recurse into the directory to see + * all the files. * * Case 2: If we *already* have that directory name as a gitlink, * we always continue to see it as a gitlink, regardless of whether @@ -1058,38 +1016,26 @@ static enum exist_status directory_exists_in_index(const char *dirname, int len) * * (a) if "show_other_directories" is true, we show it as * just a directory, unless "hide_empty_directories" is - * also true and the directory is empty, in which case - * we just ignore it entirely. - * if we are looking for ignored directories, look if it - * contains only ignored files to decide if it must be shown as - * ignored or not. + * also true, in which case we need to check if it contains any + * untracked and / or ignored files. * (b) if it looks like a git directory, and we don't have * 'no_gitlinks' set we treat it as a gitlink, and show it * as a directory. * (c) otherwise, we recurse into it. */ -enum directory_treatment { - show_directory, - ignore_directory, - recurse_into_directory -}; - -static enum directory_treatment treat_directory(struct dir_struct *dir, +static enum path_treatment treat_directory(struct dir_struct *dir, const char *dirname, int len, int exclude, const struct path_simplify *simplify) { /* The "len-1" is to strip the final '/' */ switch (directory_exists_in_index(dirname, len-1)) { case index_directory: - if ((dir->flags & DIR_SHOW_OTHER_DIRECTORIES) && exclude) - break; - - return recurse_into_directory; + return path_recurse; case index_gitdir: if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES) - return ignore_directory; - return show_directory; + return path_none; + return path_untracked; case index_nonexistent: if (dir->flags & DIR_SHOW_OTHER_DIRECTORIES) @@ -1097,72 +1043,17 @@ static enum directory_treatment treat_directory(struct dir_struct *dir, if (!(dir->flags & DIR_NO_GITLINKS)) { unsigned char sha1[20]; if (resolve_gitlink_ref(dirname, "HEAD", sha1) == 0) - return show_directory; + return path_untracked; } - return recurse_into_directory; + return path_recurse; } /* This is the "show_other_directories" case */ - /* - * We are looking for ignored files and our directory is not ignored, - * check if it contains only ignored files - */ - if ((dir->flags & DIR_SHOW_IGNORED) && !exclude) { - int ignored; - dir->flags &= ~DIR_SHOW_IGNORED; - dir->flags |= DIR_HIDE_EMPTY_DIRECTORIES; - ignored = read_directory_recursive(dir, dirname, len, 1, simplify); - dir->flags &= ~DIR_HIDE_EMPTY_DIRECTORIES; - dir->flags |= DIR_SHOW_IGNORED; - - return ignored ? ignore_directory : show_directory; - } - if (!(dir->flags & DIR_SHOW_IGNORED) && - !(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES)) - return show_directory; - if (!read_directory_recursive(dir, dirname, len, 1, simplify)) - return ignore_directory; - return show_directory; -} - -/* - * Decide what to do when we find a file while traversing the - * filesystem. Mostly two cases: - * - * 1. We are looking for ignored files - * (a) File is ignored, include it - * (b) File is in ignored path, include it - * (c) File is not ignored, exclude it - * - * 2. Other scenarios, include the file if not excluded - * - * Return 1 for exclude, 0 for include. - */ -static int treat_file(struct dir_struct *dir, struct strbuf *path, int exclude, int *dtype) -{ - struct path_exclude_check check; - int exclude_file = 0; - - if (exclude) - exclude_file = !(dir->flags & DIR_SHOW_IGNORED); - else if (dir->flags & DIR_SHOW_IGNORED) { - /* Always exclude indexed files */ - struct cache_entry *ce = index_name_exists(&the_index, - path->buf, path->len, ignore_case); - - if (ce) - return 1; - - path_exclude_check_init(&check, dir); - - if (!is_path_excluded(&check, path->buf, path->len, dtype)) - exclude_file = 1; - - path_exclude_check_clear(&check); - } + if (!(dir->flags & DIR_HIDE_EMPTY_DIRECTORIES)) + return exclude ? path_excluded : path_untracked; - return exclude_file; + return read_directory_recursive(dir, dirname, len, 1, simplify); } /* @@ -1277,57 +1168,40 @@ static int get_dtype(struct dirent *de, const char *path, int len) return dtype; } -enum path_treatment { - path_ignored, - path_handled, - path_recurse -}; - static enum path_treatment treat_one_path(struct dir_struct *dir, struct strbuf *path, const struct path_simplify *simplify, int dtype, struct dirent *de) { - int exclude = is_excluded(dir, path->buf, &dtype); - if (exclude && (dir->flags & DIR_COLLECT_IGNORED) - && exclude_matches_pathspec(path->buf, path->len, simplify)) - dir_add_ignored(dir, path->buf, path->len); + int exclude; + if (dtype == DT_UNKNOWN) + dtype = get_dtype(de, path->buf, path->len); + + /* Always exclude indexed files */ + if (dtype != DT_DIR && + cache_name_exists(path->buf, path->len, ignore_case)) + return path_none; + + exclude = is_excluded(dir, path->buf, &dtype); /* * Excluded? If we don't explicitly want to show * ignored files, ignore it */ - if (exclude && !(dir->flags & DIR_SHOW_IGNORED)) - return path_ignored; - - if (dtype == DT_UNKNOWN) - dtype = get_dtype(de, path->buf, path->len); + if (exclude && !(dir->flags & (DIR_SHOW_IGNORED|DIR_SHOW_IGNORED_TOO))) + return path_excluded; switch (dtype) { default: - return path_ignored; + return path_none; case DT_DIR: strbuf_addch(path, '/'); - - switch (treat_directory(dir, path->buf, path->len, exclude, simplify)) { - case show_directory: - break; - case recurse_into_directory: - return path_recurse; - case ignore_directory: - return path_ignored; - } - break; + return treat_directory(dir, path->buf, path->len, exclude, + simplify); case DT_REG: case DT_LNK: - switch (treat_file(dir, path, exclude, &dtype)) { - case 1: - return path_ignored; - default: - break; - } + return exclude ? path_excluded : path_untracked; } - return path_handled; } static enum path_treatment treat_path(struct dir_struct *dir, @@ -1339,11 +1213,11 @@ static enum path_treatment treat_path(struct dir_struct *dir, int dtype; if (is_dot_or_dotdot(de->d_name) || !strcmp(de->d_name, ".git")) - return path_ignored; + return path_none; strbuf_setlen(path, baselen); strbuf_addstr(path, de->d_name); if (simplify_away(path->buf, path->len, simplify)) - return path_ignored; + return path_none; dtype = DTYPE(de); return treat_one_path(dir, path, simplify, dtype, de); @@ -1357,14 +1231,16 @@ static enum path_treatment treat_path(struct dir_struct *dir, * * Also, we ignore the name ".git" (even if it is not a directory). * That likely will not change. + * + * Returns the most significant path_treatment value encountered in the scan. */ -static int read_directory_recursive(struct dir_struct *dir, +static enum path_treatment read_directory_recursive(struct dir_struct *dir, const char *base, int baselen, int check_only, const struct path_simplify *simplify) { DIR *fdir; - int contents = 0; + enum path_treatment state, subdir_state, dir_state = path_none; struct dirent *de; struct strbuf path = STRBUF_INIT; @@ -1375,27 +1251,53 @@ static int read_directory_recursive(struct dir_struct *dir, goto out; while ((de = readdir(fdir)) != NULL) { - switch (treat_path(dir, de, &path, baselen, simplify)) { - case path_recurse: - contents += read_directory_recursive(dir, path.buf, - path.len, 0, - simplify); - continue; - case path_ignored: + /* check how the file or directory should be treated */ + state = treat_path(dir, de, &path, baselen, simplify); + if (state > dir_state) + dir_state = state; + + /* recurse into subdir if instructed by treat_path */ + if (state == path_recurse) { + subdir_state = read_directory_recursive(dir, path.buf, + path.len, check_only, simplify); + if (subdir_state > dir_state) + dir_state = subdir_state; + } + + if (check_only) { + /* abort early if maximum state has been reached */ + if (dir_state == path_untracked) + break; + /* skip the dir_add_* part */ continue; - case path_handled: - break; } - contents++; - if (check_only) + + /* add the path to the appropriate result list */ + switch (state) { + case path_excluded: + if (dir->flags & DIR_SHOW_IGNORED) + dir_add_name(dir, path.buf, path.len); + else if ((dir->flags & DIR_SHOW_IGNORED_TOO) || + ((dir->flags & DIR_COLLECT_IGNORED) && + exclude_matches_pathspec(path.buf, path.len, + simplify))) + dir_add_ignored(dir, path.buf, path.len); break; - dir_add_name(dir, path.buf, path.len); + + case path_untracked: + if (!(dir->flags & DIR_SHOW_IGNORED)) + dir_add_name(dir, path.buf, path.len); + break; + + default: + break; + } } closedir(fdir); out: strbuf_release(&path); - return contents; + return dir_state; } static int cmp_name(const void *p1, const void *p2) @@ -1444,12 +1346,14 @@ static int treat_leading_path(struct dir_struct *dir, struct strbuf sb = STRBUF_INIT; int baselen, rc = 0; const char *cp; + int old_flags = dir->flags; while (len && path[len - 1] == '/') len--; if (!len) return 1; baselen = 0; + dir->flags &= ~DIR_SHOW_OTHER_DIRECTORIES; while (1) { cp = path + baselen + !!baselen; cp = memchr(cp, '/', path + len - cp); @@ -1464,7 +1368,7 @@ static int treat_leading_path(struct dir_struct *dir, if (simplify_away(sb.buf, sb.len, simplify)) break; if (treat_one_path(dir, &sb, simplify, - DT_DIR, NULL) == path_ignored) + DT_DIR, NULL) == path_none) break; /* do not recurse into it */ if (len <= baselen) { rc = 1; @@ -1472,6 +1376,7 @@ static int treat_leading_path(struct dir_struct *dir, } } strbuf_release(&sb); + dir->flags = old_flags; return rc; } @@ -1647,7 +1552,7 @@ int remove_path(const char *name) { char *slash; - if (unlink(name) && errno != ENOENT) + if (unlink(name) && errno != ENOENT && errno != ENOTDIR) return -1; slash = strrchr(name, '/'); @@ -79,7 +79,8 @@ struct dir_struct { DIR_SHOW_OTHER_DIRECTORIES = 1<<1, DIR_HIDE_EMPTY_DIRECTORIES = 1<<2, DIR_NO_GITLINKS = 1<<3, - DIR_COLLECT_IGNORED = 1<<4 + DIR_COLLECT_IGNORED = 1<<4, + DIR_SHOW_IGNORED_TOO = 1<<5 } flags; struct dir_entry **entries; struct dir_entry **ignored; @@ -110,9 +111,11 @@ struct dir_struct { * * exclude_stack points to the top of the exclude_stack, and * basebuf contains the full path to the current - * (sub)directory in the traversal. + * (sub)directory in the traversal. Exclude points to the + * matching exclude struct if the directory is excluded. */ struct exclude_stack *exclude_stack; + struct exclude *exclude; char basebuf[PATH_MAX]; }; @@ -149,22 +152,10 @@ extern int match_pathname(const char *, int, const char *, int, const char *, int, int, int); -/* - * The is_excluded() API is meant for callers that check each level of leading - * directory hierarchies with is_excluded() to avoid recursing into excluded - * directories. Callers that do not do so should use this API instead. - */ -struct path_exclude_check { - struct dir_struct *dir; - struct exclude *exclude; - struct strbuf path; -}; -extern void path_exclude_check_init(struct path_exclude_check *, struct dir_struct *); -extern void path_exclude_check_clear(struct path_exclude_check *); -extern struct exclude *last_exclude_matching_path(struct path_exclude_check *, const char *, - int namelen, int *dtype); -extern int is_path_excluded(struct path_exclude_check *, const char *, int namelen, int *dtype); +extern struct exclude *last_exclude_matching(struct dir_struct *dir, + const char *name, int *dtype); +extern int is_excluded(struct dir_struct *dir, const char *name, int *dtype); extern struct exclude_list *add_exclude_list(struct dir_struct *dir, int group_type, const char *src); @@ -120,16 +120,18 @@ static int streaming_write_entry(struct cache_entry *ce, char *path, const struct checkout *state, int to_tempfile, int *fstat_done, struct stat *statbuf) { - int result = -1; + int result = 0; int fd; fd = open_output_fd(path, ce, to_tempfile); - if (0 <= fd) { - result = stream_blob_to_fd(fd, ce->sha1, filter, 1); - *fstat_done = fstat_output(fd, state, statbuf); - result = close(fd); - } - if (result && 0 <= fd) + if (fd < 0) + return -1; + + result |= stream_blob_to_fd(fd, ce->sha1, filter, 1); + *fstat_done = fstat_output(fd, state, statbuf); + result |= close(fd); + + if (result) unlink(path); return result; } diff --git a/fast-import.c b/fast-import.c index 5f539d7d8f..6d94453026 100644 --- a/fast-import.c +++ b/fast-import.c @@ -297,7 +297,7 @@ static int failure; static FILE *pack_edges; static unsigned int show_stats = 1; static int global_argc; -static const char **global_argv; +static char **global_argv; /* Memory pools */ static size_t mem_pool_alloc = 2*1024*1024 - sizeof(struct mem_pool); @@ -3347,7 +3347,7 @@ static void parse_argv(void) read_marks(); } -int main(int argc, const char **argv) +int main(int argc, char **argv) { unsigned int i; diff --git a/fetch-pack.c b/fetch-pack.c index 6d8926a550..f156dd4fac 100644 --- a/fetch-pack.c +++ b/fetch-pack.c @@ -36,7 +36,7 @@ static int marked; #define MAX_IN_VAIN 256 static struct commit_list *rev_list; -static int non_common_revs, multi_ack, use_sideband; +static int non_common_revs, multi_ack, use_sideband, allow_tip_sha1_in_want; static void rev_list_push(struct commit *commit, int mark) { @@ -172,8 +172,8 @@ static void consume_shallow_list(struct fetch_pack_args *args, int fd) * shallow and unshallow commands every time there * is a block of have lines exchanged. */ - char line[1000]; - while (packet_read_line(fd, line, sizeof(line))) { + char *line; + while ((line = packet_read_line(fd, NULL))) { if (!prefixcmp(line, "shallow ")) continue; if (!prefixcmp(line, "unshallow ")) @@ -215,17 +215,17 @@ static int write_shallow_commits(struct strbuf *out, int use_pack_protocol) static enum ack_type get_ack(int fd, unsigned char *result_sha1) { - static char line[1000]; - int len = packet_read_line(fd, line, sizeof(line)); + int len; + char *line = packet_read_line(fd, &len); if (!len) die("git fetch-pack: expected ACK/NAK, got EOF"); - if (line[len-1] == '\n') - line[--len] = 0; if (!strcmp(line, "NAK")) return NAK; if (!prefixcmp(line, "ACK ")) { if (!get_sha1_hex(line+4, result_sha1)) { + if (len < 45) + return ACK; if (strstr(line+45, "continue")) return ACK_continue; if (strstr(line+45, "common")) @@ -245,7 +245,7 @@ static void send_request(struct fetch_pack_args *args, send_sideband(fd, -1, buf->buf, buf->len, LARGE_PACKET_MAX); packet_flush(fd); } else - safe_write(fd, buf->buf, buf->len); + write_or_die(fd, buf->buf, buf->len); } static void insert_one_alternate_ref(const struct ref *ref, void *unused) @@ -346,11 +346,11 @@ static int find_common(struct fetch_pack_args *args, state_len = req_buf.len; if (args->depth > 0) { - char line[1024]; + char *line; unsigned char sha1[20]; send_request(args, fd[1], &req_buf); - while (packet_read_line(fd[0], line, sizeof(line))) { + while ((line = packet_read_line(fd[0], NULL))) { if (!prefixcmp(line, "shallow ")) { if (get_sha1_hex(line + 8, sha1)) die("invalid shallow line: %s", line); @@ -520,47 +520,37 @@ static void mark_recent_complete_commits(struct fetch_pack_args *args, } } -static int non_matching_ref(struct string_list_item *item, void *unused) -{ - if (item->util) { - item->util = NULL; - return 0; - } - else - return 1; -} - static void filter_refs(struct fetch_pack_args *args, - struct ref **refs, struct string_list *sought) + struct ref **refs, + struct ref **sought, int nr_sought) { struct ref *newlist = NULL; struct ref **newtail = &newlist; struct ref *ref, *next; - int sought_pos; + int i; - sought_pos = 0; + i = 0; for (ref = *refs; ref; ref = next) { int keep = 0; next = ref->next; + if (!memcmp(ref->name, "refs/", 5) && check_refname_format(ref->name + 5, 0)) ; /* trash */ else { - while (sought_pos < sought->nr) { - int cmp = strcmp(ref->name, sought->items[sought_pos].string); + while (i < nr_sought) { + int cmp = strcmp(ref->name, sought[i]->name); if (cmp < 0) break; /* definitely do not have it */ else if (cmp == 0) { keep = 1; /* definitely have it */ - sought->items[sought_pos++].util = "matched"; - break; + sought[i]->matched = 1; } - else - sought_pos++; /* might have it; keep looking */ + i++; } } - if (! keep && args->fetch_all && + if (!keep && args->fetch_all && (!args->depth || prefixcmp(ref->name, "refs/tags/"))) keep = 1; @@ -573,7 +563,21 @@ static void filter_refs(struct fetch_pack_args *args, } } - filter_string_list(sought, 0, non_matching_ref, NULL); + /* Append unmatched requests to the list */ + if (allow_tip_sha1_in_want) { + for (i = 0; i < nr_sought; i++) { + ref = sought[i]; + if (ref->matched) + continue; + if (get_sha1_hex(ref->name, ref->old_sha1)) + continue; + + ref->matched = 1; + *newtail = ref; + ref->next = NULL; + newtail = &ref->next; + } + } *refs = newlist; } @@ -583,7 +587,8 @@ static void mark_alternate_complete(const struct ref *ref, void *unused) } static int everything_local(struct fetch_pack_args *args, - struct ref **refs, struct string_list *sought) + struct ref **refs, + struct ref **sought, int nr_sought) { struct ref *ref; int retval; @@ -637,7 +642,7 @@ static int everything_local(struct fetch_pack_args *args, } } - filter_refs(args, refs, sought); + filter_refs(args, refs, sought, nr_sought); for (retval = 1, ref = *refs; ref ; ref = ref->next) { const unsigned char *remote = ref->old_sha1; @@ -767,10 +772,17 @@ static int get_pack(struct fetch_pack_args *args, return 0; } +static int cmp_ref_by_name(const void *a_, const void *b_) +{ + const struct ref *a = *((const struct ref **)a_); + const struct ref *b = *((const struct ref **)b_); + return strcmp(a->name, b->name); +} + static struct ref *do_fetch_pack(struct fetch_pack_args *args, int fd[2], const struct ref *orig_ref, - struct string_list *sought, + struct ref **sought, int nr_sought, char **pack_lockfile) { struct ref *ref = copy_ref_list(orig_ref); @@ -779,6 +791,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, int agent_len; sort_ref_list(&ref, ref_compare_name); + qsort(sought, nr_sought, sizeof(*sought), cmp_ref_by_name); if (is_repository_shallow() && !server_supports("shallow")) die("Server does not support shallow clients"); @@ -808,6 +821,11 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, fprintf(stderr, "Server supports side-band\n"); use_sideband = 1; } + if (server_supports("allow-tip-sha1-in-want")) { + if (args->verbose) + fprintf(stderr, "Server supports allow-tip-sha1-in-want\n"); + allow_tip_sha1_in_want = 1; + } if (!server_supports("thin-pack")) args->use_thin_pack = 0; if (!server_supports("no-progress")) @@ -827,7 +845,7 @@ static struct ref *do_fetch_pack(struct fetch_pack_args *args, agent_len, agent_feature); } - if (everything_local(args, &ref, sought)) { + if (everything_local(args, &ref, sought, nr_sought)) { packet_flush(fd[1]); goto all_done; } @@ -890,11 +908,32 @@ static void fetch_pack_setup(void) did_setup = 1; } +static int remove_duplicates_in_refs(struct ref **ref, int nr) +{ + struct string_list names = STRING_LIST_INIT_NODUP; + int src, dst; + + for (src = dst = 0; src < nr; src++) { + struct string_list_item *item; + item = string_list_insert(&names, ref[src]->name); + if (item->util) + continue; /* already have it */ + item->util = ref[src]; + if (src != dst) + ref[dst] = ref[src]; + dst++; + } + for (src = dst; src < nr; src++) + ref[src] = NULL; + string_list_clear(&names, 0); + return dst; +} + struct ref *fetch_pack(struct fetch_pack_args *args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, - struct string_list *sought, + struct ref **sought, int nr_sought, char **pack_lockfile) { struct stat st; @@ -906,16 +945,14 @@ struct ref *fetch_pack(struct fetch_pack_args *args, st.st_mtime = 0; } - if (sought->nr) { - sort_string_list(sought); - string_list_remove_duplicates(sought, 0); - } + if (nr_sought) + nr_sought = remove_duplicates_in_refs(sought, nr_sought); if (!ref) { packet_flush(fd[1]); die("no matching remote head"); } - ref_cpy = do_fetch_pack(args, fd, ref, sought, pack_lockfile); + ref_cpy = do_fetch_pack(args, fd, ref, sought, nr_sought, pack_lockfile); if (args->depth > 0) { static struct lock_file lock; diff --git a/fetch-pack.h b/fetch-pack.h index cb148719bf..dc5266c970 100644 --- a/fetch-pack.h +++ b/fetch-pack.h @@ -20,17 +20,16 @@ struct fetch_pack_args { }; /* - * sought contains the full names of remote references that should be - * updated from. On return, the names that were found on the remote - * will have been removed from the list. The util members of the - * string_list_items are used internally; they must be NULL on entry - * (and will be NULL on exit). + * sought represents remote references that should be updated from. + * On return, the names that were found on the remote will have been + * marked as such. */ struct ref *fetch_pack(struct fetch_pack_args *args, int fd[], struct child_process *conn, const struct ref *ref, const char *dest, - struct string_list *sought, + struct ref **sought, + int nr_sought, char **pack_lockfile); #endif @@ -778,13 +778,6 @@ To restore the original branch and stop patching run \"\$cmdline --abort\"." action=yes fi - if test -f "$dotest/final-commit" - then - FIRSTLINE=$(sed 1q "$dotest/final-commit") - else - FIRSTLINE="" - fi - if test $action = skip then go_next @@ -797,6 +790,13 @@ To restore the original branch and stop patching run \"\$cmdline --abort\"." stop_here $this fi + if test -f "$dotest/final-commit" + then + FIRSTLINE=$(sed 1q "$dotest/final-commit") + else + FIRSTLINE="" + fi + say "$(eval_gettext "Applying: \$FIRSTLINE")" case "$resolved" in diff --git a/git-bisect.sh b/git-bisect.sh index 99efbe8845..d7518e9c3b 100755 --- a/git-bisect.sh +++ b/git-bisect.sh @@ -311,7 +311,23 @@ bisect_next() { res=$? # Check if we should exit because bisection is finished - test $res -eq 10 && exit 0 + if test $res -eq 10 + then + bad_rev=$(git show-ref --hash --verify refs/bisect/bad) + bad_commit=$(git show-branch $bad_rev) + echo "# first bad commit: $bad_commit" >>"$GIT_DIR/BISECT_LOG" + exit 0 + elif test $res -eq 2 + then + echo "# only skipped commits left to test" >>"$GIT_DIR/BISECT_LOG" + good_revs=$(git for-each-ref --format="--not %(objectname)" "refs/bisect/good-*") + for skipped in $(git rev-list refs/bisect/bad $good_revs) + do + skipped_commit=$(git show-branch $skipped) + echo "# possible first bad commit: $skipped_commit" >>"$GIT_DIR/BISECT_LOG" + done + exit $res + fi # Check for an error in the bisection process test $res -ne 0 && exit $res diff --git a/git-compat-util.h b/git-compat-util.h index ad4762499e..e955bb5e8b 100644 --- a/git-compat-util.h +++ b/git-compat-util.h @@ -86,6 +86,9 @@ #define _SGI_SOURCE 1 #ifdef WIN32 /* Both MinGW and MSVC */ +# if defined (_MSC_VER) +# define _WIN32_WINNT 0x0502 +# endif #define WIN32_LEAN_AND_MEAN /* stops windows.h including winsock.h */ #include <winsock2.h> #include <windows.h> @@ -160,6 +163,7 @@ typedef long intptr_t; typedef unsigned long uintptr_t; #endif +int get_st_mode_bits(const char *path, int *mode); #if defined(__CYGWIN__) #undef _XOPEN_SOURCE #include <grp.h> diff --git a/git-difftool.perl b/git-difftool.perl index 0a90de4146..8a75205537 100755 --- a/git-difftool.perl +++ b/git-difftool.perl @@ -13,9 +13,9 @@ use 5.008; use strict; use warnings; +use Error qw(:try); use File::Basename qw(dirname); use File::Copy; -use File::Compare; use File::Find; use File::stat; use File::Path qw(mkpath rmtree); @@ -83,6 +83,58 @@ sub exit_cleanup exit($status | ($status >> 8)); } +sub use_wt_file +{ + my ($repo, $workdir, $file, $sha1, $symlinks) = @_; + my $null_sha1 = '0' x 40; + + if ($sha1 ne $null_sha1 and not $symlinks) { + return 0; + } + + if (! -e "$workdir/$file") { + # If the file doesn't exist in the working tree, we cannot + # use it. + return (0, $null_sha1); + } + + my $wt_sha1 = $repo->command_oneline('hash-object', "$workdir/$file"); + my $use = ($sha1 eq $null_sha1) || ($sha1 eq $wt_sha1); + return ($use, $wt_sha1); +} + +sub changed_files +{ + my ($repo_path, $index, $worktree) = @_; + $ENV{GIT_INDEX_FILE} = $index; + $ENV{GIT_WORK_TREE} = $worktree; + my $must_unset_git_dir = 0; + if (not defined($ENV{GIT_DIR})) { + $must_unset_git_dir = 1; + $ENV{GIT_DIR} = $repo_path; + } + + my @refreshargs = qw/update-index --really-refresh -q --unmerged/; + my @gitargs = qw/diff-files --name-only -z/; + try { + Git::command_oneline(@refreshargs); + } catch Git::Error::Command with {}; + + my $line = Git::command_oneline(@gitargs); + my @files; + if (defined $line) { + @files = split('\0', $line); + } else { + @files = (); + } + + delete($ENV{GIT_INDEX_FILE}); + delete($ENV{GIT_WORK_TREE}); + delete($ENV{GIT_DIR}) if ($must_unset_git_dir); + + return map { $_ => 1 } @files; +} + sub setup_dir_diff { my ($repo, $workdir, $symlinks) = @_; @@ -106,6 +158,7 @@ sub setup_dir_diff my $null_sha1 = '0' x 40; my $lindex = ''; my $rindex = ''; + my $wtindex = ''; my %submodule; my %symlink; my @working_tree = (); @@ -159,10 +212,14 @@ EOF } if ($rmode ne $null_mode) { - if ($rsha1 ne $null_sha1) { - $rindex .= "$rmode $rsha1\t$dst_path\0"; + my ($use, $wt_sha1) = use_wt_file($repo, $workdir, + $dst_path, $rsha1, + $symlinks); + if ($use) { + push @working_tree, $dst_path; + $wtindex .= "$rmode $wt_sha1\t$dst_path\0"; } else { - push(@working_tree, $dst_path); + $rindex .= "$rmode $rsha1\t$dst_path\0"; } } } @@ -203,13 +260,21 @@ EOF $rc = system('git', 'checkout-index', '--all', "--prefix=$rdir/"); exit_cleanup($tmpdir, $rc) if $rc != 0; + $ENV{GIT_INDEX_FILE} = "$tmpdir/wtindex"; + ($inpipe, $ctx) = + $repo->command_input_pipe(qw(update-index --info-only -z --index-info)); + print($inpipe $wtindex); + $repo->command_close_pipe($inpipe, $ctx); + # If $GIT_DIR was explicitly set just for the update/checkout # commands, then it should be unset before continuing. delete($ENV{GIT_DIR}) if ($must_unset_git_dir); delete($ENV{GIT_INDEX_FILE}); # Changes in the working tree need special treatment since they are - # not part of the index + # not part of the index. Remove any trailing slash from $workdir + # before starting to avoid double slashes in symlink targets. + $workdir =~ s|/$||; for my $file (@working_tree) { my $dir = dirname($file); unless (-d "$rdir/$dir") { @@ -336,7 +401,7 @@ sub main } if ($opts{gui}) { my $guitool = Git::config('diff.guitool'); - if (length($guitool) > 0) { + if (defined($guitool) && length($guitool) > 0) { $ENV{GIT_DIFF_TOOL} = $guitool; } } @@ -373,19 +438,34 @@ sub dir_diff # should be copied back to the working tree. # Do not copy back files when symlinks are used and the # external tool did not replace the original link with a file. + # + # These hashes are loaded lazily since they aren't needed + # in the common case of --symlinks and the difftool updating + # files through the symlink. + my %wt_modified; + my %tmp_modified; + my $indices_loaded = 0; + for my $file (@worktree) { next if $symlinks && -l "$b/$file"; next if ! -f "$b/$file"; - my $diff = compare("$b/$file", "$workdir/$file"); - if ($diff == 0) { - next; - } elsif ($diff == -1) { - my $errmsg = "warning: Could not compare "; - $errmsg += "'$b/$file' with '$workdir/$file'\n"; + if (!$indices_loaded) { + %wt_modified = changed_files($repo->repo_path(), + "$tmpdir/wtindex", "$workdir"); + %tmp_modified = changed_files($repo->repo_path(), + "$tmpdir/wtindex", "$b"); + $indices_loaded = 1; + } + + if (exists $wt_modified{$file} and exists $tmp_modified{$file}) { + my $errmsg = "warning: Both files modified: "; + $errmsg .= "'$workdir/$file' and '$b/$file'.\n"; + $errmsg .= "warning: Working tree file has been left.\n"; + $errmsg .= "warning:\n"; warn $errmsg; $error = 1; - } elsif ($diff == 1) { + } elsif (exists $tmp_modified{$file}) { my $mode = stat("$b/$file")->mode; copy("$b/$file", "$workdir/$file") or exit_cleanup($tmpdir, 1); diff --git a/git-merge-one-file.sh b/git-merge-one-file.sh index 3373c040d4..07dfeb8df4 100755 --- a/git-merge-one-file.sh +++ b/git-merge-one-file.sh @@ -27,7 +27,7 @@ SUBDIRECTORY_OK=Yes cd_to_toplevel require_work_tree -if ! test "$#" -eq 7 +if test $# != 7 then echo "$LONG_USAGE" exit 1 @@ -38,7 +38,8 @@ case "${1:-.}${2:-.}${3:-.}" in # Deleted in both or deleted in one and unchanged in the other # "$1.." | "$1.$1" | "$1$1.") - if [ "$2" ]; then + if test -n "$2" + then echo "Removing $4" else # read-tree checked that index matches HEAD already, @@ -48,7 +49,8 @@ case "${1:-.}${2:-.}${3:-.}" in # we do not have it in the index, though. exec git update-index --remove -- "$4" fi - if test -f "$4"; then + if test -f "$4" + then rm -f -- "$4" && rmdir -p "$(expr "z$4" : 'z\(.*\)/')" 2>/dev/null || : fi && @@ -67,7 +69,7 @@ case "${1:-.}${2:-.}${3:-.}" in echo "Adding $4" if test -f "$4" then - echo "ERROR: untracked $4 is overwritten by the merge." + echo "ERROR: untracked $4 is overwritten by the merge." >&2 exit 1 fi git update-index --add --cacheinfo "$7" "$3" "$4" && @@ -78,9 +80,10 @@ case "${1:-.}${2:-.}${3:-.}" in # Added in both, identically (check for same permissions). # ".$3$2") - if [ "$6" != "$7" ]; then - echo "ERROR: File $4 added identically in both branches," - echo "ERROR: but permissions conflict $6->$7." + if test "$6" != "$7" + then + echo "ERROR: File $4 added identically in both branches," >&2 + echo "ERROR: but permissions conflict $6->$7." >&2 exit 1 fi echo "Adding $4" @@ -95,44 +98,36 @@ case "${1:-.}${2:-.}${3:-.}" in case ",$6,$7," in *,120000,*) - echo "ERROR: $4: Not merging symbolic link changes." + echo "ERROR: $4: Not merging symbolic link changes." >&2 exit 1 ;; *,160000,*) - echo "ERROR: $4: Not merging conflicting submodule changes." + echo "ERROR: $4: Not merging conflicting submodule changes." >&2 exit 1 ;; esac - src2=`git-unpack-file $3` + src1=$(git-unpack-file $2) + src2=$(git-unpack-file $3) case "$1" in '') echo "Added $4 in both, but differently." - # This extracts OUR file in $orig, and uses git apply to - # remove lines that are unique to ours. - orig=`git-unpack-file $2` - sz0=`wc -c <"$orig"` - @@DIFF@@ -u -La/$orig -Lb/$orig $orig $src2 | git apply --no-add - sz1=`wc -c <"$orig"` - - # If we do not have enough common material, it is not - # worth trying two-file merge using common subsections. - expr $sz0 \< $sz1 \* 2 >/dev/null || : >$orig + orig=$(git-unpack-file $2) + create_virtual_base "$orig" "$src2" ;; *) echo "Auto-merging $4" - orig=`git-unpack-file $1` + orig=$(git-unpack-file $1) ;; esac - # Be careful for funny filename such as "-L" in "$4", which - # would confuse "merge" greatly. - src1=`git-unpack-file $2` git merge-file "$src1" "$orig" "$src2" ret=$? msg= - if [ $ret -ne 0 ]; then + if test $ret != 0 || test -z "$1" + then msg='content conflict' + ret=1 fi # Create the working tree file, using "our tree" version from the @@ -140,26 +135,26 @@ case "${1:-.}${2:-.}${3:-.}" in git checkout-index -f --stage=2 -- "$4" && cat "$src1" >"$4" || exit 1 rm -f -- "$orig" "$src1" "$src2" - if [ "$6" != "$7" ]; then - if [ -n "$msg" ]; then + if test "$6" != "$7" + then + if test -n "$msg" + then msg="$msg, " fi msg="${msg}permissions conflict: $5->$6,$7" ret=1 fi - if [ "$1" = '' ]; then - ret=1 - fi - if [ $ret -ne 0 ]; then - echo "ERROR: $msg in $4" + if test $ret != 0 + then + echo "ERROR: $msg in $4" >&2 exit 1 fi exec git update-index -- "$4" ;; *) - echo "ERROR: $4: Not handling case $1 -> $2 -> $3" + echo "ERROR: $4: Not handling case $1 -> $2 -> $3" >&2 ;; esac exit 1 @@ -79,12 +79,27 @@ def p4_build_cmd(cmd): real_cmd += cmd return real_cmd -def chdir(dir): - # P4 uses the PWD environment variable rather than getcwd(). Since we're - # not using the shell, we have to set it ourselves. This path could - # be relative, so go there first, then figure out where we ended up. - os.chdir(dir) - os.environ['PWD'] = os.getcwd() +def chdir(path, is_client_path=False): + """Do chdir to the given path, and set the PWD environment + variable for use by P4. It does not look at getcwd() output. + Since we're not using the shell, it is necessary to set the + PWD environment variable explicitly. + + Normally, expand the path to force it to be absolute. This + addresses the use of relative path names inside P4 settings, + e.g. P4CONFIG=.p4config. P4 does not simply open the filename + as given; it looks for .p4config using PWD. + + If is_client_path, the path was handed to us directly by p4, + and may be a symbolic link. Do not call os.getcwd() in this + case, because it will cause p4 to think that PWD is not inside + the client path. + """ + + os.chdir(path) + if not is_client_path: + path = os.getcwd() + os.environ['PWD'] = path def die(msg): if verbose: @@ -1624,7 +1639,7 @@ class P4Submit(Command, P4UserMap): new_client_dir = True os.makedirs(self.clientPath) - chdir(self.clientPath) + chdir(self.clientPath, is_client_path=True) if self.dry_run: print "Would synchronize p4 checkout in %s" % self.clientPath else: diff --git a/git-pull.sh b/git-pull.sh index 5d97e97bd9..638aabb7b3 100755 --- a/git-pull.sh +++ b/git-pull.sh @@ -39,7 +39,7 @@ test -z "$(git ls-files -u)" || die_conflict test -f "$GIT_DIR/MERGE_HEAD" && die_merge strategy_args= diffstat= no_commit= squash= no_ff= ff_only= -log_arg= verbosity= progress= recurse_submodules= +log_arg= verbosity= progress= recurse_submodules= verify_signatures= merge_args= edit= curr_branch=$(git symbolic-ref -q HEAD) curr_branch_short="${curr_branch#refs/heads/}" @@ -125,6 +125,12 @@ do --no-recurse-submodules) recurse_submodules=--no-recurse-submodules ;; + --verify-signatures) + verify_signatures=--verify-signatures + ;; + --no-verify-signatures) + verify_signatures=--no-verify-signatures + ;; --d|--dr|--dry|--dry-|--dry-r|--dry-ru|--dry-run) dry_run=--dry-run ;; @@ -283,7 +289,7 @@ true) eval="$eval --onto $merge_head ${oldremoteref:-$merge_head}" ;; *) - eval="git-merge $diffstat $no_commit $edit $squash $no_ff $ff_only" + eval="git-merge $diffstat $no_commit $verify_signatures $edit $squash $no_ff $ff_only" eval="$eval $log_arg $strategy_args $merge_args $verbosity $progress" eval="$eval \"\$merge_name\" HEAD $merge_head" ;; diff --git a/git-rebase--am.sh b/git-rebase--am.sh index 97f31dc7af..f84854f09a 100644 --- a/git-rebase--am.sh +++ b/git-rebase--am.sh @@ -31,8 +31,8 @@ else rm -f "$GIT_DIR/rebased-patches" git format-patch -k --stdout --full-index --ignore-if-in-upstream \ - --src-prefix=a/ --dst-prefix=b/ \ - --no-renames $root_flag "$revisions" >"$GIT_DIR/rebased-patches" + --src-prefix=a/ --dst-prefix=b/ --no-renames --no-cover-letter \ + $root_flag "$revisions" >"$GIT_DIR/rebased-patches" ret=$? if test 0 != $ret diff --git a/git-rebase--interactive.sh b/git-rebase--interactive.sh index 048a140a6f..5822b2c592 100644 --- a/git-rebase--interactive.sh +++ b/git-rebase--interactive.sh @@ -57,6 +57,9 @@ rewritten="$state_dir"/rewritten dropped="$state_dir"/dropped +end="$state_dir"/end +msgnum="$state_dir"/msgnum + # A script to set the GIT_AUTHOR_NAME, GIT_AUTHOR_EMAIL, and # GIT_AUTHOR_DATE that will be used for the commit that is currently # being rebased. @@ -109,7 +112,9 @@ mark_action_done () { sed -e 1d < "$todo" >> "$todo".new mv -f "$todo".new "$todo" new_count=$(git stripspace --strip-comments <"$done" | wc -l) + echo $new_count >"$msgnum" total=$(($new_count + $(git stripspace --strip-comments <"$todo" | wc -l))) + echo $total >"$end" if test "$last_count" != "$new_count" then last_count=$new_count diff --git a/git-rebase.sh b/git-rebase.sh index b2f1c76dc3..2c692c33e9 100755 --- a/git-rebase.sh +++ b/git-rebase.sh @@ -473,7 +473,7 @@ case "$#" in head_name="detached HEAD" branch_name=HEAD ;# detached fi - orig_head=$(git rev-parse --verify "${branch_name}^0") || exit + orig_head=$(git rev-parse --verify HEAD) || exit ;; *) die "BUG: unexpected number of arguments left to parse" diff --git a/git-remote-testgit b/git-remote-testgit.sh index b395c8de59..2109070d00 100755 --- a/git-remote-testgit +++ b/git-remote-testgit.sh @@ -1,4 +1,4 @@ -#!/usr/bin/env bash +#!/bin/sh # Copyright (c) 2012 Felipe Contreras alias=$1 @@ -23,7 +23,6 @@ then testgitmarks="$dir/testgit.marks" test -e "$gitmarks" || >"$gitmarks" test -e "$testgitmarks" || >"$testgitmarks" - testgitmarks_args=( "--"{import,export}"-marks=$testgitmarks" ) fi while read line @@ -38,6 +37,7 @@ do echo "*import-marks $gitmarks" echo "*export-marks $gitmarks" fi + test -n "$GIT_REMOTE_TESTGIT_SIGNED_TAGS" && echo "signed-tags" echo ;; list) @@ -61,24 +61,55 @@ do echo "feature import-marks=$gitmarks" echo "feature export-marks=$gitmarks" fi + + if test -n "$GIT_REMOTE_TESTGIT_FAILURE" + then + echo "feature done" + exit 1 + fi + echo "feature done" - git fast-export "${testgitmarks_args[@]}" $refs | + git fast-export \ + ${testgitmarks:+"--import-marks=$testgitmarks"} \ + ${testgitmarks:+"--export-marks=$testgitmarks"} \ + $refs | sed -e "s#refs/heads/#${prefix}/heads/#g" echo "done" ;; export) - before=$(git for-each-ref --format='%(refname) %(objectname)') + if test -n "$GIT_REMOTE_TESTGIT_FAILURE" + then + # consume input so fast-export doesn't get SIGPIPE; + # git would also notice that case, but we want + # to make sure we are exercising the later + # error checks + while read line; do + test "done" = "$line" && break + done + exit 1 + fi - git fast-import "${testgitmarks_args[@]}" --quiet + before=$(git for-each-ref --format=' %(refname) %(objectname) ') - after=$(git for-each-ref --format='%(refname) %(objectname)') + git fast-import \ + ${testgitmarks:+"--import-marks=$testgitmarks"} \ + ${testgitmarks:+"--export-marks=$testgitmarks"} \ + --quiet # figure out which refs were updated - join -e 0 -o '0 1.2 2.2' -a 2 <(echo "$before") <(echo "$after") | - while read ref a b + git for-each-ref --format='%(refname) %(objectname)' | + while read ref a do - test $a == $b && continue - echo "ok $ref" + case "$before" in + *" $ref $a "*) + continue ;; # unchanged + esac + if test -z "$GIT_REMOTE_TESTGIT_PUSH_ERROR" + then + echo "ok $ref" + else + echo "error $ref $GIT_REMOTE_TESTGIT_PUSH_ERROR" + fi done echo diff --git a/git-send-email.perl b/git-send-email.perl index 70cad15ec4..bd13cc812d 100755 --- a/git-send-email.perl +++ b/git-send-email.perl @@ -54,7 +54,7 @@ git send-email [options] <file | directory | rev-list options > --[no-]bcc <str> * Email Bcc: --subject <str> * Email "Subject:" --in-reply-to <str> * Email "In-Reply-To:" - --annotate * Review each patch that will be sent in an editor. + --[no-]annotate * Review each patch that will be sent in an editor. --compose * Open an editor for introduction. --compose-encoding <str> * Encoding to assume for introduction. --8bit-encoding <str> * Encoding to assume 8bit mails if undeclared @@ -212,7 +212,8 @@ my %config_bool_settings = ( "signedoffbycc" => [\$signed_off_by_cc, undef], "signedoffcc" => [\$signed_off_by_cc, undef], # Deprecated "validate" => [\$validate, 1], - "multiedit" => [\$multiedit, undef] + "multiedit" => [\$multiedit, undef], + "annotate" => [\$annotate, undef] ); my %config_settings = ( @@ -304,7 +305,7 @@ my $rc = GetOptions("h" => \$help, "smtp-debug:i" => \$debug_net_smtp, "smtp-domain:s" => \$smtp_domain, "identity=s" => \$identity, - "annotate" => \$annotate, + "annotate!" => \$annotate, "compose" => \$compose, "quiet" => \$quiet, "cc-cmd=s" => \$cc_cmd, @@ -1047,6 +1048,47 @@ sub maildomain { return maildomain_net() || maildomain_mta() || 'localhost.localdomain'; } +sub smtp_host_string { + if (defined $smtp_server_port) { + return "$smtp_server:$smtp_server_port"; + } else { + return $smtp_server; + } +} + +# Returns 1 if authentication succeeded or was not necessary +# (smtp_user was not specified), and 0 otherwise. + +sub smtp_auth_maybe { + if (!defined $smtp_authuser || $auth) { + return 1; + } + + # Workaround AUTH PLAIN/LOGIN interaction defect + # with Authen::SASL::Cyrus + eval { + require Authen::SASL; + Authen::SASL->import(qw(Perl)); + }; + + # TODO: Authentication may fail not because credentials were + # invalid but due to other reasons, in which we should not + # reject credentials. + $auth = Git::credential({ + 'protocol' => 'smtp', + 'host' => smtp_host_string(), + 'username' => $smtp_authuser, + # if there's no password, "git credential fill" will + # give us one, otherwise it'll just pass this one. + 'password' => $smtp_authpass + }, sub { + my $cred = shift; + return !!$smtp->auth($cred->{'username'}, $cred->{'password'}); + }); + + return $auth; +} + # Returns 1 if the message was sent, and 0 otherwise. # In actuality, the whole program dies when there # is an error sending a message. @@ -1157,9 +1199,7 @@ X-Mailer: git-send-email $gitversion else { require Net::SMTP; $smtp_domain ||= maildomain(); - $smtp ||= Net::SMTP->new((defined $smtp_server_port) - ? "$smtp_server:$smtp_server_port" - : $smtp_server, + $smtp ||= Net::SMTP->new(smtp_host_string(), Hello => $smtp_domain, Debug => $debug_net_smtp); if ($smtp_encryption eq 'tls' && $smtp) { @@ -1187,31 +1227,7 @@ X-Mailer: git-send-email $gitversion defined $smtp_server_port ? " port=$smtp_server_port" : ""; } - if (defined $smtp_authuser) { - # Workaround AUTH PLAIN/LOGIN interaction defect - # with Authen::SASL::Cyrus - eval { - require Authen::SASL; - Authen::SASL->import(qw(Perl)); - }; - - if (!defined $smtp_authpass) { - - system "stty -echo"; - - do { - print "Password: "; - $_ = <STDIN>; - print "\n"; - } while (!defined $_); - - chomp($smtp_authpass = $_); - - system "stty echo"; - } - - $auth ||= $smtp->auth( $smtp_authuser, $smtp_authpass ) or die $smtp->message; - } + smtp_auth_maybe or die $smtp->message; $smtp->mail( $raw_from ) or die $smtp->message; $smtp->to( @recipients ) or die $smtp->message; diff --git a/git-sh-setup.sh b/git-sh-setup.sh index 9cfbe7f143..2f7835941e 100644 --- a/git-sh-setup.sh +++ b/git-sh-setup.sh @@ -249,6 +249,18 @@ clear_local_git_env() { unset $(git rev-parse --local-env-vars) } +# Generate a virtual base file for a two-file merge. Uses git apply to +# remove lines from $1 that are not in $2, leaving only common lines. +create_virtual_base() { + sz0=$(wc -c <"$1") + @@DIFF@@ -u -La/"$1" -Lb/"$1" "$1" "$2" | git apply --no-add + sz1=$(wc -c <"$1") + + # If we do not have enough common material, it is not + # worth trying two-file merge using common subsections. + expr $sz0 \< $sz1 \* 2 >/dev/null || : >"$1" +} + # Platform specific tweaks to work around some commands case $(uname -s) in diff --git a/git-submodule.sh b/git-submodule.sh index b3108b8ea9..79bfaac9d4 100755 --- a/git-submodule.sh +++ b/git-submodule.sh @@ -8,6 +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] update [--init] [--remote] [-N|--no-fetch] [-f|--force] [--rebase] [--reference <repository>] [--merge] [--recursive] [--] [<path>...] or: $dashless [--quiet] summary [--cached|--files] [--summary-limit <n>] [commit] [--] [<path>...] or: $dashless [--quiet] foreach [--recursive] <command> @@ -552,6 +553,82 @@ cmd_init() } # +# Unregister submodules from .git/config and remove their work tree +# +# $@ = requested paths (use '.' to deinit all submodules) +# +cmd_deinit() +{ + # parse $args after "submodule ... deinit". + while test $# -ne 0 + do + case "$1" in + -f|--force) + force=$1 + ;; + -q|--quiet) + GIT_QUIET=1 + ;; + --) + shift + break + ;; + -*) + usage + ;; + *) + break + ;; + esac + shift + done + + if test $# = 0 + then + die "$(eval_gettext "Use '.' if you really want to deinitialize all submodules")" + fi + + module_list "$@" | + while read mode sha1 stage sm_path + do + die_if_unmatched "$mode" + name=$(module_name "$sm_path") || exit + + # Remove the submodule work tree (unless the user already did it) + if test -d "$sm_path" + then + # Protect submodules containing a .git directory + if test -d "$sm_path/.git" + then + echo >&2 "$(eval_gettext "Submodule work tree '\$sm_path' contains a .git directory")" + die "$(eval_gettext "(use 'rm -rf' if you really want to remove it including all of its history)")" + fi + + if test -z "$force" + then + git rm -qn "$sm_path" || + die "$(eval_gettext "Submodule work tree '\$sm_path' contains local modifications; use '-f' to discard them")" + fi + rm -rf "$sm_path" && + say "$(eval_gettext "Cleared directory '\$sm_path'")" || + say "$(eval_gettext "Could not remove submodule work tree '\$sm_path'")" + fi + + mkdir "$sm_path" || say "$(eval_gettext "Could not create empty submodule directory '\$sm_path'")" + + # Remove the .git/config entries (unless the user already did it) + if test -n "$(git config --get-regexp submodule."$name\.")" + then + # Remove the whole section so we have a clean state when + # the user later decides to init this submodule again + url=$(git config submodule."$name".url) + git config --remove-section submodule."$name" 2>/dev/null && + say "$(eval_gettext "Submodule '\$name' (\$url) unregistered for path '\$sm_path'")" + fi + done +} + +# # Update each submodule path to correct revision, using clone and checkout as needed # # $@ = requested paths (default to all) @@ -1167,7 +1244,7 @@ cmd_sync() while test $# != 0 && test -z "$command" do case "$1" in - add | foreach | init | update | status | summary | sync) + add | foreach | init | deinit | update | status | summary | sync) command=$1 ;; -q|--quiet) diff --git a/git-svn.perl b/git-svn.perl index 6c7bd95032..d070de012c 100755 --- a/git-svn.perl +++ b/git-svn.perl @@ -113,7 +113,7 @@ my ($_stdin, $_help, $_edit, $_template, $_shared, $_version, $_fetch_all, $_no_rebase, $_fetch_parent, $_before, $_after, - $_merge, $_strategy, $_preserve_merges, $_dry_run, $_local, + $_merge, $_strategy, $_preserve_merges, $_dry_run, $_parents, $_local, $_prefix, $_no_checkout, $_url, $_verbose, $_commit_url, $_tag, $_merge_info, $_interactive); @@ -126,6 +126,7 @@ my %remote_opts = ( 'username=s' => \$Git::SVN::Prompt::_username, 'config-dir=s' => \$Git::SVN::Ra::config_dir, 'no-auth-cache' => \$Git::SVN::Prompt::_no_auth_cache, 'ignore-paths=s' => \$Git::SVN::Fetcher::_ignore_regex, + 'include-paths=s' => \$Git::SVN::Fetcher::_include_regex, 'ignore-refs=s' => \$Git::SVN::Ra::_ignore_refs_regex ); my %fc_opts = ( 'follow-parent|follow!' => \$Git::SVN::_follow_parent, 'authors-file|A=s' => \$_authors, @@ -202,6 +203,7 @@ my %cmd = ( { 'message|m=s' => \$_message, 'destination|d=s' => \$_branch_dest, 'dry-run|n' => \$_dry_run, + 'parents' => \$_parents, 'tag|t' => \$_tag, 'username=s' => \$Git::SVN::Prompt::_username, 'commit-url=s' => \$_commit_url } ], @@ -210,6 +212,7 @@ my %cmd = ( { 'message|m=s' => \$_message, 'destination|d=s' => \$_branch_dest, 'dry-run|n' => \$_dry_run, + 'parents' => \$_parents, 'username=s' => \$Git::SVN::Prompt::_username, 'commit-url=s' => \$_commit_url } ], 'set-tree' => [ \&cmd_set_tree, @@ -470,6 +473,9 @@ sub do_git_init_db { my $ignore_paths_regex = \$Git::SVN::Fetcher::_ignore_regex; command_noisy('config', "$pfx.ignore-paths", $$ignore_paths_regex) if defined $$ignore_paths_regex; + my $include_paths_regex = \$Git::SVN::Fetcher::_include_regex; + command_noisy('config', "$pfx.include-paths", $$include_paths_regex) + if defined $$include_paths_regex; my $ignore_refs_regex = \$Git::SVN::Ra::_ignore_refs_regex; command_noisy('config', "$pfx.ignore-refs", $$ignore_refs_regex) if defined $$ignore_refs_regex; @@ -669,12 +675,14 @@ sub merge_revs_into_hash { } sub merge_merge_info { - my ($mergeinfo_one, $mergeinfo_two) = @_; + my ($mergeinfo_one, $mergeinfo_two, $ignore_branch) = @_; my %result_hash = (); merge_revs_into_hash(\%result_hash, $mergeinfo_one); merge_revs_into_hash(\%result_hash, $mergeinfo_two); + delete $result_hash{$ignore_branch} if $ignore_branch; + my $result = ''; # Sort below is for consistency's sake for my $branchname (sort keys(%result_hash)) { @@ -695,6 +703,7 @@ sub populate_merge_info { my $all_parents_ok = 1; my $aggregate_mergeinfo = ''; my $rooturl = $gs->repos_root; + my ($target_branch) = $gs->full_pushurl =~ /^\Q$rooturl\E(.*)/; if (defined($rewritten_parent)) { # Replace first parent with newly-rewritten version @@ -726,7 +735,8 @@ sub populate_merge_info { # Merge previous mergeinfo values $aggregate_mergeinfo = merge_merge_info($aggregate_mergeinfo, - $par_mergeinfo, 0); + $par_mergeinfo, + $target_branch); next if $parent eq $parents[0]; # Skip first parent # Add new changes being placed in tree by merge @@ -769,7 +779,8 @@ sub populate_merge_info { my $newmergeinfo = "$branchpath:" . join(',', @revsin); $aggregate_mergeinfo = merge_merge_info($aggregate_mergeinfo, - $newmergeinfo, 1); + $newmergeinfo, + $target_branch); } if ($all_parents_ok and $aggregate_mergeinfo) { return $aggregate_mergeinfo; @@ -1163,6 +1174,10 @@ sub cmd_branch { $ctx->ls($dst, 'HEAD', 0); } and die "branch ${branch_name} already exists\n"; + if ($_parents) { + mk_parent_dirs($ctx, $dst); + } + print "Copying ${src} at r${rev} to ${dst}...\n"; $ctx->copy($src, $rev, $dst) unless $_dry_run; @@ -1170,6 +1185,17 @@ sub cmd_branch { $gs->fetch_all; } +sub mk_parent_dirs { + my ($ctx, $parent) = @_; + $parent =~ s{/[^/]*$}{}; + + if (!eval{$ctx->ls($parent, 'HEAD', 0)}) { + mk_parent_dirs($ctx, $parent); + print "Creating parent folder ${parent} ...\n"; + $ctx->mkdir($parent) unless $_dry_run; + } +} + sub cmd_find_rev { my $revision_or_hash = shift or die "SVN or git revision required ", "as a command-line argument\n"; diff --git a/git-web--browse.sh b/git-web--browse.sh index 1e827264b4..9f446798d4 100755 --- a/git-web--browse.sh +++ b/git-web--browse.sh @@ -119,8 +119,8 @@ if test -z "$browser" ; then browser_candidates="w3m elinks links lynx" fi # SECURITYSESSIONID indicates an OS X GUI login session - if test -n "$SECURITYSESSIONID" \ - -o "$TERM_PROGRAM" = "Apple_Terminal" ; then + if test -n "$SECURITYSESSIONID" || test -n "$TERM_PROGRAM" + then browser_candidates="open $browser_candidates" fi # /bin/start indicates MinGW @@ -13,7 +13,9 @@ const char git_usage_string[] = " <command> [<args>]"; const char git_more_info_string[] = - N_("See 'git help <command>' for more information on a specific command."); + N_("'git help -a' and 'git help -g' lists available subcommands and some\n" + "concept guides. See 'git help <command>' or 'git help <concept>'\n" + "to read about a specific subcommand or concept."); static struct startup_info git_startup_info; static int use_pager = -1; @@ -505,8 +507,9 @@ static int run_argv(int *argcp, const char ***argv) } -int main(int argc, const char **argv) +int main(int argc, char **av) { + const char **argv = (const char **) av; const char *cmd; startup_info = &git_startup_info; diff --git a/gitk-git/gitk b/gitk-git/gitk index b3706fc9b9..5cd00d80fe 100755 --- a/gitk-git/gitk +++ b/gitk-git/gitk @@ -1998,6 +1998,9 @@ proc mca {str} { return [string map {&& & & {}} [mc $str]] } +proc cleardropsel {w} { + $w selection clear +} proc makedroplist {w varname args} { global use_ttk if {$use_ttk} { @@ -2007,7 +2010,9 @@ proc makedroplist {w varname args} { if {$cx > $width} {set width $cx} } set gm [ttk::combobox $w -width $width -state readonly\ - -textvariable $varname -values $args] + -textvariable $varname -values $args \ + -exportselection false] + bind $gm <<ComboboxSelected>> [list $gm selection clear] } else { set gm [eval [linsert $args 0 tk_optionMenu $w $varname]] } @@ -2026,6 +2031,9 @@ proc makewindow {} { global highlight_files gdttype global searchstring sstring global bgcolor fgcolor bglist fglist diffcolors selectbgcolor + global uifgcolor uifgdisabledcolor + global filesepbgcolor filesepfgcolor + global mergecolors foundbgcolor currentsearchhitbgcolor global headctxmenu progresscanv progressitem progresscoords statusw global fprogitem fprogcoord lastprogupdate progupdatepending global rprogitem rprogcoord rownumsel numcommits @@ -2177,10 +2185,10 @@ proc makewindow {} { 0x00, 0x38, 0xff, 0x7f, 0xff, 0x7f, 0xff, 0x7f, 0x00, 0x38, 0x00, 0x1c, 0x00, 0x0e, 0x00, 0x07, 0x80, 0x03, 0xc0, 0x01}; } - image create bitmap bm-left -data $bm_left_data - image create bitmap bm-left-gray -data $bm_left_data -foreground "#999" - image create bitmap bm-right -data $bm_right_data - image create bitmap bm-right-gray -data $bm_right_data -foreground "#999" + image create bitmap bm-left -data $bm_left_data -foreground $uifgcolor + image create bitmap bm-left-gray -data $bm_left_data -foreground $uifgdisabledcolor + image create bitmap bm-right -data $bm_right_data -foreground $uifgcolor + image create bitmap bm-right-gray -data $bm_right_data -foreground $uifgdisabledcolor ${NS}::button .tf.bar.leftbut -command goback -state disabled -width 26 if {$use_ttk} { @@ -2245,7 +2253,8 @@ proc makewindow {} { set gm [makedroplist .tf.lbar.gdttype gdttype \ [mc "containing:"] \ [mc "touching paths:"] \ - [mc "adding/removing string:"]] + [mc "adding/removing string:"] \ + [mc "changing lines matching:"]] trace add variable gdttype write gdttype_change pack .tf.lbar.gdttype -side left -fill y @@ -2349,32 +2358,32 @@ proc makewindow {} { lappend fglist $ctext $ctext tag conf comment -wrap $wrapcomment - $ctext tag conf filesep -font textfontbold -back "#aaaaaa" + $ctext tag conf filesep -font textfontbold -fore $filesepfgcolor -back $filesepbgcolor $ctext tag conf hunksep -fore [lindex $diffcolors 2] $ctext tag conf d0 -fore [lindex $diffcolors 0] $ctext tag conf dresult -fore [lindex $diffcolors 1] - $ctext tag conf m0 -fore red - $ctext tag conf m1 -fore blue - $ctext tag conf m2 -fore green - $ctext tag conf m3 -fore purple - $ctext tag conf m4 -fore brown - $ctext tag conf m5 -fore "#009090" - $ctext tag conf m6 -fore magenta - $ctext tag conf m7 -fore "#808000" - $ctext tag conf m8 -fore "#009000" - $ctext tag conf m9 -fore "#ff0080" - $ctext tag conf m10 -fore cyan - $ctext tag conf m11 -fore "#b07070" - $ctext tag conf m12 -fore "#70b0f0" - $ctext tag conf m13 -fore "#70f0b0" - $ctext tag conf m14 -fore "#f0b070" - $ctext tag conf m15 -fore "#ff70b0" + $ctext tag conf m0 -fore [lindex $mergecolors 0] + $ctext tag conf m1 -fore [lindex $mergecolors 1] + $ctext tag conf m2 -fore [lindex $mergecolors 2] + $ctext tag conf m3 -fore [lindex $mergecolors 3] + $ctext tag conf m4 -fore [lindex $mergecolors 4] + $ctext tag conf m5 -fore [lindex $mergecolors 5] + $ctext tag conf m6 -fore [lindex $mergecolors 6] + $ctext tag conf m7 -fore [lindex $mergecolors 7] + $ctext tag conf m8 -fore [lindex $mergecolors 8] + $ctext tag conf m9 -fore [lindex $mergecolors 9] + $ctext tag conf m10 -fore [lindex $mergecolors 10] + $ctext tag conf m11 -fore [lindex $mergecolors 11] + $ctext tag conf m12 -fore [lindex $mergecolors 12] + $ctext tag conf m13 -fore [lindex $mergecolors 13] + $ctext tag conf m14 -fore [lindex $mergecolors 14] + $ctext tag conf m15 -fore [lindex $mergecolors 15] $ctext tag conf mmax -fore darkgrey set mergemax 16 $ctext tag conf mresult -font textfontbold $ctext tag conf msep -font textfontbold - $ctext tag conf found -back yellow - $ctext tag conf currentsearchhit -back orange + $ctext tag conf found -back $foundbgcolor + $ctext tag conf currentsearchhit -back $currentsearchhitbgcolor $ctext tag conf wwrap -wrap word .pwbottom add .bleft @@ -2559,6 +2568,7 @@ proc makewindow {} { {mc "Compare with marked commit" command compare_commits} {mc "Diff this -> marked commit" command {diffvsmark 0}} {mc "Diff marked commit -> this" command {diffvsmark 1}} + {mc "Revert this commit" command revert} } $rowctxmenu configure -tearoff 0 @@ -2721,6 +2731,14 @@ proc savestuff {w} { global viewname viewfiles viewargs viewargscmd viewperm nextviewnum global cmitmode wrapcomment datetimeformat limitdiffs global colors uicolor bgcolor fgcolor diffcolors diffcontext selectbgcolor + global uifgcolor uifgdisabledcolor + global headbgcolor headfgcolor headoutlinecolor remotebgcolor + global tagbgcolor tagfgcolor tagoutlinecolor + global reflinecolor filesepbgcolor filesepfgcolor + global mergecolors foundbgcolor currentsearchhitbgcolor + global linehoverbgcolor linehoverfgcolor linehoveroutlinecolor circlecolors + global mainheadcirclecolor workingfilescirclecolor indexcirclecolor + global linkfgcolor circleoutlinecolor global autoselect autosellen extdifftool perfile_attrs markbgcolor use_ttk global hideremotes want_ttk maxrefs @@ -2753,13 +2771,37 @@ proc savestuff {w} { puts $f [list set want_ttk $want_ttk] puts $f [list set bgcolor $bgcolor] puts $f [list set fgcolor $fgcolor] + puts $f [list set uifgcolor $uifgcolor] + puts $f [list set uifgdisabledcolor $uifgdisabledcolor] puts $f [list set colors $colors] puts $f [list set diffcolors $diffcolors] + puts $f [list set mergecolors $mergecolors] puts $f [list set markbgcolor $markbgcolor] puts $f [list set diffcontext $diffcontext] puts $f [list set selectbgcolor $selectbgcolor] + puts $f [list set foundbgcolor $foundbgcolor] + puts $f [list set currentsearchhitbgcolor $currentsearchhitbgcolor] puts $f [list set extdifftool $extdifftool] puts $f [list set perfile_attrs $perfile_attrs] + puts $f [list set headbgcolor $headbgcolor] + puts $f [list set headfgcolor $headfgcolor] + puts $f [list set headoutlinecolor $headoutlinecolor] + puts $f [list set remotebgcolor $remotebgcolor] + puts $f [list set tagbgcolor $tagbgcolor] + puts $f [list set tagfgcolor $tagfgcolor] + puts $f [list set tagoutlinecolor $tagoutlinecolor] + puts $f [list set reflinecolor $reflinecolor] + puts $f [list set filesepbgcolor $filesepbgcolor] + puts $f [list set filesepfgcolor $filesepfgcolor] + puts $f [list set linehoverbgcolor $linehoverbgcolor] + puts $f [list set linehoverfgcolor $linehoverfgcolor] + puts $f [list set linehoveroutlinecolor $linehoveroutlinecolor] + puts $f [list set mainheadcirclecolor $mainheadcirclecolor] + puts $f [list set workingfilescirclecolor $workingfilescirclecolor] + puts $f [list set indexcirclecolor $indexcirclecolor] + puts $f [list set circlecolors $circlecolors] + puts $f [list set linkfgcolor $linkfgcolor] + puts $f [list set circleoutlinecolor $circleoutlinecolor] puts $f "set geometry(main) [wm geometry .]" puts $f "set geometry(state) [wm state .]" @@ -4617,6 +4659,8 @@ proc do_file_hl {serial} { set gdtargs [concat -- $relative_paths] } elseif {$gdttype eq [mc "adding/removing string:"]} { set gdtargs [list "-S$highlight_files"] + } elseif {$gdttype eq [mc "changing lines matching:"]} { + set gdtargs [list "-G$highlight_files"] } else { # must be "containing:", i.e. we're searching commit info return @@ -5925,15 +5969,17 @@ proc drawcmittext {id row col} { global linehtag linentag linedtag selectedline global canvxmax boldids boldnameids fgcolor markedid global mainheadid nullid nullid2 circleitem circlecolors ctxbut + global mainheadcirclecolor workingfilescirclecolor indexcirclecolor + global circleoutlinecolor # listed is 0 for boundary, 1 for normal, 2 for negative, 3 for left, 4 for right set listed $cmitlisted($curview,$id) if {$id eq $nullid} { - set ofill red + set ofill $workingfilescirclecolor } elseif {$id eq $nullid2} { - set ofill green + set ofill $indexcirclecolor } elseif {$id eq $mainheadid} { - set ofill yellow + set ofill $mainheadcirclecolor } else { set ofill [lindex $circlecolors $listed] } @@ -5943,21 +5989,21 @@ proc drawcmittext {id row col} { if {$listed <= 2} { set t [$canv create oval [expr {$x - $orad}] [expr {$y - $orad}] \ [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ - -fill $ofill -outline $fgcolor -width 1 -tags circle] + -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle] } elseif {$listed == 3} { # triangle pointing left for left-side commits set t [$canv create polygon \ [expr {$x - $orad}] $y \ [expr {$x + $orad - 1}] [expr {$y - $orad}] \ [expr {$x + $orad - 1}] [expr {$y + $orad - 1}] \ - -fill $ofill -outline $fgcolor -width 1 -tags circle] + -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle] } else { # triangle pointing right for right-side commits set t [$canv create polygon \ [expr {$x + $orad - 1}] $y \ [expr {$x - $orad}] [expr {$y - $orad}] \ [expr {$x - $orad}] [expr {$y + $orad - 1}] \ - -fill $ofill -outline $fgcolor -width 1 -tags circle] + -fill $ofill -outline $circleoutlinecolor -width 1 -tags circle] } set circleitem($row) $t $canv raise $t @@ -6345,6 +6391,9 @@ proc drawtags {id x xt y1} { global idtags idheads idotherrefs mainhead global linespc lthickness global canv rowtextx curview fgcolor bgcolor ctxbut + global headbgcolor headfgcolor headoutlinecolor remotebgcolor + global tagbgcolor tagfgcolor tagoutlinecolor + global reflinecolor set marks {} set ntags 0 @@ -6382,7 +6431,7 @@ proc drawtags {id x xt y1} { set xt [expr {$xt + $delta + $wid + $lthickness + $linespc}] } set t [$canv create line $x $y1 [lindex $xvals end] $y1 \ - -width $lthickness -fill black -tags tag.$id] + -width $lthickness -fill $reflinecolor -tags tag.$id] $canv lower $t foreach tag $marks x $xvals wid $wvals { set tag_quoted [string map {% %%} $tag] @@ -6393,13 +6442,14 @@ proc drawtags {id x xt y1} { # draw a tag set t [$canv create polygon $x [expr {$yt + $delta}] $xl $yt \ $xr $yt $xr $yb $xl $yb $x [expr {$yb - $delta}] \ - -width 1 -outline black -fill yellow -tags tag.$id] + -width 1 -outline $tagoutlinecolor -fill $tagbgcolor \ + -tags tag.$id] $canv bind $t <1> [list showtag $tag_quoted 1] set rowtextx([rowofcommit $id]) [expr {$xr + $linespc}] } else { # draw a head or other ref if {[incr nheads -1] >= 0} { - set col green + set col $headbgcolor if {$tag eq $mainhead} { set font mainfontbold } @@ -6415,10 +6465,10 @@ proc drawtags {id x xt y1} { set yti [expr {$yt + 1}] set xri [expr {$x + $rwid}] $canv create polygon $xi $yti $xri $yti $xri $yb $xi $yb \ - -width 0 -fill "#ffddaa" -tags tag.$id + -width 0 -fill $remotebgcolor -tags tag.$id } } - set t [$canv create text $xl $y1 -anchor w -text $tag -fill $fgcolor \ + set t [$canv create text $xl $y1 -anchor w -text $tag -fill $headfgcolor \ -font $font -tags [list tag.$id text]] if {$ntags >= 0} { $canv bind $t <1> [list showtag $tag_quoted 1] @@ -6799,6 +6849,7 @@ proc appendwithlinks {text tags} { proc setlink {id lk} { global curview ctext pendinglinks + global linkfgcolor if {[string range $id 0 1] eq "-g"} { set id [string range $id 2 end] @@ -6816,7 +6867,7 @@ proc setlink {id lk} { set known [commitinview $id $curview] } if {$known} { - $ctext tag conf $lk -foreground blue -underline 1 + $ctext tag conf $lk -foreground $linkfgcolor -underline 1 $ctext tag bind $lk <1> [list selbyid $id] $ctext tag bind $lk <Enter> {linkcursor %W 1} $ctext tag bind $lk <Leave> {linkcursor %W -1} @@ -7571,9 +7622,13 @@ proc diffcmd {ids flags} { } proc gettreediffs {ids} { - global treediff treepending + global treediff treepending limitdiffs vfilelimit curview - if {[catch {set gdtf [open [diffcmd $ids {--no-commit-id}] r]}]} return + set cmd [diffcmd $ids {--no-commit-id}] + if {$limitdiffs && $vfilelimit($curview) ne {}} { + set cmd [concat $cmd -- $vfilelimit($curview)] + } + if {[catch {set gdtf [open $cmd r]}]} return set treepending $ids set treediff {} @@ -7617,17 +7672,7 @@ proc gettreediffline {gdtf ids} { return [expr {$nr >= $max? 2: 1}] } close $gdtf - if {$limitdiffs && $vfilelimit($curview) ne {}} { - set flist {} - foreach f $treediff { - if {[path_filter $vfilelimit($curview) $f]} { - lappend flist $f - } - } - set treediffs($ids) $flist - } else { - set treediffs($ids) $treediff - } + set treediffs($ids) $treediff unset treepending if {$cmitmode eq "tree" && [llength $diffids] == 1} { gettree $diffids @@ -8459,6 +8504,8 @@ proc lineleave {id} { proc linehover {} { global hoverx hovery hoverid hovertimer global canv linespc lthickness + global linehoverbgcolor linehoverfgcolor linehoveroutlinecolor + global commitinfo set text [lindex $commitinfo($hoverid) 0] @@ -8472,10 +8519,11 @@ proc linehover {} { set x1 [expr {$x + [font measure mainfont $text] + 2 * $lthickness}] set y1 [expr {$y + $linespc + 2 * $lthickness}] set t [$canv create rectangle $x0 $y0 $x1 $y1 \ - -fill \#ffff80 -outline black -width 1 -tags hover] + -fill $linehoverbgcolor -outline $linehoveroutlinecolor \ + -width 1 -tags hover] $canv raise $t set t [$canv create text $x $y -anchor nw -text $text -tags hover \ - -font mainfont] + -font mainfont -fill $linehoverfgcolor] $canv raise $t } @@ -9039,12 +9087,13 @@ proc domktag {} { proc redrawtags {id} { global canv linehtag idpos currentid curview cmitlisted markedid global canvxmax iddrawn circleitem mainheadid circlecolors + global mainheadcirclecolor if {![commitinview $id $curview]} return if {![info exists iddrawn($id)]} return set row [rowofcommit $id] if {$id eq $mainheadid} { - set ofill yellow + set ofill $mainheadcirclecolor } else { set ofill [lindex $circlecolors $cmitlisted($curview,$id)] } @@ -9301,6 +9350,67 @@ proc cherrypick {} { notbusy cherrypick } +proc revert {} { + global rowmenuid curview + global mainhead mainheadid + global gitdir + + set oldhead [exec git rev-parse HEAD] + set dheads [descheads $rowmenuid] + if { $dheads eq {} || [lsearch -exact $dheads $oldhead] == -1 } { + set ok [confirm_popup [mc "Commit %s is not\ + included in branch %s -- really revert it?" \ + [string range $rowmenuid 0 7] $mainhead]] + if {!$ok} return + } + nowbusy revert [mc "Reverting"] + update + + if [catch {exec git revert --no-edit $rowmenuid} err] { + notbusy revert + if [regexp {files would be overwritten by merge:(\n(( |\t)+[^\n]+\n)+)}\ + $err match files] { + regsub {\n( |\t)+} $files "\n" files + error_popup [mc "Revert failed because of local changes to\ + the following files:%s Please commit, reset or stash \ + your changes and try again." $files] + } elseif [regexp {error: could not revert} $err] { + if [confirm_popup [mc "Revert failed because of merge conflict.\n\ + Do you wish to run git citool to resolve it?"]] { + # Force citool to read MERGE_MSG + file delete [file join $gitdir "GITGUI_MSG"] + exec_citool {} $rowmenuid + } + } else { error_popup $err } + run updatecommits + return + } + + set newhead [exec git rev-parse HEAD] + if { $newhead eq $oldhead } { + notbusy revert + error_popup [mc "No changes committed"] + return + } + + addnewchild $newhead $oldhead + + if [commitinview $oldhead $curview] { + # XXX this isn't right if we have a path limit... + insertrow $newhead $oldhead $curview + if {$mainhead ne {}} { + movehead $newhead $mainhead + movedhead $newhead $mainhead + } + set mainheadid $newhead + redrawtags $oldhead + redrawtags $newhead + selbyid $newhead + } + + notbusy revert +} + proc resethead {} { global mainhead rowmenuid confirm_ok resettype NS @@ -10780,7 +10890,7 @@ proc showtag {tag isnew} { set linknum 0 if {![info exists cached_tagcontent($tag)]} { catch { - set cached_tagcontent($tag) [exec git cat-file tag $tag] + set cached_tagcontent($tag) [exec git cat-file -p $tag] } } if {[info exists cached_tagcontent($tag)]} { @@ -11641,6 +11751,15 @@ if {[catch {package require Tk 8.4} err]} { exit 1 } +# on OSX bring the current Wish process window to front +if {[tk windowingsystem] eq "aqua"} { + exec osascript -e [format { + tell application "System Events" + set frontmost of processes whose unix id is %d to true + end tell + } [pid] ] +} + # Unset GIT_TRACE var if set if { [info exists ::env(GIT_TRACE)] } { unset ::env(GIT_TRACE) @@ -11728,22 +11847,47 @@ if {[tk windowingsystem] eq "aqua"} { set colors {green red blue magenta darkgrey brown orange} if {[tk windowingsystem] eq "win32"} { set uicolor SystemButtonFace + set uifgcolor SystemButtonText + set uifgdisabledcolor SystemDisabledText set bgcolor SystemWindow - set fgcolor SystemButtonText + set fgcolor SystemWindowText set selectbgcolor SystemHighlight } else { set uicolor grey85 + set uifgcolor black + set uifgdisabledcolor "#999" set bgcolor white set fgcolor black set selectbgcolor gray85 } set diffcolors {red "#00a000" blue} set diffcontext 3 +set mergecolors {red blue green purple brown "#009090" magenta "#808000" "#009000" "#ff0080" cyan "#b07070" "#70b0f0" "#70f0b0" "#f0b070" "#ff70b0"} set ignorespace 0 set worddiff "" set markbgcolor "#e0e0ff" +set headbgcolor green +set headfgcolor black +set headoutlinecolor black +set remotebgcolor #ffddaa +set tagbgcolor yellow +set tagfgcolor black +set tagoutlinecolor black +set reflinecolor black +set filesepbgcolor #aaaaaa +set filesepfgcolor black +set linehoverbgcolor #ffff80 +set linehoverfgcolor black +set linehoveroutlinecolor black +set mainheadcirclecolor yellow +set workingfilescirclecolor red +set indexcirclecolor green set circlecolors {white blue gray blue blue} +set linkfgcolor blue +set circleoutlinecolor $fgcolor +set foundbgcolor yellow +set currentsearchhitbgcolor orange # button for popping up context menus if {[tk windowingsystem] eq "aqua"} { diff --git a/gitk-git/po/sv.po b/gitk-git/po/sv.po index 8cc98dc079..df95e01b90 100644 --- a/gitk-git/po/sv.po +++ b/gitk-git/po/sv.po @@ -1,16 +1,16 @@ # Swedish translation for gitk -# Copyright (C) 2005-2012 Paul Mackerras +# Copyright (C) 2005-2013 Paul Mackerras # This file is distributed under the same license as the gitk package. # # Mikael Magnusson <mikachu@gmail.com>, 2008. -# Peter Krefting <peter@softwolves.pp.se>, 2008, 2009, 2010, 2012. +# Peter Krefting <peter@softwolves.pp.se>, 2008, 2009, 2010, 2012, 2013. # msgid "" msgstr "" "Project-Id-Version: sv\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2012-10-03 08:09+0100\n" -"PO-Revision-Date: 2012-10-03 08:13+0100\n" +"POT-Creation-Date: 2013-05-16 08:06+0100\n" +"PO-Revision-Date: 2013-05-16 08:12+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -22,11 +22,11 @@ msgstr "" msgid "Couldn't get list of unmerged files:" msgstr "Kunde inte hämta lista över ej sammanslagna filer:" -#: gitk:210 gitk:2317 +#: gitk:210 gitk:2334 msgid "Color words" msgstr "Färga ord" -#: gitk:215 gitk:2317 gitk:7888 gitk:7921 +#: gitk:215 gitk:2334 gitk:7977 gitk:8010 msgid "Markup words" msgstr "Märk upp ord" @@ -60,11 +60,11 @@ msgstr "Fel vid körning av git log:" msgid "Reading" msgstr "Läser" -#: gitk:484 gitk:4353 +#: gitk:484 gitk:4409 msgid "Reading commits..." msgstr "Läser incheckningar..." -#: gitk:487 gitk:1625 gitk:4356 +#: gitk:487 gitk:1625 gitk:4412 msgid "No commits selected" msgstr "Inga incheckningar markerade" @@ -80,278 +80,286 @@ msgstr "Ingen incheckningsinformation är tillgänglig" msgid "mc" msgstr "mc" -#: gitk:1911 gitk:4146 gitk:9282 gitk:10824 gitk:11100 +#: gitk:1911 gitk:4202 gitk:9437 gitk:10979 gitk:11258 msgid "OK" msgstr "OK" -#: gitk:1913 gitk:4148 gitk:8871 gitk:8950 gitk:9065 gitk:9114 gitk:9284 -#: gitk:10825 gitk:11101 +#: gitk:1913 gitk:4204 gitk:8964 gitk:9043 gitk:9159 gitk:9208 gitk:9439 +#: gitk:10980 gitk:11259 msgid "Cancel" msgstr "Avbryt" -#: gitk:2040 +#: gitk:2048 msgid "Update" msgstr "Uppdatera" -#: gitk:2041 +#: gitk:2049 msgid "Reload" msgstr "Ladda om" -#: gitk:2042 +#: gitk:2050 msgid "Reread references" msgstr "Läs om referenser" -#: gitk:2043 +#: gitk:2051 msgid "List references" msgstr "Visa referenser" -#: gitk:2045 +#: gitk:2053 msgid "Start git gui" msgstr "Starta git gui" -#: gitk:2047 +#: gitk:2055 msgid "Quit" msgstr "Avsluta" -#: gitk:2039 +#: gitk:2047 msgid "File" msgstr "Arkiv" -#: gitk:2051 +#: gitk:2059 msgid "Preferences" msgstr "Inställningar" -#: gitk:2050 +#: gitk:2058 msgid "Edit" msgstr "Redigera" -#: gitk:2055 +#: gitk:2063 msgid "New view..." msgstr "Ny vy..." -#: gitk:2056 +#: gitk:2064 msgid "Edit view..." msgstr "Ändra vy..." -#: gitk:2057 +#: gitk:2065 msgid "Delete view" msgstr "Ta bort vy" -#: gitk:2059 +#: gitk:2067 msgid "All files" msgstr "Alla filer" -#: gitk:2054 gitk:3899 +#: gitk:2062 gitk:3955 msgid "View" msgstr "Visa" -#: gitk:2064 gitk:2074 gitk:2869 +#: gitk:2072 gitk:2082 gitk:2925 msgid "About gitk" msgstr "Om gitk" -#: gitk:2065 gitk:2079 +#: gitk:2073 gitk:2087 msgid "Key bindings" msgstr "Tangentbordsbindningar" -#: gitk:2063 gitk:2078 +#: gitk:2071 gitk:2086 msgid "Help" msgstr "Hjälp" -#: gitk:2156 gitk:8330 +#: gitk:2164 gitk:8420 msgid "SHA1 ID:" msgstr "SHA1-id:" -#: gitk:2192 +#: gitk:2208 msgid "Row" msgstr "Rad" -#: gitk:2230 +#: gitk:2246 msgid "Find" msgstr "Sök" -#: gitk:2231 +#: gitk:2247 msgid "next" msgstr "nästa" -#: gitk:2232 +#: gitk:2248 msgid "prev" msgstr "föreg" -#: gitk:2233 +#: gitk:2249 msgid "commit" msgstr "incheckning" -#: gitk:2236 gitk:2238 gitk:4514 gitk:4537 gitk:4561 gitk:6528 gitk:6600 -#: gitk:6685 +#: gitk:2252 gitk:2254 gitk:4570 gitk:4593 gitk:4617 gitk:6592 gitk:6664 +#: gitk:6749 msgid "containing:" msgstr "som innehÃ¥ller:" -#: gitk:2239 gitk:3381 gitk:3386 gitk:4590 +#: gitk:2255 gitk:3437 gitk:3442 gitk:4646 msgid "touching paths:" msgstr "som rör sökväg:" -#: gitk:2240 gitk:4604 +#: gitk:2256 gitk:4660 msgid "adding/removing string:" msgstr "som lägger/till tar bort sträng:" -#: gitk:2249 gitk:2251 gitk:4593 +#: gitk:2257 gitk:4662 +msgid "changing lines matching:" +msgstr "ändrar rader som matchar:" + +#: gitk:2266 gitk:2268 gitk:4649 msgid "Exact" msgstr "Exakt" -#: gitk:2251 gitk:4679 gitk:6496 +#: gitk:2268 gitk:4737 gitk:6560 msgid "IgnCase" msgstr "IgnVersaler" -#: gitk:2251 gitk:4563 gitk:4677 gitk:6492 +#: gitk:2268 gitk:4619 gitk:4735 gitk:6556 msgid "Regexp" msgstr "Reg.uttr." -#: gitk:2253 gitk:2254 gitk:4699 gitk:4729 gitk:4736 gitk:6621 gitk:6689 +#: gitk:2270 gitk:2271 gitk:4757 gitk:4787 gitk:4794 gitk:6685 gitk:6753 msgid "All fields" msgstr "Alla fält" -#: gitk:2254 gitk:4696 gitk:4729 gitk:6559 +#: gitk:2271 gitk:4754 gitk:4787 gitk:6623 msgid "Headline" msgstr "Rubrik" -#: gitk:2255 gitk:4696 gitk:6559 gitk:6689 gitk:7126 +#: gitk:2272 gitk:4754 gitk:6623 gitk:6753 gitk:7221 msgid "Comments" msgstr "Kommentarer" -#: gitk:2255 gitk:4696 gitk:4701 gitk:4736 gitk:6559 gitk:7061 gitk:8505 -#: gitk:8520 +#: gitk:2272 gitk:4754 gitk:4759 gitk:4794 gitk:6623 gitk:7156 gitk:8598 +#: gitk:8613 msgid "Author" msgstr "Författare" -#: gitk:2255 gitk:4696 gitk:6559 gitk:7063 +#: gitk:2272 gitk:4754 gitk:6623 gitk:7158 msgid "Committer" msgstr "Incheckare" -#: gitk:2286 +#: gitk:2303 msgid "Search" msgstr "Sök" -#: gitk:2294 +#: gitk:2311 msgid "Diff" msgstr "Diff" -#: gitk:2296 +#: gitk:2313 msgid "Old version" msgstr "Gammal version" -#: gitk:2298 +#: gitk:2315 msgid "New version" msgstr "Ny version" -#: gitk:2300 +#: gitk:2317 msgid "Lines of context" msgstr "Rader sammanhang" -#: gitk:2310 +#: gitk:2327 msgid "Ignore space change" msgstr "Ignorera ändringar i blanksteg" -#: gitk:2314 gitk:2316 gitk:7646 gitk:7874 +#: gitk:2331 gitk:2333 gitk:7735 gitk:7963 msgid "Line diff" msgstr "Rad-diff" -#: gitk:2379 +#: gitk:2397 msgid "Patch" msgstr "Patch" -#: gitk:2381 +#: gitk:2399 msgid "Tree" msgstr "Träd" -#: gitk:2540 gitk:2559 +#: gitk:2557 gitk:2577 msgid "Diff this -> selected" msgstr "Diff denna -> markerad" -#: gitk:2541 gitk:2560 +#: gitk:2558 gitk:2578 msgid "Diff selected -> this" msgstr "Diff markerad -> denna" -#: gitk:2542 gitk:2561 +#: gitk:2559 gitk:2579 msgid "Make patch" msgstr "Skapa patch" -#: gitk:2543 gitk:8929 +#: gitk:2560 gitk:9022 msgid "Create tag" msgstr "Skapa tagg" -#: gitk:2544 gitk:9045 +#: gitk:2561 gitk:9139 msgid "Write commit to file" msgstr "Skriv incheckning till fil" -#: gitk:2545 gitk:9102 +#: gitk:2562 gitk:9196 msgid "Create new branch" msgstr "Skapa ny gren" -#: gitk:2546 +#: gitk:2563 msgid "Cherry-pick this commit" msgstr "Plocka denna incheckning" -#: gitk:2547 +#: gitk:2564 msgid "Reset HEAD branch to here" msgstr "Ã…terställ HEAD-grenen hit" -#: gitk:2548 +#: gitk:2565 msgid "Mark this commit" msgstr "Markera denna incheckning" -#: gitk:2549 +#: gitk:2566 msgid "Return to mark" msgstr "Ã…tergÃ¥ till markering" -#: gitk:2550 +#: gitk:2567 msgid "Find descendant of this and mark" msgstr "Hitta efterföljare till denna och markera" -#: gitk:2551 +#: gitk:2568 msgid "Compare with marked commit" msgstr "Jämför med markerad incheckning" -#: gitk:2552 gitk:2562 +#: gitk:2569 gitk:2580 msgid "Diff this -> marked commit" msgstr "Diff denna -> markerad incheckning" -#: gitk:2553 gitk:2563 +#: gitk:2570 gitk:2581 msgid "Diff marked commit -> this" msgstr "Diff markerad incheckning -> denna" -#: gitk:2569 +#: gitk:2571 +msgid "Revert this commit" +msgstr "Ã…ngra denna incheckning" + +#: gitk:2587 msgid "Check out this branch" msgstr "Checka ut denna gren" -#: gitk:2570 +#: gitk:2588 msgid "Remove this branch" msgstr "Ta bort denna gren" -#: gitk:2577 +#: gitk:2595 msgid "Highlight this too" msgstr "Markera även detta" -#: gitk:2578 +#: gitk:2596 msgid "Highlight this only" msgstr "Markera bara detta" -#: gitk:2579 +#: gitk:2597 msgid "External diff" msgstr "Extern diff" -#: gitk:2580 +#: gitk:2598 msgid "Blame parent commit" msgstr "Klandra föräldraincheckning" -#: gitk:2587 +#: gitk:2605 msgid "Show origin of this line" msgstr "Visa ursprunget för den här raden" -#: gitk:2588 +#: gitk:2606 msgid "Run git gui blame on this line" msgstr "Kör git gui blame pÃ¥ den här raden" -#: gitk:2871 +#: gitk:2927 msgid "" "\n" "Gitk - a commit viewer for git\n" @@ -367,302 +375,302 @@ msgstr "" "\n" "Använd och vidareförmedla enligt villkoren i GNU General Public License" -#: gitk:2879 gitk:2944 gitk:9468 +#: gitk:2935 gitk:3000 gitk:9623 msgid "Close" msgstr "Stäng" -#: gitk:2900 +#: gitk:2956 msgid "Gitk key bindings" msgstr "Tangentbordsbindningar för Gitk" -#: gitk:2903 +#: gitk:2959 msgid "Gitk key bindings:" msgstr "Tangentbordsbindningar för Gitk:" -#: gitk:2905 +#: gitk:2961 #, tcl-format msgid "<%s-Q>\t\tQuit" msgstr "<%s-Q>\t\tAvsluta" -#: gitk:2906 +#: gitk:2962 #, tcl-format msgid "<%s-W>\t\tClose window" msgstr "<%s-W>\t\tStäng fönster" -#: gitk:2907 +#: gitk:2963 msgid "<Home>\t\tMove to first commit" msgstr "<Home>\t\tGÃ¥ till första incheckning" -#: gitk:2908 +#: gitk:2964 msgid "<End>\t\tMove to last commit" msgstr "<End>\t\tGÃ¥ till sista incheckning" -#: gitk:2909 +#: gitk:2965 msgid "<Up>, p, k\tMove up one commit" msgstr "<Upp>, p, k\tGÃ¥ en incheckning upp" -#: gitk:2910 +#: gitk:2966 msgid "<Down>, n, j\tMove down one commit" msgstr "<Ned>, n, j\tGÃ¥ en incheckning ned" -#: gitk:2911 +#: gitk:2967 msgid "<Left>, z, h\tGo back in history list" msgstr "<Vänster>, z, h\tGÃ¥ bakÃ¥t i historiken" -#: gitk:2912 +#: gitk:2968 msgid "<Right>, x, l\tGo forward in history list" msgstr "<Höger>, x, l\tGÃ¥ framÃ¥t i historiken" -#: gitk:2913 +#: gitk:2969 msgid "<PageUp>\tMove up one page in commit list" msgstr "<PageUp>\tGÃ¥ upp en sida i incheckningslistan" -#: gitk:2914 +#: gitk:2970 msgid "<PageDown>\tMove down one page in commit list" msgstr "<PageDown>\tGÃ¥ ned en sida i incheckningslistan" -#: gitk:2915 +#: gitk:2971 #, tcl-format msgid "<%s-Home>\tScroll to top of commit list" msgstr "<%s-Home>\tRulla till början av incheckningslistan" -#: gitk:2916 +#: gitk:2972 #, tcl-format msgid "<%s-End>\tScroll to bottom of commit list" msgstr "<%s-End>\tRulla till slutet av incheckningslistan" -#: gitk:2917 +#: gitk:2973 #, tcl-format msgid "<%s-Up>\tScroll commit list up one line" msgstr "<%s-Upp>\tRulla incheckningslistan upp ett steg" -#: gitk:2918 +#: gitk:2974 #, tcl-format msgid "<%s-Down>\tScroll commit list down one line" msgstr "<%s-Ned>\tRulla incheckningslistan ned ett steg" -#: gitk:2919 +#: gitk:2975 #, tcl-format msgid "<%s-PageUp>\tScroll commit list up one page" msgstr "<%s-PageUp>\tRulla incheckningslistan upp en sida" -#: gitk:2920 +#: gitk:2976 #, tcl-format msgid "<%s-PageDown>\tScroll commit list down one page" msgstr "<%s-PageDown>\tRulla incheckningslistan ned en sida" -#: gitk:2921 +#: gitk:2977 msgid "<Shift-Up>\tFind backwards (upwards, later commits)" msgstr "<Skift-Upp>\tSök bakÃ¥t (uppÃ¥t, senare incheckningar)" -#: gitk:2922 +#: gitk:2978 msgid "<Shift-Down>\tFind forwards (downwards, earlier commits)" msgstr "<Skift-Ned>\tSök framÃ¥t (nedÃ¥t, tidigare incheckningar)" -#: gitk:2923 +#: gitk:2979 msgid "<Delete>, b\tScroll diff view up one page" msgstr "<Delete>, b\tRulla diffvisningen upp en sida" -#: gitk:2924 +#: gitk:2980 msgid "<Backspace>\tScroll diff view up one page" msgstr "<Baksteg>\tRulla diffvisningen upp en sida" -#: gitk:2925 +#: gitk:2981 msgid "<Space>\t\tScroll diff view down one page" msgstr "<Blanksteg>\tRulla diffvisningen ned en sida" -#: gitk:2926 +#: gitk:2982 msgid "u\t\tScroll diff view up 18 lines" msgstr "u\t\tRulla diffvisningen upp 18 rader" -#: gitk:2927 +#: gitk:2983 msgid "d\t\tScroll diff view down 18 lines" msgstr "d\t\tRulla diffvisningen ned 18 rader" -#: gitk:2928 +#: gitk:2984 #, tcl-format msgid "<%s-F>\t\tFind" msgstr "<%s-F>\t\tSök" -#: gitk:2929 +#: gitk:2985 #, tcl-format msgid "<%s-G>\t\tMove to next find hit" msgstr "<%s-G>\t\tGÃ¥ till nästa sökträff" -#: gitk:2930 +#: gitk:2986 msgid "<Return>\tMove to next find hit" msgstr "<Return>\t\tGÃ¥ till nästa sökträff" -#: gitk:2931 +#: gitk:2987 msgid "/\t\tFocus the search box" msgstr "/\t\tFokusera sökrutan" -#: gitk:2932 +#: gitk:2988 msgid "?\t\tMove to previous find hit" msgstr "?\t\tGÃ¥ till föregÃ¥ende sökträff" -#: gitk:2933 +#: gitk:2989 msgid "f\t\tScroll diff view to next file" msgstr "f\t\tRulla diffvisningen till nästa fil" -#: gitk:2934 +#: gitk:2990 #, tcl-format msgid "<%s-S>\t\tSearch for next hit in diff view" msgstr "<%s-S>\t\tGÃ¥ till nästa sökträff i diffvisningen" -#: gitk:2935 +#: gitk:2991 #, tcl-format msgid "<%s-R>\t\tSearch for previous hit in diff view" msgstr "<%s-R>\t\tGÃ¥ till föregÃ¥ende sökträff i diffvisningen" -#: gitk:2936 +#: gitk:2992 #, tcl-format msgid "<%s-KP+>\tIncrease font size" msgstr "<%s-Num+>\tÖka teckenstorlek" -#: gitk:2937 +#: gitk:2993 #, tcl-format msgid "<%s-plus>\tIncrease font size" msgstr "<%s-plus>\tÖka teckenstorlek" -#: gitk:2938 +#: gitk:2994 #, tcl-format msgid "<%s-KP->\tDecrease font size" msgstr "<%s-Num->\tMinska teckenstorlek" -#: gitk:2939 +#: gitk:2995 #, tcl-format msgid "<%s-minus>\tDecrease font size" msgstr "<%s-minus>\tMinska teckenstorlek" -#: gitk:2940 +#: gitk:2996 msgid "<F5>\t\tUpdate" msgstr "<F5>\t\tUppdatera" -#: gitk:3395 gitk:3404 +#: gitk:3451 gitk:3460 #, tcl-format msgid "Error creating temporary directory %s:" msgstr "Fel vid skapande av temporär katalog %s:" -#: gitk:3417 +#: gitk:3473 #, tcl-format msgid "Error getting \"%s\" from %s:" msgstr "Fel vid hämtning av \"%s\" frÃ¥n %s:" -#: gitk:3480 +#: gitk:3536 msgid "command failed:" msgstr "kommando misslyckades:" -#: gitk:3629 +#: gitk:3685 msgid "No such commit" msgstr "Incheckning saknas" -#: gitk:3643 +#: gitk:3699 msgid "git gui blame: command failed:" msgstr "git gui blame: kommando misslyckades:" -#: gitk:3674 +#: gitk:3730 #, tcl-format msgid "Couldn't read merge head: %s" msgstr "Kunde inte läsa sammanslagningshuvud: %s" -#: gitk:3682 +#: gitk:3738 #, tcl-format msgid "Error reading index: %s" msgstr "Fel vid läsning av index: %s" -#: gitk:3707 +#: gitk:3763 #, tcl-format msgid "Couldn't start git blame: %s" msgstr "Kunde inte starta git blame: %s" -#: gitk:3710 gitk:6527 +#: gitk:3766 gitk:6591 msgid "Searching" msgstr "Söker" -#: gitk:3742 +#: gitk:3798 #, tcl-format msgid "Error running git blame: %s" msgstr "Fel vid körning av git blame: %s" -#: gitk:3770 +#: gitk:3826 #, tcl-format msgid "That line comes from commit %s, which is not in this view" msgstr "Raden kommer frÃ¥n incheckningen %s, som inte finns i denna vy" -#: gitk:3784 +#: gitk:3840 msgid "External diff viewer failed:" msgstr "Externt diff-verktyg misslyckades:" -#: gitk:3902 +#: gitk:3958 msgid "Gitk view definition" msgstr "Definition av Gitk-vy" -#: gitk:3906 +#: gitk:3962 msgid "Remember this view" msgstr "Spara denna vy" -#: gitk:3907 +#: gitk:3963 msgid "References (space separated list):" msgstr "Referenser (blankstegsavdelad lista):" -#: gitk:3908 +#: gitk:3964 msgid "Branches & tags:" msgstr "Grenar & taggar:" -#: gitk:3909 +#: gitk:3965 msgid "All refs" msgstr "Alla referenser" -#: gitk:3910 +#: gitk:3966 msgid "All (local) branches" msgstr "Alla (lokala) grenar" -#: gitk:3911 +#: gitk:3967 msgid "All tags" msgstr "Alla taggar" -#: gitk:3912 +#: gitk:3968 msgid "All remote-tracking branches" msgstr "Alla fjärrspÃ¥rande grenar" -#: gitk:3913 +#: gitk:3969 msgid "Commit Info (regular expressions):" msgstr "Incheckningsinfo (reguljära uttryck):" -#: gitk:3914 +#: gitk:3970 msgid "Author:" msgstr "Författare:" -#: gitk:3915 +#: gitk:3971 msgid "Committer:" msgstr "Incheckare:" -#: gitk:3916 +#: gitk:3972 msgid "Commit Message:" msgstr "Incheckningsmeddelande:" -#: gitk:3917 +#: gitk:3973 msgid "Matches all Commit Info criteria" msgstr "Motsvarar alla kriterier för incheckningsinfo" -#: gitk:3918 +#: gitk:3974 msgid "Changes to Files:" msgstr "Ändringar av filer:" -#: gitk:3919 +#: gitk:3975 msgid "Fixed String" msgstr "Fast sträng" -#: gitk:3920 +#: gitk:3976 msgid "Regular Expression" msgstr "Reguljärt uttryck" -#: gitk:3921 +#: gitk:3977 msgid "Search string:" msgstr "Söksträng:" -#: gitk:3922 +#: gitk:3978 msgid "" "Commit Dates (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" @@ -670,197 +678,201 @@ msgstr "" "Incheckingsdatum (\"2 weeks ago\", \"2009-03-17 15:27:38\", \"March 17, 2009 " "15:27:38\"):" -#: gitk:3923 +#: gitk:3979 msgid "Since:" msgstr "FrÃ¥n:" -#: gitk:3924 +#: gitk:3980 msgid "Until:" msgstr "Till:" -#: gitk:3925 +#: gitk:3981 msgid "Limit and/or skip a number of revisions (positive integer):" msgstr "Begränsa och/eller hoppa över ett antal revisioner (positivt heltal):" -#: gitk:3926 +#: gitk:3982 msgid "Number to show:" msgstr "Antal att visa:" -#: gitk:3927 +#: gitk:3983 msgid "Number to skip:" msgstr "Antal att hoppa över:" -#: gitk:3928 +#: gitk:3984 msgid "Miscellaneous options:" msgstr "Diverse alternativ:" -#: gitk:3929 +#: gitk:3985 msgid "Strictly sort by date" msgstr "Strikt datumsortering" -#: gitk:3930 +#: gitk:3986 msgid "Mark branch sides" msgstr "Markera sidogrenar" -#: gitk:3931 +#: gitk:3987 msgid "Limit to first parent" msgstr "Begränsa till första förälder" -#: gitk:3932 +#: gitk:3988 msgid "Simple history" msgstr "Enkel historik" -#: gitk:3933 +#: gitk:3989 msgid "Additional arguments to git log:" msgstr "Ytterligare argument till git log:" -#: gitk:3934 +#: gitk:3990 msgid "Enter files and directories to include, one per line:" msgstr "Ange filer och kataloger att ta med, en per rad:" -#: gitk:3935 +#: gitk:3991 msgid "Command to generate more commits to include:" msgstr "Kommando för att generera fler incheckningar att ta med:" -#: gitk:4059 +#: gitk:4115 msgid "Gitk: edit view" msgstr "Gitk: redigera vy" -#: gitk:4067 +#: gitk:4123 msgid "-- criteria for selecting revisions" msgstr " - kriterier för val av revisioner" -#: gitk:4072 +#: gitk:4128 msgid "View Name" msgstr "Namn pÃ¥ vy" -#: gitk:4147 +#: gitk:4203 msgid "Apply (F5)" msgstr "Använd (F5)" -#: gitk:4185 +#: gitk:4241 msgid "Error in commit selection arguments:" msgstr "Fel i argument för val av incheckningar:" -#: gitk:4238 gitk:4290 gitk:4749 gitk:4763 gitk:6027 gitk:11849 gitk:11850 +#: gitk:4294 gitk:4346 gitk:4807 gitk:4821 gitk:6087 gitk:12041 gitk:12042 msgid "None" msgstr "Inget" -#: gitk:4846 gitk:4851 +#: gitk:4904 gitk:4909 msgid "Descendant" msgstr "Avkomling" -#: gitk:4847 +#: gitk:4905 msgid "Not descendant" msgstr "Inte avkomling" -#: gitk:4854 gitk:4859 +#: gitk:4912 gitk:4917 msgid "Ancestor" msgstr "Förfader" -#: gitk:4855 +#: gitk:4913 msgid "Not ancestor" msgstr "Inte förfader" -#: gitk:5145 +#: gitk:5203 msgid "Local changes checked in to index but not committed" msgstr "Lokala ändringar sparade i indexet men inte incheckade" -#: gitk:5181 +#: gitk:5239 msgid "Local uncommitted changes, not checked in to index" msgstr "Lokala ändringar, ej sparade i indexet" -#: gitk:6882 +#: gitk:6971 +msgid "and many more" +msgstr "med mÃ¥nga flera" + +#: gitk:6974 msgid "many" msgstr "mÃ¥nga" -#: gitk:7065 +#: gitk:7160 msgid "Tags:" msgstr "Taggar:" -#: gitk:7082 gitk:7088 gitk:8500 +#: gitk:7177 gitk:7183 gitk:8593 msgid "Parent" msgstr "Förälder" -#: gitk:7093 +#: gitk:7188 msgid "Child" msgstr "Barn" -#: gitk:7102 +#: gitk:7197 msgid "Branch" msgstr "Gren" -#: gitk:7105 +#: gitk:7200 msgid "Follows" msgstr "Följer" -#: gitk:7108 +#: gitk:7203 msgid "Precedes" msgstr "FöregÃ¥r" -#: gitk:7653 +#: gitk:7742 #, tcl-format msgid "Error getting diffs: %s" msgstr "Fel vid hämtning av diff: %s" -#: gitk:8328 +#: gitk:8418 msgid "Goto:" msgstr "GÃ¥ till:" -#: gitk:8349 +#: gitk:8439 #, tcl-format msgid "Short SHA1 id %s is ambiguous" msgstr "Förkortat SHA1-id %s är tvetydigt" -#: gitk:8356 +#: gitk:8446 #, tcl-format msgid "Revision %s is not known" msgstr "Revisionen %s är inte känd" -#: gitk:8366 +#: gitk:8456 #, tcl-format msgid "SHA1 id %s is not known" msgstr "SHA-id:t %s är inte känt" -#: gitk:8368 +#: gitk:8458 #, tcl-format msgid "Revision %s is not in the current view" msgstr "Revisionen %s finns inte i den nuvarande vyn" -#: gitk:8507 gitk:8522 +#: gitk:8600 gitk:8615 msgid "Date" msgstr "Datum" -#: gitk:8510 +#: gitk:8603 msgid "Children" msgstr "Barn" -#: gitk:8573 +#: gitk:8666 #, tcl-format msgid "Reset %s branch to here" msgstr "Ã…terställ grenen %s hit" -#: gitk:8575 +#: gitk:8668 msgid "Detached head: can't reset" msgstr "FrÃ¥nkopplad head: kan inte Ã¥terställa" -#: gitk:8680 gitk:8686 +#: gitk:8773 gitk:8779 msgid "Skipping merge commit " msgstr "Hoppar över sammanslagningsincheckning " -#: gitk:8695 gitk:8700 +#: gitk:8788 gitk:8793 msgid "Error getting patch ID for " msgstr "Fel vid hämtning av patch-id för " -#: gitk:8696 gitk:8701 +#: gitk:8789 gitk:8794 msgid " - stopping\n" msgstr " - stannar\n" -#: gitk:8706 gitk:8709 gitk:8717 gitk:8731 gitk:8740 +#: gitk:8799 gitk:8802 gitk:8810 gitk:8824 gitk:8833 msgid "Commit " msgstr "Incheckning " -#: gitk:8710 +#: gitk:8803 msgid "" " is the same patch as\n" " " @@ -868,7 +880,7 @@ msgstr "" " är samma patch som\n" " " -#: gitk:8718 +#: gitk:8811 msgid "" " differs from\n" " " @@ -876,7 +888,7 @@ msgstr "" " skiljer sig frÃ¥n\n" " " -#: gitk:8720 +#: gitk:8813 msgid "" "Diff of commits:\n" "\n" @@ -884,131 +896,131 @@ msgstr "" "Skillnad mellan incheckningar:\n" "\n" -#: gitk:8732 gitk:8741 +#: gitk:8825 gitk:8834 #, tcl-format msgid " has %s children - stopping\n" msgstr " har %s barn - stannar\n" -#: gitk:8760 +#: gitk:8853 #, tcl-format msgid "Error writing commit to file: %s" msgstr "Fel vid skrivning av incheckning till fil: %s" -#: gitk:8766 +#: gitk:8859 #, tcl-format msgid "Error diffing commits: %s" msgstr "Fel vid jämförelse av incheckningar: %s" -#: gitk:8812 +#: gitk:8905 msgid "Top" msgstr "Topp" -#: gitk:8813 +#: gitk:8906 msgid "From" msgstr "FrÃ¥n" -#: gitk:8818 +#: gitk:8911 msgid "To" msgstr "Till" -#: gitk:8842 +#: gitk:8935 msgid "Generate patch" msgstr "Generera patch" -#: gitk:8844 +#: gitk:8937 msgid "From:" msgstr "FrÃ¥n:" -#: gitk:8853 +#: gitk:8946 msgid "To:" msgstr "Till:" -#: gitk:8862 +#: gitk:8955 msgid "Reverse" msgstr "Vänd" -#: gitk:8864 gitk:9059 +#: gitk:8957 gitk:9153 msgid "Output file:" msgstr "Utdatafil:" -#: gitk:8870 +#: gitk:8963 msgid "Generate" msgstr "Generera" -#: gitk:8908 +#: gitk:9001 msgid "Error creating patch:" msgstr "Fel vid generering av patch:" -#: gitk:8931 gitk:9047 gitk:9104 +#: gitk:9024 gitk:9141 gitk:9198 msgid "ID:" msgstr "Id:" -#: gitk:8940 +#: gitk:9033 msgid "Tag name:" msgstr "Taggnamn:" -#: gitk:8943 +#: gitk:9036 msgid "Tag message is optional" msgstr "Taggmeddelandet är valfritt" -#: gitk:8945 +#: gitk:9038 msgid "Tag message:" msgstr "Taggmeddelande:" -#: gitk:8949 gitk:9113 +#: gitk:9042 gitk:9207 msgid "Create" msgstr "Skapa" -#: gitk:8967 +#: gitk:9060 msgid "No tag name specified" msgstr "Inget taggnamn angavs" -#: gitk:8971 +#: gitk:9064 #, tcl-format msgid "Tag \"%s\" already exists" msgstr "Taggen \"%s\" finns redan" -#: gitk:8981 +#: gitk:9074 msgid "Error creating tag:" msgstr "Fel vid skapande av tagg:" -#: gitk:9056 +#: gitk:9150 msgid "Command:" msgstr "Kommando:" -#: gitk:9064 +#: gitk:9158 msgid "Write" msgstr "Skriv" -#: gitk:9082 +#: gitk:9176 msgid "Error writing commit:" msgstr "Fel vid skrivning av incheckning:" -#: gitk:9109 +#: gitk:9203 msgid "Name:" msgstr "Namn:" -#: gitk:9132 +#: gitk:9226 msgid "Please specify a name for the new branch" msgstr "Ange ett namn för den nya grenen" -#: gitk:9137 +#: gitk:9231 #, tcl-format msgid "Branch '%s' already exists. Overwrite?" msgstr "Grenen \"%s\" finns redan. Skriva över?" -#: gitk:9204 +#: gitk:9298 #, tcl-format msgid "Commit %s is already included in branch %s -- really re-apply it?" msgstr "" "Incheckningen %s finns redan pÃ¥ grenen %s -- skall den verkligen appliceras " "pÃ¥ nytt?" -#: gitk:9209 +#: gitk:9303 msgid "Cherry-picking" msgstr "Plockar" -#: gitk:9218 +#: gitk:9312 #, tcl-format msgid "" "Cherry-pick failed because of local changes to file '%s'.\n" @@ -1018,7 +1030,7 @@ msgstr "" "Checka in, Ã¥terställ eller spara undan (stash) dina ändringar och försök " "igen." -#: gitk:9224 +#: gitk:9318 msgid "" "Cherry-pick failed because of merge conflict.\n" "Do you wish to run git citool to resolve it?" @@ -1026,32 +1038,59 @@ msgstr "" "Cherry-pick misslyckades pÃ¥ grund av en sammanslagningskonflikt.\n" "Vill du köra git citool för att lösa den?" -#: gitk:9240 +#: gitk:9334 gitk:9392 msgid "No changes committed" msgstr "Inga ändringar incheckade" -#: gitk:9266 +#: gitk:9361 +#, tcl-format +msgid "Commit %s is not included in branch %s -- really revert it?" +msgstr "Incheckningen %s finns inte pÃ¥ grenen %s -- vill du verkligen Ã¥ngra?" + +#: gitk:9366 +msgid "Reverting" +msgstr "Ã…ngrar" + +#: gitk:9374 +#, tcl-format +msgid "" +"Revert failed because of local changes to the following files:%s Please " +"commit, reset or stash your changes and try again." +msgstr "" +"Misslyckades med att Ã¥ngra pÃ¥ grund av lokala ändringar i följande filer:%s. " +"Checka in, Ã¥terställ eller spara undan (stash) dina ändringar och försök " +"igen." + +#: gitk:9378 +msgid "" +"Revert failed because of merge conflict.\n" +" Do you wish to run git citool to resolve it?" +msgstr "" +"Misslyckades med att Ã¥ngra pÃ¥ grund av en sammanslagningskonflikt.\n" +" Vill du köra git citool för att lösa den?" + +#: gitk:9421 msgid "Confirm reset" msgstr "Bekräfta Ã¥terställning" -#: gitk:9268 +#: gitk:9423 #, tcl-format msgid "Reset branch %s to %s?" msgstr "Ã…terställa grenen %s till %s?" -#: gitk:9270 +#: gitk:9425 msgid "Reset type:" msgstr "Typ av Ã¥terställning:" -#: gitk:9273 +#: gitk:9428 msgid "Soft: Leave working tree and index untouched" msgstr "Mjuk: Rör inte utcheckning och index" -#: gitk:9276 +#: gitk:9431 msgid "Mixed: Leave working tree untouched, reset index" msgstr "Blandad: Rör inte utcheckning, Ã¥terställ index" -#: gitk:9279 +#: gitk:9434 msgid "" "Hard: Reset working tree and index\n" "(discard ALL local changes)" @@ -1059,19 +1098,19 @@ msgstr "" "HÃ¥rd: Ã…terställ utcheckning och index\n" "(förkastar ALLA lokala ändringar)" -#: gitk:9296 +#: gitk:9451 msgid "Resetting" msgstr "Ã…terställer" -#: gitk:9356 +#: gitk:9511 msgid "Checking out" msgstr "Checkar ut" -#: gitk:9409 +#: gitk:9564 msgid "Cannot delete the currently checked-out branch" msgstr "Kan inte ta bort den just nu utcheckade grenen" -#: gitk:9415 +#: gitk:9570 #, tcl-format msgid "" "The commits on branch %s aren't on any other branch.\n" @@ -1080,16 +1119,16 @@ msgstr "" "Incheckningarna pÃ¥ grenen %s existerar inte pÃ¥ nÃ¥gon annan gren.\n" "Vill du verkligen ta bort grenen %s?" -#: gitk:9446 +#: gitk:9601 #, tcl-format msgid "Tags and heads: %s" msgstr "Taggar och huvuden: %s" -#: gitk:9461 +#: gitk:9616 msgid "Filter" msgstr "Filter" -#: gitk:9757 +#: gitk:9912 msgid "" "Error reading commit topology information; branch and preceding/following " "tag information will be incomplete." @@ -1097,210 +1136,214 @@ msgstr "" "Fel vid läsning av information om incheckningstopologi; information om " "grenar och föregÃ¥ende/senare taggar kommer inte vara komplett." -#: gitk:10744 +#: gitk:10899 msgid "Tag" msgstr "Tagg" -#: gitk:10744 +#: gitk:10899 msgid "Id" msgstr "Id" -#: gitk:10793 +#: gitk:10948 msgid "Gitk font chooser" msgstr "Teckensnittsväljare för Gitk" -#: gitk:10810 +#: gitk:10965 msgid "B" msgstr "F" -#: gitk:10813 +#: gitk:10968 msgid "I" msgstr "K" -#: gitk:10931 +#: gitk:11086 msgid "Commit list display options" msgstr "Alternativ för incheckningslistvy" -#: gitk:10934 +#: gitk:11089 msgid "Maximum graph width (lines)" msgstr "Maximal grafbredd (rader)" -#: gitk:10937 +#: gitk:11092 #, tcl-format msgid "Maximum graph width (% of pane)" msgstr "Maximal grafbredd (% av ruta)" -#: gitk:10940 +#: gitk:11095 msgid "Show local changes" msgstr "Visa lokala ändringar" -#: gitk:10943 +#: gitk:11098 msgid "Auto-select SHA1 (length)" msgstr "Välj SHA1 (längd) automatiskt" -#: gitk:10947 +#: gitk:11102 msgid "Hide remote refs" msgstr "Dölj fjärr-referenser" -#: gitk:10951 +#: gitk:11106 msgid "Diff display options" msgstr "Alternativ för diffvy" -#: gitk:10953 +#: gitk:11108 msgid "Tab spacing" msgstr "Blanksteg för tabulatortecken" -#: gitk:10956 -msgid "Display nearby tags" -msgstr "Visa närliggande taggar" +#: gitk:11111 +msgid "Display nearby tags/heads" +msgstr "Visa närliggande taggar/huvuden" + +#: gitk:11114 +msgid "Maximum # tags/heads to show" +msgstr "Maximalt antal taggar/huvuden att visa" -#: gitk:10959 +#: gitk:11117 msgid "Limit diffs to listed paths" msgstr "Begränsa diff till listade sökvägar" -#: gitk:10962 +#: gitk:11120 msgid "Support per-file encodings" msgstr "Stöd för filspecifika teckenkodningar" -#: gitk:10968 gitk:11115 +#: gitk:11126 gitk:11273 msgid "External diff tool" msgstr "Externt diff-verktyg" -#: gitk:10969 +#: gitk:11127 msgid "Choose..." msgstr "Välj..." -#: gitk:10974 +#: gitk:11132 msgid "General options" msgstr "Allmänna inställningar" -#: gitk:10977 +#: gitk:11135 msgid "Use themed widgets" msgstr "Använd tema pÃ¥ fönsterelement" -#: gitk:10979 +#: gitk:11137 msgid "(change requires restart)" msgstr "(ändringen kräver omstart)" -#: gitk:10981 +#: gitk:11139 msgid "(currently unavailable)" msgstr "(för närvarande inte tillgängligt)" -#: gitk:10992 +#: gitk:11150 msgid "Colors: press to choose" msgstr "Färger: tryck för att välja" -#: gitk:10995 +#: gitk:11153 msgid "Interface" msgstr "Gränssnitt" -#: gitk:10996 +#: gitk:11154 msgid "interface" msgstr "gränssnitt" -#: gitk:10999 +#: gitk:11157 msgid "Background" msgstr "Bakgrund" -#: gitk:11000 gitk:11030 +#: gitk:11158 gitk:11188 msgid "background" msgstr "bakgrund" -#: gitk:11003 +#: gitk:11161 msgid "Foreground" msgstr "Förgrund" -#: gitk:11004 +#: gitk:11162 msgid "foreground" msgstr "förgrund" -#: gitk:11007 +#: gitk:11165 msgid "Diff: old lines" msgstr "Diff: gamla rader" -#: gitk:11008 +#: gitk:11166 msgid "diff old lines" msgstr "diff gamla rader" -#: gitk:11012 +#: gitk:11170 msgid "Diff: new lines" msgstr "Diff: nya rader" -#: gitk:11013 +#: gitk:11171 msgid "diff new lines" msgstr "diff nya rader" -#: gitk:11017 +#: gitk:11175 msgid "Diff: hunk header" msgstr "Diff: delhuvud" -#: gitk:11019 +#: gitk:11177 msgid "diff hunk header" msgstr "diff delhuvud" -#: gitk:11023 +#: gitk:11181 msgid "Marked line bg" msgstr "Markerad rad bakgrund" -#: gitk:11025 +#: gitk:11183 msgid "marked line background" msgstr "markerad rad bakgrund" -#: gitk:11029 +#: gitk:11187 msgid "Select bg" msgstr "Markerad bakgrund" -#: gitk:11038 +#: gitk:11196 msgid "Fonts: press to choose" msgstr "Teckensnitt: tryck för att välja" -#: gitk:11040 +#: gitk:11198 msgid "Main font" msgstr "Huvudteckensnitt" -#: gitk:11041 +#: gitk:11199 msgid "Diff display font" msgstr "Teckensnitt för diffvisning" -#: gitk:11042 +#: gitk:11200 msgid "User interface font" msgstr "Teckensnitt för användargränssnitt" -#: gitk:11064 +#: gitk:11222 msgid "Gitk preferences" msgstr "Inställningar för Gitk" -#: gitk:11073 +#: gitk:11231 msgid "General" msgstr "Allmänt" -#: gitk:11074 +#: gitk:11232 msgid "Colors" msgstr "Färger" -#: gitk:11075 +#: gitk:11233 msgid "Fonts" msgstr "Teckensnitt" -#: gitk:11125 +#: gitk:11283 #, tcl-format msgid "Gitk: choose color for %s" msgstr "Gitk: välj färg för %s" -#: gitk:11745 +#: gitk:11937 msgid "Cannot find a git repository here." msgstr "Hittar inget git-arkiv här." -#: gitk:11792 +#: gitk:11984 #, tcl-format msgid "Ambiguous argument '%s': both revision and filename" msgstr "Tvetydigt argument \"%s\": bÃ¥de revision och filnamn" -#: gitk:11804 +#: gitk:11996 msgid "Bad arguments to gitk:" msgstr "Felaktiga argument till gitk:" -#: gitk:11907 +#: gitk:12099 msgid "Command line" msgstr "Kommandorad" diff --git a/gpg-interface.h b/gpg-interface.h index cf99021842..a85cb5bc97 100644 --- a/gpg-interface.h +++ b/gpg-interface.h @@ -1,6 +1,18 @@ #ifndef GPG_INTERFACE_H #define GPG_INTERFACE_H +struct signature_check { + char *gpg_output; + char *gpg_status; + char result; /* 0 (not checked), + * N (checked but no further result), + * U (untrusted good), + * G (good) + * B (bad) */ + char *signer; + char *key; +}; + extern int sign_buffer(struct strbuf *buffer, struct strbuf *signature, const char *signing_key); extern int verify_signed_buffer(const char *payload, size_t payload_size, const char *signature, size_t signature_size, struct strbuf *gpg_output, struct strbuf *gpg_status); extern int git_gpg_config(const char *, const char *, void *); @@ -40,4 +40,11 @@ static inline void init_hash(struct hash_table *table) table->array = NULL; } +static inline void preallocate_hash(struct hash_table *table, unsigned int elts) +{ + assert(table->size == 0 && table->nr == 0 && table->array == NULL); + table->size = elts * 2; + table->array = xcalloc(sizeof(struct hash_table_entry), table->size); +} + #endif diff --git a/http-backend.c b/http-backend.c index f50e77fb28..6b85ffac27 100644 --- a/http-backend.c +++ b/http-backend.c @@ -70,7 +70,7 @@ static void format_write(int fd, const char *fmt, ...) if (n >= sizeof(buffer)) die("protocol error: impossibly long line"); - safe_write(fd, buffer, n); + write_or_die(fd, buffer, n); } static void http_status(unsigned code, const char *msg) @@ -111,7 +111,7 @@ static void hdr_cache_forever(void) static void end_headers(void) { - safe_write(1, "\r\n", 2); + write_or_die(1, "\r\n", 2); } __attribute__((format (printf, 1, 2))) @@ -157,7 +157,7 @@ static void send_strbuf(const char *type, struct strbuf *buf) hdr_int(content_length, buf->len); hdr_str(content_type, type); end_headers(); - safe_write(1, buf->buf, buf->len); + write_or_die(1, buf->buf, buf->len); } static void send_local_file(const char *the_type, const char *name) @@ -185,7 +185,7 @@ static void send_local_file(const char *the_type, const char *name) die_errno("Cannot read '%s'", p); if (!n) break; - safe_write(1, buf, n); + write_or_die(1, buf, n); } close(fd); free(buf); @@ -361,17 +361,19 @@ static void run_service(const char **argv) static int show_text_ref(const char *name, const unsigned char *sha1, int flag, void *cb_data) { + const char *name_nons = strip_namespace(name); struct strbuf *buf = cb_data; struct object *o = parse_object(sha1); if (!o) return 0; - strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name); + strbuf_addf(buf, "%s\t%s\n", sha1_to_hex(sha1), name_nons); if (o->type == OBJ_TAG) { o = deref_tag(o, name, 0); if (!o) return 0; - strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), name); + strbuf_addf(buf, "%s\t%s^{}\n", sha1_to_hex(o->sha1), + name_nons); } return 0; } @@ -402,12 +404,40 @@ static void get_info_refs(char *arg) } else { select_getanyfile(); - for_each_ref(show_text_ref, &buf); + for_each_namespaced_ref(show_text_ref, &buf); send_strbuf("text/plain", &buf); } strbuf_release(&buf); } +static int show_head_ref(const char *name, const unsigned char *sha1, + int flag, void *cb_data) +{ + struct strbuf *buf = cb_data; + + if (flag & REF_ISSYMREF) { + unsigned char sha1[20]; + const char *target = resolve_ref_unsafe(name, sha1, 1, NULL); + const char *target_nons = strip_namespace(target); + + strbuf_addf(buf, "ref: %s\n", target_nons); + } else { + strbuf_addf(buf, "%s\n", sha1_to_hex(sha1)); + } + + return 0; +} + +static void get_head(char *arg) +{ + struct strbuf buf = STRBUF_INIT; + + select_getanyfile(); + head_ref_namespaced(show_head_ref, &buf); + send_strbuf("text/plain", &buf); + strbuf_release(&buf); +} + static void get_info_packs(char *arg) { size_t objdirlen = strlen(get_object_directory()); @@ -520,7 +550,7 @@ static struct service_cmd { const char *pattern; void (*imp)(char *); } services[] = { - {"GET", "/HEAD$", get_text_file}, + {"GET", "/HEAD$", get_head}, {"GET", "/info/refs$", get_info_refs}, {"GET", "/objects/info/alternates$", get_text_file}, {"GET", "/objects/info/http-alternates$", get_text_file}, diff --git a/http-push.c b/http-push.c index bd66f6ab6e..395a8cfc10 100644 --- a/http-push.c +++ b/http-push.c @@ -1551,7 +1551,7 @@ static int remote_exists(const char *path) ret = 0; break; case HTTP_ERROR: - http_error(url, HTTP_ERROR); + error("unable to access '%s': %s", url, curl_errorstr); default: ret = -1; } @@ -5,6 +5,7 @@ #include "url.h" #include "credential.h" #include "version.h" +#include "pkt-line.h" int active_requests; int http_is_verbose; @@ -30,6 +31,7 @@ static CURL *curl_default; char curl_errorstr[CURL_ERROR_SIZE]; static int curl_ssl_verify = -1; +static int curl_ssl_try; static const char *ssl_cert; #if LIBCURL_VERSION_NUM >= 0x070903 static const char *ssl_key; @@ -162,6 +164,10 @@ static int http_options(const char *var, const char *value, void *cb) ssl_cert_password_required = 1; return 0; } + if (!strcmp("http.ssltry", var)) { + curl_ssl_try = git_config_bool(var, value); + return 0; + } if (!strcmp("http.minsessions", var)) { min_curl_sessions = git_config_int(var, value); #ifndef USE_CURL_MULTI @@ -281,7 +287,6 @@ static CURL *get_curl_handle(void) #endif if (ssl_cainfo != NULL) curl_easy_setopt(result, CURLOPT_CAINFO, ssl_cainfo); - curl_easy_setopt(result, CURLOPT_FAILONERROR, 1); if (curl_low_speed_limit > 0 && curl_low_speed_time > 0) { curl_easy_setopt(result, CURLOPT_LOW_SPEED_LIMIT, @@ -306,6 +311,11 @@ static CURL *get_curl_handle(void) if (curl_ftp_no_epsv) curl_easy_setopt(result, CURLOPT_FTP_USE_EPSV, 0); +#ifdef CURLOPT_USE_SSL + if (curl_ssl_try) + curl_easy_setopt(result, CURLOPT_USE_SSL, CURLUSESSL_TRY); +#endif + if (curl_http_proxy) { curl_easy_setopt(result, CURLOPT_PROXY, curl_http_proxy); curl_easy_setopt(result, CURLOPT_PROXYAUTH, CURLAUTH_ANY); @@ -505,6 +515,7 @@ struct active_request_slot *get_active_slot(void) curl_easy_setopt(slot->curl, CURLOPT_POSTFIELDS, NULL); curl_easy_setopt(slot->curl, CURLOPT_UPLOAD, 0); curl_easy_setopt(slot->curl, CURLOPT_HTTPGET, 1); + curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 1); if (http_auth.password) init_curl_http_auth(slot->curl); @@ -760,6 +771,25 @@ char *get_remote_object_url(const char *url, const char *hex, int handle_curl_result(struct slot_results *results) { + /* + * If we see a failing http code with CURLE_OK, we have turned off + * FAILONERROR (to keep the server's custom error response), and should + * translate the code into failure here. + */ + if (results->curl_result == CURLE_OK && + results->http_code >= 400) { + results->curl_result = CURLE_HTTP_RETURNED_ERROR; + /* + * Normally curl will already have put the "reason phrase" + * from the server into curl_errorstr; unfortunately without + * FAILONERROR it is lost, so we can give only the numeric + * status code. + */ + snprintf(curl_errorstr, sizeof(curl_errorstr), + "The requested URL returned error: %ld", + results->http_code); + } + if (results->curl_result == CURLE_OK) { credential_approve(&http_auth); return HTTP_OK; @@ -824,6 +854,8 @@ static int http_request(const char *url, struct strbuf *type, strbuf_addstr(&buf, "Pragma:"); if (options & HTTP_NO_CACHE) strbuf_addstr(&buf, " no-cache"); + if (options & HTTP_KEEP_ERROR) + curl_easy_setopt(slot->curl, CURLOPT_FAILONERROR, 0); headers = curl_slist_append(headers, buf.buf); @@ -835,7 +867,8 @@ static int http_request(const char *url, struct strbuf *type, run_active_slot(slot); ret = handle_curl_result(&results); } else { - error("Unable to start HTTP request for %s", url); + snprintf(curl_errorstr, sizeof(curl_errorstr), + "failed to start HTTP request"); ret = HTTP_START_FAILED; } @@ -861,6 +894,22 @@ static int http_request_reauth(const char *url, int ret = http_request(url, type, result, target, options); if (ret != HTTP_REAUTH) return ret; + + /* + * If we are using KEEP_ERROR, the previous request may have + * put cruft into our output stream; we should clear it out before + * making our next request. We only know how to do this for + * the strbuf case, but that is enough to satisfy current callers. + */ + if (options & HTTP_KEEP_ERROR) { + switch (target) { + case HTTP_REQUEST_STRBUF: + strbuf_reset(result); + break; + default: + die("BUG: HTTP_KEEP_ERROR is only supported with strbufs"); + } + } return http_request(url, type, result, target, options); } @@ -902,15 +951,6 @@ cleanup: return ret; } -int http_error(const char *url, int ret) -{ - /* http_request has already handled HTTP_START_FAILED. */ - if (ret != HTTP_START_FAILED) - error("%s while accessing %s", curl_errorstr, url); - - return ret; -} - int http_fetch_ref(const char *base, struct ref *ref) { char *url; @@ -42,6 +42,15 @@ #define NO_CURL_IOCTL #endif +/* + * CURLOPT_USE_SSL was known as CURLOPT_FTP_SSL up to 7.16.4, + * and the constants were known as CURLFTPSSL_* +*/ +#if !defined(CURLOPT_USE_SSL) && defined(CURLOPT_FTP_SSL) +#define CURLOPT_USE_SSL CURLOPT_FTP_SSL +#define CURLUSESSL_TRY CURLFTPSSL_TRY +#endif + struct slot_results { CURLcode curl_result; long http_code; @@ -118,6 +127,7 @@ extern char *get_remote_object_url(const char *url, const char *hex, /* Options for http_request_*() */ #define HTTP_NO_CACHE 1 +#define HTTP_KEEP_ERROR 2 /* Return values for http_request_*() */ #define HTTP_OK 0 @@ -134,12 +144,6 @@ extern char *get_remote_object_url(const char *url, const char *hex, */ int http_get_strbuf(const char *url, struct strbuf *content_type, struct strbuf *result, int options); -/* - * Prints an error message using error() containing url and curl_errorstr, - * and returns ret. - */ -int http_error(const char *url, int ret); - extern int http_fetch_ref(const char *base, struct ref *ref); /* Helpers for fetching packs */ diff --git a/log-tree.c b/log-tree.c index 3d88823871..1946e9ce8d 100644 --- a/log-tree.c +++ b/log-tree.c @@ -9,6 +9,7 @@ #include "string-list.h" #include "color.h" #include "gpg-interface.h" +#include "sequencer.h" struct decoration name_decoration = { "object names" }; @@ -174,119 +175,52 @@ static void show_children(struct rev_info *opt, struct commit *commit, int abbre } } -void show_decorations(struct rev_info *opt, struct commit *commit) +/* + * The caller makes sure there is no funny color before + * calling. format_decorations makes sure the same after return. + */ +void format_decorations(struct strbuf *sb, + const struct commit *commit, + int use_color) { const char *prefix; struct name_decoration *decoration; const char *color_commit = - diff_get_color_opt(&opt->diffopt, DIFF_COMMIT); + diff_get_color(use_color, DIFF_COMMIT); const char *color_reset = - decorate_get_color_opt(&opt->diffopt, DECORATION_NONE); + decorate_get_color(use_color, DECORATION_NONE); - if (opt->show_source && commit->util) - printf("\t%s", (char *) commit->util); - if (!opt->show_decorations) - return; decoration = lookup_decoration(&name_decoration, &commit->object); if (!decoration) return; prefix = " ("; while (decoration) { - printf("%s", prefix); - fputs(decorate_get_color_opt(&opt->diffopt, decoration->type), - stdout); + strbuf_addstr(sb, color_commit); + strbuf_addstr(sb, prefix); + strbuf_addstr(sb, decorate_get_color(use_color, decoration->type)); if (decoration->type == DECORATION_REF_TAG) - fputs("tag: ", stdout); - printf("%s", decoration->name); - fputs(color_reset, stdout); - fputs(color_commit, stdout); + strbuf_addstr(sb, "tag: "); + strbuf_addstr(sb, decoration->name); + strbuf_addstr(sb, color_reset); prefix = ", "; decoration = decoration->next; } - putchar(')'); -} - -/* - * Search for "^[-A-Za-z]+: [^@]+@" pattern. It usually matches - * Signed-off-by: and Acked-by: lines. - */ -static int detect_any_signoff(char *letter, int size) -{ - char *cp; - int seen_colon = 0; - int seen_at = 0; - int seen_name = 0; - int seen_head = 0; - - cp = letter + size; - while (letter <= --cp && *cp == '\n') - continue; - - while (letter <= cp) { - char ch = *cp--; - if (ch == '\n') - break; - - if (!seen_at) { - if (ch == '@') - seen_at = 1; - continue; - } - if (!seen_colon) { - if (ch == '@') - return 0; - else if (ch == ':') - seen_colon = 1; - else - seen_name = 1; - continue; - } - if (('A' <= ch && ch <= 'Z') || - ('a' <= ch && ch <= 'z') || - ch == '-') { - seen_head = 1; - continue; - } - /* no empty last line doesn't match */ - return 0; - } - return seen_head && seen_name; + strbuf_addstr(sb, color_commit); + strbuf_addch(sb, ')'); + strbuf_addstr(sb, color_reset); } -static void append_signoff(struct strbuf *sb, const char *signoff) +void show_decorations(struct rev_info *opt, struct commit *commit) { - static const char signed_off_by[] = "Signed-off-by: "; - size_t signoff_len = strlen(signoff); - int has_signoff = 0; - char *cp; + struct strbuf sb = STRBUF_INIT; - cp = sb->buf; - - /* First see if we already have the sign-off by the signer */ - while ((cp = strstr(cp, signed_off_by))) { - - has_signoff = 1; - - cp += strlen(signed_off_by); - if (cp + signoff_len >= sb->buf + sb->len) - break; - if (strncmp(cp, signoff, signoff_len)) - continue; - if (!isspace(cp[signoff_len])) - continue; - /* we already have him */ + if (opt->show_source && commit->util) + printf("\t%s", (char *) commit->util); + if (!opt->show_decorations) return; - } - - if (!has_signoff) - has_signoff = detect_any_signoff(sb->buf, sb->len); - - if (!has_signoff) - strbuf_addch(sb, '\n'); - - strbuf_addstr(sb, signed_off_by); - strbuf_add(sb, signoff, signoff_len); - strbuf_addch(sb, '\n'); + format_decorations(&sb, commit, opt->diffopt.use_color); + fputs(sb.buf, stdout); + strbuf_release(&sb); } static unsigned int digits_in_number(unsigned int number) @@ -622,8 +556,8 @@ void show_log(struct rev_info *opt) printf(" (from %s)", find_unique_abbrev(parent->object.sha1, abbrev_commit)); + fputs(diff_get_color_opt(&opt->diffopt, DIFF_RESET), stdout); show_decorations(opt, commit); - printf("%s", diff_get_color_opt(&opt->diffopt, DIFF_RESET)); if (opt->commit_format == CMIT_FMT_ONELINE) { putchar(' '); } else { @@ -669,8 +603,10 @@ void show_log(struct rev_info *opt) /* * And then the pretty-printed message itself */ - if (ctx.need_8bit_cte >= 0) - ctx.need_8bit_cte = has_non_ascii(opt->add_signoff); + if (ctx.need_8bit_cte >= 0 && opt->add_signoff) + ctx.need_8bit_cte = + has_non_ascii(fmt_name(getenv("GIT_COMMITTER_NAME"), + getenv("GIT_COMMITTER_EMAIL"))); ctx.date_mode = opt->date_mode; ctx.date_mode_explicit = opt->date_mode_explicit; ctx.abbrev = opt->diffopt.abbrev; @@ -683,7 +619,7 @@ void show_log(struct rev_info *opt) pretty_print_commit(&ctx, commit, &msgbuf); if (opt->add_signoff) - append_signoff(&msgbuf, opt->add_signoff); + append_signoff(&msgbuf, 0, APPEND_SIGNOFF_DEDUP); if ((ctx.fmt != CMIT_FMT_USERFORMAT) && ctx.notes_message && *ctx.notes_message) { @@ -789,11 +725,14 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log { int showed_log; struct commit_list *parents; - unsigned const char *sha1 = commit->object.sha1; + unsigned const char *sha1; if (!opt->diff && !DIFF_OPT_TST(&opt->diffopt, EXIT_WITH_STATUS)) return 0; + parse_commit(commit); + sha1 = commit->tree->object.sha1; + /* Root commit? */ parents = commit->parents; if (!parents) { @@ -816,7 +755,9 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log * parent, showing summary diff of the others * we merged _in_. */ - diff_tree_sha1(parents->item->object.sha1, sha1, "", &opt->diffopt); + parse_commit(parents->item); + diff_tree_sha1(parents->item->tree->object.sha1, + sha1, "", &opt->diffopt); log_tree_diff_flush(opt); return !opt->loginfo; } @@ -829,7 +770,9 @@ static int log_tree_diff(struct rev_info *opt, struct commit *commit, struct log for (;;) { struct commit *parent = parents->item; - diff_tree_sha1(parent->object.sha1, sha1, "", &opt->diffopt); + parse_commit(parent); + diff_tree_sha1(parent->tree->object.sha1, + sha1, "", &opt->diffopt); log_tree_diff_flush(opt); showed_log |= !opt->loginfo; diff --git a/log-tree.h b/log-tree.h index 9140f48216..d6ecd4dc46 100644 --- a/log-tree.h +++ b/log-tree.h @@ -13,6 +13,7 @@ int log_tree_diff_flush(struct rev_info *); int log_tree_commit(struct rev_info *, struct commit *); int log_tree_opt_parse(struct rev_info *, const char **, int); void show_log(struct rev_info *opt); +void format_decorations(struct strbuf *sb, const struct commit *commit, int use_color); void show_decorations(struct rev_info *opt, struct commit *commit); void log_write_email_headers(struct rev_info *opt, struct commit *commit, const char **subject_p, diff --git a/mergetools/kdiff3 b/mergetools/kdiff3 index 28fead428b..a30034f116 100644 --- a/mergetools/kdiff3 +++ b/mergetools/kdiff3 @@ -1,5 +1,5 @@ diff_cmd () { - "$merge_tool_path" --auto \ + "$merge_tool_path" \ --L1 "$MERGED (A)" --L2 "$MERGED (B)" \ "$LOCAL" "$REMOTE" >/dev/null 2>&1 } diff --git a/mergetools/p4merge b/mergetools/p4merge index 8a36916567..5a608abf9c 100644 --- a/mergetools/p4merge +++ b/mergetools/p4merge @@ -21,8 +21,12 @@ diff_cmd () { merge_cmd () { touch "$BACKUP" - $base_present || >"$BASE" - "$merge_tool_path" "$BASE" "$LOCAL" "$REMOTE" "$MERGED" + if ! $base_present + then + cp -- "$LOCAL" "$BASE" + create_virtual_base "$BASE" "$REMOTE" + fi + "$merge_tool_path" "$BASE" "$REMOTE" "$LOCAL" "$MERGED" check_unchanged } diff --git a/name-hash.c b/name-hash.c index 6d7e1980c6..617c86c537 100644 --- a/name-hash.c +++ b/name-hash.c @@ -150,6 +150,8 @@ static void lazy_init_name_hash(struct index_state *istate) if (istate->name_hash_initialized) return; + if (istate->cache_nr) + preallocate_hash(&istate->name_hash, istate->cache_nr); for (nr = 0; nr < istate->cache_nr; nr++) hash_index_entry(istate, istate->cache[nr]); istate->name_hash_initialized = 1; diff --git a/pack-refs.c b/pack-refs.c deleted file mode 100644 index 4461f71a37..0000000000 --- a/pack-refs.c +++ /dev/null @@ -1,148 +0,0 @@ -#include "cache.h" -#include "refs.h" -#include "tag.h" -#include "pack-refs.h" - -struct ref_to_prune { - struct ref_to_prune *next; - unsigned char sha1[20]; - char name[FLEX_ARRAY]; -}; - -struct pack_refs_cb_data { - unsigned int flags; - struct ref_to_prune *ref_to_prune; - FILE *refs_file; -}; - -static int do_not_prune(int flags) -{ - /* If it is already packed or if it is a symref, - * do not prune it. - */ - return (flags & (REF_ISSYMREF|REF_ISPACKED)); -} - -static int handle_one_ref(const char *path, const unsigned char *sha1, - int flags, void *cb_data) -{ - struct pack_refs_cb_data *cb = cb_data; - struct object *o; - int is_tag_ref; - - /* Do not pack the symbolic refs */ - if ((flags & REF_ISSYMREF)) - return 0; - is_tag_ref = !prefixcmp(path, "refs/tags/"); - - /* ALWAYS pack refs that were already packed or are tags */ - if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && !(flags & REF_ISPACKED)) - return 0; - - fprintf(cb->refs_file, "%s %s\n", sha1_to_hex(sha1), path); - - o = parse_object_or_die(sha1, path); - if (o->type == OBJ_TAG) { - o = deref_tag(o, path, 0); - if (o) - fprintf(cb->refs_file, "^%s\n", - sha1_to_hex(o->sha1)); - } - - if ((cb->flags & PACK_REFS_PRUNE) && !do_not_prune(flags)) { - int namelen = strlen(path) + 1; - struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen); - hashcpy(n->sha1, sha1); - strcpy(n->name, path); - n->next = cb->ref_to_prune; - cb->ref_to_prune = n; - } - return 0; -} - -/* - * Remove empty parents, but spare refs/ and immediate subdirs. - * Note: munges *name. - */ -static void try_remove_empty_parents(char *name) -{ - char *p, *q; - int i; - p = name; - for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */ - while (*p && *p != '/') - p++; - /* tolerate duplicate slashes; see check_refname_format() */ - while (*p == '/') - p++; - } - for (q = p; *q; q++) - ; - while (1) { - while (q > p && *q != '/') - q--; - while (q > p && *(q-1) == '/') - q--; - if (q == p) - break; - *q = '\0'; - if (rmdir(git_path("%s", name))) - break; - } -} - -/* make sure nobody touched the ref, and unlink */ -static void prune_ref(struct ref_to_prune *r) -{ - struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1); - - if (lock) { - unlink_or_warn(git_path("%s", r->name)); - unlock_ref(lock); - try_remove_empty_parents(r->name); - } -} - -static void prune_refs(struct ref_to_prune *r) -{ - while (r) { - prune_ref(r); - r = r->next; - } -} - -static struct lock_file packed; - -int pack_refs(unsigned int flags) -{ - int fd; - struct pack_refs_cb_data cbdata; - - memset(&cbdata, 0, sizeof(cbdata)); - cbdata.flags = flags; - - fd = hold_lock_file_for_update(&packed, git_path("packed-refs"), - LOCK_DIE_ON_ERROR); - cbdata.refs_file = fdopen(fd, "w"); - if (!cbdata.refs_file) - die_errno("unable to create ref-pack file structure"); - - /* perhaps other traits later as well */ - fprintf(cbdata.refs_file, "# pack-refs with: peeled fully-peeled \n"); - - for_each_ref(handle_one_ref, &cbdata); - if (ferror(cbdata.refs_file)) - die("failed to write ref-pack file"); - if (fflush(cbdata.refs_file) || fsync(fd) || fclose(cbdata.refs_file)) - die_errno("failed to write ref-pack file"); - /* - * Since the lock file was fdopen()'ed and then fclose()'ed above, - * assign -1 to the lock file descriptor so that commit_lock_file() - * won't try to close() it. - */ - packed.fd = -1; - if (commit_lock_file(&packed) < 0) - die_errno("unable to overwrite old ref-pack file"); - prune_refs(cbdata.ref_to_prune); - return 0; -} diff --git a/pack-refs.h b/pack-refs.h deleted file mode 100644 index 518acfb370..0000000000 --- a/pack-refs.h +++ /dev/null @@ -1,18 +0,0 @@ -#ifndef PACK_REFS_H -#define PACK_REFS_H - -/* - * Flags for controlling behaviour of pack_refs() - * PACK_REFS_PRUNE: Prune loose refs after packing - * PACK_REFS_ALL: Pack _all_ refs, not just tags and already packed refs - */ -#define PACK_REFS_PRUNE 0x0001 -#define PACK_REFS_ALL 0x0002 - -/* - * Write a packed-refs file for the current repository. - * flags: Combination of the above PACK_REFS_* flags. - */ -int pack_refs(unsigned int flags); - -#endif /* PACK_REFS_H */ diff --git a/parse-options-cb.c b/parse-options-cb.c index 0de5fb168a..be8c413cfe 100644 --- a/parse-options-cb.c +++ b/parse-options-cb.c @@ -33,6 +33,12 @@ int parse_opt_approxidate_cb(const struct option *opt, const char *arg, return 0; } +int parse_opt_expiry_date_cb(const struct option *opt, const char *arg, + int unset) +{ + return parse_expiry_date(arg, (unsigned long *)opt->value); +} + int parse_opt_color_flag_cb(const struct option *opt, const char *arg, int unset) { diff --git a/parse-options.h b/parse-options.h index 1c8bd8d5a0..c378b75b13 100644 --- a/parse-options.h +++ b/parse-options.h @@ -140,6 +140,9 @@ struct option { #define OPT_DATE(s, l, v, h) \ { OPTION_CALLBACK, (s), (l), (v), N_("time"),(h), 0, \ parse_opt_approxidate_cb } +#define OPT_EXPIRY_DATE(s, l, v, h) \ + { OPTION_CALLBACK, (s), (l), (v), N_("expiry date"),(h), 0, \ + parse_opt_expiry_date_cb } #define OPT_CALLBACK(s, l, v, a, h, f) \ { OPTION_CALLBACK, (s), (l), (v), (a), (h), 0, (f) } #define OPT_NUMBER_CALLBACK(v, h, f) \ @@ -219,6 +222,7 @@ extern int parse_options_concat(struct option *dst, size_t, struct option *src); /*----- some often used options -----*/ extern int parse_opt_abbrev_cb(const struct option *, const char *, int); extern int parse_opt_approxidate_cb(const struct option *, const char *, int); +extern int parse_opt_expiry_date_cb(const struct option *, const char *, int); extern int parse_opt_color_flag_cb(const struct option *, const char *, int); extern int parse_opt_verbosity_cb(const struct option *, const char *, int); extern int parse_opt_with_commit(const struct option *, const char *, int); @@ -1,19 +1,26 @@ /* - * I'm tired of doing "vsnprintf()" etc just to open a - * file, so here's a "return static buffer with printf" - * interface for paths. - * - * It's obviously not thread-safe. Sue me. But it's quite - * useful for doing things like - * - * f = open(mkpath("%s/%s.git", base, name), O_RDONLY); - * - * which is what it's designed for. + * Utilities for paths and pathnames */ #include "cache.h" #include "strbuf.h" #include "string-list.h" +#ifndef get_st_mode_bits +/* + * The replacement lstat(2) we use on Cygwin is incomplete and + * may return wrong permission bits. Most of the time we do not care, + * but the callsites of this wrapper do care. + */ +int get_st_mode_bits(const char *path, int *mode) +{ + struct stat st; + if (lstat(path, &st) < 0) + return -1; + *mode = st.st_mode; + return 0; +} +#endif + static char bad_path[] = "/bad-path/"; static char *get_pathname(void) @@ -389,28 +396,14 @@ const char *enter_repo(const char *path, int strict) return NULL; } -int set_shared_perm(const char *path, int mode) +static int calc_shared_perm(int mode) { - struct stat st; - int tweak, shared, orig_mode; + int tweak; - if (!shared_repository) { - if (mode) - return chmod(path, mode & ~S_IFMT); - return 0; - } - if (!mode) { - if (lstat(path, &st) < 0) - return -1; - mode = st.st_mode; - orig_mode = mode; - } else - orig_mode = 0; if (shared_repository < 0) - shared = -shared_repository; + tweak = -shared_repository; else - shared = shared_repository; - tweak = shared; + tweak = shared_repository; if (!(mode & S_IWUSR)) tweak &= ~0222; @@ -422,16 +415,28 @@ int set_shared_perm(const char *path, int mode) else mode |= tweak; - if (S_ISDIR(mode)) { + return mode; +} + + +int adjust_shared_perm(const char *path) +{ + int old_mode, new_mode; + + if (!shared_repository) + return 0; + if (get_st_mode_bits(path, &old_mode) < 0) + return -1; + + new_mode = calc_shared_perm(old_mode); + if (S_ISDIR(old_mode)) { /* Copy read bits to execute bits */ - mode |= (shared & 0444) >> 2; - mode |= FORCE_DIR_SET_GID; + new_mode |= (new_mode & 0444) >> 2; + new_mode |= FORCE_DIR_SET_GID; } - if (((shared_repository < 0 - ? (orig_mode & (FORCE_DIR_SET_GID | 0777)) - : (orig_mode & mode)) != mode) && - chmod(path, (mode & ~S_IFMT)) < 0) + if (((old_mode ^ new_mode) & ~S_IFMT) && + chmod(path, (new_mode & ~S_IFMT)) < 0) return -2; return 0; } diff --git a/perl/Git.pm b/perl/Git.pm index a69467feaa..7a252ef872 100644 --- a/perl/Git.pm +++ b/perl/Git.pm @@ -60,6 +60,7 @@ require Exporter; version exec_path html_path hash_object git_cmd_try remote_refs prompt get_tz_offset + credential credential_read credential_write temp_acquire temp_release temp_reset temp_path); @@ -269,13 +270,13 @@ sub command { if (not defined wantarray) { # Nothing to pepper the possible exception with. - _cmd_close($fh, $ctx); + _cmd_close($ctx, $fh); } elsif (not wantarray) { local $/; my $text = <$fh>; try { - _cmd_close($fh, $ctx); + _cmd_close($ctx, $fh); } catch Git::Error::Command with { # Pepper with the output: my $E = shift; @@ -288,7 +289,7 @@ sub command { my @lines = <$fh>; defined and chomp for @lines; try { - _cmd_close($fh, $ctx); + _cmd_close($ctx, $fh); } catch Git::Error::Command with { my $E = shift; $E->{'-outputref'} = \@lines; @@ -315,7 +316,7 @@ sub command_oneline { my $line = <$fh>; defined $line and chomp $line; try { - _cmd_close($fh, $ctx); + _cmd_close($ctx, $fh); } catch Git::Error::Command with { # Pepper with the output: my $E = shift; @@ -383,7 +384,7 @@ have more complicated structure. sub command_close_pipe { my ($self, $fh, $ctx) = _maybe_self(@_); $ctx ||= '<unknown>'; - _cmd_close($fh, $ctx); + _cmd_close($ctx, $fh); } =item command_bidi_pipe ( COMMAND [, ARGUMENTS... ] ) @@ -420,7 +421,7 @@ and it is the fourth value returned by C<command_bidi_pipe()>. The call idiom is: my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check'); - print "000000000\n" $out; + print $out "000000000\n"; while (<$in>) { ... } $r->command_close_bidi_pipe($pid, $in, $out, $ctx); @@ -428,23 +429,26 @@ Note that you should not rely on whatever actually is in C<CTX>; currently it is simply the command name but in future the context might have more complicated structure. +C<PIPE_IN> and C<PIPE_OUT> may be C<undef> if they have been closed prior to +calling this function. This may be useful in a query-response type of +commands where caller first writes a query and later reads response, eg: + + my ($pid, $in, $out, $ctx) = $r->command_bidi_pipe('cat-file --batch-check'); + print $out "000000000\n"; + close $out; + while (<$in>) { ... } + $r->command_close_bidi_pipe($pid, $in, undef, $ctx); + +This idiom may prevent potential dead locks caused by data sent to the output +pipe not being flushed and thus not reaching the executed command. + =cut sub command_close_bidi_pipe { local $?; - my ($pid, $in, $out, $ctx) = @_; - foreach my $fh ($in, $out) { - unless (close $fh) { - if ($!) { - carp "error closing pipe: $!"; - } elsif ($? >> 8) { - throw Git::Error::Command($ctx, $? >>8); - } - } - } - + my ($self, $pid, $in, $out, $ctx) = _maybe_self(@_); + _cmd_close($ctx, (grep { defined } ($in, $out))); waitpid $pid, 0; - if ($? >> 8) { throw Git::Error::Command($ctx, $? >>8); } @@ -1020,6 +1024,156 @@ sub _close_cat_blob { } +=item credential_read( FILEHANDLE ) + +Reads credential key-value pairs from C<FILEHANDLE>. Reading stops at EOF or +when an empty line is encountered. Each line must be of the form C<key=value> +with a non-empty key. Function returns hash with all read values. Any white +space (other than new-line character) is preserved. + +=cut + +sub credential_read { + my ($self, $reader) = _maybe_self(@_); + my %credential; + while (<$reader>) { + chomp; + if ($_ eq '') { + last; + } elsif (!/^([^=]+)=(.*)$/) { + throw Error::Simple("unable to parse git credential data:\n$_"); + } + $credential{$1} = $2; + } + return %credential; +} + +=item credential_write( FILEHANDLE, CREDENTIAL_HASHREF ) + +Writes credential key-value pairs from hash referenced by +C<CREDENTIAL_HASHREF> to C<FILEHANDLE>. Keys and values cannot contain +new-lines or NUL bytes characters, and key cannot contain equal signs nor be +empty (if they do Error::Simple is thrown). Any white space is preserved. If +value for a key is C<undef>, it will be skipped. + +If C<'url'> key exists it will be written first. (All the other key-value +pairs are written in sorted order but you should not depend on that). Once +all lines are written, an empty line is printed. + +=cut + +sub credential_write { + my ($self, $writer, $credential) = _maybe_self(@_); + my ($key, $value); + + # Check if $credential is valid prior to writing anything + while (($key, $value) = each %$credential) { + if (!defined $key || !length $key) { + throw Error::Simple("credential key empty or undefined"); + } elsif ($key =~ /[=\n\0]/) { + throw Error::Simple("credential key contains invalid characters: $key"); + } elsif (defined $value && $value =~ /[\n\0]/) { + throw Error::Simple("credential value for key=$key contains invalid characters: $value"); + } + } + + for $key (sort { + # url overwrites other fields, so it must come first + return -1 if $a eq 'url'; + return 1 if $b eq 'url'; + return $a cmp $b; + } keys %$credential) { + if (defined $credential->{$key}) { + print $writer $key, '=', $credential->{$key}, "\n"; + } + } + print $writer "\n"; +} + +sub _credential_run { + my ($self, $credential, $op) = _maybe_self(@_); + my ($pid, $reader, $writer, $ctx) = command_bidi_pipe('credential', $op); + + credential_write $writer, $credential; + close $writer; + + if ($op eq "fill") { + %$credential = credential_read $reader; + } + if (<$reader>) { + throw Error::Simple("unexpected output from git credential $op response:\n$_\n"); + } + + command_close_bidi_pipe($pid, $reader, undef, $ctx); +} + +=item credential( CREDENTIAL_HASHREF [, OPERATION ] ) + +=item credential( CREDENTIAL_HASHREF, CODE ) + +Executes C<git credential> for a given set of credentials and specified +operation. In both forms C<CREDENTIAL_HASHREF> needs to be a reference to +a hash which stores credentials. Under certain conditions the hash can +change. + +In the first form, C<OPERATION> can be C<'fill'>, C<'approve'> or C<'reject'>, +and function will execute corresponding C<git credential> sub-command. If +it's omitted C<'fill'> is assumed. In case of C<'fill'> the values stored in +C<CREDENTIAL_HASHREF> will be changed to the ones returned by the C<git +credential fill> command. The usual usage would look something like: + + my %cred = ( + 'protocol' => 'https', + 'host' => 'example.com', + 'username' => 'bob' + ); + Git::credential \%cred; + if (try_to_authenticate($cred{'username'}, $cred{'password'})) { + Git::credential \%cred, 'approve'; + ... do more stuff ... + } else { + Git::credential \%cred, 'reject'; + } + +In the second form, C<CODE> needs to be a reference to a subroutine. The +function will execute C<git credential fill> to fill the provided credential +hash, then call C<CODE> with C<CREDENTIAL_HASHREF> as the sole argument. If +C<CODE>'s return value is defined, the function will execute C<git credential +approve> (if return value yields true) or C<git credential reject> (if return +value is false). If the return value is undef, nothing at all is executed; +this is useful, for example, if the credential could neither be verified nor +rejected due to an unrelated network error. The return value is the same as +what C<CODE> returns. With this form, the usage might look as follows: + + if (Git::credential { + 'protocol' => 'https', + 'host' => 'example.com', + 'username' => 'bob' + }, sub { + my $cred = shift; + return !!try_to_authenticate($cred->{'username'}, + $cred->{'password'}); + }) { + ... do more stuff ... + } + +=cut + +sub credential { + my ($self, $credential, $op_or_code) = (_maybe_self(@_), 'fill'); + + if ('CODE' eq ref $op_or_code) { + _credential_run $credential, 'fill'; + my $ret = $op_or_code->($credential); + if (defined $ret) { + _credential_run $credential, $ret ? 'approve' : 'reject'; + } + return $ret; + } else { + _credential_run $credential, $op_or_code; + } +} + { # %TEMP_* Lexical Context my (%TEMP_FILEMAP, %TEMP_FILES); @@ -1111,7 +1265,7 @@ sub _temp_cache { $tmpdir = $self->repo_path(); } - ($$temp_fd, $fname) = File::Temp->tempfile( + ($$temp_fd, $fname) = File::Temp::tempfile( 'Git_XXXXXX', UNLINK => 1, DIR => $tmpdir, ) or throw Error::Simple("couldn't open new temp file"); @@ -1375,9 +1529,11 @@ sub _execv_git_cmd { exec('git', @_); } # Close pipe to a subprocess. sub _cmd_close { - my ($fh, $ctx) = @_; - if (not close $fh) { - if ($!) { + my $ctx = shift @_; + foreach my $fh (@_) { + if (close $fh) { + # nop + } elsif ($!) { # It's just close, no point in fatalities carp "error closing pipe: $!"; } elsif ($? >> 8) { diff --git a/perl/Git/SVN/Editor.pm b/perl/Git/SVN/Editor.pm index fa0d3c6cdd..b3bcd476da 100644 --- a/perl/Git/SVN/Editor.pm +++ b/perl/Git/SVN/Editor.pm @@ -499,6 +499,8 @@ sub apply_diff { 1; __END__ +=head1 NAME + Git::SVN::Editor - commit driver for "git svn set-tree" and dcommit =head1 SYNOPSIS diff --git a/perl/Git/SVN/Fetcher.pm b/perl/Git/SVN/Fetcher.pm index 046a7a2f31..bd174189b9 100644 --- a/perl/Git/SVN/Fetcher.pm +++ b/perl/Git/SVN/Fetcher.pm @@ -1,6 +1,7 @@ package Git::SVN::Fetcher; -use vars qw/@ISA $_ignore_regex $_preserve_empty_dirs $_placeholder_filename - @deleted_gpath %added_placeholder $repo_id/; +use vars qw/@ISA $_ignore_regex $_include_regex $_preserve_empty_dirs + $_placeholder_filename @deleted_gpath %added_placeholder + $repo_id/; use strict; use warnings; use SVN::Delta; @@ -33,6 +34,10 @@ sub new { my $v = eval { command_oneline('config', '--get', $k) }; $self->{ignore_regex} = $v; + $k = "svn-remote.$repo_id.include-paths"; + $v = eval { command_oneline('config', '--get', $k) }; + $self->{include_regex} = $v; + $k = "svn-remote.$repo_id.preserve-empty-dirs"; $v = eval { command_oneline('config', '--get', '--bool', $k) }; if ($v && $v eq 'true') { @@ -117,11 +122,18 @@ sub in_dot_git { } # return value: 0 -- don't ignore, 1 -- ignore +# This will also check whether the path is explicitly included sub is_path_ignored { my ($self, $path) = @_; return 1 if in_dot_git($path); return 1 if defined($self->{ignore_regex}) && $path =~ m!$self->{ignore_regex}!; + return 0 if defined($self->{include_regex}) && + $path =~ m!$self->{include_regex}!; + return 0 if defined($_include_regex) && + $path =~ m!$_include_regex!; + return 1 if defined($self->{include_regex}); + return 1 if defined($_include_regex); return 0 unless defined($_ignore_regex); return 1 if $path =~ m!$_ignore_regex!o; return 0; @@ -512,6 +524,8 @@ sub stash_placeholder_list { 1; __END__ +=head1 NAME + Git::SVN::Fetcher - tree delta consumer for "git svn fetch" =head1 SYNOPSIS diff --git a/perl/Git/SVN/Prompt.pm b/perl/Git/SVN/Prompt.pm index 74daa7a597..e940b08505 100644 --- a/perl/Git/SVN/Prompt.pm +++ b/perl/Git/SVN/Prompt.pm @@ -125,6 +125,8 @@ sub _read_password { 1; __END__ +=head1 NAME + Git::SVN::Prompt - authentication callbacks for git-svn =head1 SYNOPSIS diff --git a/perl/Git/SVN/Ra.pm b/perl/Git/SVN/Ra.pm index 049c97bfaf..75ecc425b6 100644 --- a/perl/Git/SVN/Ra.pm +++ b/perl/Git/SVN/Ra.pm @@ -295,7 +295,7 @@ sub gs_do_switch { my $full_url = add_path_to_url( $self->url, $path ); my ($ra, $reparented); - if ($old_url =~ m#^svn(\+ssh)?://# || + if ($old_url =~ m#^svn(\+\w+)?://# || ($full_url =~ m#^https?://# && canonicalize_url($full_url) ne $full_url)) { $_[0] = undef; @@ -627,6 +627,8 @@ sub skip_unknown_revs { 1; __END__ +=head1 NAME + Git::SVN::Ra - Subversion remote access functions for git-svn =head1 SYNOPSIS diff --git a/pkt-line.c b/pkt-line.c index eaba15f124..70f19501d0 100644 --- a/pkt-line.c +++ b/pkt-line.c @@ -1,6 +1,7 @@ #include "cache.h" #include "pkt-line.h" +char packet_buffer[LARGE_PACKET_MAX]; static const char *packet_trace_prefix = "git"; static const char trace_key[] = "GIT_TRACE_PACKET"; @@ -47,45 +48,13 @@ static void packet_trace(const char *buf, unsigned int len, int write) } /* - * Write a packetized stream, where each line is preceded by - * its length (including the header) as a 4-byte hex number. - * A length of 'zero' means end of stream (and a length of 1-3 - * would be an error). - * - * This is all pretty stupid, but we use this packetized line - * format to make a streaming format possible without ever - * over-running the read buffers. That way we'll never read - * into what might be the pack data (which should go to another - * process entirely). - * - * The writing side could use stdio, but since the reading - * side can't, we stay with pure read/write interfaces. - */ -ssize_t safe_write(int fd, const void *buf, ssize_t n) -{ - ssize_t nn = n; - while (n) { - int ret = xwrite(fd, buf, n); - if (ret > 0) { - buf = (char *) buf + ret; - n -= ret; - continue; - } - if (!ret) - die("write error (disk full?)"); - die_errno("write error"); - } - return nn; -} - -/* * If we buffered things up above (we don't, but we should), * we'd flush it here */ void packet_flush(int fd) { packet_trace("0000", 4, 1); - safe_write(fd, "0000", 4); + write_or_die(fd, "0000", 4); } void packet_buf_flush(struct strbuf *buf) @@ -121,7 +90,7 @@ void packet_write(int fd, const char *fmt, ...) va_start(args, fmt); n = format_packet(fmt, args); va_end(args); - safe_write(fd, buffer, n); + write_or_die(fd, buffer, n); } void packet_buf_write(struct strbuf *buf, const char *fmt, ...) @@ -135,13 +104,29 @@ void packet_buf_write(struct strbuf *buf, const char *fmt, ...) strbuf_add(buf, buffer, n); } -static int safe_read(int fd, void *buffer, unsigned size, int return_line_fail) +static int get_packet_data(int fd, char **src_buf, size_t *src_size, + void *dst, unsigned size, int options) { - ssize_t ret = read_in_full(fd, buffer, size); - if (ret < 0) - die_errno("read error"); - else if (ret < size) { - if (return_line_fail) + ssize_t ret; + + if (fd >= 0 && src_buf && *src_buf) + die("BUG: multiple sources given to packet_read"); + + /* Read up to "size" bytes from our source, whatever it is. */ + if (src_buf && *src_buf) { + ret = size < *src_size ? size : *src_size; + memcpy(dst, *src_buf, ret); + *src_buf += ret; + *src_size -= ret; + } else { + ret = read_in_full(fd, dst, size); + if (ret < 0) + die_errno("read error"); + } + + /* And complain if we didn't get enough bytes to satisfy the read. */ + if (ret < size) { + if (options & PACKET_READ_GENTLE_ON_EOF) return -1; die("The remote end hung up unexpectedly"); @@ -175,13 +160,14 @@ static int packet_length(const char *linelen) return len; } -static int packet_read_internal(int fd, char *buffer, unsigned size, int return_line_fail) +int packet_read(int fd, char **src_buf, size_t *src_len, + char *buffer, unsigned size, int options) { int len, ret; char linelen[4]; - ret = safe_read(fd, linelen, 4, return_line_fail); - if (return_line_fail && ret < 0) + ret = get_packet_data(fd, src_buf, src_len, linelen, 4, options); + if (ret < 0) return ret; len = packet_length(linelen); if (len < 0) @@ -193,50 +179,37 @@ static int packet_read_internal(int fd, char *buffer, unsigned size, int return_ len -= 4; if (len >= size) die("protocol error: bad line length %d", len); - ret = safe_read(fd, buffer, len, return_line_fail); - if (return_line_fail && ret < 0) + ret = get_packet_data(fd, src_buf, src_len, buffer, len, options); + if (ret < 0) return ret; + + if ((options & PACKET_READ_CHOMP_NEWLINE) && + len && buffer[len-1] == '\n') + len--; + buffer[len] = 0; packet_trace(buffer, len, 0); return len; } -int packet_read(int fd, char *buffer, unsigned size) +static char *packet_read_line_generic(int fd, + char **src, size_t *src_len, + int *dst_len) { - return packet_read_internal(fd, buffer, size, 1); + int len = packet_read(fd, src, src_len, + packet_buffer, sizeof(packet_buffer), + PACKET_READ_CHOMP_NEWLINE); + if (dst_len) + *dst_len = len; + return len ? packet_buffer : NULL; } -int packet_read_line(int fd, char *buffer, unsigned size) +char *packet_read_line(int fd, int *len_p) { - return packet_read_internal(fd, buffer, size, 0); + return packet_read_line_generic(fd, NULL, NULL, len_p); } -int packet_get_line(struct strbuf *out, - char **src_buf, size_t *src_len) +char *packet_read_line_buf(char **src, size_t *src_len, int *dst_len) { - int len; - - if (*src_len < 4) - return -1; - len = packet_length(*src_buf); - if (len < 0) - return -1; - if (!len) { - *src_buf += 4; - *src_len -= 4; - packet_trace("0000", 4, 0); - return 0; - } - if (*src_len < len) - return -2; - - *src_buf += 4; - *src_len -= 4; - len -= 4; - - strbuf_add(out, *src_buf, len); - *src_buf += len; - *src_len -= len; - packet_trace(out->buf, out->len, 0); - return len; + return packet_read_line_generic(-1, src, src_len, dst_len); } diff --git a/pkt-line.h b/pkt-line.h index 8cfeb0c31c..0a838d1656 100644 --- a/pkt-line.h +++ b/pkt-line.h @@ -5,16 +5,78 @@ #include "strbuf.h" /* - * Silly packetized line writing interface + * Write a packetized stream, where each line is preceded by + * its length (including the header) as a 4-byte hex number. + * A length of 'zero' means end of stream (and a length of 1-3 + * would be an error). + * + * This is all pretty stupid, but we use this packetized line + * format to make a streaming format possible without ever + * over-running the read buffers. That way we'll never read + * into what might be the pack data (which should go to another + * process entirely). + * + * The writing side could use stdio, but since the reading + * side can't, we stay with pure read/write interfaces. */ void packet_flush(int fd); void packet_write(int fd, const char *fmt, ...) __attribute__((format (printf, 2, 3))); void packet_buf_flush(struct strbuf *buf); void packet_buf_write(struct strbuf *buf, const char *fmt, ...) __attribute__((format (printf, 2, 3))); -int packet_read_line(int fd, char *buffer, unsigned size); -int packet_read(int fd, char *buffer, unsigned size); -int packet_get_line(struct strbuf *out, char **src_buf, size_t *src_len); -ssize_t safe_write(int, const void *, ssize_t); +/* + * Read a packetized line into the buffer, which must be at least size bytes + * long. The return value specifies the number of bytes read into the buffer. + * + * If src_buffer is not NULL (and nor is *src_buffer), it should point to a + * buffer containing the packet data to parse, of at least *src_len bytes. + * After the function returns, src_buf will be incremented and src_len + * decremented by the number of bytes consumed. + * + * If src_buffer (or *src_buffer) is NULL, then data is read from the + * descriptor "fd". + * + * If options does not contain PACKET_READ_GENTLE_ON_EOF, we will die under any + * of the following conditions: + * + * 1. Read error from descriptor. + * + * 2. Protocol error from the remote (e.g., bogus length characters). + * + * 3. Receiving a packet larger than "size" bytes. + * + * 4. Truncated output from the remote (e.g., we expected a packet but got + * EOF, or we got a partial packet followed by EOF). + * + * If options does contain PACKET_READ_GENTLE_ON_EOF, we will not die on + * condition 4 (truncated input), but instead return -1. However, we will still + * die for the other 3 conditions. + * + * If options contains PACKET_READ_CHOMP_NEWLINE, a trailing newline (if + * present) is removed from the buffer before returning. + */ +#define PACKET_READ_GENTLE_ON_EOF (1u<<0) +#define PACKET_READ_CHOMP_NEWLINE (1u<<1) +int packet_read(int fd, char **src_buffer, size_t *src_len, char + *buffer, unsigned size, int options); + +/* + * Convenience wrapper for packet_read that is not gentle, and sets the + * CHOMP_NEWLINE option. The return value is NULL for a flush packet, + * and otherwise points to a static buffer (that may be overwritten by + * subsequent calls). If the size parameter is not NULL, the length of the + * packet is written to it. + */ +char *packet_read_line(int fd, int *size); + +/* + * Same as packet_read_line, but read from a buf rather than a descriptor; + * see packet_read for details on how src_* is used. + */ +char *packet_read_line_buf(char **src_buf, size_t *src_len, int *size); + +#define DEFAULT_PACKET_MAX 1000 +#define LARGE_PACKET_MAX 65520 +extern char packet_buffer[LARGE_PACKET_MAX]; #endif @@ -5,9 +5,9 @@ # msgid "" msgstr "" -"Project-Id-Version: git 1.8.2\n" +"Project-Id-Version: git 1.8.3\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2013-03-05 12:36+0800\n" +"POT-Creation-Date: 2013-04-30 08:25+0800\n" "PO-Revision-Date: 2012-10-02 19:35+0200\n" "Last-Translator: Ralf Thielow <ralf.thielow@gmail.com>\n" "Language-Team: German <>\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n!=1);\n" -#: advice.c:49 +#: advice.c:53 #, c-format msgid "hint: %.*s\n" msgstr "Hinweis: %.*s\n" @@ -26,7 +26,7 @@ msgstr "Hinweis: %.*s\n" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:79 +#: advice.c:83 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm <file>' as\n" @@ -65,7 +65,7 @@ msgstr "Format" msgid "archive format" msgstr "Ausgabeformat" -#: archive.c:324 builtin/log.c:1115 +#: archive.c:324 builtin/log.c:1126 msgid "prefix" msgstr "Prefix" @@ -73,15 +73,15 @@ msgstr "Prefix" msgid "prepend prefix to each pathname in the archive" msgstr "stellt einen Präfix vor jeden Pfadnamen in der Ausgabe" -#: archive.c:326 builtin/archive.c:91 builtin/blame.c:2366 -#: builtin/blame.c:2367 builtin/config.c:55 builtin/fast-export.c:653 -#: builtin/fast-export.c:655 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:497 builtin/ls-files.c:500 builtin/notes.c:536 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 +#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 +#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 #: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 msgid "file" msgstr "Datei" -#: archive.c:327 builtin/archive.c:92 +#: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" msgstr "schreibt die Ausgabe in diese Datei" @@ -109,19 +109,19 @@ msgstr "besser komprimieren" msgid "list supported archive formats" msgstr "listet unterstützte Ausgabeformate auf" -#: archive.c:345 builtin/archive.c:93 builtin/clone.c:85 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 msgid "repo" msgstr "Projektarchiv" -#: archive.c:346 builtin/archive.c:94 +#: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository <repo>" msgstr "ruft das Archiv von externem Projektarchiv <Projektarchiv> ab" -#: archive.c:347 builtin/archive.c:95 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 msgid "command" msgstr "Programm" -#: archive.c:348 builtin/archive.c:96 +#: archive.c:348 builtin/archive.c:93 msgid "path to the remote git-upload-archive command" msgstr "Pfad zum externen \"git-upload-archive\"-Programm" @@ -133,6 +133,134 @@ msgstr "" "Verneinende Muster werden in Git-Attributen ignoriert.\n" "Benutzen Sie '\\!' für führende Ausrufezeichen." +#: branch.c:60 +#, c-format +msgid "Not setting branch %s as its own upstream." +msgstr "Zweig %s kann nicht sein eigener Ãœbernahmezweig sein." + +#: branch.c:82 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s by rebasing." +msgstr "Zweig %s konfiguriert zum Folgen von externem Zweig %s von %s durch " +"Neuaufbau." + +#: branch.c:83 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s." +msgstr "Zweig %s konfiguriert zum Folgen von externem Zweig %s von %s." + +#: branch.c:87 +#, c-format +msgid "Branch %s set up to track local branch %s by rebasing." +msgstr "Zweig %s konfiguriert zum Folgen von lokalem Zweig %s durch Neuaufbau." + +#: branch.c:88 +#, c-format +msgid "Branch %s set up to track local branch %s." +msgstr "Zweig %s konfiguriert zum Folgen von lokalem Zweig %s." + +#: branch.c:92 +#, c-format +msgid "Branch %s set up to track remote ref %s by rebasing." +msgstr "Zweig %s konfiguriert zum Folgen von externer Referenz %s durch " +"Neuaufbau." + +#: branch.c:93 +#, c-format +msgid "Branch %s set up to track remote ref %s." +msgstr "Zweig %s konfiguriert zum Folgen von externer Referenz %s." + +#: branch.c:97 +#, c-format +msgid "Branch %s set up to track local ref %s by rebasing." +msgstr "Zweig %s konfiguriert zum Folgen von lokaler Referenz %s durch " +"Neuaufbau." + +#: branch.c:98 +#, c-format +msgid "Branch %s set up to track local ref %s." +msgstr "Zweig %s konfiguriert zum Folgen von lokaler Referenz %s." + +#: branch.c:118 +#, c-format +msgid "Tracking not set up: name too long: %s" +msgstr "Konfiguration zum Folgen von Zweig nicht eingerichtet. Name zu lang: %s" + +#: branch.c:137 +#, c-format +msgid "Not tracking: ambiguous information for ref %s" +msgstr "Konfiguration zum Folgen von Zweig nicht eingerichtet. Referenz %s ist mehrdeutig." + +#: branch.c:182 +#, c-format +msgid "'%s' is not a valid branch name." +msgstr "'%s' ist kein gültiger Zweigname." + +#: branch.c:187 +#, c-format +msgid "A branch named '%s' already exists." +msgstr "Zweig '%s' existiert bereits." + +#: branch.c:195 +msgid "Cannot force update the current branch." +msgstr "Kann Aktualisierung des aktuellen Zweiges nicht erzwingen." + +#: branch.c:201 +#, c-format +msgid "Cannot setup tracking information; starting point '%s' is not a branch." +msgstr "" +"Kann Informationen zum Ãœbernahmezweig nicht einrichten; Startpunkt '%s' ist " +"kein Zweig." + +#: branch.c:203 +#, c-format +msgid "the requested upstream branch '%s' does not exist" +msgstr "der angeforderte externe Ãœbernahmezweig '%s' existiert nicht" + +#: branch.c:205 +msgid "" +"\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push." +msgstr "" +"\n" +"Falls Sie vorhaben, Ihre Arbeit auf einem bereits existierenden,\n" +"externen Ãœbernahmezweig aufzubauen, sollten Sie \"git fetch\"\n" +"ausführen, um diesen abzurufen.\n" +"\n" +"Falls Sie vorhaben, einen neuen lokalen Zweig zu versenden\n" +"der seinem externen Gegenstück folgen soll, können Sie\n" +"\"git push -u\" verwenden, um den externen Ãœbernahmezweig\n" +"beim Versand zu konfigurieren." + +#: branch.c:250 +#, c-format +msgid "Not a valid object name: '%s'." +msgstr "Ungültiger Objekt-Name: '%s'" + +#: branch.c:270 +#, c-format +msgid "Ambiguous object name: '%s'." +msgstr "mehrdeutiger Objekt-Name: '%s'" + +#: branch.c:275 +#, c-format +msgid "Not a valid branch point: '%s'." +msgstr "Ungültiger Verzweigungspunkt: '%s'" + +#: branch.c:281 +msgid "Failed to lock ref for update" +msgstr "Fehler beim Sperren der Referenz zur Aktualisierung." + +#: branch.c:299 +msgid "Failed to write ref" +msgstr "Fehler beim Schreiben der Referenz." + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -143,7 +271,7 @@ msgstr "'%s' sieht nicht wie eine v2 Paketdatei aus" msgid "unrecognized header: %s%s (%d)" msgstr "nicht erkannter Kopfbereich: %s%s (%d)" -#: bundle.c:89 builtin/commit.c:674 +#: bundle.c:89 builtin/commit.c:676 #, c-format msgid "could not open '%s'" msgstr "Konnte '%s' nicht öffnen" @@ -152,35 +280,35 @@ msgstr "Konnte '%s' nicht öffnen" msgid "Repository lacks these prerequisite commits:" msgstr "Dem Projektarchiv fehlen folgende vorausgesetzte Versionen:" -#: bundle.c:164 sequencer.c:566 sequencer.c:998 builtin/log.c:299 -#: builtin/log.c:751 builtin/log.c:1358 builtin/log.c:1574 builtin/merge.c:347 -#: builtin/shortlog.c:157 +#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 +#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 +#: builtin/shortlog.c:155 msgid "revision walk setup failed" msgstr "Einrichtung des Revisionsgangs fehlgeschlagen" #: bundle.c:186 #, c-format -msgid "The bundle contains %d ref" -msgid_plural "The bundle contains %d refs" -msgstr[0] "Das Paket enthält %d Referenz" -msgstr[1] "Das Paket enthält %d Referenzen" +msgid "The bundle contains this ref:" +msgid_plural "The bundle contains these %d refs:" +msgstr[0] "Das Paket enthält diese Referenz:" +msgstr[1] "Das Paket enthält diese %d Referenzen:" -#: bundle.c:192 +#: bundle.c:193 msgid "The bundle records a complete history." msgstr "Das Paket speichert eine komplette Historie." #: bundle.c:195 #, c-format -msgid "The bundle requires this ref" -msgid_plural "The bundle requires these %d refs" -msgstr[0] "Das Paket benötigt diese Referenz" -msgstr[1] "Das Paket benötigt diese %d Referenzen" +msgid "The bundle requires this ref:" +msgid_plural "The bundle requires these %d refs:" +msgstr[0] "Das Paket benötigt diese Referenz:" +msgstr[1] "Das Paket benötigt diese %d Referenzen:" #: bundle.c:294 msgid "rev-list died" msgstr "\"rev-list\" abgebrochen" -#: bundle.c:300 builtin/log.c:1254 builtin/shortlog.c:260 +#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 #, c-format msgid "unrecognized argument: %s" msgstr "nicht erkanntes Argument: %s" @@ -331,7 +459,7 @@ msgstr "" "Fehler in 'diff.dirstat' Konfigurationsvariable gefunden:\n" "%s" -#: diff.c:3468 +#: diff.c:3481 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -340,12 +468,12 @@ msgstr "" "Fehler beim Parsen des --dirstat/-X Optionsparameters:\n" "%s" -#: diff.c:3482 +#: diff.c:3495 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Fehler beim Parsen des --submodule Optionsparameters: '%s'" -#: gpg-interface.c:59 gpg-interface.c:127 +#: gpg-interface.c:59 gpg-interface.c:131 msgid "could not run gpg." msgstr "konnte gpg nicht ausführen" @@ -357,27 +485,27 @@ msgstr "gpg hat die Daten nicht akzeptiert" msgid "gpg failed to sign the data" msgstr "gpg beim Signieren der Daten fehlgeschlagen" -#: gpg-interface.c:112 +#: gpg-interface.c:115 #, c-format msgid "could not create temporary file '%s': %s" msgstr "konnte temporäre Datei '%s' nicht erstellen: %s" -#: gpg-interface.c:115 +#: gpg-interface.c:118 #, c-format msgid "failed writing detached signature to '%s': %s" msgstr "Fehler beim Schreiben der Signatur nach '%s': %s" -#: grep.c:1622 +#: grep.c:1623 #, c-format msgid "'%s': unable to read %s" msgstr "'%s': konnte nicht lesen %s" -#: grep.c:1639 +#: grep.c:1640 #, c-format msgid "'%s': %s" msgstr "'%s': %s" -#: grep.c:1650 +#: grep.c:1651 #, c-format msgid "'%s': short read %s" msgstr "'%s': read() zu kurz %s" @@ -445,8 +573,8 @@ msgstr[1] "" msgid "failed to read the cache" msgstr "Lesen des Zwischenspeichers fehlgeschlagen" -#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 -#: builtin/clone.c:586 +#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 +#: builtin/clone.c:645 msgid "unable to write new index file" msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." @@ -495,7 +623,7 @@ msgstr "kann Objekt %s '%s' nicht lesen" msgid "blob expected for %s '%s'" msgstr "Blob erwartet für %s '%s'" -#: merge-recursive.c:773 builtin/clone.c:302 +#: merge-recursive.c:773 builtin/clone.c:313 #, c-format msgid "failed to open '%s'" msgstr "Fehler beim Öffnen von '%s'" @@ -632,7 +760,7 @@ msgstr "%s ausgelassen (Ergebnis der Zusammenführung existiert bereits)" msgid "Auto-merging %s" msgstr "automatische Zusammenführung von %s" -#: merge-recursive.c:1633 git-submodule.sh:942 +#: merge-recursive.c:1633 git-submodule.sh:1029 msgid "submodule" msgstr "Unterprojekt" @@ -704,10 +832,15 @@ msgstr "Zusammenführung hat keine Version zurückgegeben" msgid "Could not parse object '%s'" msgstr "Konnte Objekt '%s' nicht parsen." -#: merge-recursive.c:2009 builtin/merge.c:643 +#: merge-recursive.c:2009 builtin/merge.c:658 msgid "Unable to write index." msgstr "Konnte Bereitstellung nicht schreiben." +#: object.c:195 +#, c-format +msgid "unable to parse object: %s" +msgstr "Konnte Objekt '%s' nicht parsen." + #: parse-options.c:489 msgid "..." msgstr "..." @@ -743,18 +876,18 @@ msgstr "Pfad '%s' befindet sich in Unterprojekt '%.*s'" msgid "'%s' is beyond a symbolic link" msgstr "'%s' ist über einem symbolischen Link" -#: remote.c:1653 +#: remote.c:1781 #, 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] "Ihr Zweig ist vor '%s' um %d Version.\n" msgstr[1] "Ihr Zweig ist vor '%s' um %d Versionen.\n" -#: remote.c:1659 +#: remote.c:1787 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (benutzen Sie \"git push\" um lokalen Versionen herauszubringen)\n" -#: remote.c:1662 +#: remote.c:1790 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -765,12 +898,12 @@ msgstr[1] "" "Ihr Zweig ist zu '%s' um %d Versionen hinterher, und kann vorgespult " "werden.\n" -#: remote.c:1670 +#: remote.c:1798 msgid " (use \"git pull\" to update your local branch)\n" msgstr "" " (benutzen Sie \"git pull\" um Ihren lokalen Zweig zu aktualisieren)\n" -#: remote.c:1673 +#: remote.c:1801 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -785,25 +918,25 @@ msgstr[1] "" "Ihr Zweig und '%s' sind divergiert,\n" "und haben jeweils %d und %d unterschiedliche Versionen.\n" -#: remote.c:1683 +#: remote.c:1811 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" " (benutzen Sie \"git pull\" um Ihren Zweig mit dem externen " "zusammenzuführen)\n" -#: sequencer.c:123 builtin/merge.c:761 builtin/merge.c:874 builtin/merge.c:984 -#: builtin/merge.c:994 +#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 +#: builtin/merge.c:1009 #, c-format msgid "Could not open '%s' for writing" msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 -#: builtin/merge.c:999 +#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 +#: builtin/merge.c:1001 builtin/merge.c:1014 #, c-format msgid "Could not write to '%s'" msgstr "Konnte nicht nach '%s' schreiben." -#: sequencer.c:146 +#: sequencer.c:229 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -811,7 +944,7 @@ msgstr "" "nach Auflösung der Konflikte, markieren Sie die korrigierten Pfade\n" "mit 'git add <Pfade>' oder 'git rm <Pfade>'" -#: sequencer.c:149 +#: sequencer.c:232 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -821,71 +954,71 @@ msgstr "" "mit 'git add <Pfade>' oder 'git rm <Pfade>'und tragen Sie das Ergebnis mit\n" "'git commit' ein" -#: sequencer.c:162 sequencer.c:774 sequencer.c:857 +#: sequencer.c:245 sequencer.c:859 sequencer.c:942 #, c-format msgid "Could not write to %s" msgstr "Konnte nicht nach %s schreiben" -#: sequencer.c:165 +#: sequencer.c:248 #, c-format msgid "Error wrapping up %s" msgstr "Fehler bei Nachbereitung von %s" -#: sequencer.c:180 +#: sequencer.c:263 msgid "Your local changes would be overwritten by cherry-pick." msgstr "" "Ihre lokalen Änderungen würden von \"cherry-pick\" überschrieben werden." -#: sequencer.c:182 +#: sequencer.c:265 msgid "Your local changes would be overwritten by revert." msgstr "Ihre lokalen Änderungen würden von \"revert\" überschrieben werden." -#: sequencer.c:185 +#: sequencer.c:268 msgid "Commit your changes or stash them to proceed." msgstr "" "Tragen Sie Ihre Änderungen ein oder benutzen Sie \"stash\" um fortzufahren." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:236 +#: sequencer.c:319 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Konnte neue Bereitstellungsdatei nicht schreiben" -#: sequencer.c:267 +#: sequencer.c:350 msgid "Could not resolve HEAD commit\n" msgstr "Konnte Version der Zweigspitze (HEAD) nicht auflösen\n" -#: sequencer.c:288 +#: sequencer.c:371 msgid "Unable to update cache tree\n" msgstr "Konnte zwischengespeicherten Baum nicht aktualisieren\n" -#: sequencer.c:333 +#: sequencer.c:416 #, c-format msgid "Could not parse commit %s\n" msgstr "Konnte Version %s nicht parsen\n" -#: sequencer.c:338 +#: sequencer.c:421 #, c-format msgid "Could not parse parent commit %s\n" msgstr "Konnte Elternversion %s nicht parsen\n" -#: sequencer.c:404 +#: sequencer.c:487 msgid "Your index file is unmerged." msgstr "Ihre Bereitstellungsdatei ist nicht zusammengeführt." -#: sequencer.c:423 +#: sequencer.c:506 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "" "Version %s ist eine Zusammenführung, aber die Option -m wurde nicht " "angegeben." -#: sequencer.c:431 +#: sequencer.c:514 #, c-format msgid "Commit %s does not have parent %d" msgstr "Version %s hat keinen Elternteil %d" -#: sequencer.c:435 +#: sequencer.c:518 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "" @@ -893,163 +1026,173 @@ msgstr "" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:448 +#: sequencer.c:531 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: kann Elternversion %s nicht parsen" -#: sequencer.c:452 +#: sequencer.c:535 #, c-format msgid "Cannot get commit message for %s" msgstr "Kann keine Versionsbeschreibung für %s bekommen" -#: sequencer.c:536 +#: sequencer.c:621 #, c-format msgid "could not revert %s... %s" -msgstr "Konnte %s nicht zurücksetzen... %s" +msgstr "Konnte %s nicht zurücknehmen... %s" -#: sequencer.c:537 +#: sequencer.c:622 #, c-format msgid "could not apply %s... %s" msgstr "Konnte %s nicht anwenden... %s" -#: sequencer.c:569 +#: sequencer.c:654 msgid "empty commit set passed" msgstr "leere Menge von Versionen übergeben" -#: sequencer.c:577 +#: sequencer.c:662 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: Fehler beim Lesen der Bereitstellung" -#: sequencer.c:582 +#: sequencer.c:667 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: Fehler beim Aktualisieren der Bereitstellung" -#: sequencer.c:640 +#: sequencer.c:725 #, c-format msgid "Cannot %s during a %s" msgstr "Kann %s nicht während eines %s durchführen" -#: sequencer.c:662 +#: sequencer.c:747 #, c-format msgid "Could not parse line %d." msgstr "Konnte Zeile %d nicht parsen." -#: sequencer.c:667 +#: sequencer.c:752 msgid "No commits parsed." msgstr "Keine Versionen geparst." -#: sequencer.c:680 +#: sequencer.c:765 #, c-format msgid "Could not open %s" msgstr "Konnte %s nicht öffnen" -#: sequencer.c:684 +#: sequencer.c:769 #, c-format msgid "Could not read %s." msgstr "Konnte %s nicht lesen." -#: sequencer.c:691 +#: sequencer.c:776 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Unbenutzbares Instruktionsblatt: %s" -#: sequencer.c:719 +#: sequencer.c:804 #, c-format msgid "Invalid key: %s" msgstr "Ungültiger Schlüssel: %s" -#: sequencer.c:722 +#: sequencer.c:807 #, c-format msgid "Invalid value for %s: %s" msgstr "Ungültiger Wert für %s: %s" -#: sequencer.c:734 +#: sequencer.c:819 #, c-format msgid "Malformed options sheet: %s" msgstr "Fehlerhaftes Optionsblatt: %s" -#: sequencer.c:755 +#: sequencer.c:840 msgid "a cherry-pick or revert is already in progress" msgstr "\"cherry-pick\" oder \"revert\" ist bereits im Gang" -#: sequencer.c:756 +#: sequencer.c:841 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "versuchen Sie \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:760 +#: sequencer.c:845 #, c-format msgid "Could not create sequencer directory %s" msgstr "Konnte \"sequencer\"-Verzeichnis %s nicht erstellen" -#: sequencer.c:776 sequencer.c:861 +#: sequencer.c:861 sequencer.c:946 #, c-format msgid "Error wrapping up %s." msgstr "Fehler beim Einpacken von %s." -#: sequencer.c:795 sequencer.c:929 +#: sequencer.c:880 sequencer.c:1014 msgid "no cherry-pick or revert in progress" msgstr "kein \"cherry-pick\" oder \"revert\" im Gang" -#: sequencer.c:797 +#: sequencer.c:882 msgid "cannot resolve HEAD" msgstr "kann Zweigspitze (HEAD) nicht auflösen" -#: sequencer.c:799 +#: sequencer.c:884 msgid "cannot abort from a branch yet to be born" msgstr "kann nicht abbrechen: bin auf einem Zweig, der noch geboren wird" -#: sequencer.c:821 builtin/apply.c:4056 +#: sequencer.c:906 builtin/apply.c:4060 #, c-format msgid "cannot open %s: %s" msgstr "Kann %s nicht öffnen: %s" -#: sequencer.c:824 +#: sequencer.c:909 #, c-format msgid "cannot read %s: %s" msgstr "Kann %s nicht lesen: %s" -#: sequencer.c:825 +#: sequencer.c:910 msgid "unexpected end of file" msgstr "Unerwartetes Dateiende" -#: sequencer.c:831 +#: sequencer.c:916 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "" "gespeicherte \"pre-cherry-pick\" Datei der Zweigspitze (HEAD) '%s' ist " "beschädigt" -#: sequencer.c:854 +#: sequencer.c:939 #, c-format msgid "Could not format %s." msgstr "Konnte %s nicht formatieren." -#: sequencer.c:1016 +#: sequencer.c:1083 +#, c-format +msgid "%s: can't cherry-pick a %s" +msgstr "%s: %s kann nicht in \"cherry-pick\" benutzt werden" + +#: sequencer.c:1085 +#, c-format +msgid "%s: bad revision" +msgstr "%s: ungültige Revision" + +#: sequencer.c:1119 msgid "Can't revert as initial commit" -msgstr "Kann nicht zu initialer Version zurücksetzen." +msgstr "Rücknahme-Version kann nicht initial sein." -#: sequencer.c:1017 +#: sequencer.c:1120 msgid "Can't cherry-pick into empty head" -msgstr "Kann \"cherry-pick\" nicht in einem leerem Kopf ausführen." +msgstr "Kann \"cherry-pick\" nicht in einem leeren Zweig ausführen." -#: sha1_name.c:1044 +#: sha1_name.c:1036 msgid "HEAD does not point to a branch" msgstr "Zweigspitze (HEAD) zeigt auf keinen Zweig" -#: sha1_name.c:1047 +#: sha1_name.c:1039 #, c-format msgid "No such branch: '%s'" msgstr "Kein solcher Zweig '%s'" -#: sha1_name.c:1049 +#: sha1_name.c:1041 #, c-format msgid "No upstream configured for branch '%s'" msgstr "Kein entferntes Projektarchiv für Zweig '%s' konfiguriert." -#: sha1_name.c:1052 +#: sha1_name.c:1044 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "" @@ -1185,121 +1328,121 @@ msgstr "geänderter Inhalt, " msgid "untracked content, " msgstr "unbeobachteter Inhalt, " -#: wt-status.c:303 +#: wt-status.c:306 #, c-format msgid "new file: %s" msgstr "neue Datei: %s" -#: wt-status.c:306 +#: wt-status.c:309 #, c-format msgid "copied: %s -> %s" msgstr "kopiert: %s -> %s" -#: wt-status.c:309 +#: wt-status.c:312 #, c-format msgid "deleted: %s" msgstr "gelöscht: %s" -#: wt-status.c:312 +#: wt-status.c:315 #, c-format msgid "modified: %s" msgstr "geändert: %s" -#: wt-status.c:315 +#: wt-status.c:318 #, c-format msgid "renamed: %s -> %s" msgstr "umbenannt: %s -> %s" -#: wt-status.c:318 +#: wt-status.c:321 #, c-format msgid "typechange: %s" msgstr "Typänderung: %s" -#: wt-status.c:321 +#: wt-status.c:324 #, c-format msgid "unknown: %s" msgstr "unbekannt: %s" -#: wt-status.c:324 +#: wt-status.c:327 #, c-format msgid "unmerged: %s" msgstr "nicht zusammengeführt: %s" -#: wt-status.c:327 +#: wt-status.c:330 #, c-format msgid "bug: unhandled diff status %c" msgstr "Fehler: unbehandelter Differenz-Status %c" -#: wt-status.c:789 +#: wt-status.c:803 msgid "You have unmerged paths." msgstr "Sie haben nicht zusammengeführte Pfade." -#: wt-status.c:792 wt-status.c:944 +#: wt-status.c:806 wt-status.c:958 msgid " (fix conflicts and run \"git commit\")" msgstr " (beheben Sie die Konflikte und führen Sie \"git commit\" aus)" -#: wt-status.c:795 +#: wt-status.c:809 msgid "All conflicts fixed but you are still merging." msgstr "" "Alle Konflikte sind behoben, aber Sie sind immer noch beim Zusammenführen." -#: wt-status.c:798 +#: wt-status.c:812 msgid " (use \"git commit\" to conclude merge)" msgstr " (benutzen Sie \"git commit\" um die Zusammenführung abzuschließen)" -#: wt-status.c:808 +#: wt-status.c:822 msgid "You are in the middle of an am session." msgstr "Eine \"am\"-Sitzung ist im Gange." -#: wt-status.c:811 +#: wt-status.c:825 msgid "The current patch is empty." msgstr "Der aktuelle Patch ist leer." -#: wt-status.c:815 +#: wt-status.c:829 msgid " (fix conflicts and then run \"git am --resolved\")" msgstr "" " (beheben Sie die Konflikte und führen Sie dann \"git am --resolved\" aus)" -#: wt-status.c:817 +#: wt-status.c:831 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (benutzen Sie \"git am --skip\" um diesen Patch auszulassen)" -#: wt-status.c:819 +#: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" " (benutzen Sie \"git am --abort\" um den ursprünglichen Zweig " "wiederherzustellen)" -#: wt-status.c:879 wt-status.c:896 +#: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Sie sind gerade beim Neuaufbau von Zweig '%s' auf '%s'." -#: wt-status.c:884 wt-status.c:901 +#: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." msgstr "Sie sind gerade beim Neuaufbau." -#: wt-status.c:887 +#: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr "" " (beheben Sie die Konflikte und führen Sie dann \"git rebase --continue\" " "aus)" -#: wt-status.c:889 +#: wt-status.c:903 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (benutzen Sie \"git rebase --skip\" um diesen Patch auszulassen)" -#: wt-status.c:891 +#: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" " (benutzen Sie \"git rebase --abort\" um den ursprünglichen Zweig " "auszuchecken)" -#: wt-status.c:904 +#: wt-status.c:918 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr " (alle Konflikte behoben: führen Sie \"git rebase --continue\" aus)" -#: wt-status.c:908 +#: wt-status.c:922 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -1307,108 +1450,147 @@ msgstr "" "Sie teilen gerade eine Version auf, während ein Neuaufbau von Zweig '%s' auf " "'%s' im Gange ist." -#: wt-status.c:913 +#: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." msgstr "Sie teilen gerade eine Version während eines Neuaufbaus auf." -#: wt-status.c:916 +#: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (Sobald Ihr Arbeitsverzeichnis sauber ist, führen Sie \"git rebase --" "continue\" aus)" -#: wt-status.c:920 +#: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Sie editieren gerade eine Version während eines Neuaufbaus von Zweig '%s' " "auf '%s'." -#: wt-status.c:925 +#: wt-status.c:939 msgid "You are currently editing a commit during a rebase." msgstr "Sie editieren gerade eine Version während eines Neuaufbaus." -#: wt-status.c:928 +#: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" " (benutzen Sie \"git commit --amend\" um die aktuelle Version nachzubessern)" -#: wt-status.c:930 +#: wt-status.c:944 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (benutzen Sie \"git rebase --continue\" sobald Ihre Änderungen " "abgeschlossen sind)" -#: wt-status.c:940 +#: wt-status.c:954 msgid "You are currently cherry-picking." msgstr "Sie führen gerade \"cherry-pick\" aus." -#: wt-status.c:947 +#: wt-status.c:961 msgid " (all conflicts fixed: run \"git commit\")" msgstr " (alle Konflikte behoben: führen Sie \"git commit\" aus)" -#: wt-status.c:958 +#: wt-status.c:970 +#, c-format +msgid "You are currently reverting commit %s." +msgstr "Sie nehmen gerade Version '%s' zurück." + +#: wt-status.c:975 +msgid " (fix conflicts and run \"git revert --continue\")" +msgstr "" +" (beheben Sie die Konflikte und führen Sie dann \"git revert --continue\" " +"aus)" + +#: wt-status.c:978 +msgid " (all conflicts fixed: run \"git revert --continue\")" +msgstr " (alle Konflikte behoben: führen Sie \"git revert --continue\" aus)" + +#: wt-status.c:980 +msgid " (use \"git revert --abort\" to cancel the revert operation)" +msgstr "" +" (benutzen Sie \"git revert --abort\" um die Umkehroperation abzubrechen)" + +#: wt-status.c:991 #, c-format -msgid "You are currently bisecting branch '%s'." -msgstr "Sie sind gerade bei einer binären Suche in Zweig '%s'." +msgid "You are currently bisecting, started from branch '%s'." +msgstr "Sie sind gerade bei einer binären Suche, gestartet von Zweig '%s'." -#: wt-status.c:962 +#: wt-status.c:995 msgid "You are currently bisecting." msgstr "Sie sind gerade bei einer binären Suche." -#: wt-status.c:965 +#: wt-status.c:998 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" " (benutzen Sie \"git bisect reset\" um zum ursprünglichen Zweig " "zurückzukehren)" -#: wt-status.c:1064 +#: wt-status.c:1173 msgid "On branch " msgstr "Auf Zweig " -#: wt-status.c:1071 +#: wt-status.c:1184 +msgid "HEAD detached at " +msgstr "Zweigspitze (HEAD) losgelöst bei " + +#: wt-status.c:1186 +msgid "HEAD detached from " +msgstr "Zweigspitze (HEAD) losgelöst von " + +#: wt-status.c:1189 msgid "Not currently on any branch." msgstr "Im Moment auf keinem Zweig." -#: wt-status.c:1083 +#: wt-status.c:1206 msgid "Initial commit" msgstr "Initiale Version" -#: wt-status.c:1097 +#: wt-status.c:1220 msgid "Untracked files" msgstr "Unbeobachtete Dateien" -#: wt-status.c:1099 +#: wt-status.c:1222 msgid "Ignored files" msgstr "Ignorierte Dateien" -#: wt-status.c:1101 +#: wt-status.c:1226 +#, c-format +msgid "" +"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" +"may speed it up, but you have to be careful not to forget to add\n" +"new files yourself (see 'git help status')." +msgstr "" +"Es dauerte %.2f Sekunden die unbeobachteten Dateien zu bestimmen.\n" +"'status -uno' könnte das beschleunigen, aber Sie müssen darauf achten,\n" +"neue Dateien selbstständig hinzuzufügen (siehe 'git help status')." + +#: wt-status.c:1232 #, c-format msgid "Untracked files not listed%s" msgstr "Unbeobachtete Dateien nicht aufgelistet%s" -#: wt-status.c:1103 +#: wt-status.c:1234 msgid " (use -u option to show untracked files)" msgstr " (benutzen Sie die Option -u um unbeobachteten Dateien anzuzeigen)" -#: wt-status.c:1109 +#: wt-status.c:1240 msgid "No changes" msgstr "Keine Änderungen" -#: wt-status.c:1114 +#: wt-status.c:1245 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" "keine Änderungen zum Eintragen hinzugefügt (benutzen Sie \"git add\" und/" "oder \"git commit -a\")\n" -#: wt-status.c:1117 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit\n" msgstr "keine Änderungen zum Eintragen hinzugefügt\n" -#: wt-status.c:1120 +#: wt-status.c:1251 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -1417,56 +1599,56 @@ msgstr "" "nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien " "(benutzen Sie \"git add\" zum Beobachten)\n" -#: wt-status.c:1123 +#: wt-status.c:1254 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "nichts zum Eintragen hinzugefügt, aber es gibt unbeobachtete Dateien\n" -#: wt-status.c:1126 +#: wt-status.c:1257 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" "nichts einzutragen (Erstellen/Kopieren Sie Dateien und benutzen Sie \"git add" "\" zum Beobachten)\n" -#: wt-status.c:1129 wt-status.c:1134 +#: wt-status.c:1260 wt-status.c:1265 #, c-format msgid "nothing to commit\n" msgstr "nichts einzutragen\n" -#: wt-status.c:1132 +#: wt-status.c:1263 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "nichts einzutragen (benutzen Sie die Option -u, um unbeobachtete Dateien " "anzuzeigen)\n" -#: wt-status.c:1136 +#: wt-status.c:1267 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "nichts einzutragen, Arbeitsverzeichnis sauber\n" -#: wt-status.c:1244 +#: wt-status.c:1375 msgid "HEAD (no branch)" msgstr "HEAD (kein Zweig)" -#: wt-status.c:1250 +#: wt-status.c:1381 msgid "Initial commit on " msgstr "Initiale Version auf " -#: wt-status.c:1265 +#: wt-status.c:1396 msgid "behind " msgstr "hinterher " -#: wt-status.c:1268 wt-status.c:1271 +#: wt-status.c:1399 wt-status.c:1402 msgid "ahead " msgstr "voraus " -#: wt-status.c:1273 +#: wt-status.c:1404 msgid ", behind " msgstr ", hinterher " -#: compat/precompose_utf8.c:58 builtin/clone.c:341 +#: compat/precompose_utf8.c:58 builtin/clone.c:352 #, c-format msgid "failed to unlink '%s'" msgstr "Konnte '%s' nicht entfernen." @@ -1475,201 +1657,236 @@ msgstr "Konnte '%s' nicht entfernen." msgid "git add [options] [--] <pathspec>..." msgstr "git add [Optionen] [--] [<Pfadspezifikation>...]" -#: builtin/add.c:63 +#. +#. * To be consistent with "git add -p" and most Git +#. * commands, we should default to being tree-wide, but +#. * this is not the original behavior and can't be +#. * changed until users trained themselves not to type +#. * "git add -u" or "git add -A". For now, we warn and +#. * keep the old behavior. Later, the behavior can be changed +#. * to tree-wide, keeping the warning for a while, and +#. * eventually we can drop the warning. +#. +#: builtin/add.c:58 +#, c-format +msgid "" +"The behavior of 'git add %s (or %s)' with no path argument from a\n" +"subdirectory of the tree will change in Git 2.0 and should not be used " +"anymore.\n" +"To add content for the whole tree, run:\n" +"\n" +" git add %s :/\n" +" (or git add %s :/)\n" +"\n" +"To restrict the command to the current directory, run:\n" +"\n" +" git add %s .\n" +" (or git add %s .)\n" +"\n" +"With the current Git version, the command is restricted to the current " +"directory.\n" +msgstr "" +"Das Verhalten von 'git add %s (oder %s)' ohne ein Pfad-Argument von\n" +"einem Unterverzeichnis aus wird in Git 2.0 geändert und sollte nicht\n" +"mehr verwendet werden.\n" +"Um Dateien des gesamten Projektverzeichnisses hinzuzufügen, führen Sie aus:\n" +"\n" +" git add %s :/\n" +" (oder git add %s :/)\n" +"\n" +"Zur Einschränkung auf das aktuelle Verzeichnis führen Sie aus:\n" +"\n" +" git add %s .\n" +" (oder git add %s .)\n" +"\n" +"Mit der aktuellen Version von Git ist das Kommando auf das aktuelle\n" +"Verzeichnis beschränkt.\n" + +#: builtin/add.c:100 +#, c-format +msgid "" +"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n" +msgstr "" +"Sie haben 'git add' weder mit '-A (--all)' noch mit '--ignore-removal'\n" +"ausgeführt. Das Verhalten des Kommandos ändert sich in Git 2.0 durch\n" +"Berücksichtigung der gelöschten Pfade.\n" +"Pfade wie '%s', die im Arbeitsverzeichnis gelöscht wurden, werden in\n" +"dieser Version von Git ignoriert.\n" +"\n" +"* 'git add --ignore-removal <Pfadspezifikation>', was der aktuelle\n" +" Standardwert ist, ignoriert gelöschte Pfade im Arbeitsverzeichnis." +"\n" +"* 'git add --all <Pfadspezifikation>' berücksichtigt ebenfalls gelöschte\n" +" Pfade." +"\n" +"Führen Sie 'git status' aus, um die gelöschten Pfade zu überprüfen.\n" + +#: builtin/add.c:144 #, c-format msgid "unexpected diff status %c" msgstr "unerwarteter Differenz-Status %c" -#: builtin/add.c:68 builtin/commit.c:231 +#: builtin/add.c:149 builtin/commit.c:233 msgid "updating files failed" msgstr "Aktualisierung der Dateien fehlgeschlagen" -#: builtin/add.c:78 +#: builtin/add.c:163 #, c-format msgid "remove '%s'\n" msgstr "lösche '%s'\n" -#: builtin/add.c:148 +#: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "" "Nicht bereitgestellte Änderungen nach Aktualisierung der Bereitstellung:" -#: builtin/add.c:151 builtin/add.c:460 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "Pfadspezifikation '%s' stimmt mit keinen Dateien überein" -#: builtin/add.c:234 +#: builtin/add.c:339 msgid "Could not read the index" msgstr "Konnte die Bereitstellung nicht lesen" -#: builtin/add.c:244 +#: builtin/add.c:349 #, c-format msgid "Could not open '%s' for writing." msgstr "Konnte '%s' nicht zum Schreiben öffnen." -#: builtin/add.c:248 +#: builtin/add.c:353 msgid "Could not write patch" msgstr "Konnte Patch nicht schreiben" -#: builtin/add.c:253 +#: builtin/add.c:358 #, c-format msgid "Could not stat '%s'" msgstr "Konnte Verzeichnis '%s' nicht lesen" -#: builtin/add.c:255 +#: builtin/add.c:360 msgid "Empty patch. Aborted." msgstr "Leerer Patch. Abgebrochen." -#: builtin/add.c:261 +#: builtin/add.c:366 #, c-format msgid "Could not apply '%s'" msgstr "Konnte '%s' nicht anwenden." -#: builtin/add.c:271 +#: builtin/add.c:376 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Die folgenden Pfade werden durch eine Ihrer \".gitignore\" Dateien " "ignoriert:\n" -#: builtin/add.c:277 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 #: builtin/rm.c:206 msgid "dry run" msgstr "Probelauf" -#: builtin/add.c:278 builtin/apply.c:4405 builtin/check-ignore.c:19 -#: builtin/commit.c:1150 builtin/count-objects.c:82 builtin/fsck.c:613 -#: builtin/log.c:1522 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 +#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "erweiterte Ausgaben" -#: builtin/add.c:280 +#: builtin/add.c:396 msgid "interactive picking" msgstr "interaktives Auswählen" -#: builtin/add.c:281 builtin/checkout.c:1031 builtin/reset.c:258 +#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 msgid "select hunks interactively" msgstr "interaktiv Bereiche auswählen" -#: builtin/add.c:282 +#: builtin/add.c:398 msgid "edit current diff and apply" msgstr "aktuelle Unterschiede editieren und anwenden" -#: builtin/add.c:283 +#: builtin/add.c:399 msgid "allow adding otherwise ignored files" msgstr "erlaubt das Hinzufügen andernfalls ignorierter Dateien" -#: builtin/add.c:284 +#: builtin/add.c:400 msgid "update tracked files" msgstr "aktualisiert beobachtete Dateien" -#: builtin/add.c:285 +#: builtin/add.c:401 msgid "record only the fact that the path will be added later" msgstr "speichert nur, dass der Pfad später hinzugefügt werden soll" -#: builtin/add.c:286 +#: builtin/add.c:402 msgid "add changes from all tracked and untracked files" msgstr "" "fügt Änderungen von allen beobachteten und unbeobachteten Dateien hinzu" -#: builtin/add.c:287 +#. takes no arguments +#: builtin/add.c:405 +msgid "ignore paths removed in the working tree (same as --no-all)" +msgstr "ignoriert gelöschte Pfade im Arbeitsverzeichnis (genau wie " +"--no-all)" + +#: builtin/add.c:407 msgid "don't add, only refresh the index" msgstr "fügt nichts hinzu, aktualisiert nur die Bereitstellung" -#: builtin/add.c:288 +#: builtin/add.c:408 msgid "just skip files which cannot be added because of errors" msgstr "" "überspringt Dateien, die aufgrund von Fehlern nicht hinzugefügt werden " "konnten" -#: builtin/add.c:289 +#: builtin/add.c:409 msgid "check if - even missing - files are ignored in dry run" msgstr "prüft ob - auch fehlende - Dateien im Probelauf ignoriert werden" -#: builtin/add.c:311 +#: builtin/add.c:431 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Verwenden Sie -f wenn Sie diese wirklich hinzufügen möchten.\n" -#: builtin/add.c:312 +#: builtin/add.c:432 msgid "no files added" msgstr "keine Dateien hinzugefügt" -#: builtin/add.c:318 +#: builtin/add.c:438 msgid "adding files failed" msgstr "Hinzufügen von Dateien fehlgeschlagen" -#. -#. * To be consistent with "git add -p" and most Git -#. * commands, we should default to being tree-wide, but -#. * this is not the original behavior and can't be -#. * changed until users trained themselves not to type -#. * "git add -u" or "git add -A". For now, we warn and -#. * keep the old behavior. Later, this warning can be -#. * turned into a die(...), and eventually we may -#. * reallow the command with a new behavior. -#. -#: builtin/add.c:335 -#, c-format -msgid "" -"The behavior of 'git add %s (or %s)' with no path argument from a\n" -"subdirectory of the tree will change in Git 2.0 and should not be used " -"anymore.\n" -"To add content for the whole tree, run:\n" -"\n" -" git add %s :/\n" -" (or git add %s :/)\n" -"\n" -"To restrict the command to the current directory, run:\n" -"\n" -" git add %s .\n" -" (or git add %s .)\n" -"\n" -"With the current Git version, the command is restricted to the current " -"directory." -msgstr "" -"Das Verhalten von 'git add %s (oder %s)' ohne ein Pfad-Argument von\n" -"einem Unterverzeichnis aus wird in Git 2.0 geändert und sollte nicht\n" -"mehr verwendet werden.\n" -"Um Dateien des gesamten Projektverzeichnisses hinzuzufügen, führen Sie aus:\n" -"\n" -" git add %s :/\n" -" (oder git add %s :/)\n" -"\n" -"Zur Einschränkung auf das aktuelle Verzeichnis führen Sie aus:\n" -"\n" -" git add %s .\n" -" (oder git add %s .)\n" -"\n" -"Mit der aktuellen Version von Git ist das Kommando auf das aktuelle\n" -"Verzeichnis beschränkt." - -#: builtin/add.c:381 +#: builtin/add.c:477 msgid "-A and -u are mutually incompatible" msgstr "Die Optionen -A und -u sind zueinander inkompatibel." -#: builtin/add.c:383 +#: builtin/add.c:495 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "" "Die Option --ignore-missing kann nur zusammen mit --dry-run verwendet werden." -#: builtin/add.c:414 +#: builtin/add.c:525 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Nichts spezifiziert, nichts hinzugefügt.\n" -#: builtin/add.c:415 +#: builtin/add.c:526 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Wollten Sie vielleicht 'git add .' sagen?\n" -#: builtin/add.c:421 builtin/check-ignore.c:67 builtin/clean.c:204 -#: builtin/commit.c:291 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 +#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 msgid "index file corrupt" msgstr "Bereitstellungsdatei beschädigt" -#: builtin/add.c:481 builtin/apply.c:4501 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "Konnte neue Bereitstellungsdatei nicht schreiben." @@ -1805,12 +2022,12 @@ msgstr "konnte symbolische Verknüpfung %s nicht lesen" msgid "unable to open or read %s" msgstr "konnte %s nicht öffnen oder lesen" -#: builtin/apply.c:2684 +#: builtin/apply.c:2688 #, c-format msgid "invalid start of line: '%c'" msgstr "Ungültiger Zeilenanfang: '%c'" -#: builtin/apply.c:2802 +#: builtin/apply.c:2806 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." @@ -1818,12 +2035,12 @@ msgstr[0] "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeile versetzt)" msgstr[1] "" "Patch-Bereich #%d erfolgreich angewendet bei %d (%d Zeilen versetzt)" -#: builtin/apply.c:2814 +#: builtin/apply.c:2818 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "Kontext reduziert zu (%ld/%ld) um Patch-Bereich bei %d anzuwenden" -#: builtin/apply.c:2820 +#: builtin/apply.c:2824 #, c-format msgid "" "while searching for:\n" @@ -1832,340 +2049,340 @@ msgstr "" "bei der Suche nach:\n" "%.*s" -#: builtin/apply.c:2839 +#: builtin/apply.c:2843 #, c-format msgid "missing binary patch data for '%s'" msgstr "keine Daten in Binär-Patch für '%s'" -#: builtin/apply.c:2942 +#: builtin/apply.c:2946 #, c-format msgid "binary patch does not apply to '%s'" msgstr "Konnte Binär-Patch nicht auf '%s' anwenden" -#: builtin/apply.c:2948 +#: builtin/apply.c:2952 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" "Binär-Patch für '%s' erzeugt falsches Ergebnis (erwartete %s, bekam %s)" -#: builtin/apply.c:2969 +#: builtin/apply.c:2973 #, c-format msgid "patch failed: %s:%ld" msgstr "Anwendung des Patches fehlgeschlagen: %s:%ld" -#: builtin/apply.c:3091 +#: builtin/apply.c:3095 #, c-format msgid "cannot checkout %s" msgstr "kann %s nicht auschecken" -#: builtin/apply.c:3136 builtin/apply.c:3145 builtin/apply.c:3189 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 #, c-format msgid "read of %s failed" msgstr "Konnte %s nicht lesen" -#: builtin/apply.c:3169 builtin/apply.c:3391 +#: builtin/apply.c:3173 builtin/apply.c:3395 #, c-format msgid "path %s has been renamed/deleted" msgstr "Pfad %s wurde umbenannt/gelöscht" -#: builtin/apply.c:3250 builtin/apply.c:3405 +#: builtin/apply.c:3254 builtin/apply.c:3409 #, c-format msgid "%s: does not exist in index" msgstr "%s ist nicht bereitgestellt" -#: builtin/apply.c:3254 builtin/apply.c:3397 builtin/apply.c:3419 +#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3259 builtin/apply.c:3413 +#: builtin/apply.c:3263 builtin/apply.c:3417 #, c-format msgid "%s: does not match index" msgstr "%s entspricht nicht der Bereitstellung" -#: builtin/apply.c:3361 +#: builtin/apply.c:3365 msgid "removal patch leaves file contents" msgstr "Lösch-Patch hinterlässt Dateiinhalte" -#: builtin/apply.c:3430 +#: builtin/apply.c:3434 #, c-format msgid "%s: wrong type" msgstr "%s: falscher Typ" -#: builtin/apply.c:3432 +#: builtin/apply.c:3436 #, c-format msgid "%s has type %o, expected %o" msgstr "%s ist vom Typ %o, erwartete %o" -#: builtin/apply.c:3533 +#: builtin/apply.c:3537 #, c-format msgid "%s: already exists in index" msgstr "%s ist bereits bereitgestellt" -#: builtin/apply.c:3536 +#: builtin/apply.c:3540 #, c-format msgid "%s: already exists in working directory" msgstr "%s existiert bereits im Arbeitsverzeichnis" -#: builtin/apply.c:3556 +#: builtin/apply.c:3560 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o)" -#: builtin/apply.c:3561 +#: builtin/apply.c:3565 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "neuer Modus (%o) von %s entspricht nicht dem alten Modus (%o) von %s" -#: builtin/apply.c:3569 +#: builtin/apply.c:3573 #, c-format msgid "%s: patch does not apply" msgstr "%s: Patch konnte nicht angewendet werden" -#: builtin/apply.c:3582 +#: builtin/apply.c:3586 #, c-format msgid "Checking patch %s..." msgstr "Prüfe Patch %s..." -#: builtin/apply.c:3675 builtin/checkout.c:215 builtin/reset.c:124 +#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry für Pfad '%s' fehlgeschlagen" -#: builtin/apply.c:3818 +#: builtin/apply.c:3822 #, c-format msgid "unable to remove %s from index" msgstr "konnte %s nicht aus der Bereitstellung entfernen" -#: builtin/apply.c:3846 +#: builtin/apply.c:3850 #, c-format msgid "corrupt patch for subproject %s" msgstr "fehlerhafter Patch für Unterprojekt %s" -#: builtin/apply.c:3850 +#: builtin/apply.c:3854 #, c-format msgid "unable to stat newly created file '%s'" msgstr "konnte neu erstellte Datei '%s' nicht lesen" -#: builtin/apply.c:3855 +#: builtin/apply.c:3859 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "kann internen Speicher für eben erstellte Datei %s nicht erzeugen" -#: builtin/apply.c:3858 builtin/apply.c:3966 +#: builtin/apply.c:3862 builtin/apply.c:3970 #, c-format msgid "unable to add cache entry for %s" msgstr "kann für %s keinen Eintrag in den Zwischenspeicher hinzufügen" -#: builtin/apply.c:3891 +#: builtin/apply.c:3895 #, c-format msgid "closing file '%s'" msgstr "schließe Datei '%s'" -#: builtin/apply.c:3940 +#: builtin/apply.c:3944 #, c-format msgid "unable to write file '%s' mode %o" msgstr "konnte Datei '%s' mit Modus %o nicht schreiben" -#: builtin/apply.c:4027 +#: builtin/apply.c:4031 #, c-format msgid "Applied patch %s cleanly." msgstr "Patch %s sauber angewendet" -#: builtin/apply.c:4035 +#: builtin/apply.c:4039 msgid "internal error" msgstr "interner Fehler" #. Say this even without --verbose -#: builtin/apply.c:4038 +#: builtin/apply.c:4042 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "Wende Patch %%s mit %d Zurückweisung an..." msgstr[1] "Wende Patch %%s mit %d Zurückweisungen an..." -#: builtin/apply.c:4048 +#: builtin/apply.c:4052 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "Verkürze Name von .rej Datei zu %.*s.rej" -#: builtin/apply.c:4069 +#: builtin/apply.c:4073 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Patch-Bereich #%d sauber angewendet." -#: builtin/apply.c:4072 +#: builtin/apply.c:4076 #, c-format msgid "Rejected hunk #%d." msgstr "Patch-Bereich #%d zurückgewiesen." -#: builtin/apply.c:4222 +#: builtin/apply.c:4226 msgid "unrecognized input" msgstr "nicht erkannte Eingabe" -#: builtin/apply.c:4233 +#: builtin/apply.c:4237 msgid "unable to read index file" msgstr "Konnte Bereitstellungsdatei nicht lesen" -#: builtin/apply.c:4352 builtin/apply.c:4355 builtin/clone.c:91 +#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 #: builtin/fetch.c:63 msgid "path" msgstr "Pfad" -#: builtin/apply.c:4353 +#: builtin/apply.c:4357 msgid "don't apply changes matching the given path" msgstr "wendet keine Änderungen im angegebenen Pfad an" -#: builtin/apply.c:4356 +#: builtin/apply.c:4360 msgid "apply changes matching the given path" msgstr "wendet Änderungen nur im angegebenen Pfad an" -#: builtin/apply.c:4358 +#: builtin/apply.c:4362 msgid "num" msgstr "Anzahl" -#: builtin/apply.c:4359 +#: builtin/apply.c:4363 msgid "remove <num> leading slashes from traditional diff paths" msgstr "" "entfernt <Anzahl> vorangestellte Schrägstriche von herkömmlichen " "Differenzpfaden" -#: builtin/apply.c:4362 +#: builtin/apply.c:4366 msgid "ignore additions made by the patch" msgstr "ignoriert hinzugefügte Zeilen des Patches" -#: builtin/apply.c:4364 +#: builtin/apply.c:4368 msgid "instead of applying the patch, output diffstat for the input" msgstr "" "anstatt der Anwendung des Patches, wird der \"diffstat\" für die Eingabe " "ausgegeben" -#: builtin/apply.c:4368 +#: builtin/apply.c:4372 msgid "show number of added and deleted lines in decimal notation" msgstr "" "zeigt die Anzahl von hinzugefügten/entfernten Zeilen in Dezimalnotation" -#: builtin/apply.c:4370 +#: builtin/apply.c:4374 msgid "instead of applying the patch, output a summary for the input" msgstr "" "anstatt der Anwendung des Patches, wird eine Zusammenfassung für die Eingabe " "ausgegeben" -#: builtin/apply.c:4372 +#: builtin/apply.c:4376 msgid "instead of applying the patch, see if the patch is applicable" msgstr "" "anstatt der Anwendung des Patches, zeige ob Patch angewendet werden kann" -#: builtin/apply.c:4374 +#: builtin/apply.c:4378 msgid "make sure the patch is applicable to the current index" msgstr "" "stellt sicher, dass der Patch in der aktuellen Bereitstellung angewendet " "werden kann" -#: builtin/apply.c:4376 +#: builtin/apply.c:4380 msgid "apply a patch without touching the working tree" msgstr "wendet einen Patch an, ohne Änderungen im Arbeitszweig vorzunehmen" -#: builtin/apply.c:4378 +#: builtin/apply.c:4382 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "wendet den Patch an (Benutzung mit --stat/--summary/--check)" -#: builtin/apply.c:4380 +#: builtin/apply.c:4384 msgid "attempt three-way merge if a patch does not apply" msgstr "" "versucht 3-Wege-Zusammenführung, wenn der Patch nicht angewendet werden " "konnte" -#: builtin/apply.c:4382 +#: builtin/apply.c:4386 msgid "build a temporary index based on embedded index information" msgstr "" "erstellt eine temporäre Bereitstellung basierend auf den integrierten " "Bereitstellungsinformationen" -#: builtin/apply.c:4384 builtin/checkout-index.c:197 builtin/ls-files.c:463 +#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 msgid "paths are separated with NUL character" msgstr "Pfade sind getrennt durch NUL Zeichen" -#: builtin/apply.c:4387 +#: builtin/apply.c:4391 msgid "ensure at least <n> lines of context match" msgstr "stellt sicher, dass mindestens <n> Zeilen des Kontextes übereinstimmen" -#: builtin/apply.c:4388 +#: builtin/apply.c:4392 msgid "action" msgstr "Aktion" -#: builtin/apply.c:4389 +#: builtin/apply.c:4393 msgid "detect new or modified lines that have whitespace errors" msgstr "ermittelt neue oder geänderte Zeilen die Fehler in Leerzeichen haben" -#: builtin/apply.c:4392 builtin/apply.c:4395 +#: builtin/apply.c:4396 builtin/apply.c:4399 msgid "ignore changes in whitespace when finding context" msgstr "ignoriert Änderungen in Leerzeichen bei der Suche des Kontextes" -#: builtin/apply.c:4398 +#: builtin/apply.c:4402 msgid "apply the patch in reverse" msgstr "wendet den Patch in umgekehrter Reihenfolge an" -#: builtin/apply.c:4400 +#: builtin/apply.c:4404 msgid "don't expect at least one line of context" msgstr "erwartet keinen Kontext" -#: builtin/apply.c:4402 +#: builtin/apply.c:4406 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "" "hinterlässt zurückgewiesene Patch-Bereiche in den entsprechenden *.rej " "Dateien" -#: builtin/apply.c:4404 +#: builtin/apply.c:4408 msgid "allow overlapping hunks" msgstr "erlaubt sich überlappende Patch-Bereiche" -#: builtin/apply.c:4407 +#: builtin/apply.c:4411 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "toleriert fehlerhaft erkannten fehlenden Zeilenumbruch am Dateiende" -#: builtin/apply.c:4410 +#: builtin/apply.c:4414 msgid "do not trust the line counts in the hunk headers" msgstr "vertraut nicht den Zeilennummern im Kopf des Patch-Bereiches" -#: builtin/apply.c:4412 +#: builtin/apply.c:4416 msgid "root" msgstr "Wurzelverzeichnis" -#: builtin/apply.c:4413 +#: builtin/apply.c:4417 msgid "prepend <root> to all filenames" msgstr "stellt <Wurzelverzeichnis> vor alle Dateinamen" -#: builtin/apply.c:4435 +#: builtin/apply.c:4439 msgid "--3way outside a repository" msgstr "" "Die Option --3way kann nicht außerhalb eines Projektarchivs verwendet werden." -#: builtin/apply.c:4443 +#: builtin/apply.c:4447 msgid "--index outside a repository" msgstr "" "Die Option --index kann nicht außerhalb eines Projektarchivs verwendet " "werden." -#: builtin/apply.c:4446 +#: builtin/apply.c:4450 msgid "--cached outside a repository" msgstr "" "Die Option --cached kann nicht außerhalb eines Projektarchivs verwendet " "werden." -#: builtin/apply.c:4462 +#: builtin/apply.c:4466 #, c-format msgid "can't open patch '%s'" msgstr "kann Patch '%s' nicht öffnen" -#: builtin/apply.c:4476 +#: builtin/apply.c:4480 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "unterdrückte %d Fehler in Leerzeichen" msgstr[1] "unterdrückte %d Fehler in Leerzeichen" -#: builtin/apply.c:4482 builtin/apply.c:4492 +#: builtin/apply.c:4486 builtin/apply.c:4496 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -2189,21 +2406,21 @@ msgstr "git archive: Externes Archiv ohne URL" msgid "git archive: expected ACK/NAK, got EOF" msgstr "git archive: habe ACK/NAK erwartet, aber EOF bekommen" -#: builtin/archive.c:63 +#: builtin/archive.c:61 #, c-format msgid "git archive: NACK %s" msgstr "git archive: NACK %s" -#: builtin/archive.c:65 +#: builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "Fehler am anderen Ende: %s" -#: builtin/archive.c:66 +#: builtin/archive.c:64 msgid "git archive: protocol error" msgstr "git archive: Protokollfehler" -#: builtin/archive.c:71 +#: builtin/archive.c:68 msgid "git archive: expected a flush" msgstr "git archive: erwartete eine Spülung (flush)" @@ -2223,120 +2440,120 @@ msgstr "aktualisiert BISECT_HEAD, anstatt die aktuelle Version auszuchecken" msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "git blame [Optionen] [rev-opts] [rev] [--] Datei" -#: builtin/blame.c:30 builtin/shortlog.c:15 +#: builtin/blame.c:30 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-opts] sind dokumentiert in git-rev-list(1)" -#: builtin/blame.c:2350 +#: builtin/blame.c:2355 msgid "Show blame entries as we find them, incrementally" msgstr "Zeigt \"blame\"-Einträge schrittweise, während wir sie generieren" -#: builtin/blame.c:2351 +#: builtin/blame.c:2356 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "Zeigt leere SHA-1 für Grenzversionen (Standard: aus)" -#: builtin/blame.c:2352 +#: builtin/blame.c:2357 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "Behandelt Ursprungsversionen nicht als Grenzen (Standard: aus)" -#: builtin/blame.c:2353 +#: builtin/blame.c:2358 msgid "Show work cost statistics" msgstr "Zeigt Statistiken zum Arbeitsaufwand" -#: builtin/blame.c:2354 +#: builtin/blame.c:2359 msgid "Show output score for blame entries" msgstr "Zeigt Ausgabebewertung für \"blame\"-Einträge" -#: builtin/blame.c:2355 +#: builtin/blame.c:2360 msgid "Show original filename (Default: auto)" msgstr "Zeigt ursprünglichen Dateinamen (Standard: auto)" -#: builtin/blame.c:2356 +#: builtin/blame.c:2361 msgid "Show original linenumber (Default: off)" msgstr "Zeigt ursprüngliche Zeilennummer (Standard: aus)" -#: builtin/blame.c:2357 +#: builtin/blame.c:2362 msgid "Show in a format designed for machine consumption" msgstr "Anzeige in einem Format für maschinelle Auswertung" -#: builtin/blame.c:2358 +#: builtin/blame.c:2363 msgid "Show porcelain format with per-line commit information" msgstr "" "Anzeige in Format für Fremdprogramme mit Versionsinformationen pro Zeile" -#: builtin/blame.c:2359 +#: builtin/blame.c:2364 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "Benutzt den gleichen Ausgabemodus wie \"git-annotate\" (Standard: aus)" -#: builtin/blame.c:2360 +#: builtin/blame.c:2365 msgid "Show raw timestamp (Default: off)" msgstr "Zeigt unbearbeiteten Zeitstempel (Standard: aus)" -#: builtin/blame.c:2361 +#: builtin/blame.c:2366 msgid "Show long commit SHA1 (Default: off)" msgstr "Zeigt langen Versions-SHA1 (Standard: aus)" -#: builtin/blame.c:2362 +#: builtin/blame.c:2367 msgid "Suppress author name and timestamp (Default: off)" msgstr "Unterdrückt den Namen des Autors und den Zeitstempel (Standard: aus)" -#: builtin/blame.c:2363 +#: builtin/blame.c:2368 msgid "Show author email instead of name (Default: off)" msgstr "Zeigt anstatt des Namens die Email-Adresse des Autors (Standard: aus)" -#: builtin/blame.c:2364 +#: builtin/blame.c:2369 msgid "Ignore whitespace differences" msgstr "Ignoriert Unterschiede in Leerzeichen" -#: builtin/blame.c:2365 +#: builtin/blame.c:2370 msgid "Spend extra cycles to find better match" msgstr "arbeite länger, um bessere Ãœbereinstimmungen zu finden" -#: builtin/blame.c:2366 +#: builtin/blame.c:2371 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "Benutzt Revisionen von <Datei> anstatt \"git-rev-list\" aufzurufen" -#: builtin/blame.c:2367 +#: builtin/blame.c:2372 msgid "Use <file>'s contents as the final image" msgstr "Benutzt Inhalte der <Datei>en als entgültiges Abbild" -#: builtin/blame.c:2368 builtin/blame.c:2369 +#: builtin/blame.c:2373 builtin/blame.c:2374 msgid "score" msgstr "Bewertung" -#: builtin/blame.c:2368 +#: builtin/blame.c:2373 msgid "Find line copies within and across files" msgstr "Findet kopierte Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2369 +#: builtin/blame.c:2374 msgid "Find line movements within and across files" msgstr "Findet verschobene Zeilen innerhalb oder zwischen Dateien" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "Process only line range n,m, counting from 1" msgstr "Verarbeitet nur Zeilen im Bereich n,m, gezählt von 1" -#: builtin/branch.c:23 +#: builtin/branch.c:24 msgid "git branch [options] [-r | -a] [--merged | --no-merged]" msgstr "git branch [Optionen] [-r | -a] [--merged | --no-merged]" -#: builtin/branch.c:24 +#: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" msgstr "git branch [Optionen] [-l] [-f] <Zweigname> [<Startpunkt>]" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) <branchname>..." msgstr "git branch [Optionen] [-r] (-d | -D) <Zweigname>..." -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" msgstr "git branch [Optionen] (-m | -M) [<alterZweig>] <neuerZweig>" -#: builtin/branch.c:145 +#: builtin/branch.c:150 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -2346,7 +2563,7 @@ msgstr "" " '%s', aber noch nicht mit der Zweigspitze (HEAD) zusammengeführt " "wurde." -#: builtin/branch.c:149 +#: builtin/branch.c:154 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -2355,12 +2572,12 @@ msgstr "" "entferne Zweig '%s' nicht, der noch nicht zusammengeführt wurde mit\n" " '%s', obwohl er mit der Zweigspitze (HEAD) zusammengeführt wurde." -#: builtin/branch.c:163 +#: builtin/branch.c:168 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "Konnte Versionsobjekt für '%s' nicht nachschlagen." -#: builtin/branch.c:167 +#: builtin/branch.c:172 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -2370,293 +2587,340 @@ msgstr "" "Wenn Sie sicher sind diesen Zweig zu entfernen, führen Sie 'git branch -D " "%s' aus." -#: builtin/branch.c:180 +#: builtin/branch.c:185 msgid "Update of config-file failed" msgstr "Aktualisierung der Konfigurationsdatei fehlgeschlagen." -#: builtin/branch.c:208 +#: builtin/branch.c:213 msgid "cannot use -a with -d" msgstr "kann -a nicht mit -d benutzen" -#: builtin/branch.c:214 +#: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" msgstr "Konnte Versionsobjekt für Zweigspitze (HEAD) nicht nachschlagen." -#: builtin/branch.c:222 +#: builtin/branch.c:227 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "" "Kann Zweig '%s' nicht entfernen, da Sie sich gerade auf diesem befinden." -#: builtin/branch.c:235 +#: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." msgstr "externer Zweig '%s' nicht gefunden" -#: builtin/branch.c:236 +#: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." msgstr "Zweig '%s' nicht gefunden." -#: builtin/branch.c:250 +#: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" msgstr "Fehler beim Entfernen des externen Zweiges '%s'" -#: builtin/branch.c:251 +#: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" msgstr "Fehler beim Entfernen des Zweiges '%s'" -#: builtin/branch.c:258 +#: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Externer Zweig %s entfernt (war %s).\n" -#: builtin/branch.c:259 +#: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "Zweig %s entfernt (war %s).\n" -#: builtin/branch.c:361 +#: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" msgstr "Zweig '%s' zeigt auf keine Version" -#: builtin/branch.c:433 +#: builtin/branch.c:453 #, c-format msgid "[%s: behind %d]" msgstr "[%s: %d hinterher]" -#: builtin/branch.c:435 +#: builtin/branch.c:455 #, c-format msgid "[behind %d]" msgstr "[%d hinterher]" -#: builtin/branch.c:439 +#: builtin/branch.c:459 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: %d voraus]" -#: builtin/branch.c:441 +#: builtin/branch.c:461 #, c-format msgid "[ahead %d]" msgstr "[%d voraus]" -#: builtin/branch.c:444 +#: builtin/branch.c:464 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: %d voraus, %d hinterher]" -#: builtin/branch.c:447 +#: builtin/branch.c:467 #, c-format msgid "[ahead %d, behind %d]" msgstr "[%d voraus, %d hinterher]" -#: builtin/branch.c:469 +#: builtin/branch.c:490 msgid " **** invalid ref ****" msgstr " **** ungültige Referenz ****" -#: builtin/branch.c:560 +#: builtin/branch.c:582 +#, c-format +msgid "(no branch, rebasing %s)" +msgstr "(kein Zweig, Neuaufbau von Zweig %s im Gange)" + +#: builtin/branch.c:585 +#, c-format +msgid "(no branch, bisect started on %s)" +msgstr "(kein Zweig, Neuaufbau begonnen bei %s)" + +#: builtin/branch.c:588 +#, c-format +msgid "(detached from %s)" +msgstr "(losgelöst von %s)" + +#: builtin/branch.c:591 msgid "(no branch)" msgstr "(kein Zweig)" -#: builtin/branch.c:593 +#: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" msgstr "Objekt '%s' zeigt auf keine Version" -#: builtin/branch.c:625 +#: builtin/branch.c:669 msgid "some refs could not be read" msgstr "Konnte einige Referenzen nicht lesen" -#: builtin/branch.c:638 +#: builtin/branch.c:682 msgid "cannot rename the current branch while not on any." msgstr "" "Kann aktuellen Zweig nicht umbenennen, solange Sie sich auf keinem befinden." -#: builtin/branch.c:648 +#: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" msgstr "Ungültiger Zweig-Name: '%s'" -#: builtin/branch.c:663 +#: builtin/branch.c:707 msgid "Branch rename failed" msgstr "Umbenennung des Zweiges fehlgeschlagen" -#: builtin/branch.c:667 +#: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "falsch benannten Zweig '%s' umbenannt" -#: builtin/branch.c:671 +#: builtin/branch.c:715 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "Zweig umbenannt zu %s, aber Zweigspitze (HEAD) ist nicht aktualisiert!" -#: builtin/branch.c:678 +#: builtin/branch.c:722 msgid "Branch is renamed, but update of config-file failed" msgstr "" "Zweig ist umbenannt, aber die Aktualisierung der Konfigurationsdatei ist " "fehlgeschlagen." -#: builtin/branch.c:693 +#: builtin/branch.c:737 #, c-format msgid "malformed object name %s" msgstr "Missgebildeter Objektname %s" -#: builtin/branch.c:717 +#: builtin/branch.c:761 #, c-format msgid "could not write branch description template: %s" msgstr "Konnte Beschreibungsvorlage für Zweig nicht schreiben: %s" -#: builtin/branch.c:747 +#: builtin/branch.c:791 msgid "Generic options" msgstr "Allgemeine Optionen" -#: builtin/branch.c:749 +#: builtin/branch.c:793 msgid "show hash and subject, give twice for upstream branch" msgstr "Zeigt Hash und Betreff; -vv: zusätzlich externen Ãœbernahmezweig" -#: builtin/branch.c:750 +#: builtin/branch.c:794 msgid "suppress informational messages" msgstr "unterdrückt Informationsmeldungen" -#: builtin/branch.c:751 +#: builtin/branch.c:795 msgid "set up tracking mode (see git-pull(1))" msgstr "stellt den Ãœbernahmemodus ein (siehe git-pull(1))" -#: builtin/branch.c:753 +#: builtin/branch.c:797 msgid "change upstream info" msgstr "ändert Informationen zum externen Ãœbernahmezweig" -#: builtin/branch.c:757 +#: builtin/branch.c:801 msgid "use colored output" msgstr "verwendet farbliche Ausgaben" -#: builtin/branch.c:758 +#: builtin/branch.c:802 msgid "act on remote-tracking branches" msgstr "wirkt auf externe Ãœbernahmezweige" -#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 -#: builtin/branch.c:794 builtin/commit.c:1366 builtin/commit.c:1367 -#: builtin/commit.c:1368 builtin/commit.c:1369 builtin/tag.c:468 +#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 +#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 +#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 msgid "commit" msgstr "Version" -#: builtin/branch.c:762 builtin/branch.c:768 +#: builtin/branch.c:806 builtin/branch.c:812 msgid "print only branches that contain the commit" msgstr "gibt nur Zweige aus, welche diese Version beinhalten" -#: builtin/branch.c:774 +#: builtin/branch.c:818 msgid "Specific git-branch actions:" msgstr "spezifische Aktionen für \"git-branch\":" -#: builtin/branch.c:775 +#: builtin/branch.c:819 msgid "list both remote-tracking and local branches" msgstr "listet externe Ãœbernahmezweige und lokale Zweige auf" -#: builtin/branch.c:777 +#: builtin/branch.c:821 msgid "delete fully merged branch" msgstr "entfernt vollständig zusammengeführten Zweig" -#: builtin/branch.c:778 +#: builtin/branch.c:822 msgid "delete branch (even if not merged)" msgstr "löscht Zweig (auch wenn nicht zusammengeführt)" -#: builtin/branch.c:779 +#: builtin/branch.c:823 msgid "move/rename a branch and its reflog" msgstr "verschiebt/benennt einen Zweig und dessen Referenzprotokoll um" -#: builtin/branch.c:780 +#: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "" "verschiebt/benennt einen Zweig um, auch wenn das Ziel bereits existiert" -#: builtin/branch.c:781 +#: builtin/branch.c:825 msgid "list branch names" msgstr "listet Zweignamen auf" -#: builtin/branch.c:782 +#: builtin/branch.c:826 msgid "create the branch's reflog" msgstr "erzeugt das Referenzprotokoll des Zweiges" -#: builtin/branch.c:784 +#: builtin/branch.c:828 msgid "edit the description for the branch" msgstr "bearbeitet die Beschreibung für den Zweig" -#: builtin/branch.c:785 +#: builtin/branch.c:829 msgid "force creation (when already exists)" msgstr "erzeuge auch, wenn der Zweig bereits existiert" -#: builtin/branch.c:788 +#: builtin/branch.c:832 msgid "print only not merged branches" msgstr "gibt nur Zweige aus, die nicht zusammengeführt sind" -#: builtin/branch.c:794 +#: builtin/branch.c:838 msgid "print only merged branches" msgstr "gibt nur Zweige aus, die zusammengeführt sind" -#: builtin/branch.c:798 +#: builtin/branch.c:842 msgid "list branches in columns" msgstr "listet Zweige in Spalten auf" -#: builtin/branch.c:811 +#: builtin/branch.c:855 msgid "Failed to resolve HEAD as a valid ref." msgstr "Konnte Zweigspitze (HEAD) nicht als gültige Referenz auflösen." -#: builtin/branch.c:816 builtin/clone.c:561 +#: builtin/branch.c:860 builtin/clone.c:619 msgid "HEAD not found below refs/heads!" msgstr "Zweigspitze (HEAD) wurde nicht unter \"refs/heads\" gefunden!" -#: builtin/branch.c:839 +#: builtin/branch.c:883 msgid "--column and --verbose are incompatible" msgstr "Die Optionen --column und --verbose sind inkompatibel." -#: builtin/branch.c:845 +#: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" msgstr "Zweigname erforderlich" -#: builtin/branch.c:860 +#: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" msgstr "" "zu losgelöster Zweigspitze (HEAD) kann keine Beschreibung hinterlegt werden" -#: builtin/branch.c:865 +#: builtin/branch.c:909 msgid "cannot edit description of more than one branch" msgstr "Beschreibung von mehr als einem Zweig kann nicht bearbeitet werden" -#: builtin/branch.c:872 +#: builtin/branch.c:916 #, c-format msgid "No commit on branch '%s' yet." msgstr "Noch keine Version in Zweig '%s'." -#: builtin/branch.c:875 +#: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." msgstr "Zweig '%s' nicht vorhanden." -#: builtin/branch.c:888 +#: builtin/branch.c:934 msgid "too many branches for a rename operation" msgstr "zu viele Zweige für eine Umbenennen-Operation angegeben" -#: builtin/branch.c:893 +#: builtin/branch.c:939 +msgid "too many branches to set new upstream" +msgstr "zu viele Zweige angegeben um neuen Ãœbernahmezweig zu setzen" + +#: builtin/branch.c:943 +#, c-format +msgid "" +"could not set upstream of HEAD to %s when it does not point to any branch." +msgstr "" +"Konnte keinen neuen Ãœbernahmezweig von Zweigspitze (HEAD) zu %s setzen,\n" +"da diese auf keinen Zweig zeigt." + +#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 +#, c-format +msgid "no such branch '%s'" +msgstr "Kein solcher Zweig '%s'" + +#: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" msgstr "Zweig '%s' existiert nicht" -#: builtin/branch.c:905 +#: builtin/branch.c:962 +msgid "too many branches to unset upstream" +msgstr "" +"zu viele Zweige angegeben um Konfiguration zu Ãœbernahmezweig zu entfernen" + +#: builtin/branch.c:966 +msgid "could not unset upstream of HEAD when it does not point to any branch." +msgstr "" +"Konnte Konfiguration zum Ãœbernahmezweig von Zweigspitze (HEAD) nicht\n" +"entfernen, da diese auf keinen Zweig zeigt." + +#: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Zweig '%s' hat keinen externen Ãœbernahmezweig gesetzt" -#: builtin/branch.c:920 +#: builtin/branch.c:987 +msgid "it does not make sense to create 'HEAD' manually" +msgstr "'HEAD' darf nicht manuell erstellt werden" + +#: builtin/branch.c:993 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "Die Optionen -a und -r bei 'git branch' können nicht gemeimsam mit einem " "Zweignamen verwendet werden." -#: builtin/branch.c:923 +#: builtin/branch.c:996 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2665,7 +2929,7 @@ msgstr "" "Die --set-upstream Option ist veraltet und wird entfernt. Benutzen Sie --" "track oder --set-upstream-to\n" -#: builtin/branch.c:940 +#: builtin/branch.c:1013 #, c-format msgid "" "\n" @@ -2676,12 +2940,12 @@ msgstr "" "Wenn Sie wollten, dass '%s' den Zweig '%s' als externen Ãœbernahmezweig hat, " "führen Sie aus:\n" -#: builtin/branch.c:941 +#: builtin/branch.c:1014 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:942 +#: builtin/branch.c:1015 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2699,45 +2963,45 @@ msgstr "Um ein Paket zu erstellen wird ein Projektarchiv benötigt." msgid "Need a repository to unbundle." msgstr "Zum Entpacken wird ein Projektarchiv benötigt." -#: builtin/cat-file.c:247 +#: builtin/cat-file.c:176 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>" msgstr "git cat-file (-t|-s|-e|-p|<Art>|--textconv) <Objekt>" -#: builtin/cat-file.c:248 +#: builtin/cat-file.c:177 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>" msgstr "git cat-file (--batch|--batch-check) < <Liste_von_Objekten>" -#: builtin/cat-file.c:266 +#: builtin/cat-file.c:195 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "<Art> kann sein: blob, tree, commit, tag" -#: builtin/cat-file.c:267 +#: builtin/cat-file.c:196 msgid "show object type" msgstr "zeigt Objektart" -#: builtin/cat-file.c:268 +#: builtin/cat-file.c:197 msgid "show object size" msgstr "zeigt Objektgröße" -#: builtin/cat-file.c:270 +#: builtin/cat-file.c:199 msgid "exit with zero when there's no error" msgstr "beendet mit Rückgabewert 0, wenn kein Fehler aufgetreten ist" -#: builtin/cat-file.c:271 +#: builtin/cat-file.c:200 msgid "pretty-print object's content" msgstr "ansprechende Anzeige des Objektinhaltes" -#: builtin/cat-file.c:273 +#: builtin/cat-file.c:202 msgid "for blob objects, run textconv on object's content" msgstr "führt eine Textkonvertierung auf den Inhalt von Blob-Objekten aus" -#: builtin/cat-file.c:275 +#: builtin/cat-file.c:204 msgid "show info and content of objects fed from the standard input" msgstr "" "Anzeige von Informationen und Inhalt von Objekten, gelesen von der Standard-" "Eingabe" -#: builtin/cat-file.c:278 +#: builtin/cat-file.c:207 msgid "show info about objects fed from the standard input" msgstr "" "Anzeige von Informationen über Objekte, gelesen von der Standard-Eingabe" @@ -2767,27 +3031,27 @@ msgstr "liest Dateinamen von der Standard-Eingabe" msgid "input paths are terminated by a null character" msgstr "Eingabepfade sind durch ein NUL Zeichen abgeschlossen" -#: builtin/check-ignore.c:18 builtin/checkout.c:1012 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "unterdrückt Fortschrittsanzeige" -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:146 msgid "cannot specify pathnames with --stdin" msgstr "Angabe von Pfadnamen kann nicht gemeinsam mit --stdin verwendet werden" -#: builtin/check-ignore.c:154 +#: builtin/check-ignore.c:149 msgid "-z only makes sense with --stdin" msgstr "Die Option -z kann nur mit --stdin verwendet werden." -#: builtin/check-ignore.c:156 +#: builtin/check-ignore.c:151 msgid "no path specified" msgstr "kein Pfad angegeben" -#: builtin/check-ignore.c:160 +#: builtin/check-ignore.c:155 msgid "--quiet is only valid with a single pathname" msgstr "Die Option --quiet ist nur mit einem einzelnen Pfadnamen gültig." -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:157 msgid "cannot have both --quiet and --verbose" msgstr "" "Die Optionen --quiet und --verbose können nicht gemeinsam verwendet werden." @@ -2847,106 +3111,106 @@ msgstr "git checkout [Optionen] <Zweig>" msgid "git checkout [options] [<branch>] -- <file>..." msgstr "git checkout [Optionen] [Zweig>] -- <Datei>..." -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format msgid "path '%s' does not have our version" msgstr "Pfad '%s' hat nicht unsere Version." -#: builtin/checkout.c:118 builtin/checkout.c:151 +#: builtin/checkout.c:119 builtin/checkout.c:152 #, c-format msgid "path '%s' does not have their version" msgstr "Pfad '%s' hat nicht deren Version." -#: builtin/checkout.c:134 +#: builtin/checkout.c:135 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "Pfad '%s' hat nicht alle notwendigen Versionen." -#: builtin/checkout.c:178 +#: builtin/checkout.c:179 #, c-format msgid "path '%s' does not have necessary versions" msgstr "Pfad '%s' hat nicht die notwendigen Versionen." -#: builtin/checkout.c:195 +#: builtin/checkout.c:196 #, c-format msgid "path '%s': cannot merge" msgstr "Pfad '%s': kann nicht zusammenführen" -#: builtin/checkout.c:212 +#: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Konnte Ergebnis der Zusammenführung von '%s' nicht hinzufügen." -#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 -#: builtin/checkout.c:245 +#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 +#: builtin/checkout.c:246 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "'%s' kann nicht mit Pfaden verwendet werden" -#: builtin/checkout.c:248 builtin/checkout.c:251 +#: builtin/checkout.c:249 builtin/checkout.c:252 #, c-format msgid "'%s' cannot be used with %s" msgstr "'%s' kann nicht mit '%s' verwendet werden" -#: builtin/checkout.c:254 +#: builtin/checkout.c:255 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "Kann nicht gleichzeitig Pfade aktualisieren und zu Zweig '%s' wechseln" -#: builtin/checkout.c:265 builtin/checkout.c:426 +#: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" msgstr "beschädigte Bereitstellungsdatei" -#: builtin/checkout.c:295 builtin/checkout.c:302 +#: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format msgid "path '%s' is unmerged" msgstr "Pfad '%s' ist nicht zusammengeführt." -#: builtin/checkout.c:448 +#: builtin/checkout.c:480 msgid "you need to resolve your current index first" msgstr "Sie müssen zuerst Ihre aktuelle Bereitstellung auflösen." -#: builtin/checkout.c:569 +#: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "Konnte \"reflog\" für '%s' nicht durchführen\n" -#: builtin/checkout.c:602 +#: builtin/checkout.c:634 msgid "HEAD is now at" msgstr "Zweigspitze (HEAD) ist jetzt bei" -#: builtin/checkout.c:609 +#: builtin/checkout.c:641 #, c-format msgid "Reset branch '%s'\n" msgstr "Setze Zweig '%s' neu\n" -#: builtin/checkout.c:612 +#: builtin/checkout.c:644 #, c-format msgid "Already on '%s'\n" msgstr "Bereits auf '%s'\n" -#: builtin/checkout.c:616 +#: builtin/checkout.c:648 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Gewechselt zu neu gesetztem Zweig '%s'\n" -#: builtin/checkout.c:618 builtin/checkout.c:955 +#: builtin/checkout.c:650 builtin/checkout.c:987 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Gewechselt zu einem neuen Zweig '%s'\n" -#: builtin/checkout.c:620 +#: builtin/checkout.c:652 #, c-format msgid "Switched to branch '%s'\n" msgstr "Gewechselt zu Zweig '%s'\n" -#: builtin/checkout.c:676 +#: builtin/checkout.c:708 #, c-format msgid " ... and %d more.\n" msgstr " ... und %d weitere.\n" #. The singular version -#: builtin/checkout.c:682 +#: builtin/checkout.c:714 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2969,7 +3233,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:700 +#: builtin/checkout.c:732 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2984,132 +3248,136 @@ msgstr "" " git branch neuer_zweig_name %s\n" "\n" -#: builtin/checkout.c:730 +#: builtin/checkout.c:762 msgid "internal error in revision walk" msgstr "interner Fehler im Revisionsgang" -#: builtin/checkout.c:734 +#: builtin/checkout.c:766 msgid "Previous HEAD position was" msgstr "Vorherige Position der Zweigspitze (HEAD) war" -#: builtin/checkout.c:761 builtin/checkout.c:950 +#: builtin/checkout.c:793 builtin/checkout.c:982 msgid "You are on a branch yet to be born" msgstr "Sie sind auf einem Zweig, der noch geboren wird" #. case (1) -#: builtin/checkout.c:886 +#: builtin/checkout.c:918 #, c-format msgid "invalid reference: %s" msgstr "Ungültige Referenz: %s" #. case (1): want a tree -#: builtin/checkout.c:925 +#: builtin/checkout.c:957 #, c-format msgid "reference is not a tree: %s" msgstr "Referenz ist kein Baum: %s" -#: builtin/checkout.c:964 +#: builtin/checkout.c:996 msgid "paths cannot be used with switching branches" msgstr "Pfade können nicht beim Wechseln von Zweigen verwendet werden" -#: builtin/checkout.c:967 builtin/checkout.c:971 +#: builtin/checkout.c:999 builtin/checkout.c:1003 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "'%s' kann nicht beim Wechseln von Zweigen verwendet werden" -#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 -#: builtin/checkout.c:986 +#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 +#: builtin/checkout.c:1018 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' kann nicht mit '%s' verwendet werden" -#: builtin/checkout.c:991 +#: builtin/checkout.c:1023 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "Kann Zweig nicht zu Nicht-Version '%s' wechseln" -#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "Zweig" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1046 msgid "create and checkout a new branch" msgstr "erzeugt und checkt einen neuen Zweig aus" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1048 msgid "create/reset and checkout a branch" msgstr "erzeugt/setzt neu und checkt einen Zweig aus" -#: builtin/checkout.c:1017 +#: builtin/checkout.c:1049 msgid "create reflog for new branch" msgstr "erzeugt Referenzprotokoll für den neuen Zweig" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1050 msgid "detach the HEAD at named commit" msgstr "setzt die Zweigspitze (HEAD) zu benannter Version" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1051 msgid "set upstream info for new branch" msgstr "setzt Informationen zum externen Ãœbernahmezweig für den neuen Zweig" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new branch" msgstr "neuer Zweig" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new unparented branch" msgstr "neuer Zweig ohne Elternversion" -#: builtin/checkout.c:1022 +#: builtin/checkout.c:1054 msgid "checkout our version for unmerged files" msgstr "checkt unsere Variante für nicht zusammengeführte Dateien aus" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1056 msgid "checkout their version for unmerged files" msgstr "checkt ihre Variante für nicht zusammengeführte Dateien aus" -#: builtin/checkout.c:1026 +#: builtin/checkout.c:1058 msgid "force checkout (throw away local modifications)" msgstr "erzwingt Auschecken (verwirft lokale Änderungen)" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1059 msgid "perform a 3-way merge with the new branch" msgstr "führt eine 3-Wege-Zusammenführung mit dem neuen Zweig aus" -#: builtin/checkout.c:1028 builtin/merge.c:215 +#: builtin/checkout.c:1060 builtin/merge.c:217 msgid "update ignored files (default)" msgstr "aktualisiert ignorierte Dateien (Standard)" -#: builtin/checkout.c:1029 builtin/log.c:1147 parse-options.h:245 +#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 msgid "style" msgstr "Stil" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1062 msgid "conflict style (merge or diff3)" msgstr "Konfliktstil (merge oder diff3)" -#: builtin/checkout.c:1033 +#: builtin/checkout.c:1065 +msgid "do not limit pathspecs to sparse entries only" +msgstr "Pfadspezifikationen ignorieren Einstellungen zum partiellen Auschecken" + +#: builtin/checkout.c:1067 msgid "second guess 'git checkout no-such-branch'" msgstr "second guess 'git checkout no-such-branch'" -#: builtin/checkout.c:1057 +#: builtin/checkout.c:1091 msgid "-b, -B and --orphan are mutually exclusive" msgstr "Die Optionen -b, -B und --orphan schließen sich gegenseitig aus." -#: builtin/checkout.c:1074 +#: builtin/checkout.c:1108 msgid "--track needs a branch name" msgstr "Bei der Option --track muss ein Zweigname angegeben werden." -#: builtin/checkout.c:1081 +#: builtin/checkout.c:1115 msgid "Missing branch name; try -b" msgstr "Vermisse Zweignamen; versuchen Sie -b" -#: builtin/checkout.c:1116 +#: builtin/checkout.c:1150 msgid "invalid path specification" msgstr "ungültige Pfadspezifikation" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1157 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -3119,12 +3387,12 @@ msgstr "" "Haben Sie beabsichtigt '%s' auszuchecken, welcher nicht als Version " "aufgelöst werden kann?" -#: builtin/checkout.c:1128 +#: builtin/checkout.c:1162 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: --detach nimmt kein Pfad-Argument '%s'" -#: builtin/checkout.c:1132 +#: builtin/checkout.c:1166 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -3173,8 +3441,8 @@ msgstr "erzwingt Aktion" msgid "remove whole directories" msgstr "löscht ganze Verzeichnisse" -#: builtin/clean.c:165 builtin/describe.c:413 builtin/grep.c:717 -#: builtin/ls-files.c:494 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 +#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "Muster" @@ -3209,220 +3477,238 @@ msgstr "" "clean.requireForce standardmäßig auf \"true\" gesetzt und weder -n noch -f " "gegeben; Säuberung verweigert" -#: builtin/clone.c:36 +#: builtin/clone.c:37 msgid "git clone [options] [--] <repo> [<dir>]" msgstr "git clone [Optionen] [--] <Projektarchiv> [<Verzeichnis>]" -#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:212 +#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 #: builtin/push.c:436 msgid "force progress reporting" msgstr "erzwingt Fortschrittsanzeige" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "don't create a checkout" msgstr "kein Auschecken" -#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 msgid "create a bare repository" msgstr "erstellt ein bloßes Projektarchiv" -#: builtin/clone.c:72 +#: builtin/clone.c:73 msgid "create a mirror repository (implies bare)" msgstr "erstellt ein Spiegelarchiv (impliziert bloßes Projektarchiv)" -#: builtin/clone.c:74 +#: builtin/clone.c:75 msgid "to clone from a local repository" msgstr "um von einem lokalen Projektarchiv zu klonen" -#: builtin/clone.c:76 +#: builtin/clone.c:77 msgid "don't use local hardlinks, always copy" msgstr "verwendet lokal keine harten Links, immer Kopien" -#: builtin/clone.c:78 +#: builtin/clone.c:79 msgid "setup as shared repository" msgstr "Einrichtung als verteiltes Projektarchiv" -#: builtin/clone.c:80 builtin/clone.c:82 +#: builtin/clone.c:81 builtin/clone.c:83 msgid "initialize submodules in the clone" msgstr "initialisiert Unterprojekte im Klon" -#: builtin/clone.c:83 builtin/init-db.c:485 +#: builtin/clone.c:84 builtin/init-db.c:485 msgid "template-directory" msgstr "Vorlagenverzeichnis" -#: builtin/clone.c:84 builtin/init-db.c:486 +#: builtin/clone.c:85 builtin/init-db.c:486 msgid "directory from which templates will be used" msgstr "Verzeichnis, von welchem die Vorlagen verwendet werden" -#: builtin/clone.c:86 +#: builtin/clone.c:87 msgid "reference repository" msgstr "referenziert Projektarchiv" -#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "Name" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "use <name> instead of 'origin' to track upstream" msgstr "verwendet <Name> statt 'origin' für externes Projektarchiv" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "checkout <branch> instead of the remote's HEAD" msgstr "" "checkt <Zweig> aus, anstatt Zweigspitze (HEAD) des externen Projektarchivs" -#: builtin/clone.c:92 +#: builtin/clone.c:93 msgid "path to git-upload-pack on the remote" msgstr "Pfad zu \"git-upload-pack\" auf der Gegenseite" -#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "Tiefe" -#: builtin/clone.c:94 +#: builtin/clone.c:95 msgid "create a shallow clone of that depth" msgstr "erstellt einen flachen Klon mit dieser Tiefe" -#: builtin/clone.c:96 +#: builtin/clone.c:97 msgid "clone only one branch, HEAD or --branch" msgstr "klont nur einen Zweig, Zweigspitze (HEAD) oder --branch" -#: builtin/clone.c:97 builtin/init-db.c:494 +#: builtin/clone.c:98 builtin/init-db.c:494 msgid "gitdir" msgstr ".git-Verzeichnis" -#: builtin/clone.c:98 builtin/init-db.c:495 +#: builtin/clone.c:99 builtin/init-db.c:495 msgid "separate git dir from working tree" msgstr "separiert Git-Verzeichnis vom Arbeitsbaum" -#: builtin/clone.c:99 +#: builtin/clone.c:100 msgid "key=value" msgstr "Schlüssel=Wert" -#: builtin/clone.c:100 +#: builtin/clone.c:101 msgid "set config inside the new repository" msgstr "setzt Konfiguration innerhalb des neuen Projektarchivs" -#: builtin/clone.c:243 +#: builtin/clone.c:254 #, c-format -msgid "reference repository '%s' is not a local directory." -msgstr "Referenziertes Projektarchiv '%s' ist kein lokales Verzeichnis." +msgid "reference repository '%s' is not a local repository." +msgstr "Referenziertes Projektarchiv '%s' ist kein lokales Projektarchiv." -#: builtin/clone.c:306 +#: builtin/clone.c:317 #, c-format msgid "failed to create directory '%s'" msgstr "Fehler beim Erstellen von Verzeichnis '%s'" -#: builtin/clone.c:308 builtin/diff.c:77 +#: builtin/clone.c:319 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/clone.c:310 +#: builtin/clone.c:321 #, c-format msgid "%s exists and is not a directory" msgstr "%s existiert und ist kein Verzeichnis" -#: builtin/clone.c:324 +#: builtin/clone.c:335 #, c-format msgid "failed to stat %s\n" msgstr "Konnte %s nicht lesen\n" -#: builtin/clone.c:346 +#: builtin/clone.c:357 #, c-format msgid "failed to create link '%s'" msgstr "Konnte Verknüpfung '%s' nicht erstellen" -#: builtin/clone.c:350 +#: builtin/clone.c:361 #, c-format msgid "failed to copy file to '%s'" msgstr "Konnte Datei nicht nach '%s' kopieren" -#: builtin/clone.c:373 +#: builtin/clone.c:384 #, c-format msgid "done.\n" msgstr "Fertig.\n" -#: builtin/clone.c:443 +#: builtin/clone.c:397 +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 "" +"Klonen erfolgreich, Auschecken ist aber fehlgeschlagen.\n" +"Sie können mit 'git status' prüfen, was ausgecheckt worden ist\n" +"und das Auschecken mit 'git checkout -f HEAD' erneut versuchen.\n" + +#: builtin/clone.c:476 #, c-format msgid "Could not find remote branch %s to clone." msgstr "Konnte zu klonenden externer Zweig %s nicht finden." -#: builtin/clone.c:552 +#: builtin/clone.c:550 +msgid "remote did not send all necessary objects" +msgstr "Fernarchiv hat nicht alle erforderlichen Objekte gesendet." + +#: builtin/clone.c:610 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" "Externe Zweigspitze (HEAD) bezieht sich auf eine nicht existierende Referenz " "und kann nicht ausgecheckt werden.\n" -#: builtin/clone.c:690 +#: builtin/clone.c:641 +msgid "unable to checkout working tree" +msgstr "Arbeitsbaum konnte nicht ausgecheckt werden" + +#: builtin/clone.c:749 msgid "Too many arguments." msgstr "Zu viele Argumente." -#: builtin/clone.c:694 +#: builtin/clone.c:753 msgid "You must specify a repository to clone." msgstr "Sie müssen ein Projektarchiv zum Klonen angeben." -#: builtin/clone.c:705 +#: builtin/clone.c:764 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "Die Optionen --bare und --origin %s sind inkompatibel." -#: builtin/clone.c:708 +#: builtin/clone.c:767 msgid "--bare and --separate-git-dir are incompatible." msgstr "Die Optionen --bare und --separate-git-dir sind inkompatibel." -#: builtin/clone.c:721 +#: builtin/clone.c:780 #, c-format msgid "repository '%s' does not exist" msgstr "Projektarchiv '%s' existiert nicht." -#: builtin/clone.c:726 +#: builtin/clone.c:785 msgid "--depth is ignored in local clones; use file:// instead." msgstr "" "Die Option --depth wird in lokalen Klonen ignoriert; benutzen Sie " "stattdessen file://" -#: builtin/clone.c:736 +#: builtin/clone.c:795 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "Zielpfad '%s' existiert bereits und ist kein leeres Verzeichnis." -#: builtin/clone.c:746 +#: builtin/clone.c:805 #, c-format msgid "working tree '%s' already exists." msgstr "Arbeitsbaum '%s' existiert bereits." -#: builtin/clone.c:759 builtin/clone.c:771 +#: builtin/clone.c:818 builtin/clone.c:830 #, c-format msgid "could not create leading directories of '%s'" msgstr "Konnte führende Verzeichnisse von '%s' nicht erstellen." -#: builtin/clone.c:762 +#: builtin/clone.c:821 #, c-format msgid "could not create work tree dir '%s'." msgstr "Konnte Arbeitsverzeichnis '%s' nicht erstellen." -#: builtin/clone.c:781 +#: builtin/clone.c:840 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Klone in bloßes Projektarchiv '%s'...\n" -#: builtin/clone.c:783 +#: builtin/clone.c:842 #, c-format msgid "Cloning into '%s'...\n" msgstr "Klone nach '%s'...\n" -#: builtin/clone.c:818 +#: builtin/clone.c:877 #, c-format msgid "Don't know how to clone %s" msgstr "Weiß nicht wie %s zu klonen ist." -#: builtin/clone.c:867 +#: builtin/clone.c:926 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "externer Zweig %s nicht im anderen Projektarchiv %s gefunden" -#: builtin/clone.c:874 +#: builtin/clone.c:933 msgid "You appear to have cloned an empty repository." msgstr "Sie scheinen ein leeres Projektarchiv geklont zu haben." @@ -3519,97 +3805,97 @@ msgstr "" "\n" "Andernfalls benutzen Sie bitte 'git reset'\n" -#: builtin/commit.c:258 +#: builtin/commit.c:260 msgid "failed to unpack HEAD tree object" msgstr "Fehler beim Entpacken des Baum-Objektes der Zweigspitze (HEAD)." -#: builtin/commit.c:300 +#: builtin/commit.c:302 msgid "unable to create temporary index" msgstr "Konnte temporäre Bereitstellung nicht erstellen." -#: builtin/commit.c:306 +#: builtin/commit.c:308 msgid "interactive add failed" msgstr "interaktives Hinzufügen fehlgeschlagen" -#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 +#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 msgid "unable to write new_index file" msgstr "Konnte new_index Datei nicht schreiben" -#: builtin/commit.c:391 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a merge." msgstr "" "Kann keine partielle Eintragung durchführen, während eine Zusammenführung im " "Gange ist." -#: builtin/commit.c:393 +#: builtin/commit.c:395 msgid "cannot do a partial commit during a cherry-pick." msgstr "" "Kann keine partielle Eintragung durchführen, während \"cherry-pick\" im " "Gange ist." -#: builtin/commit.c:403 +#: builtin/commit.c:405 msgid "cannot read the index" msgstr "Kann Bereitstellung nicht lesen" -#: builtin/commit.c:423 +#: builtin/commit.c:425 msgid "unable to write temporary index file" msgstr "Konnte temporäre Bereitstellungsdatei nicht schreiben." -#: builtin/commit.c:511 builtin/commit.c:517 +#: builtin/commit.c:513 builtin/commit.c:519 #, c-format msgid "invalid commit: %s" msgstr "Ungültige Version: %s" -#: builtin/commit.c:540 +#: builtin/commit.c:542 msgid "malformed --author parameter" msgstr "Fehlerhafter --author Parameter" -#: builtin/commit.c:560 +#: builtin/commit.c:562 #, c-format msgid "Malformed ident string: '%s'" msgstr "Fehlerhafte Identifikations-String: '%s'" -#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 +#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 #, c-format msgid "could not lookup commit %s" msgstr "Konnte Version %s nicht nachschlagen" -#: builtin/commit.c:610 builtin/shortlog.c:272 +#: builtin/commit.c:612 builtin/shortlog.c:270 #, c-format msgid "(reading log message from standard input)\n" msgstr "(lese Log-Nachricht von Standard-Eingabe)\n" -#: builtin/commit.c:612 +#: builtin/commit.c:614 msgid "could not read log from standard input" msgstr "Konnte Log nicht von Standard-Eingabe lesen." -#: builtin/commit.c:616 +#: builtin/commit.c:618 #, c-format msgid "could not read log file '%s'" msgstr "Konnte Log-Datei '%s' nicht lesen" -#: builtin/commit.c:622 +#: builtin/commit.c:624 msgid "commit has empty message" msgstr "Version hat eine leere Beschreibung" -#: builtin/commit.c:638 +#: builtin/commit.c:640 msgid "could not read MERGE_MSG" msgstr "Konnte MERGE_MSG nicht lesen" -#: builtin/commit.c:642 +#: builtin/commit.c:644 msgid "could not read SQUASH_MSG" msgstr "Konnte SQUASH_MSG nicht lesen" -#: builtin/commit.c:646 +#: builtin/commit.c:648 #, c-format msgid "could not read '%s'" msgstr "Konnte '%s' nicht lesen" -#: builtin/commit.c:707 +#: builtin/commit.c:709 msgid "could not write commit template" msgstr "Konnte Versionsvorlage nicht schreiben" -#: builtin/commit.c:718 +#: builtin/commit.c:720 #, c-format msgid "" "\n" @@ -3624,7 +3910,7 @@ msgstr "" "\t%s\n" "und versuchen Sie es erneut.\n" -#: builtin/commit.c:723 +#: builtin/commit.c:725 #, c-format msgid "" "\n" @@ -3639,7 +3925,7 @@ msgstr "" "\t%s\n" "und versuchen Sie es erneut.\n" -#: builtin/commit.c:735 +#: builtin/commit.c:737 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3650,7 +3936,7 @@ msgstr "" "Versionsbeschreibung\n" "bricht die Eintragung ab.\n" -#: builtin/commit.c:740 +#: builtin/commit.c:742 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3663,151 +3949,151 @@ msgstr "" "entfernen.\n" "Eine leere Versionsbeschreibung bricht die Eintragung ab.\n" -#: builtin/commit.c:753 +#: builtin/commit.c:755 #, c-format msgid "%sAuthor: %s" msgstr "%sAutor: %s" -#: builtin/commit.c:760 +#: builtin/commit.c:762 #, c-format msgid "%sCommitter: %s" msgstr "%sEintragender: %s" -#: builtin/commit.c:780 +#: builtin/commit.c:782 msgid "Cannot read index" msgstr "Kann Bereitstellung nicht lesen" -#: builtin/commit.c:817 +#: builtin/commit.c:819 msgid "Error building trees" msgstr "Fehler beim Erzeugen der Zweige" -#: builtin/commit.c:832 builtin/tag.c:359 +#: builtin/commit.c:834 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Bitte liefere eine Beschreibung entweder mit der Option -m oder -F.\n" -#: builtin/commit.c:929 +#: builtin/commit.c:931 #, c-format msgid "No existing author found with '%s'" msgstr "Kein existierender Autor mit '%s' gefunden." -#: builtin/commit.c:944 builtin/commit.c:1138 +#: builtin/commit.c:946 builtin/commit.c:1140 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ungültiger Modus '%s' für unbeobachtete Dateien" -#: builtin/commit.c:974 +#: builtin/commit.c:976 msgid "Using both --reset-author and --author does not make sense" msgstr "" "Die Optionen --reset-author und --author können nicht gemeinsam verwendet " "werden." -#: builtin/commit.c:985 +#: builtin/commit.c:987 msgid "You have nothing to amend." msgstr "Sie haben nichts zum nachbessern." -#: builtin/commit.c:988 +#: builtin/commit.c:990 msgid "You are in the middle of a merge -- cannot amend." msgstr "Eine Zusammenführung ist im Gange -- kann nicht nachbessern." -#: builtin/commit.c:990 +#: builtin/commit.c:992 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "\"cherry-pick\" ist im Gange -- kann nicht nachbessern." -#: builtin/commit.c:993 +#: builtin/commit.c:995 msgid "Options --squash and --fixup cannot be used together" msgstr "" "Die Optionen --squash und --fixup können nicht gemeinsam verwendet werden." -#: builtin/commit.c:1003 +#: builtin/commit.c:1005 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Es kann nur eine Option von -c/-C/-F/--fixup verwendet werden." -#: builtin/commit.c:1005 +#: builtin/commit.c:1007 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "Die Option -m kann nicht mit -c/-C/-F/--fixup kombiniert werden." -#: builtin/commit.c:1013 +#: builtin/commit.c:1015 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" "Die Option --reset--author kann nur mit -C, -c oder --amend verwendet werden." -#: builtin/commit.c:1030 +#: builtin/commit.c:1032 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Es kann nur eine Option von --include/--only/--all/--interactive/--patch " "verwendet werden." -#: builtin/commit.c:1032 +#: builtin/commit.c:1034 msgid "No paths with --include/--only does not make sense." msgstr "" "Die Optionen --include und --only können nur mit der Angabe von Pfaden " "verwendet werden." -#: builtin/commit.c:1034 +#: builtin/commit.c:1036 msgid "Clever... amending the last one with dirty index." msgstr "" "Klug... die letzte Version mit einer unsauberen Bereitstellung nachbessern." -#: builtin/commit.c:1036 +#: builtin/commit.c:1038 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "" "Explizite Pfade ohne -i oder -o angegeben; unter der Annahme von --only " "Pfaden..." -#: builtin/commit.c:1046 builtin/tag.c:575 +#: builtin/commit.c:1048 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "Ungültiger \"cleanup\" Modus %s" -#: builtin/commit.c:1051 +#: builtin/commit.c:1053 msgid "Paths with -a does not make sense." msgstr "Die Option -a kann nur mit der Angabe von Pfaden verwendet werden." -#: builtin/commit.c:1057 builtin/commit.c:1192 +#: builtin/commit.c:1059 builtin/commit.c:1194 msgid "--long and -z are incompatible" msgstr "Die Optionen --long und -z sind inkompatibel." -#: builtin/commit.c:1152 builtin/commit.c:1388 +#: builtin/commit.c:1154 builtin/commit.c:1390 msgid "show status concisely" msgstr "zeigt Status im Kurzformat" -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1156 builtin/commit.c:1392 msgid "show branch information" msgstr "zeigt Zweiginformationen" -#: builtin/commit.c:1156 builtin/commit.c:1392 builtin/push.c:426 +#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 msgid "machine-readable output" msgstr "maschinenlesbare Ausgabe" -#: builtin/commit.c:1159 builtin/commit.c:1394 +#: builtin/commit.c:1161 builtin/commit.c:1396 msgid "show status in long format (default)" msgstr "zeigt Status im Langformat (Standard)" -#: builtin/commit.c:1162 builtin/commit.c:1397 +#: builtin/commit.c:1164 builtin/commit.c:1399 msgid "terminate entries with NUL" msgstr "schließt Einträge mit NUL-Zeichen ab" -#: builtin/commit.c:1164 builtin/commit.c:1400 builtin/fast-export.c:647 -#: builtin/fast-export.c:650 builtin/tag.c:459 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 +#: builtin/fast-export.c:662 builtin/tag.c:459 msgid "mode" msgstr "Modus" -#: builtin/commit.c:1165 builtin/commit.c:1400 +#: builtin/commit.c:1167 builtin/commit.c:1402 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" "zeigt nicht beobachtete Dateien, optionale Modi: all, normal, no. (Standard: " "all)" -#: builtin/commit.c:1168 +#: builtin/commit.c:1170 msgid "show ignored files" msgstr "zeigt ignorierte Dateien" -#: builtin/commit.c:1169 parse-options.h:151 +#: builtin/commit.c:1171 parse-options.h:151 msgid "when" msgstr "wann" -#: builtin/commit.c:1170 +#: builtin/commit.c:1172 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -3815,219 +4101,219 @@ msgstr "" "ignoriert Änderungen in Unterprojekten, optional wenn: all, dirty, " "untracked. (Standard: all)" -#: builtin/commit.c:1172 +#: builtin/commit.c:1174 msgid "list untracked files in columns" msgstr "listet unbeobachtete Dateien in Spalten auf" -#: builtin/commit.c:1246 +#: builtin/commit.c:1248 msgid "couldn't look up newly created commit" msgstr "Konnte neu erstellte Version nicht nachschlagen." -#: builtin/commit.c:1248 +#: builtin/commit.c:1250 msgid "could not parse newly created commit" msgstr "Konnte neulich erstellte Version nicht analysieren." -#: builtin/commit.c:1289 +#: builtin/commit.c:1291 msgid "detached HEAD" msgstr "losgelöste Zweigspitze (HEAD)" -#: builtin/commit.c:1291 +#: builtin/commit.c:1293 msgid " (root-commit)" msgstr " (Basis-Version)" -#: builtin/commit.c:1358 +#: builtin/commit.c:1360 msgid "suppress summary after successful commit" msgstr "unterdrückt Zusammenfassung nach erfolgreicher Eintragung" -#: builtin/commit.c:1359 +#: builtin/commit.c:1361 msgid "show diff in commit message template" msgstr "zeigt Unterschiede in Versionsbeschreibungsvorlage an" -#: builtin/commit.c:1361 +#: builtin/commit.c:1363 msgid "Commit message options" msgstr "Optionen für Versionsbeschreibung" -#: builtin/commit.c:1362 builtin/tag.c:457 +#: builtin/commit.c:1364 builtin/tag.c:457 msgid "read message from file" msgstr "liest Beschreibung von Datei" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "author" msgstr "Autor" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "override author for commit" msgstr "überschreibt Autor von Version" -#: builtin/commit.c:1364 builtin/gc.c:178 +#: builtin/commit.c:1366 builtin/gc.c:178 msgid "date" msgstr "Datum" -#: builtin/commit.c:1364 +#: builtin/commit.c:1366 msgid "override date for commit" msgstr "überschreibt Datum von Version" -#: builtin/commit.c:1365 builtin/merge.c:206 builtin/notes.c:533 +#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 #: builtin/notes.c:690 builtin/tag.c:455 msgid "message" msgstr "Beschreibung" -#: builtin/commit.c:1365 +#: builtin/commit.c:1367 msgid "commit message" msgstr "Versionsbeschreibung" -#: builtin/commit.c:1366 +#: builtin/commit.c:1368 msgid "reuse and edit message from specified commit" msgstr "verwendet wieder und editiert Beschreibung von der angegebenen Version" -#: builtin/commit.c:1367 +#: builtin/commit.c:1369 msgid "reuse message from specified commit" msgstr "verwendet Beschreibung der angegebenen Version wieder" -#: builtin/commit.c:1368 +#: builtin/commit.c:1370 msgid "use autosquash formatted message to fixup specified commit" msgstr "" "verwendet eine automatisch zusammengesetzte Beschreibung zum Nachbessern der " "angegebenen Version" -#: builtin/commit.c:1369 +#: builtin/commit.c:1371 msgid "use autosquash formatted message to squash specified commit" msgstr "" "verwendet eine automatisch zusammengesetzte Beschreibung zum Zusammenführen " "der angegebenen Version" -#: builtin/commit.c:1370 +#: builtin/commit.c:1372 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "Setzt Sie als Autor der Version (verwendet mit -C/-c/--amend)" -#: builtin/commit.c:1371 builtin/log.c:1102 builtin/revert.c:109 +#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "fügt 'Signed-off-by:'-Zeile hinzu" -#: builtin/commit.c:1372 +#: builtin/commit.c:1374 msgid "use specified template file" msgstr "verwendet angegebene Vorlagendatei" -#: builtin/commit.c:1373 +#: builtin/commit.c:1375 msgid "force edit of commit" msgstr "erzwingt Bearbeitung der Version" -#: builtin/commit.c:1374 +#: builtin/commit.c:1376 msgid "default" msgstr "Standard" -#: builtin/commit.c:1374 builtin/tag.c:460 +#: builtin/commit.c:1376 builtin/tag.c:460 msgid "how to strip spaces and #comments from message" msgstr "" "wie Leerzeichen und #Kommentare von der Beschreibung getrennt werden sollen" -#: builtin/commit.c:1375 +#: builtin/commit.c:1377 msgid "include status in commit message template" msgstr "fügt Status in die Versionsbeschreibungsvorlage ein" -#: builtin/commit.c:1376 builtin/merge.c:213 builtin/tag.c:461 +#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 msgid "key id" msgstr "Schlüssel-ID" -#: builtin/commit.c:1377 builtin/merge.c:214 +#: builtin/commit.c:1379 builtin/merge.c:216 msgid "GPG sign commit" msgstr "signiert Version mit GPG" #. end commit message options -#: builtin/commit.c:1380 +#: builtin/commit.c:1382 msgid "Commit contents options" msgstr "Optionen für Versionsinhalt" -#: builtin/commit.c:1381 +#: builtin/commit.c:1383 msgid "commit all changed files" msgstr "trägt alle geänderten Dateien ein" -#: builtin/commit.c:1382 +#: builtin/commit.c:1384 msgid "add specified files to index for commit" msgstr "trägt die angegebenen Dateien zusätzlich zur Bereitstellung ein" -#: builtin/commit.c:1383 +#: builtin/commit.c:1385 msgid "interactively add files" msgstr "interaktives Hinzufügen von Dateien" -#: builtin/commit.c:1384 +#: builtin/commit.c:1386 msgid "interactively add changes" msgstr "interaktives Hinzufügen von Änderungen" -#: builtin/commit.c:1385 +#: builtin/commit.c:1387 msgid "commit only specified files" msgstr "trägt nur die angegebenen Dateien ein" -#: builtin/commit.c:1386 +#: builtin/commit.c:1388 msgid "bypass pre-commit hook" msgstr "umgeht \"pre-commit hook\"" -#: builtin/commit.c:1387 +#: builtin/commit.c:1389 msgid "show what would be committed" msgstr "zeigt an, was eingetragen werden würde" -#: builtin/commit.c:1398 +#: builtin/commit.c:1400 msgid "amend previous commit" msgstr "ändert vorherige Version" -#: builtin/commit.c:1399 +#: builtin/commit.c:1401 msgid "bypass post-rewrite hook" msgstr "umgeht \"post-rewrite hook\"" -#: builtin/commit.c:1404 +#: builtin/commit.c:1406 msgid "ok to record an empty change" msgstr "erlaubt Aufzeichnung einer leeren Änderung" -#: builtin/commit.c:1407 +#: builtin/commit.c:1409 msgid "ok to record a change with an empty message" msgstr "erlaubt Aufzeichnung einer Änderung mit einer leeren Beschreibung" -#: builtin/commit.c:1439 +#: builtin/commit.c:1441 msgid "could not parse HEAD commit" msgstr "Konnte Version der Zweigspitze (HEAD) nicht analysieren." -#: builtin/commit.c:1477 builtin/merge.c:508 +#: builtin/commit.c:1479 builtin/merge.c:510 #, c-format msgid "could not open '%s' for reading" msgstr "Konnte '%s' nicht zum Lesen öffnen." -#: builtin/commit.c:1484 +#: builtin/commit.c:1486 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Beschädigte MERGE_HEAD-Datei (%s)" -#: builtin/commit.c:1491 +#: builtin/commit.c:1493 msgid "could not read MERGE_MODE" msgstr "Konnte MERGE_MODE nicht lesen" -#: builtin/commit.c:1510 +#: builtin/commit.c:1512 #, c-format msgid "could not read commit message: %s" msgstr "Konnte Versionsbeschreibung nicht lesen: %s" -#: builtin/commit.c:1524 +#: builtin/commit.c:1526 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Eintragung abgebrochen; Sie haben die Beschreibung nicht editiert.\n" -#: builtin/commit.c:1529 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Eintragung aufgrund leerer Versionsbeschreibung abgebrochen.\n" -#: builtin/commit.c:1544 builtin/merge.c:832 builtin/merge.c:857 +#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 msgid "failed to write commit object" msgstr "Fehler beim Schreiben des Versionsobjektes." -#: builtin/commit.c:1565 +#: builtin/commit.c:1567 msgid "cannot lock HEAD ref" msgstr "Kann Referenz der Zweigspitze (HEAD) nicht sperren." -#: builtin/commit.c:1569 +#: builtin/commit.c:1571 msgid "cannot update HEAD ref" msgstr "Kann Referenz der Zweigspitze (HEAD) nicht aktualisieren." -#: builtin/commit.c:1580 +#: builtin/commit.c:1582 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -4154,9 +4440,13 @@ msgstr "schließt Werte mit NUL-Byte ab" msgid "respect include directives on lookup" msgstr "beachtet \"include\"-Direktiven beim Nachschlagen" -#: builtin/count-objects.c:69 -msgid "git count-objects [-v]" -msgstr "git count-objects [-v]" +#: builtin/count-objects.c:82 +msgid "git count-objects [-v] [-H | --human-readable]" +msgstr "git count-objects [-v] [-H | --human-readable]" + +#: builtin/count-objects.c:97 +msgid "print sizes in human readable format" +msgstr "gibt Größenangaben in menschenlesbaren Format aus" #: builtin/describe.c:15 msgid "git describe [options] <committish>*" @@ -4166,47 +4456,47 @@ msgstr "git describe [Optionen] <committish>*" msgid "git describe [options] --dirty" msgstr "git describe [Optionen] --dirty" -#: builtin/describe.c:234 +#: builtin/describe.c:233 #, c-format msgid "annotated tag %s not available" msgstr "annotierte Markierung %s ist nicht verfügbar" -#: builtin/describe.c:238 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s has no embedded name" msgstr "annotierte Markierung %s hat keinen eingebetteten Namen" -#: builtin/describe.c:240 +#: builtin/describe.c:239 #, c-format msgid "tag '%s' is really '%s' here" msgstr "Markierung '%s' ist eigentlich '%s' hier" -#: builtin/describe.c:267 +#: builtin/describe.c:266 #, c-format msgid "Not a valid object name %s" msgstr "%s ist kein gültiger Objekt-Name" -#: builtin/describe.c:270 +#: builtin/describe.c:269 #, c-format msgid "%s is not a valid '%s' object" msgstr "%s ist kein gültiges '%s' Objekt" -#: builtin/describe.c:287 +#: builtin/describe.c:286 #, c-format msgid "no tag exactly matches '%s'" msgstr "kein Markierung entspricht exakt '%s'" -#: builtin/describe.c:289 +#: builtin/describe.c:288 #, c-format msgid "searching to describe %s\n" msgstr "suche zur Beschreibung von %s\n" -#: builtin/describe.c:329 +#: builtin/describe.c:328 #, c-format msgid "finished search at %s\n" msgstr "beendete Suche bei %s\n" -#: builtin/describe.c:353 +#: builtin/describe.c:352 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -4215,7 +4505,7 @@ msgstr "" "Keine annotierten Markierungen können '%s' beschreiben.\n" "Jedoch gab es nicht annotierte Markierungen: versuchen Sie --tags." -#: builtin/describe.c:357 +#: builtin/describe.c:356 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -4224,12 +4514,12 @@ msgstr "" "Keine Markierungen können '%s' beschreiben.\n" "Versuchen Sie --always oder erstellen Sie einige Markierungen." -#: builtin/describe.c:378 +#: builtin/describe.c:377 #, c-format msgid "traversed %lu commits\n" msgstr "%lu Versionen durchlaufen\n" -#: builtin/describe.c:381 +#: builtin/describe.c:380 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -4238,60 +4528,60 @@ msgstr "" "mehr als %i Markierungen gefunden; Führe die ersten %i auf\n" "Suche bei %s aufgegeben\n" -#: builtin/describe.c:403 +#: builtin/describe.c:402 msgid "find the tag that comes after the commit" msgstr "findet die Markierung, die nach der Version kommt" -#: builtin/describe.c:404 +#: builtin/describe.c:403 msgid "debug search strategy on stderr" msgstr "protokolliert die Suchstrategie in der Standard-Fehlerausgabe" +#: builtin/describe.c:404 +msgid "use any ref" +msgstr "verwendet alle Referenzen" + #: builtin/describe.c:405 -msgid "use any ref in .git/refs" -msgstr "verwendet alle Referenzen in .git/refs" +msgid "use any tag, even unannotated" +msgstr "verwendet jede Markierung, auch nicht-annotierte" #: builtin/describe.c:406 -msgid "use any tag in .git/refs/tags" -msgstr "verwendet alle Markierungen in .git/refs/tags" - -#: builtin/describe.c:407 msgid "always use long format" msgstr "verwendet immer langes Format" -#: builtin/describe.c:410 +#: builtin/describe.c:409 msgid "only output exact matches" msgstr "gibt nur exakte Ãœbereinstimmungen aus" -#: builtin/describe.c:412 +#: builtin/describe.c:411 msgid "consider <n> most recent tags (default: 10)" msgstr "betrachtet die jüngsten <n> Markierungen (Standard: 10)" -#: builtin/describe.c:414 +#: builtin/describe.c:413 msgid "only consider tags matching <pattern>" msgstr "betrachtet nur Markierungen die <Muster> entsprechen" -#: builtin/describe.c:416 builtin/name-rev.c:238 +#: builtin/describe.c:415 builtin/name-rev.c:238 msgid "show abbreviated commit object as fallback" msgstr "zeigt gekürztes Versionsobjekt, wenn sonst nichts zutrifft" -#: builtin/describe.c:417 +#: builtin/describe.c:416 msgid "mark" msgstr "Kennzeichen" -#: builtin/describe.c:418 +#: builtin/describe.c:417 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "" "fügt <Kennzeichen> bei geändertem Arbeitsbaum hinzu (Standard: \"-dirty\")" -#: builtin/describe.c:436 +#: builtin/describe.c:435 msgid "--long is incompatible with --abbrev=0" msgstr "Die Optionen --long und --abbrev=0 sind inkompatibel." -#: builtin/describe.c:462 +#: builtin/describe.c:461 msgid "No names found, cannot describe anything." msgstr "Keine Namen gefunden, kann nichts beschreiben." -#: builtin/describe.c:482 +#: builtin/describe.c:481 msgid "--dirty is incompatible with committishes" msgstr "Die Option --dirty kann nicht mit Versionen verwendet werden." @@ -4333,40 +4623,40 @@ msgstr "unbehandeltes Objekt '%s' angegeben" msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-opts]" -#: builtin/fast-export.c:646 +#: builtin/fast-export.c:658 msgid "show progress after <n> objects" msgstr "zeigt Fortschritt nach <n> Objekten an" -#: builtin/fast-export.c:648 +#: builtin/fast-export.c:660 msgid "select handling of signed tags" msgstr "wählt Behandlung von signierten Markierungen" -#: builtin/fast-export.c:651 +#: builtin/fast-export.c:663 msgid "select handling of tags that tag filtered objects" msgstr "wählt Behandlung von Markierungen, die gefilterte Objekte markieren" -#: builtin/fast-export.c:654 +#: builtin/fast-export.c:666 msgid "Dump marks to this file" msgstr "Schreibt Kennzeichen in diese Datei" -#: builtin/fast-export.c:656 +#: builtin/fast-export.c:668 msgid "Import marks from this file" msgstr "Importiert Kennzeichen von dieser Datei" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:670 msgid "Fake a tagger when tags lack one" msgstr "" "erzeugt künstlich einen Markierungsersteller, wenn die Markierung keinen hat" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:672 msgid "Output full tree for each commit" msgstr "gibt für jede Version den gesamten Baum aus" -#: builtin/fast-export.c:662 +#: builtin/fast-export.c:674 msgid "Use the done feature to terminate the stream" msgstr "Benutzt die \"done\"-Funktion um den Strom abzuschließen" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:675 msgid "Skip output of blob data" msgstr "Ãœberspringt Ausgabe von Blob-Daten" @@ -4443,7 +4733,7 @@ msgstr "vertieft die Historie eines flachen Klon" msgid "convert to a complete repository" msgstr "konvertiert zu einem vollständigen Projektarchiv" -#: builtin/fetch.c:88 builtin/log.c:1119 +#: builtin/fetch.c:88 builtin/log.c:1130 msgid "dir" msgstr "Verzeichnis" @@ -4631,29 +4921,29 @@ msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" "git fmt-merge-msg [-m <Beschreibung>] [--log[=<n>]|--no-log] [--file <Datei>]" -#: builtin/fmt-merge-msg.c:659 builtin/fmt-merge-msg.c:662 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 #: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 msgid "n" msgstr "Anzahl" -#: builtin/fmt-merge-msg.c:660 +#: builtin/fmt-merge-msg.c:664 msgid "populate log with at most <n> entries from shortlog" msgstr "fügt Historie mit höchstens <n> Einträgen von \"shortlog\" hinzu" -#: builtin/fmt-merge-msg.c:663 +#: builtin/fmt-merge-msg.c:667 msgid "alias for --log (deprecated)" msgstr "Alias für --log (veraltet)" -#: builtin/fmt-merge-msg.c:666 +#: builtin/fmt-merge-msg.c:670 msgid "text" msgstr "Text" -#: builtin/fmt-merge-msg.c:667 +#: builtin/fmt-merge-msg.c:671 msgid "use <text> as start of message" msgstr "verwendet <Text> als Beschreibungsanfang" -#: builtin/fmt-merge-msg.c:668 +#: builtin/fmt-merge-msg.c:672 msgid "file to read from" msgstr "Datei zum Einlesen" @@ -4993,36 +5283,31 @@ msgstr "zeigt Verwendung" msgid "no pattern given." msgstr "keine Muster angegeben" -#: builtin/grep.c:825 -#, c-format -msgid "bad object %s" -msgstr "ungültiges Objekt %s" - -#: builtin/grep.c:868 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "" "Die Option --open-files-in-pager kann nur innerhalb des Arbeitsbaums " "verwendet werden." -#: builtin/grep.c:891 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "" "Die Optionen --cached und --untracked können nicht mit --no-index verwendet " "werden." -#: builtin/grep.c:896 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "" "Die Optionen --no-index und --untracked können nicht mit Versionen verwendet " "werden." -#: builtin/grep.c:899 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" "Die Option --[no-]exclude-standard kann nicht mit beobachteten Inhalten " "verwendet werden." -#: builtin/grep.c:907 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "Die Option --cached kann nicht mit Zweigen verwendet werden." @@ -5062,50 +5347,54 @@ msgstr "speichert Datei wie sie ist, ohne Filter" msgid "process file as it were from this path" msgstr "verarbeitet Datei, als ob sie von diesem Pfad wäre" -#: builtin/help.c:42 +#: builtin/help.c:43 msgid "print all available commands" msgstr "Anzeige aller vorhandenen Kommandos" -#: builtin/help.c:43 +#: builtin/help.c:44 +msgid "print list of useful guides" +msgstr "zeigt Liste von allgemein verwendeten Anleitungen" + +#: builtin/help.c:45 msgid "show man page" msgstr "zeigt Handbuch" -#: builtin/help.c:44 +#: builtin/help.c:46 msgid "show manual in web browser" msgstr "zeigt Handbuch in einem Webbrowser" -#: builtin/help.c:46 +#: builtin/help.c:48 msgid "show info page" msgstr "zeigt Info-Seite" -#: builtin/help.c:52 -msgid "git help [--all] [--man|--web|--info] [command]" -msgstr "git help [--all] [--man|--web|--info] [Kommando]" +#: builtin/help.c:54 +msgid "git help [--all] [--guides] [--man|--web|--info] [command]" +msgstr "git help [--all] [--guides] [--man|--web|--info] [Kommando]" -#: builtin/help.c:64 +#: builtin/help.c:66 #, c-format msgid "unrecognized help format '%s'" msgstr "nicht erkanntes Hilfeformat: %s" -#: builtin/help.c:92 +#: builtin/help.c:94 msgid "Failed to start emacsclient." msgstr "Konnte emacsclient nicht starten." -#: builtin/help.c:105 +#: builtin/help.c:107 msgid "Failed to parse emacsclient version." msgstr "Konnte Version des emacsclient nicht parsen." -#: builtin/help.c:113 +#: builtin/help.c:115 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "Version des emacsclient '%d' ist zu alt (< 22)." -#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 +#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 #, c-format msgid "failed to exec '%s': %s" msgstr "Fehler beim Ausführen von '%s': %s" -#: builtin/help.c:216 +#: builtin/help.c:218 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -5114,7 +5403,7 @@ msgstr "" "'%s': Pfad für nicht unterstützten Handbuchbetrachter.\n" "Sie könnten stattdessen 'man.<Werkzeug>.cmd' benutzen." -#: builtin/help.c:228 +#: builtin/help.c:230 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -5123,304 +5412,336 @@ msgstr "" "'%s': Kommando für unterstützten Handbuchbetrachter.\n" "Sie könnten stattdessen 'man.<Werkzeug>.path' benutzen." -#: builtin/help.c:349 +#: builtin/help.c:351 #, c-format msgid "'%s': unknown man viewer." msgstr "'%s': unbekannter Handbuch-Betrachter." -#: builtin/help.c:366 +#: builtin/help.c:368 msgid "no man viewer handled the request" msgstr "kein Handbuch-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:374 +#: builtin/help.c:376 msgid "no info viewer handled the request" msgstr "kein Informations-Betrachter konnte mit dieser Anfrage umgehen" -#: builtin/help.c:429 builtin/help.c:436 +#: builtin/help.c:422 +msgid "Defining attributes per path" +msgstr "Definition von Attributen pro Pfad" + +#: builtin/help.c:423 +msgid "A Git glossary" +msgstr "Ein Git-Glossar" + +#: builtin/help.c:424 +msgid "Specifies intentionally untracked files to ignore" +msgstr "Spezifikation von bewusst ignorierten, unbeobachteten Dateien" + +#: builtin/help.c:425 +msgid "Defining submodule properties" +msgstr "Definition von Unterprojekt-Eigenschaften" + +#: builtin/help.c:426 +msgid "Specifying revisions and ranges for Git" +msgstr "Spezifikation von Revisionen und Bereichen für Git" + +#: builtin/help.c:427 +msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" +msgstr "Eine einführende Anleitung zu Git (für Version 1.5.1 oder neuer)" + +#: builtin/help.c:428 +msgid "An overview of recommended workflows with Git" +msgstr "Eine Ãœbersicht über empfohlene Arbeitsabläufe mit Git" + +#: builtin/help.c:440 +msgid "The common Git guides are:\n" +msgstr "Die allgemein verwendeten Git-Anleitungen sind:\n" + +#: builtin/help.c:462 builtin/help.c:478 #, c-format msgid "usage: %s%s" msgstr "Verwendung: %s%s" -#: builtin/help.c:452 +#: builtin/help.c:494 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "für `git %s' wurde der Alias `%s' angelegt" -#: builtin/index-pack.c:170 +#: builtin/index-pack.c:182 #, c-format msgid "object type mismatch at %s" msgstr "Objekt-Typen passen bei %s nicht zusammen" -#: builtin/index-pack.c:190 +#: builtin/index-pack.c:202 msgid "object of unexpected type" msgstr "Objekt hat unerwarteten Typ" -#: builtin/index-pack.c:227 +#: builtin/index-pack.c:239 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "kann %d Byte nicht lesen" msgstr[1] "kann %d Bytes nicht lesen" -#: builtin/index-pack.c:237 +#: builtin/index-pack.c:249 msgid "early EOF" msgstr "zu frühes Dateiende" -#: builtin/index-pack.c:238 +#: builtin/index-pack.c:250 msgid "read error on input" msgstr "Fehler beim Lesen der Eingabe" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:262 msgid "used more bytes than were available" msgstr "verwendete mehr Bytes als verfügbar waren" -#: builtin/index-pack.c:257 +#: builtin/index-pack.c:269 msgid "pack too large for current definition of off_t" msgstr "Paket ist zu groß für die aktuelle Definition von off_t" -#: builtin/index-pack.c:273 +#: builtin/index-pack.c:285 #, c-format msgid "unable to create '%s'" msgstr "konnte '%s' nicht erstellen" -#: builtin/index-pack.c:278 +#: builtin/index-pack.c:290 #, c-format msgid "cannot open packfile '%s'" msgstr "Kann Paketdatei '%s' nicht öffnen" -#: builtin/index-pack.c:292 +#: builtin/index-pack.c:304 msgid "pack signature mismatch" msgstr "Paketsignatur stimmt nicht überein" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:306 #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "Paketversion %<PRIu32> nicht unterstützt" -#: builtin/index-pack.c:312 +#: builtin/index-pack.c:324 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "Paket hat ein ungültiges Objekt bei Versatz %lu: %s" -#: builtin/index-pack.c:434 +#: builtin/index-pack.c:446 #, c-format msgid "inflate returned %d" msgstr "Dekomprimierung gab %d zurück" -#: builtin/index-pack.c:483 +#: builtin/index-pack.c:495 msgid "offset value overflow for delta base object" msgstr "Wert für Versatz bei Differenzobjekt übergelaufen" -#: builtin/index-pack.c:491 +#: builtin/index-pack.c:503 msgid "delta base offset is out of bound" msgstr "" "Wert für Versatz bei Differenzobjekt liegt außerhalb des gültigen Bereichs" -#: builtin/index-pack.c:499 +#: builtin/index-pack.c:511 #, c-format msgid "unknown object type %d" msgstr "Unbekannter Objekt-Typ %d" -#: builtin/index-pack.c:530 +#: builtin/index-pack.c:542 msgid "cannot pread pack file" msgstr "Kann Paketdatei %s nicht lesen" -#: builtin/index-pack.c:532 +#: builtin/index-pack.c:544 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "frühzeitiges Ende der Paketdatei, vermisse %lu Byte" msgstr[1] "frühzeitiges Ende der Paketdatei, vermisse %lu Bytes" -#: builtin/index-pack.c:558 +#: builtin/index-pack.c:570 msgid "serious inflate inconsistency" msgstr "ernsthafte Inkonsistenz nach Dekomprimierung" -#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678 -#: builtin/index-pack.c:712 builtin/index-pack.c:721 +#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 +#: builtin/index-pack.c:724 builtin/index-pack.c:733 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "SHA1 KOLLISION MIT %s GEFUNDEN !" -#: builtin/index-pack.c:652 builtin/pack-objects.c:170 +#: builtin/index-pack.c:664 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "kann %s nicht lesen" -#: builtin/index-pack.c:718 +#: builtin/index-pack.c:730 #, c-format msgid "cannot read existing object %s" msgstr "Kann existierendes Objekt %s nicht lesen." -#: builtin/index-pack.c:732 +#: builtin/index-pack.c:744 #, c-format msgid "invalid blob object %s" msgstr "ungültiges Blob-Objekt %s" -#: builtin/index-pack.c:747 +#: builtin/index-pack.c:759 #, c-format msgid "invalid %s" msgstr "Ungültiger Objekt-Typ %s" -#: builtin/index-pack.c:749 +#: builtin/index-pack.c:761 msgid "Error in object" msgstr "Fehler in Objekt" -#: builtin/index-pack.c:751 +#: builtin/index-pack.c:763 #, c-format msgid "Not all child objects of %s are reachable" msgstr "Nicht alle Kind-Objekte von %s sind erreichbar" -#: builtin/index-pack.c:821 builtin/index-pack.c:847 +#: builtin/index-pack.c:833 builtin/index-pack.c:863 msgid "failed to apply delta" msgstr "Konnte Dateiunterschied nicht anwenden" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Receiving objects" msgstr "Empfange Objekte" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Indexing objects" msgstr "Indiziere Objekte" -#: builtin/index-pack.c:1012 +#: builtin/index-pack.c:1030 msgid "pack is corrupted (SHA1 mismatch)" msgstr "Paket ist beschädigt (SHA1 unterschiedlich)" -#: builtin/index-pack.c:1017 +#: builtin/index-pack.c:1035 msgid "cannot fstat packfile" msgstr "kann Paketdatei nicht lesen" -#: builtin/index-pack.c:1020 +#: builtin/index-pack.c:1038 msgid "pack has junk at the end" msgstr "Paketende enthält nicht verwendbaren Inhalt" -#: builtin/index-pack.c:1031 +#: builtin/index-pack.c:1049 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "Fehler beim Ausführen von \"parse_pack_objects()\"" -#: builtin/index-pack.c:1054 +#: builtin/index-pack.c:1072 msgid "Resolving deltas" msgstr "Löse Unterschiede auf" -#: builtin/index-pack.c:1064 +#: builtin/index-pack.c:1082 #, c-format msgid "unable to create thread: %s" msgstr "kann Thread nicht erzeugen: %s" -#: builtin/index-pack.c:1106 +#: builtin/index-pack.c:1124 msgid "confusion beyond insanity" msgstr "Fehler beim Auflösen der Unterschiede" -#: builtin/index-pack.c:1112 +#: builtin/index-pack.c:1132 #, c-format msgid "completed with %d local objects" msgstr "vervollständigt mit %d lokalen Objekten" -#: builtin/index-pack.c:1121 +#: builtin/index-pack.c:1142 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "Unerwartete Prüfsumme für %s (Festplattenfehler?)" -#: builtin/index-pack.c:1125 +#: builtin/index-pack.c:1146 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "Paket hat %d unaufgelöste Unterschied" msgstr[1] "Paket hat %d unaufgelöste Unterschiede" -#: builtin/index-pack.c:1150 +#: builtin/index-pack.c:1171 #, c-format msgid "unable to deflate appended object (%d)" msgstr "Konnte angehängtes Objekt (%d) nicht komprimieren" -#: builtin/index-pack.c:1229 +#: builtin/index-pack.c:1250 #, c-format msgid "local object %s is corrupt" msgstr "lokales Objekt %s ist beschädigt" -#: builtin/index-pack.c:1253 +#: builtin/index-pack.c:1274 msgid "error while closing pack file" msgstr "Fehler beim Schließen der Paketdatei" -#: builtin/index-pack.c:1266 +#: builtin/index-pack.c:1287 #, c-format msgid "cannot write keep file '%s'" msgstr "Kann Paketbeschreibungsdatei '%s' nicht schreiben" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1295 #, c-format msgid "cannot close written keep file '%s'" msgstr "Kann eben erstellte Paketbeschreibungsdatei '%s' nicht schließen" -#: builtin/index-pack.c:1287 +#: builtin/index-pack.c:1308 msgid "cannot store pack file" msgstr "Kann Paketdatei nicht speichern" -#: builtin/index-pack.c:1298 +#: builtin/index-pack.c:1319 msgid "cannot store index file" msgstr "Kann Indexdatei nicht speichern" -#: builtin/index-pack.c:1331 +#: builtin/index-pack.c:1352 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "\"pack.indexversion=%<PRIu32>\" ist ungültig" -#: builtin/index-pack.c:1337 +#: builtin/index-pack.c:1358 #, c-format msgid "invalid number of threads specified (%d)" msgstr "ungültige Anzahl von Threads angegeben (%d)" -#: builtin/index-pack.c:1341 builtin/index-pack.c:1514 +#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 #, c-format msgid "no threads support, ignoring %s" msgstr "keine Unterstützung von Threads, '%s' wird ignoriert" -#: builtin/index-pack.c:1399 +#: builtin/index-pack.c:1420 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Kann existierende Paketdatei '%s' nicht öffnen" -#: builtin/index-pack.c:1401 +#: builtin/index-pack.c:1422 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "Kann existierende Indexdatei für Paket '%s' nicht öffnen" -#: builtin/index-pack.c:1448 +#: builtin/index-pack.c:1469 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "kein Unterschied: %d Objekt" msgstr[1] "kein Unterschied: %d Objekte" -#: builtin/index-pack.c:1455 +#: builtin/index-pack.c:1476 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "Länge der Objekt-Liste = %d: %lu Objekt" msgstr[1] "Länge der Objekt-Liste = %d: %lu Objekte" -#: builtin/index-pack.c:1482 +#: builtin/index-pack.c:1503 msgid "Cannot come back to cwd" msgstr "Kann nicht zurück zu Arbeitsverzeichnis wechseln" -#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 -#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 +#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 +#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 #, c-format msgid "bad %s" msgstr "%s ist ungültig" -#: builtin/index-pack.c:1559 +#: builtin/index-pack.c:1580 msgid "--fix-thin cannot be used without --stdin" msgstr "Die Option --fix-thin kann nicht ohne --stdin verwendet werden." -#: builtin/index-pack.c:1563 builtin/index-pack.c:1573 +#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "Name der Paketdatei '%s' endet nicht mit '.pack'" -#: builtin/index-pack.c:1582 +#: builtin/index-pack.c:1603 msgid "--verify with no packfile name given" msgstr "Die Option --verify wurde ohne Namen der Paketdatei angegeben." @@ -5589,247 +5910,242 @@ msgstr "Kann nicht auf aktuelles Arbeitsverzeichnis zugreifen." msgid "Cannot access work tree '%s'" msgstr "Kann nicht auf Arbeitsbaum '%s' zugreifen." -#: builtin/log.c:39 -msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" -msgstr "git log [<Optionen>] [<seit>..<bis>] [[--] <Pfad>...]\n" - #: builtin/log.c:40 +msgid "git log [<options>] [<revision range>] [[--] <path>...]\n" +msgstr "git log [<Optionen>] [Revisionsbereich>] [[--] <Pfad>...]\n" + +#: builtin/log.c:41 msgid " or: git show [options] <object>..." msgstr " oder: git show [Optionen] <Objekt>..." -#: builtin/log.c:102 +#: builtin/log.c:103 msgid "suppress diff output" msgstr "unterdrückt Ausgabe der Unterschiede" -#: builtin/log.c:103 +#: builtin/log.c:104 msgid "show source" msgstr "zeigt Quelle" -#: builtin/log.c:104 +#: builtin/log.c:105 msgid "Use mail map file" msgstr "verwendet \"mailmap\"-Datei" -#: builtin/log.c:105 +#: builtin/log.c:106 msgid "decorate options" msgstr "decorate-Optionen" -#: builtin/log.c:198 +#: builtin/log.c:199 #, c-format msgid "Final output: %d %s\n" msgstr "letzte Ausgabe: %d %s\n" -#: builtin/log.c:419 builtin/log.c:511 +#: builtin/log.c:422 builtin/log.c:514 #, c-format msgid "Could not read object %s" msgstr "Kann Objekt %s nicht lesen." -#: builtin/log.c:535 +#: builtin/log.c:538 #, c-format msgid "Unknown type: %d" msgstr "Unbekannter Typ: %d" -#: builtin/log.c:627 +#: builtin/log.c:638 msgid "format.headers without value" msgstr "format.headers ohne Wert" -#: builtin/log.c:701 +#: builtin/log.c:720 msgid "name of output directory is too long" msgstr "Name des Ausgabeverzeichnisses ist zu lang." -#: builtin/log.c:717 +#: builtin/log.c:736 #, c-format msgid "Cannot open patch file %s" msgstr "Kann Patch-Datei %s nicht öffnen" -#: builtin/log.c:731 +#: builtin/log.c:750 msgid "Need exactly one range." msgstr "Brauche genau einen Versionsbereich." -#: builtin/log.c:739 +#: builtin/log.c:758 msgid "Not a range." msgstr "Kein Versionsbereich." -#: builtin/log.c:812 +#: builtin/log.c:860 msgid "Cover letter needs email format" msgstr "Anschreiben benötigt E-Mail-Format" -#: builtin/log.c:885 +#: builtin/log.c:936 #, c-format msgid "insane in-reply-to: %s" msgstr "ungültiges in-reply-to: %s" -#: builtin/log.c:913 +#: builtin/log.c:964 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "git format-patch [Optionen] [<seit> | <Revisionsbereich>]" -#: builtin/log.c:958 +#: builtin/log.c:1009 msgid "Two output directories?" msgstr "Zwei Ausgabeverzeichnisse?" -#: builtin/log.c:1097 +#: builtin/log.c:1108 msgid "use [PATCH n/m] even with a single patch" msgstr "verwendet [PATCH n/m] auch mit einzelnem Patch" -#: builtin/log.c:1100 +#: builtin/log.c:1111 msgid "use [PATCH] even with multiple patches" msgstr "verwendet [PATCH] auch mit mehreren Patches" -#: builtin/log.c:1104 +#: builtin/log.c:1115 msgid "print patches to standard out" msgstr "Ausgabe der Patches in Standard-Ausgabe" -#: builtin/log.c:1106 +#: builtin/log.c:1117 msgid "generate a cover letter" msgstr "erzeugt ein Deckblatt" -#: builtin/log.c:1108 +#: builtin/log.c:1119 msgid "use simple number sequence for output file names" msgstr "verwendet einfache Nummernfolge für die Namen der Ausgabedateien" -#: builtin/log.c:1109 +#: builtin/log.c:1120 msgid "sfx" msgstr "Dateiendung" -#: builtin/log.c:1110 +#: builtin/log.c:1121 msgid "use <sfx> instead of '.patch'" msgstr "verwendet <Dateiendung> anstatt '.patch'" -#: builtin/log.c:1112 +#: builtin/log.c:1123 msgid "start numbering patches at <n> instead of 1" msgstr "beginnt die Nummerierung der Patches bei <n> anstatt bei 1" -#: builtin/log.c:1114 +#: builtin/log.c:1125 msgid "mark the series as Nth re-roll" msgstr "kennzeichnet die Serie als n-te Fassung" -#: builtin/log.c:1116 +#: builtin/log.c:1127 msgid "Use [<prefix>] instead of [PATCH]" msgstr "verwendet [<Prefix>] anstatt [PATCH]" -#: builtin/log.c:1119 +#: builtin/log.c:1130 msgid "store resulting files in <dir>" msgstr "speichert erzeugte Dateien in <Verzeichnis>" -#: builtin/log.c:1122 +#: builtin/log.c:1133 msgid "don't strip/add [PATCH]" msgstr "[PATCH] wird nicht entfernt/hinzugefügt" -#: builtin/log.c:1125 +#: builtin/log.c:1136 msgid "don't output binary diffs" msgstr "gibt keine binären Unterschiede aus" -#: builtin/log.c:1127 +#: builtin/log.c:1138 msgid "don't include a patch matching a commit upstream" msgstr "" "schließt keine Patches ein, die einer Version im Ãœbernahmezweig entsprechen" -#: builtin/log.c:1129 +#: builtin/log.c:1140 msgid "show patch format instead of default (patch + stat)" msgstr "zeigt Patchformat anstatt des Standards (Patch + Zusammenfassung)" -#: builtin/log.c:1131 +#: builtin/log.c:1142 msgid "Messaging" msgstr "Email-Einstellungen" -#: builtin/log.c:1132 +#: builtin/log.c:1143 msgid "header" msgstr "Header" -#: builtin/log.c:1133 +#: builtin/log.c:1144 msgid "add email header" msgstr "fügt Email-Header hinzu" -#: builtin/log.c:1134 builtin/log.c:1136 +#: builtin/log.c:1145 builtin/log.c:1147 msgid "email" msgstr "Email" -#: builtin/log.c:1134 +#: builtin/log.c:1145 msgid "add To: header" msgstr "fügt \"To:\"-Header hinzu" -#: builtin/log.c:1136 +#: builtin/log.c:1147 msgid "add Cc: header" msgstr "fügt \"Cc:\"-Header hinzu" -#: builtin/log.c:1138 +#: builtin/log.c:1149 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1139 +#: builtin/log.c:1150 msgid "make first mail a reply to <message-id>" msgstr "macht aus erster Email eine Antwort zu <message-id>" -#: builtin/log.c:1140 builtin/log.c:1143 +#: builtin/log.c:1151 builtin/log.c:1154 msgid "boundary" msgstr "Grenze" -#: builtin/log.c:1141 +#: builtin/log.c:1152 msgid "attach the patch" msgstr "hängt einen Patch an" -#: builtin/log.c:1144 +#: builtin/log.c:1155 msgid "inline the patch" msgstr "fügt den Patch direkt in die Nachricht ein" -#: builtin/log.c:1148 +#: builtin/log.c:1159 msgid "enable message threading, styles: shallow, deep" msgstr "aktiviert Nachrichtenverkettung, Stile: shallow, deep" -#: builtin/log.c:1150 +#: builtin/log.c:1161 msgid "signature" msgstr "Signatur" -#: builtin/log.c:1151 +#: builtin/log.c:1162 msgid "add a signature" msgstr "fügt eine Signatur hinzu" -#: builtin/log.c:1153 +#: builtin/log.c:1164 msgid "don't print the patch filenames" msgstr "zeigt keine Dateinamen der Patches" -#: builtin/log.c:1202 -#, c-format -msgid "bogus committer info %s" -msgstr "unechte Einreicher-Informationen %s" - -#: builtin/log.c:1247 +#: builtin/log.c:1248 msgid "-n and -k are mutually exclusive." msgstr "Die Optionen -n und -k schließen sich gegenseitig aus." -#: builtin/log.c:1249 +#: builtin/log.c:1250 msgid "--subject-prefix and -k are mutually exclusive." msgstr "Die Optionen --subject-prefix und -k schließen sich gegenseitig aus." -#: builtin/log.c:1257 +#: builtin/log.c:1258 msgid "--name-only does not make sense" msgstr "Die Option --name-only kann nicht verwendet werden." -#: builtin/log.c:1259 +#: builtin/log.c:1260 msgid "--name-status does not make sense" msgstr "Die Option --name-status kann nicht verwendet werden." -#: builtin/log.c:1261 +#: builtin/log.c:1262 msgid "--check does not make sense" msgstr "Die Option --check kann nicht verwendet werden." -#: builtin/log.c:1284 +#: builtin/log.c:1285 msgid "standard output, or directory, which one?" msgstr "Standard-Ausgabe oder Verzeichnis, welches von beidem?" -#: builtin/log.c:1286 +#: builtin/log.c:1287 #, c-format msgid "Could not create directory '%s'" msgstr "Konnte Verzeichnis '%s' nicht erstellen." -#: builtin/log.c:1439 +#: builtin/log.c:1435 msgid "Failed to create output files" msgstr "Fehler beim Erstellen der Ausgabedateien." -#: builtin/log.c:1488 +#: builtin/log.c:1484 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<Ãœbernahmezweig> [<Arbeitszweig> [<Limit>]]]" -#: builtin/log.c:1543 +#: builtin/log.c:1539 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -5837,105 +6153,105 @@ msgstr "" "Konnte gefolgten, externen Zweig nicht finden, bitte geben Sie <upstream> " "manuell an.\n" -#: builtin/log.c:1556 builtin/log.c:1558 builtin/log.c:1570 +#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 #, c-format msgid "Unknown commit %s" msgstr "Unbekannte Version %s" -#: builtin/ls-files.c:409 +#: builtin/ls-files.c:402 msgid "git ls-files [options] [<file>...]" msgstr "git ls-files [Optionen] [<Datei>...]" -#: builtin/ls-files.c:466 +#: builtin/ls-files.c:459 msgid "identify the file status with tags" msgstr "zeigt den Dateistatus mit Markierungen" -#: builtin/ls-files.c:468 +#: builtin/ls-files.c:461 msgid "use lowercase letters for 'assume unchanged' files" msgstr "" "verwendet Kleinbuchstaben für Dateien mit 'assume unchanged' Markierung" -#: builtin/ls-files.c:470 +#: builtin/ls-files.c:463 msgid "show cached files in the output (default)" msgstr "zeigt zwischengespeicherten Dateien in der Ausgabe an (Standard)" -#: builtin/ls-files.c:472 +#: builtin/ls-files.c:465 msgid "show deleted files in the output" msgstr "zeigt entfernte Dateien in der Ausgabe an" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:467 msgid "show modified files in the output" msgstr "zeigt geänderte Dateien in der Ausgabe an" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:469 msgid "show other files in the output" msgstr "zeigt sonstige Dateien in der Ausgabe an" -#: builtin/ls-files.c:478 +#: builtin/ls-files.c:471 msgid "show ignored files in the output" msgstr "zeigt ignorierte Dateien in der Ausgabe an" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:474 msgid "show staged contents' object name in the output" msgstr "zeigt Objektnamen von Inhalten in der Bereitstellung in der Ausgabe an" -#: builtin/ls-files.c:483 +#: builtin/ls-files.c:476 msgid "show files on the filesystem that need to be removed" msgstr "zeigt Dateien im Dateisystem, die gelöscht werden müssen, an" -#: builtin/ls-files.c:485 +#: builtin/ls-files.c:478 msgid "show 'other' directories' name only" msgstr "zeigt nur Namen von 'sonstigen' Verzeichnissen an" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:481 msgid "don't show empty directories" msgstr "zeigt keine leeren Verzeichnisse an" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:484 msgid "show unmerged files in the output" msgstr "zeigt nicht zusammengeführte Dateien in der Ausgabe an" -#: builtin/ls-files.c:493 +#: builtin/ls-files.c:486 msgid "show resolve-undo information" msgstr "zeigt 'resolve-undo' Informationen an" -#: builtin/ls-files.c:495 +#: builtin/ls-files.c:488 msgid "skip files matching pattern" msgstr "lässt Dateien aus, die einem Muster entsprechen" -#: builtin/ls-files.c:498 +#: builtin/ls-files.c:491 msgid "exclude patterns are read from <file>" msgstr "schließt Muster, gelesen von <Datei>, aus" -#: builtin/ls-files.c:501 +#: builtin/ls-files.c:494 msgid "read additional per-directory exclude patterns in <file>" msgstr "liest zusätzliche pro-Verzeichnis Auschlussmuster aus <Datei>" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:496 msgid "add the standard git exclusions" msgstr "fügt die standardmäßigen Git-Ausschlüsse hinzu" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:499 msgid "make the output relative to the project top directory" msgstr "Ausgabe relativ zum Projektverzeichnis" -#: builtin/ls-files.c:509 +#: builtin/ls-files.c:502 msgid "if any <file> is not in the index, treat this as an error" msgstr "" "behandle es als Fehler, wenn sich eine <Datei> nicht in der Bereitstellung " "befindet" -#: builtin/ls-files.c:510 +#: builtin/ls-files.c:503 msgid "tree-ish" msgstr "Versionsreferenz" -#: builtin/ls-files.c:511 +#: builtin/ls-files.c:504 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "" "gibt vor, dass Pfade, die seit <Versionsreferenz> gelöscht wurden, immer " "noch vorhanden sind" -#: builtin/ls-files.c:513 +#: builtin/ls-files.c:506 msgid "show debugging data" msgstr "zeigt Ausgaben zur Fehlersuche an" @@ -6051,114 +6367,118 @@ msgstr "erlaubt Vorspulen (Standard)" msgid "abort if fast-forward is not possible" msgstr "bricht ab, wenn kein Vorspulen möglich ist" -#: builtin/merge.c:202 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:203 +msgid "Verify that the named commit has a valid GPG signature" +msgstr "überprüft die genannte Version auf eine gültige GPG-Signatur" + +#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112 msgid "strategy" msgstr "Strategie" -#: builtin/merge.c:203 +#: builtin/merge.c:205 msgid "merge strategy to use" msgstr "zu verwendende Zusammenführungsstrategie" -#: builtin/merge.c:204 +#: builtin/merge.c:206 msgid "option=value" msgstr "Option=Wert" -#: builtin/merge.c:205 +#: builtin/merge.c:207 msgid "option for selected merge strategy" msgstr "Option für ausgewählte Zusammenführungsstrategie" -#: builtin/merge.c:207 +#: builtin/merge.c:209 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" "führt Versionsbeschreibung zusammen (für eine Zusammenführung, die kein " "Vorspulen war)" -#: builtin/merge.c:211 +#: builtin/merge.c:213 msgid "abort the current in-progress merge" msgstr "bricht die sich im Gange befindliche Zusammenführung ab" -#: builtin/merge.c:240 +#: builtin/merge.c:242 msgid "could not run stash." msgstr "Konnte \"stash\" nicht ausführen." -#: builtin/merge.c:245 +#: builtin/merge.c:247 msgid "stash failed" msgstr "\"stash\" fehlgeschlagen" -#: builtin/merge.c:250 +#: builtin/merge.c:252 #, c-format msgid "not a valid object: %s" msgstr "kein gültiges Objekt: %s" -#: builtin/merge.c:269 builtin/merge.c:286 +#: builtin/merge.c:271 builtin/merge.c:288 msgid "read-tree failed" msgstr "read-tree fehlgeschlagen" -#: builtin/merge.c:316 +#: builtin/merge.c:318 msgid " (nothing to squash)" msgstr " (nichts zu quetschen)" -#: builtin/merge.c:329 +#: builtin/merge.c:331 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Quetsche Version -- Zweigspitze (HEAD) wird nicht aktualisiert\n" -#: builtin/merge.c:361 +#: builtin/merge.c:363 msgid "Writing SQUASH_MSG" msgstr "Schreibe SQUASH_MSG" -#: builtin/merge.c:363 +#: builtin/merge.c:365 msgid "Finishing SQUASH_MSG" msgstr "Schließe SQUASH_MSG ab" -#: builtin/merge.c:386 +#: builtin/merge.c:388 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "" "Keine Zusammenführungsbeschreibung -- Zweigspitze (HEAD) wird nicht " "aktualisiert\n" -#: builtin/merge.c:436 +#: builtin/merge.c:438 #, c-format msgid "'%s' does not point to a commit" msgstr "'%s' zeigt auf keine Version" -#: builtin/merge.c:535 +#: builtin/merge.c:550 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Ungültiger branch.%s.mergeoptions String: %s" -#: builtin/merge.c:628 +#: builtin/merge.c:643 msgid "git write-tree failed to write a tree" msgstr "\"git write-tree\" schlug beim Schreiben eines Baumes fehl" -#: builtin/merge.c:656 +#: builtin/merge.c:671 msgid "Not handling anything other than two heads merge." msgstr "Es wird nur die Zusammenführung von zwei Zweigen behandelt." -#: builtin/merge.c:670 +#: builtin/merge.c:685 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Unbekannte Option für merge-recursive: -X%s" -#: builtin/merge.c:684 +#: builtin/merge.c:699 #, c-format msgid "unable to write %s" msgstr "konnte %s nicht schreiben" -#: builtin/merge.c:773 +#: builtin/merge.c:788 #, c-format msgid "Could not read from '%s'" msgstr "konnte nicht von '%s' lesen" -#: builtin/merge.c:782 +#: builtin/merge.c:797 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Zusammenführung wurde nicht eingetragen; benutzen Sie 'git commit' um die " "Zusammenführung abzuschließen.\n" -#: builtin/merge.c:788 +#: builtin/merge.c:803 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6175,56 +6495,56 @@ msgstr "" "Zeilen beginnend mit '%c' werden ignoriert, und eine leere Beschreibung " "bricht die Eintragung ab.\n" -#: builtin/merge.c:812 +#: builtin/merge.c:827 msgid "Empty commit message." msgstr "Leere Versionsbeschreibung" -#: builtin/merge.c:824 +#: builtin/merge.c:839 #, c-format msgid "Wonderful.\n" msgstr "Wunderbar.\n" -#: builtin/merge.c:889 +#: builtin/merge.c:904 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Automatische Zusammenführung fehlgeschlagen; beheben Sie die Konflikte und " "tragen Sie dann das Ergebnis ein.\n" -#: builtin/merge.c:905 +#: builtin/merge.c:920 #, c-format msgid "'%s' is not a commit" msgstr "'%s' ist keine Version" -#: builtin/merge.c:946 +#: builtin/merge.c:961 msgid "No current branch." msgstr "Sie befinden sich auf keinem Zweig." -#: builtin/merge.c:948 +#: builtin/merge.c:963 msgid "No remote for the current branch." msgstr "Kein externes Archiv für den aktuellen Zweig." -#: builtin/merge.c:950 +#: builtin/merge.c:965 msgid "No default upstream defined for the current branch." msgstr "" "Es ist kein externes Standard-Projektarchiv für den aktuellen Zweig " "definiert." -#: builtin/merge.c:955 +#: builtin/merge.c:970 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "Kein externer Ãœbernahmezweig für %s von %s" -#: builtin/merge.c:1042 builtin/merge.c:1199 +#: builtin/merge.c:1057 builtin/merge.c:1214 #, c-format msgid "%s - not something we can merge" msgstr "%s - nichts was wir zusammenführen können" -#: builtin/merge.c:1110 +#: builtin/merge.c:1125 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "Es gibt keine Zusammenführung zum Abbrechen (vermisse MERGE_HEAD)" -#: builtin/merge.c:1126 git-pull.sh:31 +#: builtin/merge.c:1141 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6232,12 +6552,12 @@ msgstr "" "Sie haben Ihre Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert).\n" "Bitte tragen Sie Ihre Änderungen ein, bevor Sie zusammenführen können." -#: builtin/merge.c:1129 git-pull.sh:34 +#: builtin/merge.c:1144 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "" "Sie haben Ihre Zusammenführung nicht abgeschlossen (MERGE_HEAD existiert)." -#: builtin/merge.c:1133 +#: builtin/merge.c:1148 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6245,82 +6565,104 @@ msgstr "" "Sie haben \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert).\n" "Bitte tragen Sie Ihre Änderungen ein, bevor Sie zusammenführen können." -#: builtin/merge.c:1136 +#: builtin/merge.c:1151 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" "Sie haben \"cherry-pick\" nicht abgeschlossen (CHERRY_PICK_HEAD existiert)." -#: builtin/merge.c:1145 +#: builtin/merge.c:1160 msgid "You cannot combine --squash with --no-ff." msgstr "Sie können --squash nicht mit --no-ff kombinieren." -#: builtin/merge.c:1150 +#: builtin/merge.c:1165 msgid "You cannot combine --no-ff with --ff-only." msgstr "Sie können --no-ff nicht mit --ff--only kombinieren." -#: builtin/merge.c:1157 +#: builtin/merge.c:1172 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Keine Version angegeben und merge.defaultToUpstream ist nicht gesetzt." -#: builtin/merge.c:1189 +#: builtin/merge.c:1204 msgid "Can merge only exactly one commit into empty head" msgstr "Kann nur exakt eine Version in einem leeren Zweig zusammenführen." -#: builtin/merge.c:1192 +#: builtin/merge.c:1207 msgid "Squash commit into empty head not supported yet" msgstr "Bin auf einem Zweig, der noch geboren wird; kann nicht quetschen." -#: builtin/merge.c:1194 +#: builtin/merge.c:1209 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" "Nicht vorzuspulende Version kann nicht in einem leeren Zweig verwendet " "werden." -#: builtin/merge.c:1310 +#: builtin/merge.c:1265 +#, c-format +msgid "Commit %s has an untrusted GPG signature, allegedly by %s." +msgstr "" +"Version %s hat eine nicht vertrauenswürdige GPG-Signatur, angeblich von %s." + +#: builtin/merge.c:1268 +#, c-format +msgid "Commit %s has a bad GPG signature allegedly by %s." +msgstr "Version %s hat eine ungültige GPG-Signatur, angeblich von %s." + +#. 'N' +#: builtin/merge.c:1271 +#, c-format +msgid "Commit %s does not have a GPG signature." +msgstr "Version %s hat keine GPG-Signatur." + +#: builtin/merge.c:1274 +#, c-format +msgid "Commit %s has a good GPG signature by %s\n" +msgstr "Version %s hat eine gültige GPG-Signatur von %s\n" + +#: builtin/merge.c:1358 #, c-format msgid "Updating %s..%s\n" msgstr "Aktualisiere %s..%s\n" -#: builtin/merge.c:1349 +#: builtin/merge.c:1397 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Probiere wirklich triviale \"in-index\"-Zusammenführung...\n" -#: builtin/merge.c:1356 +#: builtin/merge.c:1404 #, c-format msgid "Nope.\n" msgstr "Nein.\n" -#: builtin/merge.c:1388 +#: builtin/merge.c:1436 msgid "Not possible to fast-forward, aborting." msgstr "Vorspulen nicht möglich, breche ab." -#: builtin/merge.c:1411 builtin/merge.c:1490 +#: builtin/merge.c:1459 builtin/merge.c:1538 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Rücklauf des Zweiges bis zum Ursprung...\n" -#: builtin/merge.c:1415 +#: builtin/merge.c:1463 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Probiere Zusammenführungsstrategie %s...\n" -#: builtin/merge.c:1481 +#: builtin/merge.c:1529 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Keine Zusammenführungsstrategie behandelt diese Zusammenführung.\n" -#: builtin/merge.c:1483 +#: builtin/merge.c:1531 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Zusammenführung mit Strategie %s fehlgeschlagen.\n" -#: builtin/merge.c:1492 +#: builtin/merge.c:1540 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Benutzen Sie \"%s\" um die Auflösung per Hand vorzubereiten.\n" -#: builtin/merge.c:1504 +#: builtin/merge.c:1552 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -7396,11 +7738,15 @@ msgstr "entfernt lokal gelöschte Referenzen" msgid "bypass pre-push hook" msgstr "umgeht \"pre-push hook\"" -#: builtin/push.c:448 +#: builtin/push.c:440 +msgid "push missing but relevant tags" +msgstr "versendet fehlende, aber relevante Markierungen" + +#: builtin/push.c:450 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "Die Option --delete ist inkompatibel mit --all, --mirror und --tags." -#: builtin/push.c:450 +#: builtin/push.c:452 msgid "--delete doesn't make sense without any refs" msgstr "Die Option --delete kann nur mit Referenzen verwendet werden." @@ -8177,16 +8523,16 @@ msgstr "" "erster Verwendung aus." #: builtin/revert.c:22 -msgid "git revert [options] <commit-ish>" -msgstr "git revert [options] <Versionsangabe>" +msgid "git revert [options] <commit-ish>..." +msgstr "git revert [Optionen] <Versionsangabe>..." #: builtin/revert.c:23 msgid "git revert <subcommand>" msgstr "git revert <Unterkommando>" #: builtin/revert.c:28 -msgid "git cherry-pick [options] <commit-ish>" -msgstr "git cherry-pick [Optionen] <Versionsangabe>" +msgid "git cherry-pick [options] <commit-ish>..." +msgstr "git cherry-pick [Optionen] <Versionsangabe>..." #: builtin/revert.c:29 msgid "git cherry-pick <subcommand>" @@ -8340,33 +8686,31 @@ msgid "git rm: unable to remove %s" msgstr "git rm: konnte %s nicht löschen" #: builtin/shortlog.c:13 -msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" -msgstr "" -"git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] " -"[<Versionsidentifikation>... ]" +msgid "git shortlog [<options>] [<revision range>] [[--] [<path>...]]" +msgstr "git shortlog [<Optionen>] [Revisionsbereich] [[--] <Pfad>...]" -#: builtin/shortlog.c:133 +#: builtin/shortlog.c:131 #, c-format msgid "Missing author: %s" msgstr "fehlender Autor: %s" -#: builtin/shortlog.c:229 +#: builtin/shortlog.c:227 msgid "sort output according to the number of commits per author" msgstr "sortiert die Ausgabe entsprechend der Anzahl von Versionen pro Autor" -#: builtin/shortlog.c:231 +#: builtin/shortlog.c:229 msgid "Suppress commit descriptions, only provides commit count" msgstr "Unterdrückt Versionsbeschreibungen, liefert nur Anzahl der Versionen" -#: builtin/shortlog.c:233 +#: builtin/shortlog.c:231 msgid "Show the email address of each author" msgstr "Zeigt die Email-Adresse von jedem Autor" -#: builtin/shortlog.c:234 +#: builtin/shortlog.c:232 msgid "w[,i1[,i2]]" msgstr "w[,i1[,i2]]" -#: builtin/shortlog.c:235 +#: builtin/shortlog.c:233 msgid "Linewrap output" msgstr "Ausgabe mit Zeilenumbrüchen" @@ -8386,68 +8730,68 @@ msgstr "" msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "git show-branch (-g|--reflog)[=<n>[,<Basis>]] [--list] [<Referenz>]" -#: builtin/show-branch.c:651 +#: builtin/show-branch.c:650 msgid "show remote-tracking and local branches" msgstr "zeigt externe Ãœbernahmezweige und lokale Zweige an" -#: builtin/show-branch.c:653 +#: builtin/show-branch.c:652 msgid "show remote-tracking branches" msgstr "zeigt externe Ãœbernahmezweige an" -#: builtin/show-branch.c:655 +#: builtin/show-branch.c:654 msgid "color '*!+-' corresponding to the branch" msgstr "färbt '*!+-' entsprechend des Zweiges ein" -#: builtin/show-branch.c:657 +#: builtin/show-branch.c:656 msgid "show <n> more commits after the common ancestor" msgstr "zeigt <n> weitere Versionen nach dem gemeinsamen Vorfahren" -#: builtin/show-branch.c:659 +#: builtin/show-branch.c:658 msgid "synonym to more=-1" msgstr "Synonym für more=-1" -#: builtin/show-branch.c:660 +#: builtin/show-branch.c:659 msgid "suppress naming strings" msgstr "unterdrückt Namen" -#: builtin/show-branch.c:662 +#: builtin/show-branch.c:661 msgid "include the current branch" msgstr "bezieht den aktuellen Zweig ein" -#: builtin/show-branch.c:664 +#: builtin/show-branch.c:663 msgid "name commits with their object names" msgstr "benennt Versionen nach ihren Objektnamen" -#: builtin/show-branch.c:666 +#: builtin/show-branch.c:665 msgid "show possible merge bases" msgstr "zeigt mögliche Basen für Zusammenführung" -#: builtin/show-branch.c:668 +#: builtin/show-branch.c:667 msgid "show refs unreachable from any other ref" msgstr "zeigt Referenzen die unerreichbar von allen anderen Referenzen sind" -#: builtin/show-branch.c:670 +#: builtin/show-branch.c:669 msgid "show commits in topological order" msgstr "zeigt Versionen in topologischer Ordnung" -#: builtin/show-branch.c:672 +#: builtin/show-branch.c:671 msgid "show only commits not on the first branch" msgstr "zeigt nur Versionen, die sich nicht im ersten Zweig befinden" -#: builtin/show-branch.c:674 +#: builtin/show-branch.c:673 msgid "show merges reachable from only one tip" msgstr "" "zeigt Zusammenführungen, die nur von einer Zweigspitze aus erreichbar sind" -#: builtin/show-branch.c:676 +#: builtin/show-branch.c:675 msgid "show commits where no parent comes before its children" msgstr "zeigt Versionen, wo kein Elternteil vor seinem Kind kommt" -#: builtin/show-branch.c:678 +#: builtin/show-branch.c:677 msgid "<n>[,<base>]" msgstr "<n>[,<Basis>]" -#: builtin/show-branch.c:679 +#: builtin/show-branch.c:678 msgid "show <n> most recent ref-log entries starting at base" msgstr "" "zeigt die <n> jüngsten Einträge im Referenzprotokoll beginnend an der Basis" @@ -8920,10 +9264,15 @@ msgid "only useful for debugging" msgstr "nur nützlich für Fehlersuche" #: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." +msgid "" +"'git help -a' and 'git help -g' lists available subcommands and some\n" +"concept guides. See 'git help <command>' or 'git help <concept>'\n" +"to read about a specific subcommand or concept." msgstr "" -"Siehe 'git help <Kommando>' für weitere Informationen zu einem spezifischen " -"Kommando" +"'git help -a' und 'git help -g' listet verfügbare Unterkommandos und\n" +"einige Anleitungen zu Git-Konzepten auf. Benutzen Sie 'git help <Kommando>'\n" +"oder 'git help <Konzept>' um mehr über ein spezifisches Kommando oder\n" +"Konzept zu erfahren." #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -9310,16 +9659,16 @@ msgstr "" "angeben.\n" "(Sie können dafür \"git bisect bad\" und \"git bisect good\" benutzen.)" -#: git-bisect.sh:347 git-bisect.sh:474 +#: git-bisect.sh:363 git-bisect.sh:490 msgid "We are not bisecting." msgstr "keine binäre Suche im Gange" -#: git-bisect.sh:354 +#: git-bisect.sh:370 #, sh-format msgid "'$invalid' is not a valid commit" msgstr "'$invalid' ist keine gültige Version" -#: git-bisect.sh:363 +#: git-bisect.sh:379 #, sh-format msgid "" "Could not check out original HEAD '$branch'.\n" @@ -9328,25 +9677,25 @@ msgstr "" "Konnte die ursprüngliche Zweigspitze (HEAD) '$branch' nicht auschecken.\n" "Versuchen Sie 'git bisect reset <Version>'." -#: git-bisect.sh:390 +#: git-bisect.sh:406 msgid "No logfile given" msgstr "Keine Log-Datei gegeben" -#: git-bisect.sh:391 +#: git-bisect.sh:407 #, sh-format msgid "cannot read $file for replaying" msgstr "kann $file nicht für das Abspielen lesen" -#: git-bisect.sh:408 +#: git-bisect.sh:424 msgid "?? what are you talking about?" msgstr "?? Was reden Sie da?" -#: git-bisect.sh:420 +#: git-bisect.sh:436 #, sh-format msgid "running $command" msgstr "führe $command aus" -#: git-bisect.sh:427 +#: git-bisect.sh:443 #, sh-format msgid "" "bisect run failed:\n" @@ -9355,11 +9704,11 @@ msgstr "" "'bisect run' fehlgeschlagen:\n" "Rückkehrwert $res von '$command' ist < 0 oder >= 128" -#: git-bisect.sh:453 +#: git-bisect.sh:469 msgid "bisect run cannot continue any more" msgstr "'bisect run' kann nicht mehr fortgesetzt werden" -#: git-bisect.sh:459 +#: git-bisect.sh:475 #, sh-format msgid "" "bisect run failed:\n" @@ -9368,7 +9717,7 @@ msgstr "" "'bisect run' fehlgeschlagen:\n" "'bisect_state $state' wurde mit Fehlerwert $res beendet" -#: git-bisect.sh:466 +#: git-bisect.sh:482 msgid "bisect run success" msgstr "'bisect run' erfolgreich ausgeführt" @@ -9389,7 +9738,7 @@ msgid "Pull is not possible because you have unmerged files." msgstr "" "\"pull\" ist nicht möglich, weil Sie nicht zusammengeführte Dateien haben." -#: git-pull.sh:197 +#: git-pull.sh:203 msgid "updating an unborn branch with changes added to the index" msgstr "" "Aktualisiere eine ungeborenen Zweig mit Änderungen, die zur Bereitstellung " @@ -9399,7 +9748,7 @@ msgstr "" #. The working tree and the index file is still based on the #. $orig_head commit, but we are merging into $curr_head. #. First update the working tree to match $curr_head. -#: git-pull.sh:229 +#: git-pull.sh:235 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -9409,11 +9758,11 @@ msgstr "" "Warnung: Die Anforderung aktualisierte die Spitze des aktuellen Zweiges.\n" "Warnung: Spule Ihren Arbeitszweig von Version $orig_head vor." -#: git-pull.sh:254 +#: git-pull.sh:260 msgid "Cannot merge multiple branches into empty head" msgstr "Kann nicht mehrere Zweige in einen ungeborenen Zweig zusammenführen" -#: git-pull.sh:258 +#: git-pull.sh:264 msgid "Cannot rebase onto multiple branches" msgstr "kann nicht auf mehrere Zweige neu aufbauen" @@ -9680,39 +10029,39 @@ msgstr "Kein Zweigname spezifiziert" msgid "(To restore them type \"git stash apply\")" msgstr "(Zur Wiederherstellung geben Sie \"git stash apply\" ein)" -#: git-submodule.sh:90 +#: git-submodule.sh:91 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "Kann eine Komponente von URL '$remoteurl' nicht extrahieren" -#: git-submodule.sh:195 +#: git-submodule.sh:196 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" "Keine Unterprojekt-Zuordnung in .gitmodules für Pfad '$sm_path' gefunden" -#: git-submodule.sh:238 +#: git-submodule.sh:239 #, sh-format msgid "Clone of '$url' into submodule path '$sm_path' failed" msgstr "Klonen von '$url' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen" -#: git-submodule.sh:250 +#: git-submodule.sh:251 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "" "Git-Verzeichnis '$a' ist Teil des Unterprojekt-Pfades '$b', oder umgekehrt" -#: git-submodule.sh:343 +#: git-submodule.sh:349 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "repo URL: '$repo' muss absolut sein oder mit ./|../ beginnen" -#: git-submodule.sh:360 +#: git-submodule.sh:366 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "'$sm_path' existiert bereits in der Bereitstellung" -#: git-submodule.sh:364 +#: git-submodule.sh:370 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9723,25 +10072,25 @@ msgstr "" "$sm_path\n" "Benutzen Sie -f wenn Sie diesen wirklich hinzufügen möchten." -#: git-submodule.sh:382 +#: git-submodule.sh:388 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "" "Füge existierendes Projektarchiv in '$sm_path' der Bereitstellung hinzu." -#: git-submodule.sh:384 +#: git-submodule.sh:390 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "'$sm_path' existiert bereits und ist kein gültiges Git-Projektarchiv" -#: git-submodule.sh:392 +#: git-submodule.sh:398 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "" "Ein Git-Verzeichnis für '$sm_name' wurde lokal gefunden mit den Fernarchiv" "(en):" -#: git-submodule.sh:394 +#: git-submodule.sh:400 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" @@ -9749,7 +10098,7 @@ msgstr "" "Wenn Sie dieses lokale Git-Verzeichnis wiederverwenden möchtest, anstatt " "erneut zu klonen" -#: git-submodule.sh:396 +#: git-submodule.sh:402 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" @@ -9757,7 +10106,7 @@ msgstr "" "benutzen Sie die Option '--force'. Wenn das lokale Git-Verzeichnis nicht das " "korrekte Projektarchiv ist" -#: git-submodule.sh:397 +#: git-submodule.sh:403 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " @@ -9766,157 +10115,262 @@ msgstr "" "oder Sie sich unsicher sind, was das bedeutet, wählen Sie einen anderen " "Namenmit der Option '--name'." -#: git-submodule.sh:399 +#: git-submodule.sh:405 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "Reaktiviere lokales Git-Verzeichnis für Unterprojekt '$sm_name'." -#: git-submodule.sh:411 +#: git-submodule.sh:417 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "Unfähig Unterprojekt '$sm_path' auszuchecken" -#: git-submodule.sh:416 +#: git-submodule.sh:422 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "Hinzufügen von Unterprojekt '$sm_path' fehlgeschlagen" -#: git-submodule.sh:425 +#: git-submodule.sh:431 #, sh-format msgid "Failed to register submodule '$sm_path'" -msgstr "Registierung von Unterprojekt '$sm_path' fehlgeschlagen" +msgstr "" +"Fehler beim Eintragen von Unterprojekt '$sm_path' in die Konfiguration." -#: git-submodule.sh:468 +#: git-submodule.sh:474 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "Betrete '$prefix$sm_path'" -#: git-submodule.sh:482 +#: git-submodule.sh:488 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "Stoppe bei '$sm_path'; Skript gab nicht-Null Status zurück." -#: git-submodule.sh:526 +#: git-submodule.sh:532 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "Keine URL für Unterprojekt-Pfad '$sm_path' in .gitmodules gefunden" -#: git-submodule.sh:535 +#: git-submodule.sh:541 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" -msgstr "Registrierung der URL für Unterprojekt-Pfad '$sm_path' fehlgeschlagen" +msgstr "" +"Fehler beim Eintragen der URL für Unterprojekt-Pfad '$sm_path' in die " +"Konfiguration." -#: git-submodule.sh:537 +#: git-submodule.sh:543 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" -msgstr "Unterprojekt '$name' ($url) ist für Pfad '$sm_path' registriert" +msgstr "" +"Unterprojekt '$name' ($url) für Pfad '$sm_path' in die Konfiguration " +"eingetragen" -#: git-submodule.sh:545 +#: git-submodule.sh:551 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" -"Registrierung des Aktualisierungsmodus für Unterprojekt-Pfad '$sm_path' " -"fehlgeschlagen" +"Fehler bei Änderung des Aktualisierungsmodus für Unterprojekt-Pfad " +"'$sm_path' in der Konfiguration." + +#: git-submodule.sh:588 +#, sh-format +msgid "Use '.' if you really want to deinitialize all submodules" +msgstr "" +"Verwenden Sie '.' wenn Sie wirklich alle Unterprojekte\n" +"deinitialisieren möchten." + +#: git-submodule.sh:603 +#, sh-format +msgid "Submodule work tree '$sm_path' contains a .git directory" +msgstr "" +"Arbeitsbaum des Unterprojekts in '$sm_path' enthält ein .git-Verzeichnis" + +#: git-submodule.sh:604 +#, sh-format +msgid "" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" +"(benutzen Sie 'rm -rf' wenn Sie dieses Unterprojekt wirklich mitsamt\n" +"seiner Historie löschen möchten)" + +#: git-submodule.sh:610 +#, sh-format +msgid "" +"Submodule work tree '$sm_path' contains local modifications; use '-f' to " +"discard them" +msgstr "" +"Arbeitsbaum von Unterprojekt in '$sm_path' enthält lokale Änderungen; " +"verwenden Sie '-f' um diese zu verwerfen" + +#: git-submodule.sh:613 +#, sh-format +msgid "Cleared directory '$sm_path'" +msgstr "Verzeichnis '$sm_path' bereinigt." + +#: git-submodule.sh:614 +#, sh-format +msgid "Could not remove submodule work tree '$sm_path'" +msgstr "Konnte Arbeitsbaum des Unterprojektes in '$sm_path' nicht löschen." -#: git-submodule.sh:649 +#: git-submodule.sh:617 +#, sh-format +msgid "Could not create empty submodule directory '$sm_path'" +msgstr "" +"Konnte kein leeres Verzeichnis für Unterprojekt in '$sm_path' erstellen." + +#: git-submodule.sh:626 +#, sh-format +msgid "Submodule '$name' ($url) unregistered for path '$sm_path'" +msgstr "" +"Unterprojekt '$name' ($url) für Pfad '$sm_path' wurde aus der Konfiguration " +"entfernt." + +#: git-submodule.sh:731 #, sh-format msgid "" -"Submodule path '$sm_path' not initialized\n" +"Submodule path '$prefix$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -"Unterprojekt-Pfad '$sm_path' ist nicht initialisiert\n" +"Unterprojekt-Pfad '$prefix$sm_path' ist nicht initialisiert.\n" "Vielleicht möchten Sie 'update --init' benutzen?" -#: git-submodule.sh:662 +#: git-submodule.sh:744 #, sh-format -msgid "Unable to find current revision in submodule path '$sm_path'" -msgstr "Konnte aktuelle Revision in Unterprojekt-Pfad '$sm_path' nicht finden" +msgid "Unable to find current revision in submodule path '$prefix$sm_path'" +msgstr "" +"Konnte aktuelle Revision in Unterprojekt-Pfad '$prefix$sm_path' nicht finden." -#: git-submodule.sh:671 git-submodule.sh:695 +#: git-submodule.sh:753 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "Konnte in Unterprojekt-Pfad '$sm_path' nicht anfordern" -#: git-submodule.sh:709 +#: git-submodule.sh:777 +#, sh-format +msgid "Unable to fetch in submodule path '$prefix$sm_path'" +msgstr "Konnte in Unterprojekt-Pfad '$prefix$sm_path' nicht anfordern" + +#: git-submodule.sh:791 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" -msgstr "Neuaufbau von '$sha1' in Unterprojekt-Pfad '$sm_path' nicht möglich" +msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'" +msgstr "" +"Neuaufbau von '$sha1' in Unterprojekt-Pfad '$prefix$sm_path' nicht möglich" -#: git-submodule.sh:710 +#: git-submodule.sh:792 #, sh-format -msgid "Submodule path '$sm_path': rebased into '$sha1'" -msgstr "Unterprojekt-Pfad '$sm_path': neu aufgebaut in '$sha1'" +msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'" +msgstr "Unterprojekt-Pfad '$prefix$sm_path': neu aufgebaut in '$sha1'" -#: git-submodule.sh:715 +#: git-submodule.sh:797 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$sm_path'" +msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'" msgstr "" -"Zusammenführung von '$sha1' in Unterprojekt-Pfad '$sm_path' fehlgeschlagen" +"Zusammenführung von '$sha1' in Unterprojekt-Pfad '$prefix$sm_path' " +"fehlgeschlagen" -#: git-submodule.sh:716 +#: git-submodule.sh:798 #, sh-format -msgid "Submodule path '$sm_path': merged in '$sha1'" -msgstr "Unterprojekt-Pfad '$sm_path': zusammengeführt in '$sha1'" +msgid "Submodule path '$prefix$sm_path': merged in '$sha1'" +msgstr "Unterprojekt-Pfad '$prefix$sm_path': zusammengeführt in '$sha1'" -#: git-submodule.sh:721 +#: git-submodule.sh:803 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" -msgstr "Konnte '$sha1' in Unterprojekt-Pfad '$sm_path' nicht auschecken." +msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'" +msgstr "" +"Konnte '$sha1' in Unterprojekt-Pfad '$prefix$sm_path' nicht auschecken." -#: git-submodule.sh:722 +#: git-submodule.sh:804 #, sh-format -msgid "Submodule path '$sm_path': checked out '$sha1'" -msgstr "Unterprojekt-Pfad: '$sm_path': '$sha1' ausgecheckt" +msgid "Submodule path '$prefix$sm_path': checked out '$sha1'" +msgstr "Unterprojekt-Pfad: '$prefix$sm_path': '$sha1' ausgecheckt" -#: git-submodule.sh:744 git-submodule.sh:1066 +#: git-submodule.sh:831 #, sh-format -msgid "Failed to recurse into submodule path '$sm_path'" -msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'" +msgid "Failed to recurse into submodule path '$prefix$sm_path'" +msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$prefix$sm_path'" -#: git-submodule.sh:852 +#: git-submodule.sh:939 msgid "The --cached option cannot be used with the --files option" msgstr "" "Die Optionen --cached und --files können nicht gemeinsam verwendet werden." #. unexpected type -#: git-submodule.sh:892 +#: git-submodule.sh:979 #, sh-format msgid "unexpected mode $mod_dst" msgstr "unerwarteter Modus $mod_dst" -#: git-submodule.sh:910 +#: git-submodule.sh:997 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Warnung: $name beinhaltet nicht Version $sha1_src" -#: git-submodule.sh:913 +#: git-submodule.sh:1000 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Warnung: $name beinhaltet nicht Version $sha1_dst" -#: git-submodule.sh:916 +#: git-submodule.sh:1003 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" " Warnung: $name beinhaltet nicht die Versionen $sha1_src und $sha1_dst" -#: git-submodule.sh:941 +#: git-submodule.sh:1028 msgid "blob" msgstr "Blob" -#: git-submodule.sh:979 +#: git-submodule.sh:1066 msgid "Submodules changed but not updated:" msgstr "Unterprojekte geändert, aber nicht aktualisiert:" -#: git-submodule.sh:981 +#: git-submodule.sh:1068 msgid "Submodule changes to be committed:" msgstr "Änderungen in Unterprojekt zum Eintragen:" -#: git-submodule.sh:1129 +#: git-submodule.sh:1153 +#, sh-format +msgid "Failed to recurse into submodule path '$sm_path'" +msgstr "Fehler bei Rekursion in Unterprojekt-Pfad '$sm_path'" + +#: git-submodule.sh:1216 #, sh-format msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "Synchronisiere Unterprojekt-URL für '$prefix$sm_path'" +#~ msgid "It took %.2f seconds to enumerate untracked files. 'status -uno'" +#~ msgstr "" +#~ "Es dauerte %.2f Sekunden die unbeobachteten Dateien zu bestimmen.'status -" +#~ "uno'" + +#~ msgid "may speed it up, but you have to be careful not to forget to add" +#~ msgstr "könnte das beschleunigen, aber Sie müssen darauf achten, neue" + +#~ msgid "new files yourself (see 'git help status')." +#~ msgstr "Dateien selbstständig hinzuzufügen (siehe 'git help status')." + +#~ msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +#~ msgstr "" +#~ "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] " +#~ "[<Versionsidentifikation>... ]" + +#~ msgid "See 'git help <command>' for more information on a specific command." +#~ msgstr "" +#~ "Siehe 'git help <Kommando>' für weitere Informationen zu einem " +#~ "spezifischen Kommando" + +#~ msgid "use any ref in .git/refs" +#~ msgstr "verwendet alle Referenzen in .git/refs" + +#~ msgid "use any tag in .git/refs/tags" +#~ msgstr "verwendet alle Markierungen in .git/refs/tags" + +#~ msgid "bad object %s" +#~ msgstr "ungültiges Objekt %s" + +#~ msgid "bogus committer info %s" +#~ msgstr "unechte Einreicher-Informationen %s" + #~ msgid "can't fdopen 'show' output fd" #~ msgstr "konnte Datei-Deskriptor für Ausgabe von 'show' nicht öffnen" diff --git a/po/git.pot b/po/git.pot index a826dcbf9f..4a9d4efed9 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: 2013-03-05 12:36+0800\n" +"POT-Creation-Date: 2013-04-30 08:25+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" @@ -18,7 +18,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=INTEGER; plural=EXPRESSION;\n" -#: advice.c:49 +#: advice.c:53 #, c-format msgid "hint: %.*s\n" msgstr "" @@ -27,7 +27,7 @@ msgstr "" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:79 +#: advice.c:83 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm <file>' as\n" @@ -60,7 +60,7 @@ msgstr "" msgid "archive format" msgstr "" -#: archive.c:324 builtin/log.c:1115 +#: archive.c:324 builtin/log.c:1126 msgid "prefix" msgstr "" @@ -68,15 +68,15 @@ msgstr "" msgid "prepend prefix to each pathname in the archive" msgstr "" -#: archive.c:326 builtin/archive.c:91 builtin/blame.c:2366 -#: builtin/blame.c:2367 builtin/config.c:55 builtin/fast-export.c:653 -#: builtin/fast-export.c:655 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:497 builtin/ls-files.c:500 builtin/notes.c:536 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 +#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 +#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 #: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 msgid "file" msgstr "" -#: archive.c:327 builtin/archive.c:92 +#: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" msgstr "" @@ -104,19 +104,19 @@ msgstr "" msgid "list supported archive formats" msgstr "" -#: archive.c:345 builtin/archive.c:93 builtin/clone.c:85 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 msgid "repo" msgstr "" -#: archive.c:346 builtin/archive.c:94 +#: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository <repo>" msgstr "" -#: archive.c:347 builtin/archive.c:95 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 msgid "command" msgstr "" -#: archive.c:348 builtin/archive.c:96 +#: archive.c:348 builtin/archive.c:93 msgid "path to the remote git-upload-archive command" msgstr "" @@ -126,6 +126,120 @@ msgid "" "Use '\\!' for literal leading exclamation." msgstr "" +#: branch.c:60 +#, c-format +msgid "Not setting branch %s as its own upstream." +msgstr "" + +#: branch.c:82 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s by rebasing." +msgstr "" + +#: branch.c:83 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s." +msgstr "" + +#: branch.c:87 +#, c-format +msgid "Branch %s set up to track local branch %s by rebasing." +msgstr "" + +#: branch.c:88 +#, c-format +msgid "Branch %s set up to track local branch %s." +msgstr "" + +#: branch.c:92 +#, c-format +msgid "Branch %s set up to track remote ref %s by rebasing." +msgstr "" + +#: branch.c:93 +#, c-format +msgid "Branch %s set up to track remote ref %s." +msgstr "" + +#: branch.c:97 +#, c-format +msgid "Branch %s set up to track local ref %s by rebasing." +msgstr "" + +#: branch.c:98 +#, c-format +msgid "Branch %s set up to track local ref %s." +msgstr "" + +#: branch.c:118 +#, c-format +msgid "Tracking not set up: name too long: %s" +msgstr "" + +#: branch.c:137 +#, c-format +msgid "Not tracking: ambiguous information for ref %s" +msgstr "" + +#: branch.c:182 +#, c-format +msgid "'%s' is not a valid branch name." +msgstr "" + +#: branch.c:187 +#, c-format +msgid "A branch named '%s' already exists." +msgstr "" + +#: branch.c:195 +msgid "Cannot force update the current branch." +msgstr "" + +#: branch.c:201 +#, c-format +msgid "Cannot setup tracking information; starting point '%s' is not a branch." +msgstr "" + +#: branch.c:203 +#, c-format +msgid "the requested upstream branch '%s' does not exist" +msgstr "" + +#: branch.c:205 +msgid "" +"\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push." +msgstr "" + +#: branch.c:250 +#, c-format +msgid "Not a valid object name: '%s'." +msgstr "" + +#: branch.c:270 +#, c-format +msgid "Ambiguous object name: '%s'." +msgstr "" + +#: branch.c:275 +#, c-format +msgid "Not a valid branch point: '%s'." +msgstr "" + +#: branch.c:281 +msgid "Failed to lock ref for update" +msgstr "" + +#: branch.c:299 +msgid "Failed to write ref" +msgstr "" + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -136,7 +250,7 @@ msgstr "" msgid "unrecognized header: %s%s (%d)" msgstr "" -#: bundle.c:89 builtin/commit.c:674 +#: bundle.c:89 builtin/commit.c:676 #, c-format msgid "could not open '%s'" msgstr "" @@ -145,27 +259,27 @@ msgstr "" msgid "Repository lacks these prerequisite commits:" msgstr "" -#: bundle.c:164 sequencer.c:566 sequencer.c:998 builtin/log.c:299 -#: builtin/log.c:751 builtin/log.c:1358 builtin/log.c:1574 builtin/merge.c:347 -#: builtin/shortlog.c:157 +#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 +#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 +#: builtin/shortlog.c:155 msgid "revision walk setup failed" msgstr "" #: bundle.c:186 #, c-format -msgid "The bundle contains %d ref" -msgid_plural "The bundle contains %d refs" +msgid "The bundle contains this ref:" +msgid_plural "The bundle contains these %d refs:" msgstr[0] "" msgstr[1] "" -#: bundle.c:192 +#: bundle.c:193 msgid "The bundle records a complete history." msgstr "" #: bundle.c:195 #, c-format -msgid "The bundle requires this ref" -msgid_plural "The bundle requires these %d refs" +msgid "The bundle requires this ref:" +msgid_plural "The bundle requires these %d refs:" msgstr[0] "" msgstr[1] "" @@ -173,7 +287,7 @@ msgstr[1] "" msgid "rev-list died" msgstr "" -#: bundle.c:300 builtin/log.c:1254 builtin/shortlog.c:260 +#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 #, c-format msgid "unrecognized argument: %s" msgstr "" @@ -321,19 +435,19 @@ msgid "" "%s" msgstr "" -#: diff.c:3468 +#: diff.c:3481 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" "%s" msgstr "" -#: diff.c:3482 +#: diff.c:3495 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "" -#: gpg-interface.c:59 gpg-interface.c:127 +#: gpg-interface.c:59 gpg-interface.c:131 msgid "could not run gpg." msgstr "" @@ -345,27 +459,27 @@ msgstr "" msgid "gpg failed to sign the data" msgstr "" -#: gpg-interface.c:112 +#: gpg-interface.c:115 #, c-format msgid "could not create temporary file '%s': %s" msgstr "" -#: gpg-interface.c:115 +#: gpg-interface.c:118 #, c-format msgid "failed writing detached signature to '%s': %s" msgstr "" -#: grep.c:1622 +#: grep.c:1623 #, c-format msgid "'%s': unable to read %s" msgstr "" -#: grep.c:1639 +#: grep.c:1640 #, c-format msgid "'%s': %s" msgstr "" -#: grep.c:1650 +#: grep.c:1651 #, c-format msgid "'%s': short read %s" msgstr "" @@ -425,8 +539,8 @@ msgstr[1] "" msgid "failed to read the cache" msgstr "" -#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 -#: builtin/clone.c:586 +#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 +#: builtin/clone.c:645 msgid "unable to write new index file" msgstr "" @@ -475,7 +589,7 @@ msgstr "" msgid "blob expected for %s '%s'" msgstr "" -#: merge-recursive.c:773 builtin/clone.c:302 +#: merge-recursive.c:773 builtin/clone.c:313 #, c-format msgid "failed to open '%s'" msgstr "" @@ -602,7 +716,7 @@ msgstr "" msgid "Auto-merging %s" msgstr "" -#: merge-recursive.c:1633 git-submodule.sh:942 +#: merge-recursive.c:1633 git-submodule.sh:1029 msgid "submodule" msgstr "" @@ -672,10 +786,15 @@ msgstr "" msgid "Could not parse object '%s'" msgstr "" -#: merge-recursive.c:2009 builtin/merge.c:643 +#: merge-recursive.c:2009 builtin/merge.c:658 msgid "Unable to write index." msgstr "" +#: object.c:195 +#, c-format +msgid "unable to parse object: %s" +msgstr "" + #: parse-options.c:489 msgid "..." msgstr "" @@ -711,18 +830,18 @@ msgstr "" msgid "'%s' is beyond a symbolic link" msgstr "" -#: remote.c:1653 +#: remote.c:1781 #, 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:1659 +#: remote.c:1787 msgid " (use \"git push\" to publish your local commits)\n" msgstr "" -#: remote.c:1662 +#: remote.c:1790 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -730,11 +849,11 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: remote.c:1670 +#: remote.c:1798 msgid " (use \"git pull\" to update your local branch)\n" msgstr "" -#: remote.c:1673 +#: remote.c:1801 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -745,257 +864,267 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: remote.c:1683 +#: remote.c:1811 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr "" -#: sequencer.c:123 builtin/merge.c:761 builtin/merge.c:874 builtin/merge.c:984 -#: builtin/merge.c:994 +#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 +#: builtin/merge.c:1009 #, c-format msgid "Could not open '%s' for writing" msgstr "" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 -#: builtin/merge.c:999 +#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 +#: builtin/merge.c:1001 builtin/merge.c:1014 #, c-format msgid "Could not write to '%s'" msgstr "" -#: sequencer.c:146 +#: sequencer.c:229 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" msgstr "" -#: sequencer.c:149 +#: sequencer.c:232 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" "and commit the result with 'git commit'" msgstr "" -#: sequencer.c:162 sequencer.c:774 sequencer.c:857 +#: sequencer.c:245 sequencer.c:859 sequencer.c:942 #, c-format msgid "Could not write to %s" msgstr "" -#: sequencer.c:165 +#: sequencer.c:248 #, c-format msgid "Error wrapping up %s" msgstr "" -#: sequencer.c:180 +#: sequencer.c:263 msgid "Your local changes would be overwritten by cherry-pick." msgstr "" -#: sequencer.c:182 +#: sequencer.c:265 msgid "Your local changes would be overwritten by revert." msgstr "" -#: sequencer.c:185 +#: sequencer.c:268 msgid "Commit your changes or stash them to proceed." msgstr "" #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:236 +#: sequencer.c:319 #, c-format msgid "%s: Unable to write new index file" msgstr "" -#: sequencer.c:267 +#: sequencer.c:350 msgid "Could not resolve HEAD commit\n" msgstr "" -#: sequencer.c:288 +#: sequencer.c:371 msgid "Unable to update cache tree\n" msgstr "" -#: sequencer.c:333 +#: sequencer.c:416 #, c-format msgid "Could not parse commit %s\n" msgstr "" -#: sequencer.c:338 +#: sequencer.c:421 #, c-format msgid "Could not parse parent commit %s\n" msgstr "" -#: sequencer.c:404 +#: sequencer.c:487 msgid "Your index file is unmerged." msgstr "" -#: sequencer.c:423 +#: sequencer.c:506 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "" -#: sequencer.c:431 +#: sequencer.c:514 #, c-format msgid "Commit %s does not have parent %d" msgstr "" -#: sequencer.c:435 +#: sequencer.c:518 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:448 +#: sequencer.c:531 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "" -#: sequencer.c:452 +#: sequencer.c:535 #, c-format msgid "Cannot get commit message for %s" msgstr "" -#: sequencer.c:536 +#: sequencer.c:621 #, c-format msgid "could not revert %s... %s" msgstr "" -#: sequencer.c:537 +#: sequencer.c:622 #, c-format msgid "could not apply %s... %s" msgstr "" -#: sequencer.c:569 +#: sequencer.c:654 msgid "empty commit set passed" msgstr "" -#: sequencer.c:577 +#: sequencer.c:662 #, c-format msgid "git %s: failed to read the index" msgstr "" -#: sequencer.c:582 +#: sequencer.c:667 #, c-format msgid "git %s: failed to refresh the index" msgstr "" -#: sequencer.c:640 +#: sequencer.c:725 #, c-format msgid "Cannot %s during a %s" msgstr "" -#: sequencer.c:662 +#: sequencer.c:747 #, c-format msgid "Could not parse line %d." msgstr "" -#: sequencer.c:667 +#: sequencer.c:752 msgid "No commits parsed." msgstr "" -#: sequencer.c:680 +#: sequencer.c:765 #, c-format msgid "Could not open %s" msgstr "" -#: sequencer.c:684 +#: sequencer.c:769 #, c-format msgid "Could not read %s." msgstr "" -#: sequencer.c:691 +#: sequencer.c:776 #, c-format msgid "Unusable instruction sheet: %s" msgstr "" -#: sequencer.c:719 +#: sequencer.c:804 #, c-format msgid "Invalid key: %s" msgstr "" -#: sequencer.c:722 +#: sequencer.c:807 #, c-format msgid "Invalid value for %s: %s" msgstr "" -#: sequencer.c:734 +#: sequencer.c:819 #, c-format msgid "Malformed options sheet: %s" msgstr "" -#: sequencer.c:755 +#: sequencer.c:840 msgid "a cherry-pick or revert is already in progress" msgstr "" -#: sequencer.c:756 +#: sequencer.c:841 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "" -#: sequencer.c:760 +#: sequencer.c:845 #, c-format msgid "Could not create sequencer directory %s" msgstr "" -#: sequencer.c:776 sequencer.c:861 +#: sequencer.c:861 sequencer.c:946 #, c-format msgid "Error wrapping up %s." msgstr "" -#: sequencer.c:795 sequencer.c:929 +#: sequencer.c:880 sequencer.c:1014 msgid "no cherry-pick or revert in progress" msgstr "" -#: sequencer.c:797 +#: sequencer.c:882 msgid "cannot resolve HEAD" msgstr "" -#: sequencer.c:799 +#: sequencer.c:884 msgid "cannot abort from a branch yet to be born" msgstr "" -#: sequencer.c:821 builtin/apply.c:4056 +#: sequencer.c:906 builtin/apply.c:4060 #, c-format msgid "cannot open %s: %s" msgstr "" -#: sequencer.c:824 +#: sequencer.c:909 #, c-format msgid "cannot read %s: %s" msgstr "" -#: sequencer.c:825 +#: sequencer.c:910 msgid "unexpected end of file" msgstr "" -#: sequencer.c:831 +#: sequencer.c:916 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "" -#: sequencer.c:854 +#: sequencer.c:939 #, c-format msgid "Could not format %s." msgstr "" -#: sequencer.c:1016 +#: sequencer.c:1083 +#, c-format +msgid "%s: can't cherry-pick a %s" +msgstr "" + +#: sequencer.c:1085 +#, c-format +msgid "%s: bad revision" +msgstr "" + +#: sequencer.c:1119 msgid "Can't revert as initial commit" msgstr "" -#: sequencer.c:1017 +#: sequencer.c:1120 msgid "Can't cherry-pick into empty head" msgstr "" -#: sha1_name.c:1044 +#: sha1_name.c:1036 msgid "HEAD does not point to a branch" msgstr "" -#: sha1_name.c:1047 +#: sha1_name.c:1039 #, c-format msgid "No such branch: '%s'" msgstr "" -#: sha1_name.c:1049 +#: sha1_name.c:1041 #, c-format msgid "No upstream configured for branch '%s'" msgstr "" -#: sha1_name.c:1052 +#: sha1_name.c:1044 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "" @@ -1118,261 +1247,294 @@ msgstr "" msgid "untracked content, " msgstr "" -#: wt-status.c:303 +#: wt-status.c:306 #, c-format msgid "new file: %s" msgstr "" -#: wt-status.c:306 +#: wt-status.c:309 #, c-format msgid "copied: %s -> %s" msgstr "" -#: wt-status.c:309 +#: wt-status.c:312 #, c-format msgid "deleted: %s" msgstr "" -#: wt-status.c:312 +#: wt-status.c:315 #, c-format msgid "modified: %s" msgstr "" -#: wt-status.c:315 +#: wt-status.c:318 #, c-format msgid "renamed: %s -> %s" msgstr "" -#: wt-status.c:318 +#: wt-status.c:321 #, c-format msgid "typechange: %s" msgstr "" -#: wt-status.c:321 +#: wt-status.c:324 #, c-format msgid "unknown: %s" msgstr "" -#: wt-status.c:324 +#: wt-status.c:327 #, c-format msgid "unmerged: %s" msgstr "" -#: wt-status.c:327 +#: wt-status.c:330 #, c-format msgid "bug: unhandled diff status %c" msgstr "" -#: wt-status.c:789 +#: wt-status.c:803 msgid "You have unmerged paths." msgstr "" -#: wt-status.c:792 wt-status.c:944 +#: wt-status.c:806 wt-status.c:958 msgid " (fix conflicts and run \"git commit\")" msgstr "" -#: wt-status.c:795 +#: wt-status.c:809 msgid "All conflicts fixed but you are still merging." msgstr "" -#: wt-status.c:798 +#: wt-status.c:812 msgid " (use \"git commit\" to conclude merge)" msgstr "" -#: wt-status.c:808 +#: wt-status.c:822 msgid "You are in the middle of an am session." msgstr "" -#: wt-status.c:811 +#: wt-status.c:825 msgid "The current patch is empty." msgstr "" -#: wt-status.c:815 +#: wt-status.c:829 msgid " (fix conflicts and then run \"git am --resolved\")" msgstr "" -#: wt-status.c:817 +#: wt-status.c:831 msgid " (use \"git am --skip\" to skip this patch)" msgstr "" -#: wt-status.c:819 +#: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr "" -#: wt-status.c:879 wt-status.c:896 +#: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "" -#: wt-status.c:884 wt-status.c:901 +#: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." msgstr "" -#: wt-status.c:887 +#: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr "" -#: wt-status.c:889 +#: wt-status.c:903 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr "" -#: wt-status.c:891 +#: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr "" -#: wt-status.c:904 +#: wt-status.c:918 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr "" -#: wt-status.c:908 +#: wt-status.c:922 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." msgstr "" -#: wt-status.c:913 +#: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." msgstr "" -#: wt-status.c:916 +#: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" -#: wt-status.c:920 +#: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" -#: wt-status.c:925 +#: wt-status.c:939 msgid "You are currently editing a commit during a rebase." msgstr "" -#: wt-status.c:928 +#: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" -#: wt-status.c:930 +#: wt-status.c:944 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" -#: wt-status.c:940 +#: wt-status.c:954 msgid "You are currently cherry-picking." msgstr "" -#: wt-status.c:947 +#: wt-status.c:961 msgid " (all conflicts fixed: run \"git commit\")" msgstr "" -#: wt-status.c:958 +#: wt-status.c:970 +#, c-format +msgid "You are currently reverting commit %s." +msgstr "" + +#: wt-status.c:975 +msgid " (fix conflicts and run \"git revert --continue\")" +msgstr "" + +#: wt-status.c:978 +msgid " (all conflicts fixed: run \"git revert --continue\")" +msgstr "" + +#: wt-status.c:980 +msgid " (use \"git revert --abort\" to cancel the revert operation)" +msgstr "" + +#: wt-status.c:991 #, c-format -msgid "You are currently bisecting branch '%s'." +msgid "You are currently bisecting, started from branch '%s'." msgstr "" -#: wt-status.c:962 +#: wt-status.c:995 msgid "You are currently bisecting." msgstr "" -#: wt-status.c:965 +#: wt-status.c:998 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" -#: wt-status.c:1064 +#: wt-status.c:1173 msgid "On branch " msgstr "" -#: wt-status.c:1071 +#: wt-status.c:1184 +msgid "HEAD detached at " +msgstr "" + +#: wt-status.c:1186 +msgid "HEAD detached from " +msgstr "" + +#: wt-status.c:1189 msgid "Not currently on any branch." msgstr "" -#: wt-status.c:1083 +#: wt-status.c:1206 msgid "Initial commit" msgstr "" -#: wt-status.c:1097 +#: wt-status.c:1220 msgid "Untracked files" msgstr "" -#: wt-status.c:1099 +#: wt-status.c:1222 msgid "Ignored files" msgstr "" -#: wt-status.c:1101 +#: wt-status.c:1226 +#, c-format +msgid "" +"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" +"may speed it up, but you have to be careful not to forget to add\n" +"new files yourself (see 'git help status')." +msgstr "" + +#: wt-status.c:1232 #, c-format msgid "Untracked files not listed%s" msgstr "" -#: wt-status.c:1103 +#: wt-status.c:1234 msgid " (use -u option to show untracked files)" msgstr "" -#: wt-status.c:1109 +#: wt-status.c:1240 msgid "No changes" msgstr "" -#: wt-status.c:1114 +#: wt-status.c:1245 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" -#: wt-status.c:1117 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit\n" msgstr "" -#: wt-status.c:1120 +#: wt-status.c:1251 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " "track)\n" msgstr "" -#: wt-status.c:1123 +#: wt-status.c:1254 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "" -#: wt-status.c:1126 +#: wt-status.c:1257 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" -#: wt-status.c:1129 wt-status.c:1134 +#: wt-status.c:1260 wt-status.c:1265 #, c-format msgid "nothing to commit\n" msgstr "" -#: wt-status.c:1132 +#: wt-status.c:1263 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" -#: wt-status.c:1136 +#: wt-status.c:1267 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "" -#: wt-status.c:1244 +#: wt-status.c:1375 msgid "HEAD (no branch)" msgstr "" -#: wt-status.c:1250 +#: wt-status.c:1381 msgid "Initial commit on " msgstr "" -#: wt-status.c:1265 +#: wt-status.c:1396 msgid "behind " msgstr "" -#: wt-status.c:1268 wt-status.c:1271 +#: wt-status.c:1399 wt-status.c:1402 msgid "ahead " msgstr "" -#: wt-status.c:1273 +#: wt-status.c:1404 msgid ", behind " msgstr "" -#: compat/precompose_utf8.c:58 builtin/clone.c:341 +#: compat/precompose_utf8.c:58 builtin/clone.c:352 #, c-format msgid "failed to unlink '%s'" msgstr "" @@ -1381,179 +1543,200 @@ msgstr "" msgid "git add [options] [--] <pathspec>..." msgstr "" -#: builtin/add.c:63 +#. +#. * To be consistent with "git add -p" and most Git +#. * commands, we should default to being tree-wide, but +#. * this is not the original behavior and can't be +#. * changed until users trained themselves not to type +#. * "git add -u" or "git add -A". For now, we warn and +#. * keep the old behavior. Later, the behavior can be changed +#. * to tree-wide, keeping the warning for a while, and +#. * eventually we can drop the warning. +#. +#: builtin/add.c:58 +#, c-format +msgid "" +"The behavior of 'git add %s (or %s)' with no path argument from a\n" +"subdirectory of the tree will change in Git 2.0 and should not be used " +"anymore.\n" +"To add content for the whole tree, run:\n" +"\n" +" git add %s :/\n" +" (or git add %s :/)\n" +"\n" +"To restrict the command to the current directory, run:\n" +"\n" +" git add %s .\n" +" (or git add %s .)\n" +"\n" +"With the current Git version, the command is restricted to the current " +"directory.\n" +msgstr "" + +#: builtin/add.c:100 +#, c-format +msgid "" +"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n" +msgstr "" + +#: builtin/add.c:144 #, c-format msgid "unexpected diff status %c" msgstr "" -#: builtin/add.c:68 builtin/commit.c:231 +#: builtin/add.c:149 builtin/commit.c:233 msgid "updating files failed" msgstr "" -#: builtin/add.c:78 +#: builtin/add.c:163 #, c-format msgid "remove '%s'\n" msgstr "" -#: builtin/add.c:148 +#: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "" -#: builtin/add.c:151 builtin/add.c:460 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "" -#: builtin/add.c:234 +#: builtin/add.c:339 msgid "Could not read the index" msgstr "" -#: builtin/add.c:244 +#: builtin/add.c:349 #, c-format msgid "Could not open '%s' for writing." msgstr "" -#: builtin/add.c:248 +#: builtin/add.c:353 msgid "Could not write patch" msgstr "" -#: builtin/add.c:253 +#: builtin/add.c:358 #, c-format msgid "Could not stat '%s'" msgstr "" -#: builtin/add.c:255 +#: builtin/add.c:360 msgid "Empty patch. Aborted." msgstr "" -#: builtin/add.c:261 +#: builtin/add.c:366 #, c-format msgid "Could not apply '%s'" msgstr "" -#: builtin/add.c:271 +#: builtin/add.c:376 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" -#: builtin/add.c:277 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 #: builtin/rm.c:206 msgid "dry run" msgstr "" -#: builtin/add.c:278 builtin/apply.c:4405 builtin/check-ignore.c:19 -#: builtin/commit.c:1150 builtin/count-objects.c:82 builtin/fsck.c:613 -#: builtin/log.c:1522 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 +#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "" -#: builtin/add.c:280 +#: builtin/add.c:396 msgid "interactive picking" msgstr "" -#: builtin/add.c:281 builtin/checkout.c:1031 builtin/reset.c:258 +#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 msgid "select hunks interactively" msgstr "" -#: builtin/add.c:282 +#: builtin/add.c:398 msgid "edit current diff and apply" msgstr "" -#: builtin/add.c:283 +#: builtin/add.c:399 msgid "allow adding otherwise ignored files" msgstr "" -#: builtin/add.c:284 +#: builtin/add.c:400 msgid "update tracked files" msgstr "" -#: builtin/add.c:285 +#: builtin/add.c:401 msgid "record only the fact that the path will be added later" msgstr "" -#: builtin/add.c:286 +#: builtin/add.c:402 msgid "add changes from all tracked and untracked files" msgstr "" -#: builtin/add.c:287 +#. takes no arguments +#: builtin/add.c:405 +msgid "ignore paths removed in the working tree (same as --no-all)" +msgstr "" + +#: builtin/add.c:407 msgid "don't add, only refresh the index" msgstr "" -#: builtin/add.c:288 +#: builtin/add.c:408 msgid "just skip files which cannot be added because of errors" msgstr "" -#: builtin/add.c:289 +#: builtin/add.c:409 msgid "check if - even missing - files are ignored in dry run" msgstr "" -#: builtin/add.c:311 +#: builtin/add.c:431 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "" -#: builtin/add.c:312 +#: builtin/add.c:432 msgid "no files added" msgstr "" -#: builtin/add.c:318 +#: builtin/add.c:438 msgid "adding files failed" msgstr "" -#. -#. * To be consistent with "git add -p" and most Git -#. * commands, we should default to being tree-wide, but -#. * this is not the original behavior and can't be -#. * changed until users trained themselves not to type -#. * "git add -u" or "git add -A". For now, we warn and -#. * keep the old behavior. Later, this warning can be -#. * turned into a die(...), and eventually we may -#. * reallow the command with a new behavior. -#. -#: builtin/add.c:335 -#, c-format -msgid "" -"The behavior of 'git add %s (or %s)' with no path argument from a\n" -"subdirectory of the tree will change in Git 2.0 and should not be used " -"anymore.\n" -"To add content for the whole tree, run:\n" -"\n" -" git add %s :/\n" -" (or git add %s :/)\n" -"\n" -"To restrict the command to the current directory, run:\n" -"\n" -" git add %s .\n" -" (or git add %s .)\n" -"\n" -"With the current Git version, the command is restricted to the current " -"directory." -msgstr "" - -#: builtin/add.c:381 +#: builtin/add.c:477 msgid "-A and -u are mutually incompatible" msgstr "" -#: builtin/add.c:383 +#: builtin/add.c:495 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "" -#: builtin/add.c:414 +#: builtin/add.c:525 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "" -#: builtin/add.c:415 +#: builtin/add.c:526 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "" -#: builtin/add.c:421 builtin/check-ignore.c:67 builtin/clean.c:204 -#: builtin/commit.c:291 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 +#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 msgid "index file corrupt" msgstr "" -#: builtin/add.c:481 builtin/apply.c:4501 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "" @@ -1681,342 +1864,342 @@ msgstr "" msgid "unable to open or read %s" msgstr "" -#: builtin/apply.c:2684 +#: builtin/apply.c:2688 #, c-format msgid "invalid start of line: '%c'" msgstr "" -#: builtin/apply.c:2802 +#: builtin/apply.c:2806 #, 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:2814 +#: builtin/apply.c:2818 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "" -#: builtin/apply.c:2820 +#: builtin/apply.c:2824 #, c-format msgid "" "while searching for:\n" "%.*s" msgstr "" -#: builtin/apply.c:2839 +#: builtin/apply.c:2843 #, c-format msgid "missing binary patch data for '%s'" msgstr "" -#: builtin/apply.c:2942 +#: builtin/apply.c:2946 #, c-format msgid "binary patch does not apply to '%s'" msgstr "" -#: builtin/apply.c:2948 +#: builtin/apply.c:2952 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "" -#: builtin/apply.c:2969 +#: builtin/apply.c:2973 #, c-format msgid "patch failed: %s:%ld" msgstr "" -#: builtin/apply.c:3091 +#: builtin/apply.c:3095 #, c-format msgid "cannot checkout %s" msgstr "" -#: builtin/apply.c:3136 builtin/apply.c:3145 builtin/apply.c:3189 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 #, c-format msgid "read of %s failed" msgstr "" -#: builtin/apply.c:3169 builtin/apply.c:3391 +#: builtin/apply.c:3173 builtin/apply.c:3395 #, c-format msgid "path %s has been renamed/deleted" msgstr "" -#: builtin/apply.c:3250 builtin/apply.c:3405 +#: builtin/apply.c:3254 builtin/apply.c:3409 #, c-format msgid "%s: does not exist in index" msgstr "" -#: builtin/apply.c:3254 builtin/apply.c:3397 builtin/apply.c:3419 +#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 #, c-format msgid "%s: %s" msgstr "" -#: builtin/apply.c:3259 builtin/apply.c:3413 +#: builtin/apply.c:3263 builtin/apply.c:3417 #, c-format msgid "%s: does not match index" msgstr "" -#: builtin/apply.c:3361 +#: builtin/apply.c:3365 msgid "removal patch leaves file contents" msgstr "" -#: builtin/apply.c:3430 +#: builtin/apply.c:3434 #, c-format msgid "%s: wrong type" msgstr "" -#: builtin/apply.c:3432 +#: builtin/apply.c:3436 #, c-format msgid "%s has type %o, expected %o" msgstr "" -#: builtin/apply.c:3533 +#: builtin/apply.c:3537 #, c-format msgid "%s: already exists in index" msgstr "" -#: builtin/apply.c:3536 +#: builtin/apply.c:3540 #, c-format msgid "%s: already exists in working directory" msgstr "" -#: builtin/apply.c:3556 +#: builtin/apply.c:3560 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "" -#: builtin/apply.c:3561 +#: builtin/apply.c:3565 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "" -#: builtin/apply.c:3569 +#: builtin/apply.c:3573 #, c-format msgid "%s: patch does not apply" msgstr "" -#: builtin/apply.c:3582 +#: builtin/apply.c:3586 #, c-format msgid "Checking patch %s..." msgstr "" -#: builtin/apply.c:3675 builtin/checkout.c:215 builtin/reset.c:124 +#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "" -#: builtin/apply.c:3818 +#: builtin/apply.c:3822 #, c-format msgid "unable to remove %s from index" msgstr "" -#: builtin/apply.c:3846 +#: builtin/apply.c:3850 #, c-format msgid "corrupt patch for subproject %s" msgstr "" -#: builtin/apply.c:3850 +#: builtin/apply.c:3854 #, c-format msgid "unable to stat newly created file '%s'" msgstr "" -#: builtin/apply.c:3855 +#: builtin/apply.c:3859 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "" -#: builtin/apply.c:3858 builtin/apply.c:3966 +#: builtin/apply.c:3862 builtin/apply.c:3970 #, c-format msgid "unable to add cache entry for %s" msgstr "" -#: builtin/apply.c:3891 +#: builtin/apply.c:3895 #, c-format msgid "closing file '%s'" msgstr "" -#: builtin/apply.c:3940 +#: builtin/apply.c:3944 #, c-format msgid "unable to write file '%s' mode %o" msgstr "" -#: builtin/apply.c:4027 +#: builtin/apply.c:4031 #, c-format msgid "Applied patch %s cleanly." msgstr "" -#: builtin/apply.c:4035 +#: builtin/apply.c:4039 msgid "internal error" msgstr "" #. Say this even without --verbose -#: builtin/apply.c:4038 +#: builtin/apply.c:4042 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:4048 +#: builtin/apply.c:4052 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "" -#: builtin/apply.c:4069 +#: builtin/apply.c:4073 #, c-format msgid "Hunk #%d applied cleanly." msgstr "" -#: builtin/apply.c:4072 +#: builtin/apply.c:4076 #, c-format msgid "Rejected hunk #%d." msgstr "" -#: builtin/apply.c:4222 +#: builtin/apply.c:4226 msgid "unrecognized input" msgstr "" -#: builtin/apply.c:4233 +#: builtin/apply.c:4237 msgid "unable to read index file" msgstr "" -#: builtin/apply.c:4352 builtin/apply.c:4355 builtin/clone.c:91 +#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 #: builtin/fetch.c:63 msgid "path" msgstr "" -#: builtin/apply.c:4353 +#: builtin/apply.c:4357 msgid "don't apply changes matching the given path" msgstr "" -#: builtin/apply.c:4356 +#: builtin/apply.c:4360 msgid "apply changes matching the given path" msgstr "" -#: builtin/apply.c:4358 +#: builtin/apply.c:4362 msgid "num" msgstr "" -#: builtin/apply.c:4359 +#: builtin/apply.c:4363 msgid "remove <num> leading slashes from traditional diff paths" msgstr "" -#: builtin/apply.c:4362 +#: builtin/apply.c:4366 msgid "ignore additions made by the patch" msgstr "" -#: builtin/apply.c:4364 +#: builtin/apply.c:4368 msgid "instead of applying the patch, output diffstat for the input" msgstr "" -#: builtin/apply.c:4368 +#: builtin/apply.c:4372 msgid "show number of added and deleted lines in decimal notation" msgstr "" -#: builtin/apply.c:4370 +#: builtin/apply.c:4374 msgid "instead of applying the patch, output a summary for the input" msgstr "" -#: builtin/apply.c:4372 +#: builtin/apply.c:4376 msgid "instead of applying the patch, see if the patch is applicable" msgstr "" -#: builtin/apply.c:4374 +#: builtin/apply.c:4378 msgid "make sure the patch is applicable to the current index" msgstr "" -#: builtin/apply.c:4376 +#: builtin/apply.c:4380 msgid "apply a patch without touching the working tree" msgstr "" -#: builtin/apply.c:4378 +#: builtin/apply.c:4382 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "" -#: builtin/apply.c:4380 +#: builtin/apply.c:4384 msgid "attempt three-way merge if a patch does not apply" msgstr "" -#: builtin/apply.c:4382 +#: builtin/apply.c:4386 msgid "build a temporary index based on embedded index information" msgstr "" -#: builtin/apply.c:4384 builtin/checkout-index.c:197 builtin/ls-files.c:463 +#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 msgid "paths are separated with NUL character" msgstr "" -#: builtin/apply.c:4387 +#: builtin/apply.c:4391 msgid "ensure at least <n> lines of context match" msgstr "" -#: builtin/apply.c:4388 +#: builtin/apply.c:4392 msgid "action" msgstr "" -#: builtin/apply.c:4389 +#: builtin/apply.c:4393 msgid "detect new or modified lines that have whitespace errors" msgstr "" -#: builtin/apply.c:4392 builtin/apply.c:4395 +#: builtin/apply.c:4396 builtin/apply.c:4399 msgid "ignore changes in whitespace when finding context" msgstr "" -#: builtin/apply.c:4398 +#: builtin/apply.c:4402 msgid "apply the patch in reverse" msgstr "" -#: builtin/apply.c:4400 +#: builtin/apply.c:4404 msgid "don't expect at least one line of context" msgstr "" -#: builtin/apply.c:4402 +#: builtin/apply.c:4406 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "" -#: builtin/apply.c:4404 +#: builtin/apply.c:4408 msgid "allow overlapping hunks" msgstr "" -#: builtin/apply.c:4407 +#: builtin/apply.c:4411 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "" -#: builtin/apply.c:4410 +#: builtin/apply.c:4414 msgid "do not trust the line counts in the hunk headers" msgstr "" -#: builtin/apply.c:4412 +#: builtin/apply.c:4416 msgid "root" msgstr "" -#: builtin/apply.c:4413 +#: builtin/apply.c:4417 msgid "prepend <root> to all filenames" msgstr "" -#: builtin/apply.c:4435 +#: builtin/apply.c:4439 msgid "--3way outside a repository" msgstr "" -#: builtin/apply.c:4443 +#: builtin/apply.c:4447 msgid "--index outside a repository" msgstr "" -#: builtin/apply.c:4446 +#: builtin/apply.c:4450 msgid "--cached outside a repository" msgstr "" -#: builtin/apply.c:4462 +#: builtin/apply.c:4466 #, c-format msgid "can't open patch '%s'" msgstr "" -#: builtin/apply.c:4476 +#: builtin/apply.c:4480 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "" msgstr[1] "" -#: builtin/apply.c:4482 builtin/apply.c:4492 +#: builtin/apply.c:4486 builtin/apply.c:4496 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -2040,21 +2223,21 @@ msgstr "" msgid "git archive: expected ACK/NAK, got EOF" msgstr "" -#: builtin/archive.c:63 +#: builtin/archive.c:61 #, c-format msgid "git archive: NACK %s" msgstr "" -#: builtin/archive.c:65 +#: builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "" -#: builtin/archive.c:66 +#: builtin/archive.c:64 msgid "git archive: protocol error" msgstr "" -#: builtin/archive.c:71 +#: builtin/archive.c:68 msgid "git archive: expected a flush" msgstr "" @@ -2074,430 +2257,472 @@ msgstr "" msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "" -#: builtin/blame.c:30 builtin/shortlog.c:15 +#: builtin/blame.c:30 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "" -#: builtin/blame.c:2350 +#: builtin/blame.c:2355 msgid "Show blame entries as we find them, incrementally" msgstr "" -#: builtin/blame.c:2351 +#: builtin/blame.c:2356 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "" -#: builtin/blame.c:2352 +#: builtin/blame.c:2357 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "" -#: builtin/blame.c:2353 +#: builtin/blame.c:2358 msgid "Show work cost statistics" msgstr "" -#: builtin/blame.c:2354 +#: builtin/blame.c:2359 msgid "Show output score for blame entries" msgstr "" -#: builtin/blame.c:2355 +#: builtin/blame.c:2360 msgid "Show original filename (Default: auto)" msgstr "" -#: builtin/blame.c:2356 +#: builtin/blame.c:2361 msgid "Show original linenumber (Default: off)" msgstr "" -#: builtin/blame.c:2357 +#: builtin/blame.c:2362 msgid "Show in a format designed for machine consumption" msgstr "" -#: builtin/blame.c:2358 +#: builtin/blame.c:2363 msgid "Show porcelain format with per-line commit information" msgstr "" -#: builtin/blame.c:2359 +#: builtin/blame.c:2364 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "" -#: builtin/blame.c:2360 +#: builtin/blame.c:2365 msgid "Show raw timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2361 +#: builtin/blame.c:2366 msgid "Show long commit SHA1 (Default: off)" msgstr "" -#: builtin/blame.c:2362 +#: builtin/blame.c:2367 msgid "Suppress author name and timestamp (Default: off)" msgstr "" -#: builtin/blame.c:2363 +#: builtin/blame.c:2368 msgid "Show author email instead of name (Default: off)" msgstr "" -#: builtin/blame.c:2364 +#: builtin/blame.c:2369 msgid "Ignore whitespace differences" msgstr "" -#: builtin/blame.c:2365 +#: builtin/blame.c:2370 msgid "Spend extra cycles to find better match" msgstr "" -#: builtin/blame.c:2366 +#: builtin/blame.c:2371 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "" -#: builtin/blame.c:2367 +#: builtin/blame.c:2372 msgid "Use <file>'s contents as the final image" msgstr "" -#: builtin/blame.c:2368 builtin/blame.c:2369 +#: builtin/blame.c:2373 builtin/blame.c:2374 msgid "score" msgstr "" -#: builtin/blame.c:2368 +#: builtin/blame.c:2373 msgid "Find line copies within and across files" msgstr "" -#: builtin/blame.c:2369 +#: builtin/blame.c:2374 msgid "Find line movements within and across files" msgstr "" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "n,m" msgstr "" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "Process only line range n,m, counting from 1" msgstr "" -#: builtin/branch.c:23 +#: builtin/branch.c:24 msgid "git branch [options] [-r | -a] [--merged | --no-merged]" msgstr "" -#: builtin/branch.c:24 +#: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" msgstr "" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) <branchname>..." msgstr "" -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" msgstr "" -#: builtin/branch.c:145 +#: builtin/branch.c:150 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" " '%s', but not yet merged to HEAD." msgstr "" -#: builtin/branch.c:149 +#: builtin/branch.c:154 #, 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:163 +#: builtin/branch.c:168 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "" -#: builtin/branch.c:167 +#: builtin/branch.c:172 #, 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:180 +#: builtin/branch.c:185 msgid "Update of config-file failed" msgstr "" -#: builtin/branch.c:208 +#: builtin/branch.c:213 msgid "cannot use -a with -d" msgstr "" -#: builtin/branch.c:214 +#: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" msgstr "" -#: builtin/branch.c:222 +#: builtin/branch.c:227 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "" -#: builtin/branch.c:235 +#: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." msgstr "" -#: builtin/branch.c:236 +#: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." msgstr "" -#: builtin/branch.c:250 +#: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" msgstr "" -#: builtin/branch.c:251 +#: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" msgstr "" -#: builtin/branch.c:258 +#: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:259 +#: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "" -#: builtin/branch.c:361 +#: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" msgstr "" -#: builtin/branch.c:433 +#: builtin/branch.c:453 #, c-format msgid "[%s: behind %d]" msgstr "" -#: builtin/branch.c:435 +#: builtin/branch.c:455 #, c-format msgid "[behind %d]" msgstr "" -#: builtin/branch.c:439 +#: builtin/branch.c:459 #, c-format msgid "[%s: ahead %d]" msgstr "" -#: builtin/branch.c:441 +#: builtin/branch.c:461 #, c-format msgid "[ahead %d]" msgstr "" -#: builtin/branch.c:444 +#: builtin/branch.c:464 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:447 +#: builtin/branch.c:467 #, c-format msgid "[ahead %d, behind %d]" msgstr "" -#: builtin/branch.c:469 +#: builtin/branch.c:490 msgid " **** invalid ref ****" msgstr "" -#: builtin/branch.c:560 +#: builtin/branch.c:582 +#, c-format +msgid "(no branch, rebasing %s)" +msgstr "" + +#: builtin/branch.c:585 +#, c-format +msgid "(no branch, bisect started on %s)" +msgstr "" + +#: builtin/branch.c:588 +#, c-format +msgid "(detached from %s)" +msgstr "" + +#: builtin/branch.c:591 msgid "(no branch)" msgstr "" -#: builtin/branch.c:593 +#: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" msgstr "" -#: builtin/branch.c:625 +#: builtin/branch.c:669 msgid "some refs could not be read" msgstr "" -#: builtin/branch.c:638 +#: builtin/branch.c:682 msgid "cannot rename the current branch while not on any." msgstr "" -#: builtin/branch.c:648 +#: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" msgstr "" -#: builtin/branch.c:663 +#: builtin/branch.c:707 msgid "Branch rename failed" msgstr "" -#: builtin/branch.c:667 +#: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "" -#: builtin/branch.c:671 +#: builtin/branch.c:715 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "" -#: builtin/branch.c:678 +#: builtin/branch.c:722 msgid "Branch is renamed, but update of config-file failed" msgstr "" -#: builtin/branch.c:693 +#: builtin/branch.c:737 #, c-format msgid "malformed object name %s" msgstr "" -#: builtin/branch.c:717 +#: builtin/branch.c:761 #, c-format msgid "could not write branch description template: %s" msgstr "" -#: builtin/branch.c:747 +#: builtin/branch.c:791 msgid "Generic options" msgstr "" -#: builtin/branch.c:749 +#: builtin/branch.c:793 msgid "show hash and subject, give twice for upstream branch" msgstr "" -#: builtin/branch.c:750 +#: builtin/branch.c:794 msgid "suppress informational messages" msgstr "" -#: builtin/branch.c:751 +#: builtin/branch.c:795 msgid "set up tracking mode (see git-pull(1))" msgstr "" -#: builtin/branch.c:753 +#: builtin/branch.c:797 msgid "change upstream info" msgstr "" -#: builtin/branch.c:757 +#: builtin/branch.c:801 msgid "use colored output" msgstr "" -#: builtin/branch.c:758 +#: builtin/branch.c:802 msgid "act on remote-tracking branches" msgstr "" -#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 -#: builtin/branch.c:794 builtin/commit.c:1366 builtin/commit.c:1367 -#: builtin/commit.c:1368 builtin/commit.c:1369 builtin/tag.c:468 +#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 +#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 +#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 msgid "commit" msgstr "" -#: builtin/branch.c:762 builtin/branch.c:768 +#: builtin/branch.c:806 builtin/branch.c:812 msgid "print only branches that contain the commit" msgstr "" -#: builtin/branch.c:774 +#: builtin/branch.c:818 msgid "Specific git-branch actions:" msgstr "" -#: builtin/branch.c:775 +#: builtin/branch.c:819 msgid "list both remote-tracking and local branches" msgstr "" -#: builtin/branch.c:777 +#: builtin/branch.c:821 msgid "delete fully merged branch" msgstr "" -#: builtin/branch.c:778 +#: builtin/branch.c:822 msgid "delete branch (even if not merged)" msgstr "" -#: builtin/branch.c:779 +#: builtin/branch.c:823 msgid "move/rename a branch and its reflog" msgstr "" -#: builtin/branch.c:780 +#: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "" -#: builtin/branch.c:781 +#: builtin/branch.c:825 msgid "list branch names" msgstr "" -#: builtin/branch.c:782 +#: builtin/branch.c:826 msgid "create the branch's reflog" msgstr "" -#: builtin/branch.c:784 +#: builtin/branch.c:828 msgid "edit the description for the branch" msgstr "" -#: builtin/branch.c:785 +#: builtin/branch.c:829 msgid "force creation (when already exists)" msgstr "" -#: builtin/branch.c:788 +#: builtin/branch.c:832 msgid "print only not merged branches" msgstr "" -#: builtin/branch.c:794 +#: builtin/branch.c:838 msgid "print only merged branches" msgstr "" -#: builtin/branch.c:798 +#: builtin/branch.c:842 msgid "list branches in columns" msgstr "" -#: builtin/branch.c:811 +#: builtin/branch.c:855 msgid "Failed to resolve HEAD as a valid ref." msgstr "" -#: builtin/branch.c:816 builtin/clone.c:561 +#: builtin/branch.c:860 builtin/clone.c:619 msgid "HEAD not found below refs/heads!" msgstr "" -#: builtin/branch.c:839 +#: builtin/branch.c:883 msgid "--column and --verbose are incompatible" msgstr "" -#: builtin/branch.c:845 +#: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" msgstr "" -#: builtin/branch.c:860 +#: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" msgstr "" -#: builtin/branch.c:865 +#: builtin/branch.c:909 msgid "cannot edit description of more than one branch" msgstr "" -#: builtin/branch.c:872 +#: builtin/branch.c:916 #, c-format msgid "No commit on branch '%s' yet." msgstr "" -#: builtin/branch.c:875 +#: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." msgstr "" -#: builtin/branch.c:888 +#: builtin/branch.c:934 msgid "too many branches for a rename operation" msgstr "" -#: builtin/branch.c:893 +#: builtin/branch.c:939 +msgid "too many branches to set new upstream" +msgstr "" + +#: builtin/branch.c:943 +#, c-format +msgid "" +"could not set upstream of HEAD to %s when it does not point to any branch." +msgstr "" + +#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 +#, c-format +msgid "no such branch '%s'" +msgstr "" + +#: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" msgstr "" -#: builtin/branch.c:905 +#: builtin/branch.c:962 +msgid "too many branches to unset upstream" +msgstr "" + +#: builtin/branch.c:966 +msgid "could not unset upstream of HEAD when it does not point to any branch." +msgstr "" + +#: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" msgstr "" -#: builtin/branch.c:920 +#: builtin/branch.c:987 +msgid "it does not make sense to create 'HEAD' manually" +msgstr "" + +#: builtin/branch.c:993 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" -#: builtin/branch.c:923 +#: builtin/branch.c:996 #, 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:940 +#: builtin/branch.c:1013 #, c-format msgid "" "\n" @@ -2505,12 +2730,12 @@ msgid "" "\n" msgstr "" -#: builtin/branch.c:941 +#: builtin/branch.c:1014 #, c-format msgid " git branch -d %s\n" msgstr "" -#: builtin/branch.c:942 +#: builtin/branch.c:1015 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr "" @@ -2528,43 +2753,43 @@ msgstr "" msgid "Need a repository to unbundle." msgstr "" -#: builtin/cat-file.c:247 +#: builtin/cat-file.c:176 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>" msgstr "" -#: builtin/cat-file.c:248 +#: builtin/cat-file.c:177 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>" msgstr "" -#: builtin/cat-file.c:266 +#: builtin/cat-file.c:195 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "" -#: builtin/cat-file.c:267 +#: builtin/cat-file.c:196 msgid "show object type" msgstr "" -#: builtin/cat-file.c:268 +#: builtin/cat-file.c:197 msgid "show object size" msgstr "" -#: builtin/cat-file.c:270 +#: builtin/cat-file.c:199 msgid "exit with zero when there's no error" msgstr "" -#: builtin/cat-file.c:271 +#: builtin/cat-file.c:200 msgid "pretty-print object's content" msgstr "" -#: builtin/cat-file.c:273 +#: builtin/cat-file.c:202 msgid "for blob objects, run textconv on object's content" msgstr "" -#: builtin/cat-file.c:275 +#: builtin/cat-file.c:204 msgid "show info and content of objects fed from the standard input" msgstr "" -#: builtin/cat-file.c:278 +#: builtin/cat-file.c:207 msgid "show info about objects fed from the standard input" msgstr "" @@ -2592,27 +2817,27 @@ msgstr "" msgid "input paths are terminated by a null character" msgstr "" -#: builtin/check-ignore.c:18 builtin/checkout.c:1012 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "" -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:146 msgid "cannot specify pathnames with --stdin" msgstr "" -#: builtin/check-ignore.c:154 +#: builtin/check-ignore.c:149 msgid "-z only makes sense with --stdin" msgstr "" -#: builtin/check-ignore.c:156 +#: builtin/check-ignore.c:151 msgid "no path specified" msgstr "" -#: builtin/check-ignore.c:160 +#: builtin/check-ignore.c:155 msgid "--quiet is only valid with a single pathname" msgstr "" -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:157 msgid "cannot have both --quiet and --verbose" msgstr "" @@ -2668,106 +2893,106 @@ msgstr "" msgid "git checkout [options] [<branch>] -- <file>..." msgstr "" -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format msgid "path '%s' does not have our version" msgstr "" -#: builtin/checkout.c:118 builtin/checkout.c:151 +#: builtin/checkout.c:119 builtin/checkout.c:152 #, c-format msgid "path '%s' does not have their version" msgstr "" -#: builtin/checkout.c:134 +#: builtin/checkout.c:135 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "" -#: builtin/checkout.c:178 +#: builtin/checkout.c:179 #, c-format msgid "path '%s' does not have necessary versions" msgstr "" -#: builtin/checkout.c:195 +#: builtin/checkout.c:196 #, c-format msgid "path '%s': cannot merge" msgstr "" -#: builtin/checkout.c:212 +#: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" msgstr "" -#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 -#: builtin/checkout.c:245 +#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 +#: builtin/checkout.c:246 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "" -#: builtin/checkout.c:248 builtin/checkout.c:251 +#: builtin/checkout.c:249 builtin/checkout.c:252 #, c-format msgid "'%s' cannot be used with %s" msgstr "" -#: builtin/checkout.c:254 +#: builtin/checkout.c:255 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "" -#: builtin/checkout.c:265 builtin/checkout.c:426 +#: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" msgstr "" -#: builtin/checkout.c:295 builtin/checkout.c:302 +#: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format msgid "path '%s' is unmerged" msgstr "" -#: builtin/checkout.c:448 +#: builtin/checkout.c:480 msgid "you need to resolve your current index first" msgstr "" -#: builtin/checkout.c:569 +#: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "" -#: builtin/checkout.c:602 +#: builtin/checkout.c:634 msgid "HEAD is now at" msgstr "" -#: builtin/checkout.c:609 +#: builtin/checkout.c:641 #, c-format msgid "Reset branch '%s'\n" msgstr "" -#: builtin/checkout.c:612 +#: builtin/checkout.c:644 #, c-format msgid "Already on '%s'\n" msgstr "" -#: builtin/checkout.c:616 +#: builtin/checkout.c:648 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "" -#: builtin/checkout.c:618 builtin/checkout.c:955 +#: builtin/checkout.c:650 builtin/checkout.c:987 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "" -#: builtin/checkout.c:620 +#: builtin/checkout.c:652 #, c-format msgid "Switched to branch '%s'\n" msgstr "" -#: builtin/checkout.c:676 +#: builtin/checkout.c:708 #, c-format msgid " ... and %d more.\n" msgstr "" #. The singular version -#: builtin/checkout.c:682 +#: builtin/checkout.c:714 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2782,7 +3007,7 @@ msgid_plural "" msgstr[0] "" msgstr[1] "" -#: builtin/checkout.c:700 +#: builtin/checkout.c:732 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2792,144 +3017,148 @@ msgid "" "\n" msgstr "" -#: builtin/checkout.c:730 +#: builtin/checkout.c:762 msgid "internal error in revision walk" msgstr "" -#: builtin/checkout.c:734 +#: builtin/checkout.c:766 msgid "Previous HEAD position was" msgstr "" -#: builtin/checkout.c:761 builtin/checkout.c:950 +#: builtin/checkout.c:793 builtin/checkout.c:982 msgid "You are on a branch yet to be born" msgstr "" #. case (1) -#: builtin/checkout.c:886 +#: builtin/checkout.c:918 #, c-format msgid "invalid reference: %s" msgstr "" #. case (1): want a tree -#: builtin/checkout.c:925 +#: builtin/checkout.c:957 #, c-format msgid "reference is not a tree: %s" msgstr "" -#: builtin/checkout.c:964 +#: builtin/checkout.c:996 msgid "paths cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:967 builtin/checkout.c:971 +#: builtin/checkout.c:999 builtin/checkout.c:1003 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "" -#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 -#: builtin/checkout.c:986 +#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 +#: builtin/checkout.c:1018 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "" -#: builtin/checkout.c:991 +#: builtin/checkout.c:1023 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "" -#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1046 msgid "create and checkout a new branch" msgstr "" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1048 msgid "create/reset and checkout a branch" msgstr "" -#: builtin/checkout.c:1017 +#: builtin/checkout.c:1049 msgid "create reflog for new branch" msgstr "" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1050 msgid "detach the HEAD at named commit" msgstr "" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1051 msgid "set upstream info for new branch" msgstr "" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new branch" msgstr "" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new unparented branch" msgstr "" -#: builtin/checkout.c:1022 +#: builtin/checkout.c:1054 msgid "checkout our version for unmerged files" msgstr "" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1056 msgid "checkout their version for unmerged files" msgstr "" -#: builtin/checkout.c:1026 +#: builtin/checkout.c:1058 msgid "force checkout (throw away local modifications)" msgstr "" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1059 msgid "perform a 3-way merge with the new branch" msgstr "" -#: builtin/checkout.c:1028 builtin/merge.c:215 +#: builtin/checkout.c:1060 builtin/merge.c:217 msgid "update ignored files (default)" msgstr "" -#: builtin/checkout.c:1029 builtin/log.c:1147 parse-options.h:245 +#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 msgid "style" msgstr "" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1062 msgid "conflict style (merge or diff3)" msgstr "" -#: builtin/checkout.c:1033 +#: builtin/checkout.c:1065 +msgid "do not limit pathspecs to sparse entries only" +msgstr "" + +#: builtin/checkout.c:1067 msgid "second guess 'git checkout no-such-branch'" msgstr "" -#: builtin/checkout.c:1057 +#: builtin/checkout.c:1091 msgid "-b, -B and --orphan are mutually exclusive" msgstr "" -#: builtin/checkout.c:1074 +#: builtin/checkout.c:1108 msgid "--track needs a branch name" msgstr "" -#: builtin/checkout.c:1081 +#: builtin/checkout.c:1115 msgid "Missing branch name; try -b" msgstr "" -#: builtin/checkout.c:1116 +#: builtin/checkout.c:1150 msgid "invalid path specification" msgstr "" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1157 #, 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:1128 +#: builtin/checkout.c:1162 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "" -#: builtin/checkout.c:1132 +#: builtin/checkout.c:1166 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -2976,8 +3205,8 @@ msgstr "" msgid "remove whole directories" msgstr "" -#: builtin/clean.c:165 builtin/describe.c:413 builtin/grep.c:717 -#: builtin/ls-files.c:494 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 +#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "" @@ -3008,215 +3237,230 @@ msgid "" "clean" msgstr "" -#: builtin/clone.c:36 +#: builtin/clone.c:37 msgid "git clone [options] [--] <repo> [<dir>]" msgstr "" -#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:212 +#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 #: builtin/push.c:436 msgid "force progress reporting" msgstr "" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "don't create a checkout" msgstr "" -#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 msgid "create a bare repository" msgstr "" -#: builtin/clone.c:72 +#: builtin/clone.c:73 msgid "create a mirror repository (implies bare)" msgstr "" -#: builtin/clone.c:74 +#: builtin/clone.c:75 msgid "to clone from a local repository" msgstr "" -#: builtin/clone.c:76 +#: builtin/clone.c:77 msgid "don't use local hardlinks, always copy" msgstr "" -#: builtin/clone.c:78 +#: builtin/clone.c:79 msgid "setup as shared repository" msgstr "" -#: builtin/clone.c:80 builtin/clone.c:82 +#: builtin/clone.c:81 builtin/clone.c:83 msgid "initialize submodules in the clone" msgstr "" -#: builtin/clone.c:83 builtin/init-db.c:485 +#: builtin/clone.c:84 builtin/init-db.c:485 msgid "template-directory" msgstr "" -#: builtin/clone.c:84 builtin/init-db.c:486 +#: builtin/clone.c:85 builtin/init-db.c:486 msgid "directory from which templates will be used" msgstr "" -#: builtin/clone.c:86 +#: builtin/clone.c:87 msgid "reference repository" msgstr "" -#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "use <name> instead of 'origin' to track upstream" msgstr "" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "checkout <branch> instead of the remote's HEAD" msgstr "" -#: builtin/clone.c:92 +#: builtin/clone.c:93 msgid "path to git-upload-pack on the remote" msgstr "" -#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "" -#: builtin/clone.c:94 +#: builtin/clone.c:95 msgid "create a shallow clone of that depth" msgstr "" -#: builtin/clone.c:96 +#: builtin/clone.c:97 msgid "clone only one branch, HEAD or --branch" msgstr "" -#: builtin/clone.c:97 builtin/init-db.c:494 +#: builtin/clone.c:98 builtin/init-db.c:494 msgid "gitdir" msgstr "" -#: builtin/clone.c:98 builtin/init-db.c:495 +#: builtin/clone.c:99 builtin/init-db.c:495 msgid "separate git dir from working tree" msgstr "" -#: builtin/clone.c:99 +#: builtin/clone.c:100 msgid "key=value" msgstr "" -#: builtin/clone.c:100 +#: builtin/clone.c:101 msgid "set config inside the new repository" msgstr "" -#: builtin/clone.c:243 +#: builtin/clone.c:254 #, c-format -msgid "reference repository '%s' is not a local directory." +msgid "reference repository '%s' is not a local repository." msgstr "" -#: builtin/clone.c:306 +#: builtin/clone.c:317 #, c-format msgid "failed to create directory '%s'" msgstr "" -#: builtin/clone.c:308 builtin/diff.c:77 +#: builtin/clone.c:319 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "" -#: builtin/clone.c:310 +#: builtin/clone.c:321 #, c-format msgid "%s exists and is not a directory" msgstr "" -#: builtin/clone.c:324 +#: builtin/clone.c:335 #, c-format msgid "failed to stat %s\n" msgstr "" -#: builtin/clone.c:346 +#: builtin/clone.c:357 #, c-format msgid "failed to create link '%s'" msgstr "" -#: builtin/clone.c:350 +#: builtin/clone.c:361 #, c-format msgid "failed to copy file to '%s'" msgstr "" -#: builtin/clone.c:373 +#: builtin/clone.c:384 #, c-format msgid "done.\n" msgstr "" -#: builtin/clone.c:443 +#: builtin/clone.c:397 +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:476 #, c-format msgid "Could not find remote branch %s to clone." msgstr "" -#: builtin/clone.c:552 +#: builtin/clone.c:550 +msgid "remote did not send all necessary objects" +msgstr "" + +#: builtin/clone.c:610 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" -#: builtin/clone.c:690 +#: builtin/clone.c:641 +msgid "unable to checkout working tree" +msgstr "" + +#: builtin/clone.c:749 msgid "Too many arguments." msgstr "" -#: builtin/clone.c:694 +#: builtin/clone.c:753 msgid "You must specify a repository to clone." msgstr "" -#: builtin/clone.c:705 +#: builtin/clone.c:764 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "" -#: builtin/clone.c:708 +#: builtin/clone.c:767 msgid "--bare and --separate-git-dir are incompatible." msgstr "" -#: builtin/clone.c:721 +#: builtin/clone.c:780 #, c-format msgid "repository '%s' does not exist" msgstr "" -#: builtin/clone.c:726 +#: builtin/clone.c:785 msgid "--depth is ignored in local clones; use file:// instead." msgstr "" -#: builtin/clone.c:736 +#: builtin/clone.c:795 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "" -#: builtin/clone.c:746 +#: builtin/clone.c:805 #, c-format msgid "working tree '%s' already exists." msgstr "" -#: builtin/clone.c:759 builtin/clone.c:771 +#: builtin/clone.c:818 builtin/clone.c:830 #, c-format msgid "could not create leading directories of '%s'" msgstr "" -#: builtin/clone.c:762 +#: builtin/clone.c:821 #, c-format msgid "could not create work tree dir '%s'." msgstr "" -#: builtin/clone.c:781 +#: builtin/clone.c:840 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "" -#: builtin/clone.c:783 +#: builtin/clone.c:842 #, c-format msgid "Cloning into '%s'...\n" msgstr "" -#: builtin/clone.c:818 +#: builtin/clone.c:877 #, c-format msgid "Don't know how to clone %s" msgstr "" -#: builtin/clone.c:867 +#: builtin/clone.c:926 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "" -#: builtin/clone.c:874 +#: builtin/clone.c:933 msgid "You appear to have cloned an empty repository." msgstr "" @@ -3291,93 +3535,93 @@ msgid "" "Otherwise, please use 'git reset'\n" msgstr "" -#: builtin/commit.c:258 +#: builtin/commit.c:260 msgid "failed to unpack HEAD tree object" msgstr "" -#: builtin/commit.c:300 +#: builtin/commit.c:302 msgid "unable to create temporary index" msgstr "" -#: builtin/commit.c:306 +#: builtin/commit.c:308 msgid "interactive add failed" msgstr "" -#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 +#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 msgid "unable to write new_index file" msgstr "" -#: builtin/commit.c:391 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a merge." msgstr "" -#: builtin/commit.c:393 +#: builtin/commit.c:395 msgid "cannot do a partial commit during a cherry-pick." msgstr "" -#: builtin/commit.c:403 +#: builtin/commit.c:405 msgid "cannot read the index" msgstr "" -#: builtin/commit.c:423 +#: builtin/commit.c:425 msgid "unable to write temporary index file" msgstr "" -#: builtin/commit.c:511 builtin/commit.c:517 +#: builtin/commit.c:513 builtin/commit.c:519 #, c-format msgid "invalid commit: %s" msgstr "" -#: builtin/commit.c:540 +#: builtin/commit.c:542 msgid "malformed --author parameter" msgstr "" -#: builtin/commit.c:560 +#: builtin/commit.c:562 #, c-format msgid "Malformed ident string: '%s'" msgstr "" -#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 +#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 #, c-format msgid "could not lookup commit %s" msgstr "" -#: builtin/commit.c:610 builtin/shortlog.c:272 +#: builtin/commit.c:612 builtin/shortlog.c:270 #, c-format msgid "(reading log message from standard input)\n" msgstr "" -#: builtin/commit.c:612 +#: builtin/commit.c:614 msgid "could not read log from standard input" msgstr "" -#: builtin/commit.c:616 +#: builtin/commit.c:618 #, c-format msgid "could not read log file '%s'" msgstr "" -#: builtin/commit.c:622 +#: builtin/commit.c:624 msgid "commit has empty message" msgstr "" -#: builtin/commit.c:638 +#: builtin/commit.c:640 msgid "could not read MERGE_MSG" msgstr "" -#: builtin/commit.c:642 +#: builtin/commit.c:644 msgid "could not read SQUASH_MSG" msgstr "" -#: builtin/commit.c:646 +#: builtin/commit.c:648 #, c-format msgid "could not read '%s'" msgstr "" -#: builtin/commit.c:707 +#: builtin/commit.c:709 msgid "could not write commit template" msgstr "" -#: builtin/commit.c:718 +#: builtin/commit.c:720 #, c-format msgid "" "\n" @@ -3387,7 +3631,7 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:723 +#: builtin/commit.c:725 #, c-format msgid "" "\n" @@ -3397,14 +3641,14 @@ msgid "" "and try again.\n" msgstr "" -#: builtin/commit.c:735 +#: builtin/commit.c:737 #, 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:740 +#: builtin/commit.c:742 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3412,351 +3656,351 @@ msgid "" "An empty message aborts the commit.\n" msgstr "" -#: builtin/commit.c:753 +#: builtin/commit.c:755 #, c-format msgid "%sAuthor: %s" msgstr "" -#: builtin/commit.c:760 +#: builtin/commit.c:762 #, c-format msgid "%sCommitter: %s" msgstr "" -#: builtin/commit.c:780 +#: builtin/commit.c:782 msgid "Cannot read index" msgstr "" -#: builtin/commit.c:817 +#: builtin/commit.c:819 msgid "Error building trees" msgstr "" -#: builtin/commit.c:832 builtin/tag.c:359 +#: builtin/commit.c:834 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "" -#: builtin/commit.c:929 +#: builtin/commit.c:931 #, c-format msgid "No existing author found with '%s'" msgstr "" -#: builtin/commit.c:944 builtin/commit.c:1138 +#: builtin/commit.c:946 builtin/commit.c:1140 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "" -#: builtin/commit.c:974 +#: builtin/commit.c:976 msgid "Using both --reset-author and --author does not make sense" msgstr "" -#: builtin/commit.c:985 +#: builtin/commit.c:987 msgid "You have nothing to amend." msgstr "" -#: builtin/commit.c:988 +#: builtin/commit.c:990 msgid "You are in the middle of a merge -- cannot amend." msgstr "" -#: builtin/commit.c:990 +#: builtin/commit.c:992 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "" -#: builtin/commit.c:993 +#: builtin/commit.c:995 msgid "Options --squash and --fixup cannot be used together" msgstr "" -#: builtin/commit.c:1003 +#: builtin/commit.c:1005 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "" -#: builtin/commit.c:1005 +#: builtin/commit.c:1007 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "" -#: builtin/commit.c:1013 +#: builtin/commit.c:1015 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "" -#: builtin/commit.c:1030 +#: builtin/commit.c:1032 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" -#: builtin/commit.c:1032 +#: builtin/commit.c:1034 msgid "No paths with --include/--only does not make sense." msgstr "" -#: builtin/commit.c:1034 +#: builtin/commit.c:1036 msgid "Clever... amending the last one with dirty index." msgstr "" -#: builtin/commit.c:1036 +#: builtin/commit.c:1038 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "" -#: builtin/commit.c:1046 builtin/tag.c:575 +#: builtin/commit.c:1048 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "" -#: builtin/commit.c:1051 +#: builtin/commit.c:1053 msgid "Paths with -a does not make sense." msgstr "" -#: builtin/commit.c:1057 builtin/commit.c:1192 +#: builtin/commit.c:1059 builtin/commit.c:1194 msgid "--long and -z are incompatible" msgstr "" -#: builtin/commit.c:1152 builtin/commit.c:1388 +#: builtin/commit.c:1154 builtin/commit.c:1390 msgid "show status concisely" msgstr "" -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1156 builtin/commit.c:1392 msgid "show branch information" msgstr "" -#: builtin/commit.c:1156 builtin/commit.c:1392 builtin/push.c:426 +#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 msgid "machine-readable output" msgstr "" -#: builtin/commit.c:1159 builtin/commit.c:1394 +#: builtin/commit.c:1161 builtin/commit.c:1396 msgid "show status in long format (default)" msgstr "" -#: builtin/commit.c:1162 builtin/commit.c:1397 +#: builtin/commit.c:1164 builtin/commit.c:1399 msgid "terminate entries with NUL" msgstr "" -#: builtin/commit.c:1164 builtin/commit.c:1400 builtin/fast-export.c:647 -#: builtin/fast-export.c:650 builtin/tag.c:459 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 +#: builtin/fast-export.c:662 builtin/tag.c:459 msgid "mode" msgstr "" -#: builtin/commit.c:1165 builtin/commit.c:1400 +#: builtin/commit.c:1167 builtin/commit.c:1402 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "" -#: builtin/commit.c:1168 +#: builtin/commit.c:1170 msgid "show ignored files" msgstr "" -#: builtin/commit.c:1169 parse-options.h:151 +#: builtin/commit.c:1171 parse-options.h:151 msgid "when" msgstr "" -#: builtin/commit.c:1170 +#: builtin/commit.c:1172 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" msgstr "" -#: builtin/commit.c:1172 +#: builtin/commit.c:1174 msgid "list untracked files in columns" msgstr "" -#: builtin/commit.c:1246 +#: builtin/commit.c:1248 msgid "couldn't look up newly created commit" msgstr "" -#: builtin/commit.c:1248 +#: builtin/commit.c:1250 msgid "could not parse newly created commit" msgstr "" -#: builtin/commit.c:1289 +#: builtin/commit.c:1291 msgid "detached HEAD" msgstr "" -#: builtin/commit.c:1291 +#: builtin/commit.c:1293 msgid " (root-commit)" msgstr "" -#: builtin/commit.c:1358 +#: builtin/commit.c:1360 msgid "suppress summary after successful commit" msgstr "" -#: builtin/commit.c:1359 +#: builtin/commit.c:1361 msgid "show diff in commit message template" msgstr "" -#: builtin/commit.c:1361 +#: builtin/commit.c:1363 msgid "Commit message options" msgstr "" -#: builtin/commit.c:1362 builtin/tag.c:457 +#: builtin/commit.c:1364 builtin/tag.c:457 msgid "read message from file" msgstr "" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "author" msgstr "" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "override author for commit" msgstr "" -#: builtin/commit.c:1364 builtin/gc.c:178 +#: builtin/commit.c:1366 builtin/gc.c:178 msgid "date" msgstr "" -#: builtin/commit.c:1364 +#: builtin/commit.c:1366 msgid "override date for commit" msgstr "" -#: builtin/commit.c:1365 builtin/merge.c:206 builtin/notes.c:533 +#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 #: builtin/notes.c:690 builtin/tag.c:455 msgid "message" msgstr "" -#: builtin/commit.c:1365 +#: builtin/commit.c:1367 msgid "commit message" msgstr "" -#: builtin/commit.c:1366 +#: builtin/commit.c:1368 msgid "reuse and edit message from specified commit" msgstr "" -#: builtin/commit.c:1367 +#: builtin/commit.c:1369 msgid "reuse message from specified commit" msgstr "" -#: builtin/commit.c:1368 +#: builtin/commit.c:1370 msgid "use autosquash formatted message to fixup specified commit" msgstr "" -#: builtin/commit.c:1369 +#: builtin/commit.c:1371 msgid "use autosquash formatted message to squash specified commit" msgstr "" -#: builtin/commit.c:1370 +#: builtin/commit.c:1372 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "" -#: builtin/commit.c:1371 builtin/log.c:1102 builtin/revert.c:109 +#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "" -#: builtin/commit.c:1372 +#: builtin/commit.c:1374 msgid "use specified template file" msgstr "" -#: builtin/commit.c:1373 +#: builtin/commit.c:1375 msgid "force edit of commit" msgstr "" -#: builtin/commit.c:1374 +#: builtin/commit.c:1376 msgid "default" msgstr "" -#: builtin/commit.c:1374 builtin/tag.c:460 +#: builtin/commit.c:1376 builtin/tag.c:460 msgid "how to strip spaces and #comments from message" msgstr "" -#: builtin/commit.c:1375 +#: builtin/commit.c:1377 msgid "include status in commit message template" msgstr "" -#: builtin/commit.c:1376 builtin/merge.c:213 builtin/tag.c:461 +#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 msgid "key id" msgstr "" -#: builtin/commit.c:1377 builtin/merge.c:214 +#: builtin/commit.c:1379 builtin/merge.c:216 msgid "GPG sign commit" msgstr "" #. end commit message options -#: builtin/commit.c:1380 +#: builtin/commit.c:1382 msgid "Commit contents options" msgstr "" -#: builtin/commit.c:1381 +#: builtin/commit.c:1383 msgid "commit all changed files" msgstr "" -#: builtin/commit.c:1382 +#: builtin/commit.c:1384 msgid "add specified files to index for commit" msgstr "" -#: builtin/commit.c:1383 +#: builtin/commit.c:1385 msgid "interactively add files" msgstr "" -#: builtin/commit.c:1384 +#: builtin/commit.c:1386 msgid "interactively add changes" msgstr "" -#: builtin/commit.c:1385 +#: builtin/commit.c:1387 msgid "commit only specified files" msgstr "" -#: builtin/commit.c:1386 +#: builtin/commit.c:1388 msgid "bypass pre-commit hook" msgstr "" -#: builtin/commit.c:1387 +#: builtin/commit.c:1389 msgid "show what would be committed" msgstr "" -#: builtin/commit.c:1398 +#: builtin/commit.c:1400 msgid "amend previous commit" msgstr "" -#: builtin/commit.c:1399 +#: builtin/commit.c:1401 msgid "bypass post-rewrite hook" msgstr "" -#: builtin/commit.c:1404 +#: builtin/commit.c:1406 msgid "ok to record an empty change" msgstr "" -#: builtin/commit.c:1407 +#: builtin/commit.c:1409 msgid "ok to record a change with an empty message" msgstr "" -#: builtin/commit.c:1439 +#: builtin/commit.c:1441 msgid "could not parse HEAD commit" msgstr "" -#: builtin/commit.c:1477 builtin/merge.c:508 +#: builtin/commit.c:1479 builtin/merge.c:510 #, c-format msgid "could not open '%s' for reading" msgstr "" -#: builtin/commit.c:1484 +#: builtin/commit.c:1486 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "" -#: builtin/commit.c:1491 +#: builtin/commit.c:1493 msgid "could not read MERGE_MODE" msgstr "" -#: builtin/commit.c:1510 +#: builtin/commit.c:1512 #, c-format msgid "could not read commit message: %s" msgstr "" -#: builtin/commit.c:1524 +#: builtin/commit.c:1526 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "" -#: builtin/commit.c:1529 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "" -#: builtin/commit.c:1544 builtin/merge.c:832 builtin/merge.c:857 +#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 msgid "failed to write commit object" msgstr "" -#: builtin/commit.c:1565 +#: builtin/commit.c:1567 msgid "cannot lock HEAD ref" msgstr "" -#: builtin/commit.c:1569 +#: builtin/commit.c:1571 msgid "cannot update HEAD ref" msgstr "" -#: builtin/commit.c:1580 +#: builtin/commit.c:1582 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -3879,8 +4123,12 @@ msgstr "" msgid "respect include directives on lookup" msgstr "" -#: builtin/count-objects.c:69 -msgid "git count-objects [-v]" +#: builtin/count-objects.c:82 +msgid "git count-objects [-v] [-H | --human-readable]" +msgstr "" + +#: builtin/count-objects.c:97 +msgid "print sizes in human readable format" msgstr "" #: builtin/describe.c:15 @@ -3891,125 +4139,125 @@ msgstr "" msgid "git describe [options] --dirty" msgstr "" -#: builtin/describe.c:234 +#: builtin/describe.c:233 #, c-format msgid "annotated tag %s not available" msgstr "" -#: builtin/describe.c:238 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s has no embedded name" msgstr "" -#: builtin/describe.c:240 +#: builtin/describe.c:239 #, c-format msgid "tag '%s' is really '%s' here" msgstr "" -#: builtin/describe.c:267 +#: builtin/describe.c:266 #, c-format msgid "Not a valid object name %s" msgstr "" -#: builtin/describe.c:270 +#: builtin/describe.c:269 #, c-format msgid "%s is not a valid '%s' object" msgstr "" -#: builtin/describe.c:287 +#: builtin/describe.c:286 #, c-format msgid "no tag exactly matches '%s'" msgstr "" -#: builtin/describe.c:289 +#: builtin/describe.c:288 #, c-format msgid "searching to describe %s\n" msgstr "" -#: builtin/describe.c:329 +#: builtin/describe.c:328 #, c-format msgid "finished search at %s\n" msgstr "" -#: builtin/describe.c:353 +#: builtin/describe.c:352 #, c-format msgid "" "No annotated tags can describe '%s'.\n" "However, there were unannotated tags: try --tags." msgstr "" -#: builtin/describe.c:357 +#: builtin/describe.c:356 #, c-format msgid "" "No tags can describe '%s'.\n" "Try --always, or create some tags." msgstr "" -#: builtin/describe.c:378 +#: builtin/describe.c:377 #, c-format msgid "traversed %lu commits\n" msgstr "" -#: builtin/describe.c:381 +#: builtin/describe.c:380 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" "gave up search at %s\n" msgstr "" -#: builtin/describe.c:403 +#: builtin/describe.c:402 msgid "find the tag that comes after the commit" msgstr "" -#: builtin/describe.c:404 +#: builtin/describe.c:403 msgid "debug search strategy on stderr" msgstr "" -#: builtin/describe.c:405 -msgid "use any ref in .git/refs" +#: builtin/describe.c:404 +msgid "use any ref" msgstr "" -#: builtin/describe.c:406 -msgid "use any tag in .git/refs/tags" +#: builtin/describe.c:405 +msgid "use any tag, even unannotated" msgstr "" -#: builtin/describe.c:407 +#: builtin/describe.c:406 msgid "always use long format" msgstr "" -#: builtin/describe.c:410 +#: builtin/describe.c:409 msgid "only output exact matches" msgstr "" -#: builtin/describe.c:412 +#: builtin/describe.c:411 msgid "consider <n> most recent tags (default: 10)" msgstr "" -#: builtin/describe.c:414 +#: builtin/describe.c:413 msgid "only consider tags matching <pattern>" msgstr "" -#: builtin/describe.c:416 builtin/name-rev.c:238 +#: builtin/describe.c:415 builtin/name-rev.c:238 msgid "show abbreviated commit object as fallback" msgstr "" -#: builtin/describe.c:417 +#: builtin/describe.c:416 msgid "mark" msgstr "" -#: builtin/describe.c:418 +#: builtin/describe.c:417 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "" -#: builtin/describe.c:436 +#: builtin/describe.c:435 msgid "--long is incompatible with --abbrev=0" msgstr "" -#: builtin/describe.c:462 +#: builtin/describe.c:461 msgid "No names found, cannot describe anything." msgstr "" -#: builtin/describe.c:482 +#: builtin/describe.c:481 msgid "--dirty is incompatible with committishes" msgstr "" @@ -4051,39 +4299,39 @@ msgstr "" msgid "git fast-export [rev-list-opts]" msgstr "" -#: builtin/fast-export.c:646 +#: builtin/fast-export.c:658 msgid "show progress after <n> objects" msgstr "" -#: builtin/fast-export.c:648 +#: builtin/fast-export.c:660 msgid "select handling of signed tags" msgstr "" -#: builtin/fast-export.c:651 +#: builtin/fast-export.c:663 msgid "select handling of tags that tag filtered objects" msgstr "" -#: builtin/fast-export.c:654 +#: builtin/fast-export.c:666 msgid "Dump marks to this file" msgstr "" -#: builtin/fast-export.c:656 +#: builtin/fast-export.c:668 msgid "Import marks from this file" msgstr "" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:670 msgid "Fake a tagger when tags lack one" msgstr "" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:672 msgid "Output full tree for each commit" msgstr "" -#: builtin/fast-export.c:662 +#: builtin/fast-export.c:674 msgid "Use the done feature to terminate the stream" msgstr "" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:675 msgid "Skip output of blob data" msgstr "" @@ -4159,7 +4407,7 @@ msgstr "" msgid "convert to a complete repository" msgstr "" -#: builtin/fetch.c:88 builtin/log.c:1119 +#: builtin/fetch.c:88 builtin/log.c:1130 msgid "dir" msgstr "" @@ -4334,29 +4582,29 @@ msgstr "" msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" -#: builtin/fmt-merge-msg.c:659 builtin/fmt-merge-msg.c:662 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 #: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 msgid "n" msgstr "" -#: builtin/fmt-merge-msg.c:660 +#: builtin/fmt-merge-msg.c:664 msgid "populate log with at most <n> entries from shortlog" msgstr "" -#: builtin/fmt-merge-msg.c:663 +#: builtin/fmt-merge-msg.c:667 msgid "alias for --log (deprecated)" msgstr "" -#: builtin/fmt-merge-msg.c:666 +#: builtin/fmt-merge-msg.c:670 msgid "text" msgstr "" -#: builtin/fmt-merge-msg.c:667 +#: builtin/fmt-merge-msg.c:671 msgid "use <text> as start of message" msgstr "" -#: builtin/fmt-merge-msg.c:668 +#: builtin/fmt-merge-msg.c:672 msgid "file to read from" msgstr "" @@ -4688,28 +4936,23 @@ msgstr "" msgid "no pattern given." msgstr "" -#: builtin/grep.c:825 -#, c-format -msgid "bad object %s" -msgstr "" - -#: builtin/grep.c:868 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "" -#: builtin/grep.c:891 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "" -#: builtin/grep.c:896 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "" -#: builtin/grep.c:899 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "" -#: builtin/grep.c:907 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "" @@ -4747,360 +4990,396 @@ msgstr "" msgid "process file as it were from this path" msgstr "" -#: builtin/help.c:42 +#: builtin/help.c:43 msgid "print all available commands" msgstr "" -#: builtin/help.c:43 +#: builtin/help.c:44 +msgid "print list of useful guides" +msgstr "" + +#: builtin/help.c:45 msgid "show man page" msgstr "" -#: builtin/help.c:44 +#: builtin/help.c:46 msgid "show manual in web browser" msgstr "" -#: builtin/help.c:46 +#: builtin/help.c:48 msgid "show info page" msgstr "" -#: builtin/help.c:52 -msgid "git help [--all] [--man|--web|--info] [command]" +#: builtin/help.c:54 +msgid "git help [--all] [--guides] [--man|--web|--info] [command]" msgstr "" -#: builtin/help.c:64 +#: builtin/help.c:66 #, c-format msgid "unrecognized help format '%s'" msgstr "" -#: builtin/help.c:92 +#: builtin/help.c:94 msgid "Failed to start emacsclient." msgstr "" -#: builtin/help.c:105 +#: builtin/help.c:107 msgid "Failed to parse emacsclient version." msgstr "" -#: builtin/help.c:113 +#: builtin/help.c:115 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "" -#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 +#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 #, c-format msgid "failed to exec '%s': %s" msgstr "" -#: builtin/help.c:216 +#: builtin/help.c:218 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" "Please consider using 'man.<tool>.cmd' instead." msgstr "" -#: builtin/help.c:228 +#: builtin/help.c:230 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" "Please consider using 'man.<tool>.path' instead." msgstr "" -#: builtin/help.c:349 +#: builtin/help.c:351 #, c-format msgid "'%s': unknown man viewer." msgstr "" -#: builtin/help.c:366 +#: builtin/help.c:368 msgid "no man viewer handled the request" msgstr "" -#: builtin/help.c:374 +#: builtin/help.c:376 msgid "no info viewer handled the request" msgstr "" -#: builtin/help.c:429 builtin/help.c:436 +#: builtin/help.c:422 +msgid "Defining attributes per path" +msgstr "" + +#: builtin/help.c:423 +msgid "A Git glossary" +msgstr "" + +#: builtin/help.c:424 +msgid "Specifies intentionally untracked files to ignore" +msgstr "" + +#: builtin/help.c:425 +msgid "Defining submodule properties" +msgstr "" + +#: builtin/help.c:426 +msgid "Specifying revisions and ranges for Git" +msgstr "" + +#: builtin/help.c:427 +msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" +msgstr "" + +#: builtin/help.c:428 +msgid "An overview of recommended workflows with Git" +msgstr "" + +#: builtin/help.c:440 +msgid "The common Git guides are:\n" +msgstr "" + +#: builtin/help.c:462 builtin/help.c:478 #, c-format msgid "usage: %s%s" msgstr "" -#: builtin/help.c:452 +#: builtin/help.c:494 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "" -#: builtin/index-pack.c:170 +#: builtin/index-pack.c:182 #, c-format msgid "object type mismatch at %s" msgstr "" -#: builtin/index-pack.c:190 +#: builtin/index-pack.c:202 msgid "object of unexpected type" msgstr "" -#: builtin/index-pack.c:227 +#: builtin/index-pack.c:239 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:237 +#: builtin/index-pack.c:249 msgid "early EOF" msgstr "" -#: builtin/index-pack.c:238 +#: builtin/index-pack.c:250 msgid "read error on input" msgstr "" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:262 msgid "used more bytes than were available" msgstr "" -#: builtin/index-pack.c:257 +#: builtin/index-pack.c:269 msgid "pack too large for current definition of off_t" msgstr "" -#: builtin/index-pack.c:273 +#: builtin/index-pack.c:285 #, c-format msgid "unable to create '%s'" msgstr "" -#: builtin/index-pack.c:278 +#: builtin/index-pack.c:290 #, c-format msgid "cannot open packfile '%s'" msgstr "" -#: builtin/index-pack.c:292 +#: builtin/index-pack.c:304 msgid "pack signature mismatch" msgstr "" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:306 #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "" -#: builtin/index-pack.c:312 +#: builtin/index-pack.c:324 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "" -#: builtin/index-pack.c:434 +#: builtin/index-pack.c:446 #, c-format msgid "inflate returned %d" msgstr "" -#: builtin/index-pack.c:483 +#: builtin/index-pack.c:495 msgid "offset value overflow for delta base object" msgstr "" -#: builtin/index-pack.c:491 +#: builtin/index-pack.c:503 msgid "delta base offset is out of bound" msgstr "" -#: builtin/index-pack.c:499 +#: builtin/index-pack.c:511 #, c-format msgid "unknown object type %d" msgstr "" -#: builtin/index-pack.c:530 +#: builtin/index-pack.c:542 msgid "cannot pread pack file" msgstr "" -#: builtin/index-pack.c:532 +#: builtin/index-pack.c:544 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:558 +#: builtin/index-pack.c:570 msgid "serious inflate inconsistency" msgstr "" -#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678 -#: builtin/index-pack.c:712 builtin/index-pack.c:721 +#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 +#: builtin/index-pack.c:724 builtin/index-pack.c:733 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "" -#: builtin/index-pack.c:652 builtin/pack-objects.c:170 +#: builtin/index-pack.c:664 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "" -#: builtin/index-pack.c:718 +#: builtin/index-pack.c:730 #, c-format msgid "cannot read existing object %s" msgstr "" -#: builtin/index-pack.c:732 +#: builtin/index-pack.c:744 #, c-format msgid "invalid blob object %s" msgstr "" -#: builtin/index-pack.c:747 +#: builtin/index-pack.c:759 #, c-format msgid "invalid %s" msgstr "" -#: builtin/index-pack.c:749 +#: builtin/index-pack.c:761 msgid "Error in object" msgstr "" -#: builtin/index-pack.c:751 +#: builtin/index-pack.c:763 #, c-format msgid "Not all child objects of %s are reachable" msgstr "" -#: builtin/index-pack.c:821 builtin/index-pack.c:847 +#: builtin/index-pack.c:833 builtin/index-pack.c:863 msgid "failed to apply delta" msgstr "" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Receiving objects" msgstr "" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Indexing objects" msgstr "" -#: builtin/index-pack.c:1012 +#: builtin/index-pack.c:1030 msgid "pack is corrupted (SHA1 mismatch)" msgstr "" -#: builtin/index-pack.c:1017 +#: builtin/index-pack.c:1035 msgid "cannot fstat packfile" msgstr "" -#: builtin/index-pack.c:1020 +#: builtin/index-pack.c:1038 msgid "pack has junk at the end" msgstr "" -#: builtin/index-pack.c:1031 +#: builtin/index-pack.c:1049 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "" -#: builtin/index-pack.c:1054 +#: builtin/index-pack.c:1072 msgid "Resolving deltas" msgstr "" -#: builtin/index-pack.c:1064 +#: builtin/index-pack.c:1082 #, c-format msgid "unable to create thread: %s" msgstr "" -#: builtin/index-pack.c:1106 +#: builtin/index-pack.c:1124 msgid "confusion beyond insanity" msgstr "" -#: builtin/index-pack.c:1112 +#: builtin/index-pack.c:1132 #, c-format msgid "completed with %d local objects" msgstr "" -#: builtin/index-pack.c:1121 +#: builtin/index-pack.c:1142 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "" -#: builtin/index-pack.c:1125 +#: builtin/index-pack.c:1146 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1150 +#: builtin/index-pack.c:1171 #, c-format msgid "unable to deflate appended object (%d)" msgstr "" -#: builtin/index-pack.c:1229 +#: builtin/index-pack.c:1250 #, c-format msgid "local object %s is corrupt" msgstr "" -#: builtin/index-pack.c:1253 +#: builtin/index-pack.c:1274 msgid "error while closing pack file" msgstr "" -#: builtin/index-pack.c:1266 +#: builtin/index-pack.c:1287 #, c-format msgid "cannot write keep file '%s'" msgstr "" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1295 #, c-format msgid "cannot close written keep file '%s'" msgstr "" -#: builtin/index-pack.c:1287 +#: builtin/index-pack.c:1308 msgid "cannot store pack file" msgstr "" -#: builtin/index-pack.c:1298 +#: builtin/index-pack.c:1319 msgid "cannot store index file" msgstr "" -#: builtin/index-pack.c:1331 +#: builtin/index-pack.c:1352 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "" -#: builtin/index-pack.c:1337 +#: builtin/index-pack.c:1358 #, c-format msgid "invalid number of threads specified (%d)" msgstr "" -#: builtin/index-pack.c:1341 builtin/index-pack.c:1514 +#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 #, c-format msgid "no threads support, ignoring %s" msgstr "" -#: builtin/index-pack.c:1399 +#: builtin/index-pack.c:1420 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "" -#: builtin/index-pack.c:1401 +#: builtin/index-pack.c:1422 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "" -#: builtin/index-pack.c:1448 +#: builtin/index-pack.c:1469 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1455 +#: builtin/index-pack.c:1476 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "" msgstr[1] "" -#: builtin/index-pack.c:1482 +#: builtin/index-pack.c:1503 msgid "Cannot come back to cwd" msgstr "" -#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 -#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 +#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 +#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 #, c-format msgid "bad %s" msgstr "" -#: builtin/index-pack.c:1559 +#: builtin/index-pack.c:1580 msgid "--fix-thin cannot be used without --stdin" msgstr "" -#: builtin/index-pack.c:1563 builtin/index-pack.c:1573 +#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "" -#: builtin/index-pack.c:1582 +#: builtin/index-pack.c:1603 msgid "--verify with no packfile name given" msgstr "" @@ -5264,345 +5543,340 @@ msgstr "" msgid "Cannot access work tree '%s'" msgstr "" -#: builtin/log.c:39 -msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" +#: builtin/log.c:40 +msgid "git log [<options>] [<revision range>] [[--] <path>...]\n" msgstr "" -#: builtin/log.c:40 +#: builtin/log.c:41 msgid " or: git show [options] <object>..." msgstr "" -#: builtin/log.c:102 +#: builtin/log.c:103 msgid "suppress diff output" msgstr "" -#: builtin/log.c:103 +#: builtin/log.c:104 msgid "show source" msgstr "" -#: builtin/log.c:104 +#: builtin/log.c:105 msgid "Use mail map file" msgstr "" -#: builtin/log.c:105 +#: builtin/log.c:106 msgid "decorate options" msgstr "" -#: builtin/log.c:198 +#: builtin/log.c:199 #, c-format msgid "Final output: %d %s\n" msgstr "" -#: builtin/log.c:419 builtin/log.c:511 +#: builtin/log.c:422 builtin/log.c:514 #, c-format msgid "Could not read object %s" msgstr "" -#: builtin/log.c:535 +#: builtin/log.c:538 #, c-format msgid "Unknown type: %d" msgstr "" -#: builtin/log.c:627 +#: builtin/log.c:638 msgid "format.headers without value" msgstr "" -#: builtin/log.c:701 +#: builtin/log.c:720 msgid "name of output directory is too long" msgstr "" -#: builtin/log.c:717 +#: builtin/log.c:736 #, c-format msgid "Cannot open patch file %s" msgstr "" -#: builtin/log.c:731 +#: builtin/log.c:750 msgid "Need exactly one range." msgstr "" -#: builtin/log.c:739 +#: builtin/log.c:758 msgid "Not a range." msgstr "" -#: builtin/log.c:812 +#: builtin/log.c:860 msgid "Cover letter needs email format" msgstr "" -#: builtin/log.c:885 +#: builtin/log.c:936 #, c-format msgid "insane in-reply-to: %s" msgstr "" -#: builtin/log.c:913 +#: builtin/log.c:964 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "" -#: builtin/log.c:958 +#: builtin/log.c:1009 msgid "Two output directories?" msgstr "" -#: builtin/log.c:1097 +#: builtin/log.c:1108 msgid "use [PATCH n/m] even with a single patch" msgstr "" -#: builtin/log.c:1100 +#: builtin/log.c:1111 msgid "use [PATCH] even with multiple patches" msgstr "" -#: builtin/log.c:1104 +#: builtin/log.c:1115 msgid "print patches to standard out" msgstr "" -#: builtin/log.c:1106 +#: builtin/log.c:1117 msgid "generate a cover letter" msgstr "" -#: builtin/log.c:1108 +#: builtin/log.c:1119 msgid "use simple number sequence for output file names" msgstr "" -#: builtin/log.c:1109 +#: builtin/log.c:1120 msgid "sfx" msgstr "" -#: builtin/log.c:1110 +#: builtin/log.c:1121 msgid "use <sfx> instead of '.patch'" msgstr "" -#: builtin/log.c:1112 +#: builtin/log.c:1123 msgid "start numbering patches at <n> instead of 1" msgstr "" -#: builtin/log.c:1114 +#: builtin/log.c:1125 msgid "mark the series as Nth re-roll" msgstr "" -#: builtin/log.c:1116 +#: builtin/log.c:1127 msgid "Use [<prefix>] instead of [PATCH]" msgstr "" -#: builtin/log.c:1119 +#: builtin/log.c:1130 msgid "store resulting files in <dir>" msgstr "" -#: builtin/log.c:1122 +#: builtin/log.c:1133 msgid "don't strip/add [PATCH]" msgstr "" -#: builtin/log.c:1125 +#: builtin/log.c:1136 msgid "don't output binary diffs" msgstr "" -#: builtin/log.c:1127 +#: builtin/log.c:1138 msgid "don't include a patch matching a commit upstream" msgstr "" -#: builtin/log.c:1129 +#: builtin/log.c:1140 msgid "show patch format instead of default (patch + stat)" msgstr "" -#: builtin/log.c:1131 +#: builtin/log.c:1142 msgid "Messaging" msgstr "" -#: builtin/log.c:1132 +#: builtin/log.c:1143 msgid "header" msgstr "" -#: builtin/log.c:1133 +#: builtin/log.c:1144 msgid "add email header" msgstr "" -#: builtin/log.c:1134 builtin/log.c:1136 +#: builtin/log.c:1145 builtin/log.c:1147 msgid "email" msgstr "" -#: builtin/log.c:1134 +#: builtin/log.c:1145 msgid "add To: header" msgstr "" -#: builtin/log.c:1136 +#: builtin/log.c:1147 msgid "add Cc: header" msgstr "" -#: builtin/log.c:1138 +#: builtin/log.c:1149 msgid "message-id" msgstr "" -#: builtin/log.c:1139 +#: builtin/log.c:1150 msgid "make first mail a reply to <message-id>" msgstr "" -#: builtin/log.c:1140 builtin/log.c:1143 +#: builtin/log.c:1151 builtin/log.c:1154 msgid "boundary" msgstr "" -#: builtin/log.c:1141 +#: builtin/log.c:1152 msgid "attach the patch" msgstr "" -#: builtin/log.c:1144 +#: builtin/log.c:1155 msgid "inline the patch" msgstr "" -#: builtin/log.c:1148 +#: builtin/log.c:1159 msgid "enable message threading, styles: shallow, deep" msgstr "" -#: builtin/log.c:1150 +#: builtin/log.c:1161 msgid "signature" msgstr "" -#: builtin/log.c:1151 +#: builtin/log.c:1162 msgid "add a signature" msgstr "" -#: builtin/log.c:1153 +#: builtin/log.c:1164 msgid "don't print the patch filenames" msgstr "" -#: builtin/log.c:1202 -#, c-format -msgid "bogus committer info %s" -msgstr "" - -#: builtin/log.c:1247 +#: builtin/log.c:1248 msgid "-n and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1249 +#: builtin/log.c:1250 msgid "--subject-prefix and -k are mutually exclusive." msgstr "" -#: builtin/log.c:1257 +#: builtin/log.c:1258 msgid "--name-only does not make sense" msgstr "" -#: builtin/log.c:1259 +#: builtin/log.c:1260 msgid "--name-status does not make sense" msgstr "" -#: builtin/log.c:1261 +#: builtin/log.c:1262 msgid "--check does not make sense" msgstr "" -#: builtin/log.c:1284 +#: builtin/log.c:1285 msgid "standard output, or directory, which one?" msgstr "" -#: builtin/log.c:1286 +#: builtin/log.c:1287 #, c-format msgid "Could not create directory '%s'" msgstr "" -#: builtin/log.c:1439 +#: builtin/log.c:1435 msgid "Failed to create output files" msgstr "" -#: builtin/log.c:1488 +#: builtin/log.c:1484 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "" -#: builtin/log.c:1543 +#: builtin/log.c:1539 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" msgstr "" -#: builtin/log.c:1556 builtin/log.c:1558 builtin/log.c:1570 +#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 #, c-format msgid "Unknown commit %s" msgstr "" -#: builtin/ls-files.c:409 +#: builtin/ls-files.c:402 msgid "git ls-files [options] [<file>...]" msgstr "" -#: builtin/ls-files.c:466 +#: builtin/ls-files.c:459 msgid "identify the file status with tags" msgstr "" -#: builtin/ls-files.c:468 +#: builtin/ls-files.c:461 msgid "use lowercase letters for 'assume unchanged' files" msgstr "" -#: builtin/ls-files.c:470 +#: builtin/ls-files.c:463 msgid "show cached files in the output (default)" msgstr "" -#: builtin/ls-files.c:472 +#: builtin/ls-files.c:465 msgid "show deleted files in the output" msgstr "" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:467 msgid "show modified files in the output" msgstr "" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:469 msgid "show other files in the output" msgstr "" -#: builtin/ls-files.c:478 +#: builtin/ls-files.c:471 msgid "show ignored files in the output" msgstr "" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:474 msgid "show staged contents' object name in the output" msgstr "" -#: builtin/ls-files.c:483 +#: builtin/ls-files.c:476 msgid "show files on the filesystem that need to be removed" msgstr "" -#: builtin/ls-files.c:485 +#: builtin/ls-files.c:478 msgid "show 'other' directories' name only" msgstr "" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:481 msgid "don't show empty directories" msgstr "" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:484 msgid "show unmerged files in the output" msgstr "" -#: builtin/ls-files.c:493 +#: builtin/ls-files.c:486 msgid "show resolve-undo information" msgstr "" -#: builtin/ls-files.c:495 +#: builtin/ls-files.c:488 msgid "skip files matching pattern" msgstr "" -#: builtin/ls-files.c:498 +#: builtin/ls-files.c:491 msgid "exclude patterns are read from <file>" msgstr "" -#: builtin/ls-files.c:501 +#: builtin/ls-files.c:494 msgid "read additional per-directory exclude patterns in <file>" msgstr "" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:496 msgid "add the standard git exclusions" msgstr "" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:499 msgid "make the output relative to the project top directory" msgstr "" -#: builtin/ls-files.c:509 +#: builtin/ls-files.c:502 msgid "if any <file> is not in the index, treat this as an error" msgstr "" -#: builtin/ls-files.c:510 +#: builtin/ls-files.c:503 msgid "tree-ish" msgstr "" -#: builtin/ls-files.c:511 +#: builtin/ls-files.c:504 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "" -#: builtin/ls-files.c:513 +#: builtin/ls-files.c:506 msgid "show debugging data" msgstr "" @@ -5709,108 +5983,112 @@ msgstr "" msgid "abort if fast-forward is not possible" msgstr "" -#: builtin/merge.c:202 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:203 +msgid "Verify that the named commit has a valid GPG signature" +msgstr "" + +#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112 msgid "strategy" msgstr "" -#: builtin/merge.c:203 +#: builtin/merge.c:205 msgid "merge strategy to use" msgstr "" -#: builtin/merge.c:204 +#: builtin/merge.c:206 msgid "option=value" msgstr "" -#: builtin/merge.c:205 +#: builtin/merge.c:207 msgid "option for selected merge strategy" msgstr "" -#: builtin/merge.c:207 +#: builtin/merge.c:209 msgid "merge commit message (for a non-fast-forward merge)" msgstr "" -#: builtin/merge.c:211 +#: builtin/merge.c:213 msgid "abort the current in-progress merge" msgstr "" -#: builtin/merge.c:240 +#: builtin/merge.c:242 msgid "could not run stash." msgstr "" -#: builtin/merge.c:245 +#: builtin/merge.c:247 msgid "stash failed" msgstr "" -#: builtin/merge.c:250 +#: builtin/merge.c:252 #, c-format msgid "not a valid object: %s" msgstr "" -#: builtin/merge.c:269 builtin/merge.c:286 +#: builtin/merge.c:271 builtin/merge.c:288 msgid "read-tree failed" msgstr "" -#: builtin/merge.c:316 +#: builtin/merge.c:318 msgid " (nothing to squash)" msgstr "" -#: builtin/merge.c:329 +#: builtin/merge.c:331 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "" -#: builtin/merge.c:361 +#: builtin/merge.c:363 msgid "Writing SQUASH_MSG" msgstr "" -#: builtin/merge.c:363 +#: builtin/merge.c:365 msgid "Finishing SQUASH_MSG" msgstr "" -#: builtin/merge.c:386 +#: builtin/merge.c:388 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "" -#: builtin/merge.c:436 +#: builtin/merge.c:438 #, c-format msgid "'%s' does not point to a commit" msgstr "" -#: builtin/merge.c:535 +#: builtin/merge.c:550 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "" -#: builtin/merge.c:628 +#: builtin/merge.c:643 msgid "git write-tree failed to write a tree" msgstr "" -#: builtin/merge.c:656 +#: builtin/merge.c:671 msgid "Not handling anything other than two heads merge." msgstr "" -#: builtin/merge.c:670 +#: builtin/merge.c:685 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "" -#: builtin/merge.c:684 +#: builtin/merge.c:699 #, c-format msgid "unable to write %s" msgstr "" -#: builtin/merge.c:773 +#: builtin/merge.c:788 #, c-format msgid "Could not read from '%s'" msgstr "" -#: builtin/merge.c:782 +#: builtin/merge.c:797 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" -#: builtin/merge.c:788 +#: builtin/merge.c:803 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -5820,140 +6098,161 @@ msgid "" "the commit.\n" msgstr "" -#: builtin/merge.c:812 +#: builtin/merge.c:827 msgid "Empty commit message." msgstr "" -#: builtin/merge.c:824 +#: builtin/merge.c:839 #, c-format msgid "Wonderful.\n" msgstr "" -#: builtin/merge.c:889 +#: builtin/merge.c:904 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" -#: builtin/merge.c:905 +#: builtin/merge.c:920 #, c-format msgid "'%s' is not a commit" msgstr "" -#: builtin/merge.c:946 +#: builtin/merge.c:961 msgid "No current branch." msgstr "" -#: builtin/merge.c:948 +#: builtin/merge.c:963 msgid "No remote for the current branch." msgstr "" -#: builtin/merge.c:950 +#: builtin/merge.c:965 msgid "No default upstream defined for the current branch." msgstr "" -#: builtin/merge.c:955 +#: builtin/merge.c:970 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "" -#: builtin/merge.c:1042 builtin/merge.c:1199 +#: builtin/merge.c:1057 builtin/merge.c:1214 #, c-format msgid "%s - not something we can merge" msgstr "" -#: builtin/merge.c:1110 +#: builtin/merge.c:1125 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "" -#: builtin/merge.c:1126 git-pull.sh:31 +#: builtin/merge.c:1141 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." msgstr "" -#: builtin/merge.c:1129 git-pull.sh:34 +#: builtin/merge.c:1144 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "" -#: builtin/merge.c:1133 +#: builtin/merge.c:1148 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." msgstr "" -#: builtin/merge.c:1136 +#: builtin/merge.c:1151 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "" -#: builtin/merge.c:1145 +#: builtin/merge.c:1160 msgid "You cannot combine --squash with --no-ff." msgstr "" -#: builtin/merge.c:1150 +#: builtin/merge.c:1165 msgid "You cannot combine --no-ff with --ff-only." msgstr "" -#: builtin/merge.c:1157 +#: builtin/merge.c:1172 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" -#: builtin/merge.c:1189 +#: builtin/merge.c:1204 msgid "Can merge only exactly one commit into empty head" msgstr "" -#: builtin/merge.c:1192 +#: builtin/merge.c:1207 msgid "Squash commit into empty head not supported yet" msgstr "" -#: builtin/merge.c:1194 +#: builtin/merge.c:1209 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" -#: builtin/merge.c:1310 +#: builtin/merge.c:1265 +#, c-format +msgid "Commit %s has an untrusted GPG signature, allegedly by %s." +msgstr "" + +#: builtin/merge.c:1268 +#, c-format +msgid "Commit %s has a bad GPG signature allegedly by %s." +msgstr "" + +#. 'N' +#: builtin/merge.c:1271 +#, c-format +msgid "Commit %s does not have a GPG signature." +msgstr "" + +#: builtin/merge.c:1274 +#, c-format +msgid "Commit %s has a good GPG signature by %s\n" +msgstr "" + +#: builtin/merge.c:1358 #, c-format msgid "Updating %s..%s\n" msgstr "" -#: builtin/merge.c:1349 +#: builtin/merge.c:1397 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "" -#: builtin/merge.c:1356 +#: builtin/merge.c:1404 #, c-format msgid "Nope.\n" msgstr "" -#: builtin/merge.c:1388 +#: builtin/merge.c:1436 msgid "Not possible to fast-forward, aborting." msgstr "" -#: builtin/merge.c:1411 builtin/merge.c:1490 +#: builtin/merge.c:1459 builtin/merge.c:1538 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "" -#: builtin/merge.c:1415 +#: builtin/merge.c:1463 #, c-format msgid "Trying merge strategy %s...\n" msgstr "" -#: builtin/merge.c:1481 +#: builtin/merge.c:1529 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "" -#: builtin/merge.c:1483 +#: builtin/merge.c:1531 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "" -#: builtin/merge.c:1492 +#: builtin/merge.c:1540 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "" -#: builtin/merge.c:1504 +#: builtin/merge.c:1552 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -6902,11 +7201,15 @@ msgstr "" msgid "bypass pre-push hook" msgstr "" -#: builtin/push.c:448 -msgid "--delete is incompatible with --all, --mirror and --tags" +#: builtin/push.c:440 +msgid "push missing but relevant tags" msgstr "" #: builtin/push.c:450 +msgid "--delete is incompatible with --all, --mirror and --tags" +msgstr "" + +#: builtin/push.c:452 msgid "--delete doesn't make sense without any refs" msgstr "" @@ -7639,7 +7942,7 @@ msgid "" msgstr "" #: builtin/revert.c:22 -msgid "git revert [options] <commit-ish>" +msgid "git revert [options] <commit-ish>..." msgstr "" #: builtin/revert.c:23 @@ -7647,7 +7950,7 @@ msgid "git revert <subcommand>" msgstr "" #: builtin/revert.c:28 -msgid "git cherry-pick [options] <commit-ish>" +msgid "git cherry-pick [options] <commit-ish>..." msgstr "" #: builtin/revert.c:29 @@ -7790,31 +8093,31 @@ msgid "git rm: unable to remove %s" msgstr "" #: builtin/shortlog.c:13 -msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +msgid "git shortlog [<options>] [<revision range>] [[--] [<path>...]]" msgstr "" -#: builtin/shortlog.c:133 +#: builtin/shortlog.c:131 #, c-format msgid "Missing author: %s" msgstr "" -#: builtin/shortlog.c:229 +#: builtin/shortlog.c:227 msgid "sort output according to the number of commits per author" msgstr "" -#: builtin/shortlog.c:231 +#: builtin/shortlog.c:229 msgid "Suppress commit descriptions, only provides commit count" msgstr "" -#: builtin/shortlog.c:233 +#: builtin/shortlog.c:231 msgid "Show the email address of each author" msgstr "" -#: builtin/shortlog.c:234 +#: builtin/shortlog.c:232 msgid "w[,i1[,i2]]" msgstr "" -#: builtin/shortlog.c:235 +#: builtin/shortlog.c:233 msgid "Linewrap output" msgstr "" @@ -7830,67 +8133,67 @@ msgstr "" msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "" -#: builtin/show-branch.c:651 +#: builtin/show-branch.c:650 msgid "show remote-tracking and local branches" msgstr "" -#: builtin/show-branch.c:653 +#: builtin/show-branch.c:652 msgid "show remote-tracking branches" msgstr "" -#: builtin/show-branch.c:655 +#: builtin/show-branch.c:654 msgid "color '*!+-' corresponding to the branch" msgstr "" -#: builtin/show-branch.c:657 +#: builtin/show-branch.c:656 msgid "show <n> more commits after the common ancestor" msgstr "" -#: builtin/show-branch.c:659 +#: builtin/show-branch.c:658 msgid "synonym to more=-1" msgstr "" -#: builtin/show-branch.c:660 +#: builtin/show-branch.c:659 msgid "suppress naming strings" msgstr "" -#: builtin/show-branch.c:662 +#: builtin/show-branch.c:661 msgid "include the current branch" msgstr "" -#: builtin/show-branch.c:664 +#: builtin/show-branch.c:663 msgid "name commits with their object names" msgstr "" -#: builtin/show-branch.c:666 +#: builtin/show-branch.c:665 msgid "show possible merge bases" msgstr "" -#: builtin/show-branch.c:668 +#: builtin/show-branch.c:667 msgid "show refs unreachable from any other ref" msgstr "" -#: builtin/show-branch.c:670 +#: builtin/show-branch.c:669 msgid "show commits in topological order" msgstr "" -#: builtin/show-branch.c:672 +#: builtin/show-branch.c:671 msgid "show only commits not on the first branch" msgstr "" -#: builtin/show-branch.c:674 +#: builtin/show-branch.c:673 msgid "show merges reachable from only one tip" msgstr "" -#: builtin/show-branch.c:676 +#: builtin/show-branch.c:675 msgid "show commits where no parent comes before its children" msgstr "" -#: builtin/show-branch.c:678 +#: builtin/show-branch.c:677 msgid "<n>[,<base>]" msgstr "" -#: builtin/show-branch.c:679 +#: builtin/show-branch.c:678 msgid "show <n> most recent ref-log entries starting at base" msgstr "" @@ -8337,7 +8640,10 @@ msgid "only useful for debugging" msgstr "" #: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." +msgid "" +"'git help -a' and 'git help -g' lists available subcommands and some\n" +"concept guides. See 'git help <command>' or 'git help <concept>'\n" +"to read about a specific subcommand or concept." msgstr "" #: parse-options.h:156 @@ -8674,59 +8980,59 @@ msgid "" "(You can use \"git bisect bad\" and \"git bisect good\" for that.)" msgstr "" -#: git-bisect.sh:347 git-bisect.sh:474 +#: git-bisect.sh:363 git-bisect.sh:490 msgid "We are not bisecting." msgstr "" -#: git-bisect.sh:354 +#: git-bisect.sh:370 #, sh-format msgid "'$invalid' is not a valid commit" msgstr "" -#: git-bisect.sh:363 +#: git-bisect.sh:379 #, sh-format msgid "" "Could not check out original HEAD '$branch'.\n" "Try 'git bisect reset <commit>'." msgstr "" -#: git-bisect.sh:390 +#: git-bisect.sh:406 msgid "No logfile given" msgstr "" -#: git-bisect.sh:391 +#: git-bisect.sh:407 #, sh-format msgid "cannot read $file for replaying" msgstr "" -#: git-bisect.sh:408 +#: git-bisect.sh:424 msgid "?? what are you talking about?" msgstr "" -#: git-bisect.sh:420 +#: git-bisect.sh:436 #, sh-format msgid "running $command" msgstr "" -#: git-bisect.sh:427 +#: git-bisect.sh:443 #, sh-format msgid "" "bisect run failed:\n" "exit code $res from '$command' is < 0 or >= 128" msgstr "" -#: git-bisect.sh:453 +#: git-bisect.sh:469 msgid "bisect run cannot continue any more" msgstr "" -#: git-bisect.sh:459 +#: git-bisect.sh:475 #, sh-format msgid "" "bisect run failed:\n" "'bisect_state $state' exited with error code $res" msgstr "" -#: git-bisect.sh:466 +#: git-bisect.sh:482 msgid "bisect run success" msgstr "" @@ -8741,7 +9047,7 @@ msgstr "" msgid "Pull is not possible because you have unmerged files." msgstr "" -#: git-pull.sh:197 +#: git-pull.sh:203 msgid "updating an unborn branch with changes added to the index" msgstr "" @@ -8749,7 +9055,7 @@ msgstr "" #. The working tree and the index file is still based on the #. $orig_head commit, but we are merging into $curr_head. #. First update the working tree to match $curr_head. -#: git-pull.sh:229 +#: git-pull.sh:235 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -8757,11 +9063,11 @@ msgid "" "Warning: commit $orig_head." msgstr "" -#: git-pull.sh:254 +#: git-pull.sh:260 msgid "Cannot merge multiple branches into empty head" msgstr "" -#: git-pull.sh:258 +#: git-pull.sh:264 msgid "Cannot rebase onto multiple branches" msgstr "" @@ -9002,37 +9308,37 @@ msgstr "" msgid "(To restore them type \"git stash apply\")" msgstr "" -#: git-submodule.sh:90 +#: git-submodule.sh:91 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "" -#: git-submodule.sh:195 +#: git-submodule.sh:196 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" -#: git-submodule.sh:238 +#: git-submodule.sh:239 #, sh-format msgid "Clone of '$url' into submodule path '$sm_path' failed" msgstr "" -#: git-submodule.sh:250 +#: git-submodule.sh:251 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "" -#: git-submodule.sh:343 +#: git-submodule.sh:349 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "" -#: git-submodule.sh:360 +#: git-submodule.sh:366 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "" -#: git-submodule.sh:364 +#: git-submodule.sh:370 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9040,180 +9346,233 @@ msgid "" "Use -f if you really want to add it." msgstr "" -#: git-submodule.sh:382 +#: git-submodule.sh:388 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "" -#: git-submodule.sh:384 +#: git-submodule.sh:390 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "" -#: git-submodule.sh:392 +#: git-submodule.sh:398 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "" -#: git-submodule.sh:394 +#: git-submodule.sh:400 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" msgstr "" -#: git-submodule.sh:396 +#: git-submodule.sh:402 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" msgstr "" -#: git-submodule.sh:397 +#: git-submodule.sh:403 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " "option." msgstr "" -#: git-submodule.sh:399 +#: git-submodule.sh:405 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "" -#: git-submodule.sh:411 +#: git-submodule.sh:417 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "" -#: git-submodule.sh:416 +#: git-submodule.sh:422 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "" -#: git-submodule.sh:425 +#: git-submodule.sh:431 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "" -#: git-submodule.sh:468 +#: git-submodule.sh:474 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:482 +#: git-submodule.sh:488 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "" -#: git-submodule.sh:526 +#: git-submodule.sh:532 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "" -#: git-submodule.sh:535 +#: git-submodule.sh:541 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:537 +#: git-submodule.sh:543 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "" -#: git-submodule.sh:545 +#: git-submodule.sh:551 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:649 +#: git-submodule.sh:588 +#, sh-format +msgid "Use '.' if you really want to deinitialize all submodules" +msgstr "" + +#: git-submodule.sh:603 +#, sh-format +msgid "Submodule work tree '$sm_path' contains a .git directory" +msgstr "" + +#: git-submodule.sh:604 +#, sh-format +msgid "" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" + +#: git-submodule.sh:610 +#, sh-format +msgid "" +"Submodule work tree '$sm_path' contains local modifications; use '-f' to " +"discard them" +msgstr "" + +#: git-submodule.sh:613 +#, sh-format +msgid "Cleared directory '$sm_path'" +msgstr "" + +#: git-submodule.sh:614 +#, sh-format +msgid "Could not remove submodule work tree '$sm_path'" +msgstr "" + +#: git-submodule.sh:617 +#, sh-format +msgid "Could not create empty submodule directory '$sm_path'" +msgstr "" + +#: git-submodule.sh:626 +#, sh-format +msgid "Submodule '$name' ($url) unregistered for path '$sm_path'" +msgstr "" + +#: git-submodule.sh:731 #, sh-format msgid "" -"Submodule path '$sm_path' not initialized\n" +"Submodule path '$prefix$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -#: git-submodule.sh:662 +#: git-submodule.sh:744 #, sh-format -msgid "Unable to find current revision in submodule path '$sm_path'" +msgid "Unable to find current revision in submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:671 git-submodule.sh:695 +#: git-submodule.sh:753 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "" -#: git-submodule.sh:709 +#: git-submodule.sh:777 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" +msgid "Unable to fetch in submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:710 +#: git-submodule.sh:791 #, sh-format -msgid "Submodule path '$sm_path': rebased into '$sha1'" +msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:715 +#: git-submodule.sh:792 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$sm_path'" +msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'" msgstr "" -#: git-submodule.sh:716 +#: git-submodule.sh:797 #, sh-format -msgid "Submodule path '$sm_path': merged in '$sha1'" +msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:721 +#: git-submodule.sh:798 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" +msgid "Submodule path '$prefix$sm_path': merged in '$sha1'" msgstr "" -#: git-submodule.sh:722 +#: git-submodule.sh:803 #, sh-format -msgid "Submodule path '$sm_path': checked out '$sha1'" +msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:744 git-submodule.sh:1066 +#: git-submodule.sh:804 #, sh-format -msgid "Failed to recurse into submodule path '$sm_path'" +msgid "Submodule path '$prefix$sm_path': checked out '$sha1'" +msgstr "" + +#: git-submodule.sh:831 +#, sh-format +msgid "Failed to recurse into submodule path '$prefix$sm_path'" msgstr "" -#: git-submodule.sh:852 +#: git-submodule.sh:939 msgid "The --cached option cannot be used with the --files option" msgstr "" #. unexpected type -#: git-submodule.sh:892 +#: git-submodule.sh:979 #, sh-format msgid "unexpected mode $mod_dst" msgstr "" -#: git-submodule.sh:910 +#: git-submodule.sh:997 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr "" -#: git-submodule.sh:913 +#: git-submodule.sh:1000 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr "" -#: git-submodule.sh:916 +#: git-submodule.sh:1003 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" -#: git-submodule.sh:941 +#: git-submodule.sh:1028 msgid "blob" msgstr "" -#: git-submodule.sh:979 +#: git-submodule.sh:1066 msgid "Submodules changed but not updated:" msgstr "" -#: git-submodule.sh:981 +#: git-submodule.sh:1068 msgid "Submodule changes to be committed:" msgstr "" -#: git-submodule.sh:1129 +#: git-submodule.sh:1153 +#, sh-format +msgid "Failed to recurse into submodule path '$sm_path'" +msgstr "" + +#: git-submodule.sh:1216 #, sh-format msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "" @@ -5,10 +5,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git 1.8.2\n" +"Project-Id-Version: git 1.8.3\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2013-03-05 12:36+0800\n" -"PO-Revision-Date: 2013-03-05 09:17+0100\n" +"POT-Creation-Date: 2013-04-30 08:25+0800\n" +"PO-Revision-Date: 2013-04-30 12:22+0100\n" "Last-Translator: Peter Krefting <peter@softwolves.pp.se>\n" "Language-Team: Swedish <tp-sv@listor.tp-sv.se>\n" "Language: sv\n" @@ -17,7 +17,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: advice.c:49 +#: advice.c:53 #, c-format msgid "hint: %.*s\n" msgstr "tips: %.*s\n" @@ -26,7 +26,7 @@ msgstr "tips: %.*s\n" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:79 +#: advice.c:83 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm <file>' as\n" @@ -65,7 +65,7 @@ msgstr "fmt" msgid "archive format" msgstr "arkivformat" -#: archive.c:324 builtin/log.c:1115 +#: archive.c:324 builtin/log.c:1126 msgid "prefix" msgstr "prefix" @@ -73,15 +73,15 @@ msgstr "prefix" msgid "prepend prefix to each pathname in the archive" msgstr "lägg till prefix till varje sökväg i arkivet" -#: archive.c:326 builtin/archive.c:91 builtin/blame.c:2366 -#: builtin/blame.c:2367 builtin/config.c:55 builtin/fast-export.c:653 -#: builtin/fast-export.c:655 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:497 builtin/ls-files.c:500 builtin/notes.c:536 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 +#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 +#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 #: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 msgid "file" msgstr "fil" -#: archive.c:327 builtin/archive.c:92 +#: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" msgstr "skriv arkivet till filen" @@ -109,19 +109,19 @@ msgstr "komprimera bättre" msgid "list supported archive formats" msgstr "visa understödda arkivformat" -#: archive.c:345 builtin/archive.c:93 builtin/clone.c:85 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 msgid "repo" msgstr "arkiv" -#: archive.c:346 builtin/archive.c:94 +#: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository <repo>" msgstr "hämta arkivet frÃ¥n fjärrarkivet <arkiv>" -#: archive.c:347 builtin/archive.c:95 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 msgid "command" msgstr "kommando" -#: archive.c:348 builtin/archive.c:96 +#: archive.c:348 builtin/archive.c:93 msgid "path to the remote git-upload-archive command" msgstr "sökväg till kommandot git-upload-archive pÃ¥ fjärren" @@ -133,6 +133,130 @@ msgstr "" "Negativa mönster ignoreras i git-attribut\n" "Använd '\\!' för att inleda med ett utropstecken." +#: branch.c:60 +#, c-format +msgid "Not setting branch %s as its own upstream." +msgstr "Ställer inte in grenen %s som sin egen uppströmsgren." + +#: branch.c:82 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s by rebasing." +msgstr "" +"Grenen %s ställdes in att spÃ¥ra fjärrgrenen %s frÃ¥n %s genom ombasering." + +#: branch.c:83 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s." +msgstr "Grenen %s ställdes in att spÃ¥ra fjärrgrenen %s frÃ¥n %s." + +#: branch.c:87 +#, c-format +msgid "Branch %s set up to track local branch %s by rebasing." +msgstr "Grenen %s ställdes in att spÃ¥ra den lokala grenen %s genom ombasering." + +#: branch.c:88 +#, c-format +msgid "Branch %s set up to track local branch %s." +msgstr "Grenen %s ställdes in att spÃ¥ra den lokala grenen %s." + +#: branch.c:92 +#, c-format +msgid "Branch %s set up to track remote ref %s by rebasing." +msgstr "Grenen %s ställdes in att spÃ¥ra fjärreferensen %s genom ombasering." + +#: branch.c:93 +#, c-format +msgid "Branch %s set up to track remote ref %s." +msgstr "Grenen %s ställdes in att spÃ¥ra fjärreferensen %s." + +#: branch.c:97 +#, c-format +msgid "Branch %s set up to track local ref %s by rebasing." +msgstr "" +"Grenen %s ställdes in att spÃ¥ra den lokala referensen %s genom ombasering." + +#: branch.c:98 +#, c-format +msgid "Branch %s set up to track local ref %s." +msgstr "Grenen %s ställdes in att spÃ¥ra den lokala referensen %s." + +#: branch.c:118 +#, c-format +msgid "Tracking not set up: name too long: %s" +msgstr "SpÃ¥rning har inte ställts in: namnet för lÃ¥ngt: %s" + +#: branch.c:137 +#, c-format +msgid "Not tracking: ambiguous information for ref %s" +msgstr "SpÃ¥rar inte: tvetydig information för referensen %s" + +#: branch.c:182 +#, c-format +msgid "'%s' is not a valid branch name." +msgstr "\"%s\" är inte ett giltigt grennamn." + +#: branch.c:187 +#, c-format +msgid "A branch named '%s' already exists." +msgstr "Det finns redan en gren som heter \"%s\"" + +#: branch.c:195 +msgid "Cannot force update the current branch." +msgstr "Kan inte tvinga uppdatering av aktuell gren." + +#: branch.c:201 +#, c-format +msgid "Cannot setup tracking information; starting point '%s' is not a branch." +msgstr "Kan inte ställa in spÃ¥rning; startpunkten \"%s\" är inte en gren." + +#: branch.c:203 +#, c-format +msgid "the requested upstream branch '%s' does not exist" +msgstr "den efterfrÃ¥gade uppströmsgrenen \"%s\" finns inte" + +#: branch.c:205 +msgid "" +"\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push." +msgstr "" +"\n" +"Om du har tänkt basera ditt arbete pÃ¥ en uppströmsgren\n" +"som redan finns pÃ¥ fjärren kan du behöva köra \"git fetch\"\n" +"för att hämta den.\n" +"\n" +"Om du har tänkt sända in en ny lokal gren som skall\n" +"spÃ¥ra dess fjärrmotsvarighet kan du använda \"git push -u\"\n" +"för att ställa in uppströmskonfigurationen när du sänder in." + +#: branch.c:250 +#, c-format +msgid "Not a valid object name: '%s'." +msgstr "Objektnamnet är inte giltigt: \"%s\"." + +#: branch.c:270 +#, c-format +msgid "Ambiguous object name: '%s'." +msgstr "Objektnamnet är tvetydigt: \"%s\"." + +#: branch.c:275 +#, c-format +msgid "Not a valid branch point: '%s'." +msgstr "Avgreningspunkten är inte giltig: \"%s\"" + +#: branch.c:281 +msgid "Failed to lock ref for update" +msgstr "Misslyckades lÃ¥sa referens för uppdatering" + +#: branch.c:299 +msgid "Failed to write ref" +msgstr "Misslyckades skriva referens" + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -143,7 +267,7 @@ msgstr "'%s' ser inte ut som en v2-bundle-fil" msgid "unrecognized header: %s%s (%d)" msgstr "okänt huvud: %s%s (%d)" -#: bundle.c:89 builtin/commit.c:674 +#: bundle.c:89 builtin/commit.c:676 #, c-format msgid "could not open '%s'" msgstr "kunde inte öppna \"%s\"" @@ -152,35 +276,35 @@ msgstr "kunde inte öppna \"%s\"" msgid "Repository lacks these prerequisite commits:" msgstr "Arkivet saknar dessa nödvändiga incheckningar:" -#: bundle.c:164 sequencer.c:566 sequencer.c:998 builtin/log.c:299 -#: builtin/log.c:751 builtin/log.c:1358 builtin/log.c:1574 builtin/merge.c:347 -#: builtin/shortlog.c:157 +#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 +#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 +#: builtin/shortlog.c:155 msgid "revision walk setup failed" msgstr "misslyckades skapa revisionstraversering" #: bundle.c:186 #, c-format -msgid "The bundle contains %d ref" -msgid_plural "The bundle contains %d refs" -msgstr[0] "Paketet (bundlen) innehÃ¥ller %d referens" -msgstr[1] "Paketet (bundlen) innehÃ¥ller %d referenser" +msgid "The bundle contains this ref:" +msgid_plural "The bundle contains these %d refs:" +msgstr[0] "Paketet (bundlen) denna referens:" +msgstr[1] "Paketet (bundlen) dessa %d referenser:" -#: bundle.c:192 +#: bundle.c:193 msgid "The bundle records a complete history." msgstr "Paketet (bundlen) beskriver en komplett historik." #: bundle.c:195 #, c-format -msgid "The bundle requires this ref" -msgid_plural "The bundle requires these %d refs" -msgstr[0] "Paketet (bundlen) kräver denna referens" -msgstr[1] "Paketet (bundlen) kräver dessa %d referenser" +msgid "The bundle requires this ref:" +msgid_plural "The bundle requires these %d refs:" +msgstr[0] "Paketet (bundlen) kräver denna referens:" +msgstr[1] "Paketet (bundlen) kräver dessa %d referenser:" #: bundle.c:294 msgid "rev-list died" msgstr "rev-list dog" -#: bundle.c:300 builtin/log.c:1254 builtin/shortlog.c:260 +#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 #, c-format msgid "unrecognized argument: %s" msgstr "okänt argument: %s" @@ -330,7 +454,7 @@ msgstr "" "Hittade fel i konfigurationsvariabeln \"diff.dirstat\":\n" "%s" -#: diff.c:3468 +#: diff.c:3481 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -339,12 +463,12 @@ msgstr "" "Misslyckades tolka argument till flaggan --dirstat/-X;\n" "%s" -#: diff.c:3482 +#: diff.c:3495 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "Misslyckades tolka argument till flaggan --submodule: \"%s\"" -#: gpg-interface.c:59 gpg-interface.c:127 +#: gpg-interface.c:59 gpg-interface.c:131 msgid "could not run gpg." msgstr "kunde inte köra gpg." @@ -356,27 +480,27 @@ msgstr "gpg godtog inte data" msgid "gpg failed to sign the data" msgstr "gpg misslyckades signera data" -#: gpg-interface.c:112 +#: gpg-interface.c:115 #, c-format msgid "could not create temporary file '%s': %s" msgstr "kunde inte skapa temporära filen \"%s\": %s" -#: gpg-interface.c:115 +#: gpg-interface.c:118 #, c-format msgid "failed writing detached signature to '%s': %s" msgstr "misslyckades skriva fristÃ¥ende signatur till \"%s\": %s" -#: grep.c:1622 +#: grep.c:1623 #, c-format msgid "'%s': unable to read %s" msgstr "\"%s\" kunde inte läsa %s" -#: grep.c:1639 +#: grep.c:1640 #, c-format msgid "'%s': %s" msgstr "\"%s\": %s" -#: grep.c:1650 +#: grep.c:1651 #, c-format msgid "'%s': short read %s" msgstr "\"%s\": kort läsning %s" @@ -444,8 +568,8 @@ msgstr[1] "" msgid "failed to read the cache" msgstr "misslyckads läsa cachen" -#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 -#: builtin/clone.c:586 +#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 +#: builtin/clone.c:645 msgid "unable to write new index file" msgstr "kunde inte skriva ny indexfil" @@ -494,7 +618,7 @@ msgstr "kan inte läsa objektet %s: \"%s\"" msgid "blob expected for %s '%s'" msgstr "blob förväntades för %s \"%s\"" -#: merge-recursive.c:773 builtin/clone.c:302 +#: merge-recursive.c:773 builtin/clone.c:313 #, c-format msgid "failed to open '%s'" msgstr "misslyckades öppna \"%s\"" @@ -628,7 +752,7 @@ msgstr "Hoppade över %s (sammanslagen samma som befintlig)" msgid "Auto-merging %s" msgstr "SlÃ¥r ihop %s automatiskt" -#: merge-recursive.c:1633 git-submodule.sh:942 +#: merge-recursive.c:1633 git-submodule.sh:1029 msgid "submodule" msgstr "undermodul" @@ -699,10 +823,15 @@ msgstr "sammanslagningen returnerade ingen incheckning" msgid "Could not parse object '%s'" msgstr "Kunde inte tolka objektet \"%s\"" -#: merge-recursive.c:2009 builtin/merge.c:643 +#: merge-recursive.c:2009 builtin/merge.c:658 msgid "Unable to write index." msgstr "Kunde inte skriva indexet." +#: object.c:195 +#, c-format +msgid "unable to parse object: %s" +msgstr "kunde inte tolka objektet: %s" + #: parse-options.c:489 msgid "..." msgstr "..." @@ -738,18 +867,18 @@ msgstr "Sökvägen \"%s\" är i undermodulen \"%.*s\"" msgid "'%s' is beyond a symbolic link" msgstr "\"%s\" är pÃ¥ andra sidan av en symbolisk länk" -#: remote.c:1653 +#: remote.c:1781 #, 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] "Din gren ligger före \"%s\" med %d incheckning.\n" msgstr[1] "Din gren ligger före \"%s\" med %d incheckningar.\n" -#: remote.c:1659 +#: remote.c:1787 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (använd \"git push\" för att publicera dina lokala incheckningar)\n" -#: remote.c:1662 +#: remote.c:1790 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -759,11 +888,11 @@ msgstr[0] "" msgstr[1] "" "Din gren ligger efter \"%s\" med %d incheckningar, och kan snabbspolas.\n" -#: remote.c:1670 +#: remote.c:1798 msgid " (use \"git pull\" to update your local branch)\n" msgstr " (använd \"git pull\" för att uppdatera din lokala gren)\n" -#: remote.c:1673 +#: remote.c:1801 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -778,23 +907,23 @@ msgstr[1] "" "Din gren och \"%s\" har divergerat,\n" "och har %d respektive %d olika incheckningar.\n" -#: remote.c:1683 +#: remote.c:1811 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr " (använd \"git pull\" för att slÃ¥ ihop fjärrgrenen med din egen)\n" -#: sequencer.c:123 builtin/merge.c:761 builtin/merge.c:874 builtin/merge.c:984 -#: builtin/merge.c:994 +#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 +#: builtin/merge.c:1009 #, c-format msgid "Could not open '%s' for writing" msgstr "Kunde inte öppna \"%s\" för skrivning" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 -#: builtin/merge.c:999 +#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 +#: builtin/merge.c:1001 builtin/merge.c:1014 #, c-format msgid "Could not write to '%s'" msgstr "Kunde inte skriva till \"%s\"" -#: sequencer.c:146 +#: sequencer.c:229 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -802,7 +931,7 @@ msgstr "" "efter att ha löst konflikterna, markera de rättade sökvägarna\n" "med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"" -#: sequencer.c:149 +#: sequencer.c:232 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -812,228 +941,238 @@ msgstr "" "med \"git add <sökvägar>\" eller \"git rm <sökvägar>\"\n" "och checka in resultatet med \"git commit\"" -#: sequencer.c:162 sequencer.c:774 sequencer.c:857 +#: sequencer.c:245 sequencer.c:859 sequencer.c:942 #, c-format msgid "Could not write to %s" msgstr "Kunde inte skriva till %s" -#: sequencer.c:165 +#: sequencer.c:248 #, c-format msgid "Error wrapping up %s" msgstr "Fel vid ombrytning av %s" -#: sequencer.c:180 +#: sequencer.c:263 msgid "Your local changes would be overwritten by cherry-pick." msgstr "Dina lokala ändringar skulle skrivas över av \"cherry-pick\"." -#: sequencer.c:182 +#: sequencer.c:265 msgid "Your local changes would be overwritten by revert." msgstr "Dina lokala ändringar skulle skrivas över av \"revert\"." -#: sequencer.c:185 +#: sequencer.c:268 msgid "Commit your changes or stash them to proceed." msgstr "Checka in dina ändringar eller använd \"stash\" för att fortsätta." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:236 +#: sequencer.c:319 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Kunde inte skriva ny indexfil" -#: sequencer.c:267 +#: sequencer.c:350 msgid "Could not resolve HEAD commit\n" msgstr "Kunde inte bestämma HEAD:s incheckning\n" -#: sequencer.c:288 +#: sequencer.c:371 msgid "Unable to update cache tree\n" msgstr "Kan inte uppdatera cacheträd\n" -#: sequencer.c:333 +#: sequencer.c:416 #, c-format msgid "Could not parse commit %s\n" msgstr "Kunde inte tolka incheckningen %s\n" -#: sequencer.c:338 +#: sequencer.c:421 #, c-format msgid "Could not parse parent commit %s\n" msgstr "Kunde inte tolka föräldraincheckningen %s\n" -#: sequencer.c:404 +#: sequencer.c:487 msgid "Your index file is unmerged." msgstr "Din indexfil har inte slagits ihop." -#: sequencer.c:423 +#: sequencer.c:506 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "Incheckning %s är en sammanslagning, men flaggan -m angavs inte." -#: sequencer.c:431 +#: sequencer.c:514 #, c-format msgid "Commit %s does not have parent %d" msgstr "Incheckning %s har inte förälder %d" -#: sequencer.c:435 +#: sequencer.c:518 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "Huvudlinje angavs, men incheckningen %s är inte en sammanslagning" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:448 +#: sequencer.c:531 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: kan inte tolka föräldraincheckningen %s" -#: sequencer.c:452 +#: sequencer.c:535 #, c-format msgid "Cannot get commit message for %s" msgstr "Kan inte hämta incheckningsmeddelande för %s" -#: sequencer.c:536 +#: sequencer.c:621 #, c-format msgid "could not revert %s... %s" msgstr "kunde inte Ã¥ngra %s... %s" -#: sequencer.c:537 +#: sequencer.c:622 #, c-format msgid "could not apply %s... %s" msgstr "kunde inte tillämpa %s... %s" -#: sequencer.c:569 +#: sequencer.c:654 msgid "empty commit set passed" msgstr "den angivna uppsättningen incheckningar är tom" -#: sequencer.c:577 +#: sequencer.c:662 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: misslyckades läsa indexet" -#: sequencer.c:582 +#: sequencer.c:667 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: misslyckades uppdatera indexet" -#: sequencer.c:640 +#: sequencer.c:725 #, c-format msgid "Cannot %s during a %s" msgstr "kan inte %s under en %s" -#: sequencer.c:662 +#: sequencer.c:747 #, c-format msgid "Could not parse line %d." msgstr "Kan inte tolka rad %d." -#: sequencer.c:667 +#: sequencer.c:752 msgid "No commits parsed." msgstr "Inga incheckningar lästes." -#: sequencer.c:680 +#: sequencer.c:765 #, c-format msgid "Could not open %s" msgstr "Kunde inte öppna %s" -#: sequencer.c:684 +#: sequencer.c:769 #, c-format msgid "Could not read %s." msgstr "kunde inte läsa %s." -#: sequencer.c:691 +#: sequencer.c:776 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Oanvändbart manus: %s" -#: sequencer.c:719 +#: sequencer.c:804 #, c-format msgid "Invalid key: %s" msgstr "Felaktig nyckel: %s" -#: sequencer.c:722 +#: sequencer.c:807 #, c-format msgid "Invalid value for %s: %s" msgstr "Felaktigt värde för %s: %s" -#: sequencer.c:734 +#: sequencer.c:819 #, c-format msgid "Malformed options sheet: %s" msgstr "Trasigt manus: %s" -#: sequencer.c:755 +#: sequencer.c:840 msgid "a cherry-pick or revert is already in progress" msgstr "en \"cherry-pick\" eller \"revert\" pÃ¥gÃ¥r redan" -#: sequencer.c:756 +#: sequencer.c:841 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "testa \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:760 +#: sequencer.c:845 #, c-format msgid "Could not create sequencer directory %s" msgstr "Kunde inte skapa \"sequencer\"-katalogen \"%s\"" -#: sequencer.c:776 sequencer.c:861 +#: sequencer.c:861 sequencer.c:946 #, c-format msgid "Error wrapping up %s." msgstr "Fel vid ombrytning av %s." -#: sequencer.c:795 sequencer.c:929 +#: sequencer.c:880 sequencer.c:1014 msgid "no cherry-pick or revert in progress" msgstr "ingen \"cherry-pick\" eller \"revert\" pÃ¥gÃ¥r" -#: sequencer.c:797 +#: sequencer.c:882 msgid "cannot resolve HEAD" msgstr "kan inte bestämma HEAD" -#: sequencer.c:799 +#: sequencer.c:884 msgid "cannot abort from a branch yet to be born" msgstr "kan inte avbryta frÃ¥n en gren som ännu inte är född" -#: sequencer.c:821 builtin/apply.c:4056 +#: sequencer.c:906 builtin/apply.c:4060 #, c-format msgid "cannot open %s: %s" msgstr "kan inte öppna %s: %s" -#: sequencer.c:824 +#: sequencer.c:909 #, c-format msgid "cannot read %s: %s" msgstr "kan inte läsa %s: %s" -#: sequencer.c:825 +#: sequencer.c:910 msgid "unexpected end of file" msgstr "oväntat filslut" -#: sequencer.c:831 +#: sequencer.c:916 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "sparad HEAD-fil frÃ¥n före \"cherry-pick\", \"%s\", är trasig" -#: sequencer.c:854 +#: sequencer.c:939 #, c-format msgid "Could not format %s." msgstr "Kunde inte formatera %s." -#: sequencer.c:1016 +#: sequencer.c:1083 +#, c-format +msgid "%s: can't cherry-pick a %s" +msgstr "%s: kan inte göra \"cherry-pick\" pÃ¥ typen \"%s\"" + +#: sequencer.c:1085 +#, c-format +msgid "%s: bad revision" +msgstr "%s: felaktig revision" + +#: sequencer.c:1119 msgid "Can't revert as initial commit" msgstr "Kan inte Ã¥ngra som första incheckning" -#: sequencer.c:1017 +#: sequencer.c:1120 msgid "Can't cherry-pick into empty head" msgstr "Kan inte göra \"cherry-pick\" i ett tomt huvud" -#: sha1_name.c:1044 +#: sha1_name.c:1036 msgid "HEAD does not point to a branch" msgstr "HEAD pekar inte pÃ¥ en gren" -#: sha1_name.c:1047 +#: sha1_name.c:1039 #, c-format msgid "No such branch: '%s'" msgstr "Okänd gren: \"%s\"" -#: sha1_name.c:1049 +#: sha1_name.c:1041 #, c-format msgid "No upstream configured for branch '%s'" msgstr "Ingen standarduppström angiven för grenen \"%s\"" -#: sha1_name.c:1052 +#: sha1_name.c:1044 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "Uppströmsgrenen \"%s\" är inte lagrad som en fjärrspÃ¥rande gren" @@ -1162,113 +1301,113 @@ msgstr "ändrat innehÃ¥ll, " msgid "untracked content, " msgstr "ospÃ¥rat innehÃ¥ll, " -#: wt-status.c:303 +#: wt-status.c:306 #, c-format msgid "new file: %s" msgstr "ny fil: %s" -#: wt-status.c:306 +#: wt-status.c:309 #, c-format msgid "copied: %s -> %s" msgstr "kopierad: %s -> %s" -#: wt-status.c:309 +#: wt-status.c:312 #, c-format msgid "deleted: %s" msgstr "borttagen: %s" -#: wt-status.c:312 +#: wt-status.c:315 #, c-format msgid "modified: %s" msgstr "ändrad: %s" -#: wt-status.c:315 +#: wt-status.c:318 #, c-format msgid "renamed: %s -> %s" msgstr "namnbyte: %s -> %s" -#: wt-status.c:318 +#: wt-status.c:321 #, c-format msgid "typechange: %s" msgstr "typbyte: %s" -#: wt-status.c:321 +#: wt-status.c:324 #, c-format msgid "unknown: %s" msgstr "okänd: %s" -#: wt-status.c:324 +#: wt-status.c:327 #, c-format msgid "unmerged: %s" msgstr "osammansl.: %s" -#: wt-status.c:327 +#: wt-status.c:330 #, c-format msgid "bug: unhandled diff status %c" msgstr "programfel: diff-status %c ej hanterad" -#: wt-status.c:789 +#: wt-status.c:803 msgid "You have unmerged paths." msgstr "Du har ej sammanslagna sökvägar." -#: wt-status.c:792 wt-status.c:944 +#: wt-status.c:806 wt-status.c:958 msgid " (fix conflicts and run \"git commit\")" msgstr " (rätta konflikter och kör \"git commit\")" -#: wt-status.c:795 +#: wt-status.c:809 msgid "All conflicts fixed but you are still merging." msgstr "Alla konflikter har rättats men du är fortfarande i en sammanslagning." -#: wt-status.c:798 +#: wt-status.c:812 msgid " (use \"git commit\" to conclude merge)" msgstr " (använd \"git commit\" för att slutföra sammanslagningen)" -#: wt-status.c:808 +#: wt-status.c:822 msgid "You are in the middle of an am session." msgstr "Du är i mitten av en körning av \"git am\"." -#: wt-status.c:811 +#: wt-status.c:825 msgid "The current patch is empty." msgstr "Aktuell patch är tom." -#: wt-status.c:815 +#: wt-status.c:829 msgid " (fix conflicts and then run \"git am --resolved\")" msgstr " (rätta konflikter och kör sedan \"git am --resolved\")" -#: wt-status.c:817 +#: wt-status.c:831 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (använd \"git am --skip\" för att hoppa över patchen)" -#: wt-status.c:819 +#: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr " (använd \"git am --abort\" för att Ã¥terställa ursprungsgrenen)" -#: wt-status.c:879 wt-status.c:896 +#: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Du hÃ¥ller pÃ¥ att ombasera grenen \"%s\" ovanpÃ¥ \"%s\"." -#: wt-status.c:884 wt-status.c:901 +#: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." msgstr "Du hÃ¥ller pÃ¥ med en ombasering." -#: wt-status.c:887 +#: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (rätta konflikter och kör sedan \"git rebase --continue\")" -#: wt-status.c:889 +#: wt-status.c:903 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (använd \"git rebase --skip\" för att hoppa över patchen)" -#: wt-status.c:891 +#: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr " (använd \"git rebase --abort\" för att checka ut ursprungsgrenen)" -#: wt-status.c:904 +#: wt-status.c:918 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr " (alla konflikter rättade: kör \"git rebase --continue\")" -#: wt-status.c:908 +#: wt-status.c:922 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -1276,104 +1415,140 @@ msgstr "" "Du hÃ¥ller pÃ¥ att dela upp en incheckning medan du ombaserar grenen \"%s\" " "ovanpÃ¥ \"%s\"." -#: wt-status.c:913 +#: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." msgstr "Du hÃ¥ller pÃ¥ att dela upp en incheckning i en ombasering." -#: wt-status.c:916 +#: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr " (SÃ¥ fort din arbetskatalog är ren, kör \"git rebase --continue\")" -#: wt-status.c:920 +#: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Du hÃ¥ller pÃ¥ att redigera en incheckning medan du ombaserar grenen \"%s\" " "ovanpÃ¥ \"%s\"." -#: wt-status.c:925 +#: wt-status.c:939 msgid "You are currently editing a commit during a rebase." msgstr "Du hÃ¥ller pÃ¥ att redigera en incheckning under en ombasering." -#: wt-status.c:928 +#: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" " (använd \"git commit --amend\" för att lägga till pÃ¥ aktuell incheckning)" -#: wt-status.c:930 +#: wt-status.c:944 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr " (använd \"git rebase --continue\" när du är nöjd med dina ändringar)" -#: wt-status.c:940 +#: wt-status.c:954 msgid "You are currently cherry-picking." msgstr "Du hÃ¥ller pÃ¥ med en \"cherry-pick\"." -#: wt-status.c:947 +#: wt-status.c:961 msgid " (all conflicts fixed: run \"git commit\")" msgstr " (alla konflikter har rättats: kör \"git commit\")" -#: wt-status.c:958 +#: wt-status.c:970 +#, c-format +msgid "You are currently reverting commit %s." +msgstr "Du hÃ¥ller pÃ¥ med att Ã¥ngra incheckningen %s." + +#: wt-status.c:975 +msgid " (fix conflicts and run \"git revert --continue\")" +msgstr " (rätta konflikter och kör sedan \"git revert --continue\")" + +#: wt-status.c:978 +msgid " (all conflicts fixed: run \"git revert --continue\")" +msgstr " (alla konflikter rättade: kör \"git revert --continue\")" + +#: wt-status.c:980 +msgid " (use \"git revert --abort\" to cancel the revert operation)" +msgstr " (använd \"git revert --abort\" för att avbryta Ã¥ngrandet)" + +#: wt-status.c:991 #, c-format -msgid "You are currently bisecting branch '%s'." -msgstr "Du hÃ¥ller pÃ¥ med en \"bisect\" pÃ¥ grenen \"%s\"." +msgid "You are currently bisecting, started from branch '%s'." +msgstr "Du hÃ¥ller pÃ¥ med en \"bisect\", startad frÃ¥n grenen \"%s\"." -#: wt-status.c:962 +#: wt-status.c:995 msgid "You are currently bisecting." msgstr "Du hÃ¥ller pÃ¥ med en \"bisect\"." -#: wt-status.c:965 +#: wt-status.c:998 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr "" " (använd \"git bisect reset\" för att komma tillbaka till ursprungsgrenen)" -#: wt-status.c:1064 +#: wt-status.c:1173 msgid "On branch " msgstr "PÃ¥ grenen " -#: wt-status.c:1071 +#: wt-status.c:1184 +msgid "HEAD detached at " +msgstr "HEAD frÃ¥nkopplad vid " + +#: wt-status.c:1186 +msgid "HEAD detached from " +msgstr "HEAD frÃ¥nkopplad frÃ¥n " + +#: wt-status.c:1189 msgid "Not currently on any branch." msgstr "Inte pÃ¥ nÃ¥gon gren för närvarande." -#: wt-status.c:1083 +#: wt-status.c:1206 msgid "Initial commit" msgstr "Första incheckning" -#: wt-status.c:1097 +#: wt-status.c:1220 msgid "Untracked files" msgstr "OspÃ¥rade filer" -#: wt-status.c:1099 +#: wt-status.c:1222 msgid "Ignored files" msgstr "Ignorerade filer" +#: wt-status.c:1226 +#, c-format +msgid "" +"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" +"may speed it up, but you have to be careful not to forget to add\n" +"new files yourself (see 'git help status')." +msgstr "" +"Det tog %.2f sekunder att räkna upp ospÃ¥rade filer. \"status -uno\"\n" +"kan gÃ¥ snabbare, men du mÃ¥ste vara försiktig sÃ¥ du inte glömmer\n" +"lägga till nya filer själv (se \"git help status\")." + # %s är nästa sträng eller tom. -#: wt-status.c:1101 +#: wt-status.c:1232 #, c-format msgid "Untracked files not listed%s" msgstr "OspÃ¥rade filer visas ej%s" -#: wt-status.c:1103 +#: wt-status.c:1234 msgid " (use -u option to show untracked files)" msgstr " (använd flaggan -u för att visa ospÃ¥rade filer)" -#: wt-status.c:1109 +#: wt-status.c:1240 msgid "No changes" msgstr "Inga ändringar" -#: wt-status.c:1114 +#: wt-status.c:1245 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "" "inga ändringar att checka in (använd \"git add\" och/eller \"git commit -a" "\")\n" -#: wt-status.c:1117 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit\n" msgstr "inga ändringar att checka in\n" -#: wt-status.c:1120 +#: wt-status.c:1251 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -1382,52 +1557,52 @@ msgstr "" "inget köat för incheckning, men ospÃ¥rade filer finns (spÃ¥ra med \"git add" "\")\n" -#: wt-status.c:1123 +#: wt-status.c:1254 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "inget köat för incheckning, men ospÃ¥rade filer finns\n" -#: wt-status.c:1126 +#: wt-status.c:1257 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "inget att checka in (skapa/kopiera filer och spÃ¥ra med \"git add\")\n" -#: wt-status.c:1129 wt-status.c:1134 +#: wt-status.c:1260 wt-status.c:1265 #, c-format msgid "nothing to commit\n" msgstr "inget att checka in\n" -#: wt-status.c:1132 +#: wt-status.c:1263 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "inget att checka in (använd -u för att visa ospÃ¥rade filer)\n" -#: wt-status.c:1136 +#: wt-status.c:1267 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "inget att checka in, arbetskatalogen ren\n" -#: wt-status.c:1244 +#: wt-status.c:1375 msgid "HEAD (no branch)" msgstr "HEAD (ingen gren)" -#: wt-status.c:1250 +#: wt-status.c:1381 msgid "Initial commit on " msgstr "Första incheckning pÃ¥ " -#: wt-status.c:1265 +#: wt-status.c:1396 msgid "behind " msgstr "efter " -#: wt-status.c:1268 wt-status.c:1271 +#: wt-status.c:1399 wt-status.c:1402 msgid "ahead " msgstr "före " -#: wt-status.c:1273 +#: wt-status.c:1404 msgid ", behind " msgstr ", efter " -#: compat/precompose_utf8.c:58 builtin/clone.c:341 +#: compat/precompose_utf8.c:58 builtin/clone.c:352 #, c-format msgid "failed to unlink '%s'" msgstr "misslyckades ta bort länken \"%s\"" @@ -1436,193 +1611,226 @@ msgstr "misslyckades ta bort länken \"%s\"" msgid "git add [options] [--] <pathspec>..." msgstr "git add [flaggor] [--] <sökväg>..." -#: builtin/add.c:63 +#. +#. * To be consistent with "git add -p" and most Git +#. * commands, we should default to being tree-wide, but +#. * this is not the original behavior and can't be +#. * changed until users trained themselves not to type +#. * "git add -u" or "git add -A". For now, we warn and +#. * keep the old behavior. Later, the behavior can be changed +#. * to tree-wide, keeping the warning for a while, and +#. * eventually we can drop the warning. +#. +#: builtin/add.c:58 +#, c-format +msgid "" +"The behavior of 'git add %s (or %s)' with no path argument from a\n" +"subdirectory of the tree will change in Git 2.0 and should not be used " +"anymore.\n" +"To add content for the whole tree, run:\n" +"\n" +" git add %s :/\n" +" (or git add %s :/)\n" +"\n" +"To restrict the command to the current directory, run:\n" +"\n" +" git add %s .\n" +" (or git add %s .)\n" +"\n" +"With the current Git version, the command is restricted to the current " +"directory.\n" +msgstr "" +"Beteendet för \"git add %s (eller %s)\" utan sökvägsargument frÃ¥n en\n" +"underkatalog i ett träd kommer ändras i Git 2.0 och bör inte längre " +"användas.\n" +"För att lägga till innehÃ¥llet för hela trädet, använd:\n" +"\n" +" git add %s :/\n" +" (eller git add %s :/)\n" +"\n" +"För att begränsa kommandot till aktuell katalog, använd:\n" +"\n" +" git add %s .\n" +" (eller git add %s .)\n" +"\n" +"I nuvarande version av Git begränsas kommandot till aktuell katalog.\n" + +#: builtin/add.c:100 +#, c-format +msgid "" +"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n" +msgstr "" +"Du körde \"git add\" utan varken \"-A (--all)\" eller \"--ignore-removal\".\n" +"Beteendet kommer ändras i Git 2.0 vad gäller sökvägar du tagit bort.\n" +"Sökvägar som \"%s\", som har\n" +"tagits bort frÃ¥n din arbetskatalog ignoreras i den här versionen av Git.\n" +"\n" +"* \"git add --ignore-removal <sökväg>\", som är förvalet just nu,\n" +" ignorerar sökvägar du har tagit bort frÃ¥n arbetskatalogen.\n" +"\n" +"* \"git add --all <sökväg>\" lÃ¥ter dig även registrera borttagningarna.\n" +"\n" +"Kör \"git status\" för att kontrollera sökvägarna du tagit bort frÃ¥n\n" +"arbetskatalogen.\n" + +#: builtin/add.c:144 #, c-format msgid "unexpected diff status %c" msgstr "diff-status %c förväntades inte" -#: builtin/add.c:68 builtin/commit.c:231 +#: builtin/add.c:149 builtin/commit.c:233 msgid "updating files failed" msgstr "misslyckades uppdatera filer" -#: builtin/add.c:78 +#: builtin/add.c:163 #, c-format msgid "remove '%s'\n" msgstr "ta bort \"%s\"\n" -#: builtin/add.c:148 +#: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "OspÃ¥rade ändringar efter att ha uppdaterat indexet:" -#: builtin/add.c:151 builtin/add.c:460 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "sökvägsangivelsen \"%s\" motsvarade inte nÃ¥gra filer" -#: builtin/add.c:234 +#: builtin/add.c:339 msgid "Could not read the index" msgstr "Kunde inte läsa indexet" -#: builtin/add.c:244 +#: builtin/add.c:349 #, c-format msgid "Could not open '%s' for writing." msgstr "Kunde inte öppna \"%s\" för skrivning" -#: builtin/add.c:248 +#: builtin/add.c:353 msgid "Could not write patch" msgstr "Kunde inte skriva patch" -#: builtin/add.c:253 +#: builtin/add.c:358 #, c-format msgid "Could not stat '%s'" msgstr "Kunde inte ta status pÃ¥ \"%s\"" -#: builtin/add.c:255 +#: builtin/add.c:360 msgid "Empty patch. Aborted." msgstr "Tom patch. Avbryter." -#: builtin/add.c:261 +#: builtin/add.c:366 #, c-format msgid "Could not apply '%s'" msgstr "Kunde inte tillämpa \"%s\"" -#: builtin/add.c:271 +#: builtin/add.c:376 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "Följande sökvägar ignoreras av en av dina .gitignore-filer:\n" -#: builtin/add.c:277 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 #: builtin/rm.c:206 msgid "dry run" msgstr "testkörning" -#: builtin/add.c:278 builtin/apply.c:4405 builtin/check-ignore.c:19 -#: builtin/commit.c:1150 builtin/count-objects.c:82 builtin/fsck.c:613 -#: builtin/log.c:1522 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 +#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "var pratsam" -#: builtin/add.c:280 +#: builtin/add.c:396 msgid "interactive picking" msgstr "plocka interaktivt" -#: builtin/add.c:281 builtin/checkout.c:1031 builtin/reset.c:258 +#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 msgid "select hunks interactively" msgstr "välj stycken interaktivt" -#: builtin/add.c:282 +#: builtin/add.c:398 msgid "edit current diff and apply" msgstr "redigera aktuell diff och applicera" -#: builtin/add.c:283 +#: builtin/add.c:399 msgid "allow adding otherwise ignored files" msgstr "tillÃ¥t lägga till annars ignorerade filer" -#: builtin/add.c:284 +#: builtin/add.c:400 msgid "update tracked files" msgstr "uppdatera spÃ¥rade filer" -#: builtin/add.c:285 +#: builtin/add.c:401 msgid "record only the fact that the path will be added later" msgstr "registrera endast att sökvägen kommer läggas till senare" -#: builtin/add.c:286 +#: builtin/add.c:402 msgid "add changes from all tracked and untracked files" msgstr "lägg till ändringar frÃ¥n alla spÃ¥rade och ospÃ¥rade filer" -#: builtin/add.c:287 +#. takes no arguments +#: builtin/add.c:405 +msgid "ignore paths removed in the working tree (same as --no-all)" +msgstr "ignorera sökvägar borttagna i arbetskatalogen (samma som --no-all)" + +#: builtin/add.c:407 msgid "don't add, only refresh the index" msgstr "lägg inte till, uppdatera endast indexet" -#: builtin/add.c:288 +#: builtin/add.c:408 msgid "just skip files which cannot be added because of errors" msgstr "hoppa bara över filer som inte kan läggas till pÃ¥ grund av fel" -#: builtin/add.c:289 +#: builtin/add.c:409 msgid "check if - even missing - files are ignored in dry run" msgstr "se om - även saknade - filer ignoreras i testkörning" -#: builtin/add.c:311 +#: builtin/add.c:431 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Använd -f om du verkligen vill lägga till dem.\n" -#: builtin/add.c:312 +#: builtin/add.c:432 msgid "no files added" msgstr "inga filer har lagts till" -#: builtin/add.c:318 +#: builtin/add.c:438 msgid "adding files failed" msgstr "misslyckades lägga till filer" -#. -#. * To be consistent with "git add -p" and most Git -#. * commands, we should default to being tree-wide, but -#. * this is not the original behavior and can't be -#. * changed until users trained themselves not to type -#. * "git add -u" or "git add -A". For now, we warn and -#. * keep the old behavior. Later, this warning can be -#. * turned into a die(...), and eventually we may -#. * reallow the command with a new behavior. -#. -#: builtin/add.c:335 -#, c-format -msgid "" -"The behavior of 'git add %s (or %s)' with no path argument from a\n" -"subdirectory of the tree will change in Git 2.0 and should not be used " -"anymore.\n" -"To add content for the whole tree, run:\n" -"\n" -" git add %s :/\n" -" (or git add %s :/)\n" -"\n" -"To restrict the command to the current directory, run:\n" -"\n" -" git add %s .\n" -" (or git add %s .)\n" -"\n" -"With the current Git version, the command is restricted to the current " -"directory." -msgstr "" -"Beteendet för \"git add %s (eller %s)\" utan sökvägsargument frÃ¥n en\n" -"underkatalog i ett träd kommer ändras i Git 2.0 och bör inte längre " -"användas.\n" -"För att lägga till innehÃ¥llet för hela trädet, använd:\n" -"\n" -" git add %s :/\n" -" (eller git add %s :/)\n" -"\n" -"För att begränsa kommandot till aktuell katalog, använd:\n" -"\n" -" git add %s .\n" -" (eller git add %s .)\n" -"\n" -"I nuvarande version av Git begränsas kommandot till aktuell katalog." - -#: builtin/add.c:381 +#: builtin/add.c:477 msgid "-A and -u are mutually incompatible" msgstr "-A och -u är ömsesidigt inkompatibla" -#: builtin/add.c:383 +#: builtin/add.c:495 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "Flaggan --ignore-missing kan endast användas tillsammans med --dry-run" -#: builtin/add.c:414 +#: builtin/add.c:525 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Inget angivet, inget tillagt.\n" -#: builtin/add.c:415 +#: builtin/add.c:526 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Kanske menade du att skriva \"git add .\"?\n" -#: builtin/add.c:421 builtin/check-ignore.c:67 builtin/clean.c:204 -#: builtin/commit.c:291 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 +#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 msgid "index file corrupt" msgstr "indexfilen trasig" -#: builtin/add.c:481 builtin/apply.c:4501 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "Kunde inte skriva ny indexfil" @@ -1755,24 +1963,24 @@ msgstr "kunde inte läsa symboliska länken %s" msgid "unable to open or read %s" msgstr "kunde inte öppna eller läsa %s" -#: builtin/apply.c:2684 +#: builtin/apply.c:2688 #, c-format msgid "invalid start of line: '%c'" msgstr "felaktig inledning pÃ¥ rad: \"%c\"" -#: builtin/apply.c:2802 +#: builtin/apply.c:2806 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." msgstr[0] "Stycke %d lyckades pÃ¥ %d (offset %d rad)." msgstr[1] "Stycke %d lyckades pÃ¥ %d (offset %d rader)." -#: builtin/apply.c:2814 +#: builtin/apply.c:2818 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "Sammanhang reducerat till (%ld/%ld) för att tillämpa fragment vid %d" -#: builtin/apply.c:2820 +#: builtin/apply.c:2824 #, c-format msgid "" "while searching for:\n" @@ -1781,318 +1989,318 @@ msgstr "" "vid sökning efter:\n" "%.*s" -#: builtin/apply.c:2839 +#: builtin/apply.c:2843 #, c-format msgid "missing binary patch data for '%s'" msgstr "saknar binära patchdata för \"%s\"" -#: builtin/apply.c:2942 +#: builtin/apply.c:2946 #, c-format msgid "binary patch does not apply to '%s'" msgstr "binärpatchen kan inte tillämpas pÃ¥ \"%s\"" -#: builtin/apply.c:2948 +#: builtin/apply.c:2952 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "binärpatchen pÃ¥ \"%s\" ger felaktigt resultat (förväntade %s, fick %s)" -#: builtin/apply.c:2969 +#: builtin/apply.c:2973 #, c-format msgid "patch failed: %s:%ld" msgstr "patch misslyckades: %s:%ld" -#: builtin/apply.c:3091 +#: builtin/apply.c:3095 #, c-format msgid "cannot checkout %s" msgstr "kan inte checka ut %s" -#: builtin/apply.c:3136 builtin/apply.c:3145 builtin/apply.c:3189 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 #, c-format msgid "read of %s failed" msgstr "misslyckades läsa %s" -#: builtin/apply.c:3169 builtin/apply.c:3391 +#: builtin/apply.c:3173 builtin/apply.c:3395 #, c-format msgid "path %s has been renamed/deleted" msgstr "sökvägen %s har ändrat namn/tagits bort" -#: builtin/apply.c:3250 builtin/apply.c:3405 +#: builtin/apply.c:3254 builtin/apply.c:3409 #, c-format msgid "%s: does not exist in index" msgstr "%s: finns inte i indexet" -#: builtin/apply.c:3254 builtin/apply.c:3397 builtin/apply.c:3419 +#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3259 builtin/apply.c:3413 +#: builtin/apply.c:3263 builtin/apply.c:3417 #, c-format msgid "%s: does not match index" msgstr "%s: motsvarar inte indexet" -#: builtin/apply.c:3361 +#: builtin/apply.c:3365 msgid "removal patch leaves file contents" msgstr "patch för borttagning lämnar kvar filinnehÃ¥ll" -#: builtin/apply.c:3430 +#: builtin/apply.c:3434 #, c-format msgid "%s: wrong type" msgstr "%s: fel typ" -#: builtin/apply.c:3432 +#: builtin/apply.c:3436 #, c-format msgid "%s has type %o, expected %o" msgstr "%s har typen %o, förväntade %o" -#: builtin/apply.c:3533 +#: builtin/apply.c:3537 #, c-format msgid "%s: already exists in index" msgstr "%s: finns redan i indexet" -#: builtin/apply.c:3536 +#: builtin/apply.c:3540 #, c-format msgid "%s: already exists in working directory" msgstr "%s: finns redan i arbetskatalogen" -#: builtin/apply.c:3556 +#: builtin/apply.c:3560 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o)" -#: builtin/apply.c:3561 +#: builtin/apply.c:3565 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "nytt läge (%o) för %s motsvarar inte gammalt läge (%o) för %s" -#: builtin/apply.c:3569 +#: builtin/apply.c:3573 #, c-format msgid "%s: patch does not apply" msgstr "%s: patchen kan inte tillämpas" -#: builtin/apply.c:3582 +#: builtin/apply.c:3586 #, c-format msgid "Checking patch %s..." msgstr "Kontrollerar patchen %s..." -#: builtin/apply.c:3675 builtin/checkout.c:215 builtin/reset.c:124 +#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "make_cache_entry misslyckades för sökvägen \"%s\"" -#: builtin/apply.c:3818 +#: builtin/apply.c:3822 #, c-format msgid "unable to remove %s from index" msgstr "kan inte ta bort %s frÃ¥n indexet" -#: builtin/apply.c:3846 +#: builtin/apply.c:3850 #, c-format msgid "corrupt patch for subproject %s" msgstr "trasig patch för underprojektet %s" -#: builtin/apply.c:3850 +#: builtin/apply.c:3854 #, c-format msgid "unable to stat newly created file '%s'" msgstr "kan inte ta status pÃ¥ nyligen skapade filen \"%s\"" -#: builtin/apply.c:3855 +#: builtin/apply.c:3859 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "kan inte skapa säkerhetsminne för nyligen skapade filen %s" -#: builtin/apply.c:3858 builtin/apply.c:3966 +#: builtin/apply.c:3862 builtin/apply.c:3970 #, c-format msgid "unable to add cache entry for %s" msgstr "kan inte lägga till cachepost för %s" -#: builtin/apply.c:3891 +#: builtin/apply.c:3895 #, c-format msgid "closing file '%s'" msgstr "stänger filen \"%s\"" -#: builtin/apply.c:3940 +#: builtin/apply.c:3944 #, c-format msgid "unable to write file '%s' mode %o" msgstr "kan inte skriva filen \"%s\" läge %o" -#: builtin/apply.c:4027 +#: builtin/apply.c:4031 #, c-format msgid "Applied patch %s cleanly." msgstr "Tillämpade patchen %s rent." -#: builtin/apply.c:4035 +#: builtin/apply.c:4039 msgid "internal error" msgstr "internt fel" #. Say this even without --verbose -#: builtin/apply.c:4038 +#: builtin/apply.c:4042 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "Tillämpade patchen %%s med %d refuserad..." msgstr[1] "Tillämpade patchen %%s med %d refuserade..." -#: builtin/apply.c:4048 +#: builtin/apply.c:4052 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "trunkerar .rej-filnamnet till %.*s.rej" -#: builtin/apply.c:4069 +#: builtin/apply.c:4073 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Stycke %d tillämpades rent." -#: builtin/apply.c:4072 +#: builtin/apply.c:4076 #, c-format msgid "Rejected hunk #%d." msgstr "Refuserar stycke %d." -#: builtin/apply.c:4222 +#: builtin/apply.c:4226 msgid "unrecognized input" msgstr "indata känns inte igen" -#: builtin/apply.c:4233 +#: builtin/apply.c:4237 msgid "unable to read index file" msgstr "kan inte läsa indexfilen" -#: builtin/apply.c:4352 builtin/apply.c:4355 builtin/clone.c:91 +#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 #: builtin/fetch.c:63 msgid "path" msgstr "sökväg" -#: builtin/apply.c:4353 +#: builtin/apply.c:4357 msgid "don't apply changes matching the given path" msgstr "tillämpa inte ändringar som motsvarar given sökväg" -#: builtin/apply.c:4356 +#: builtin/apply.c:4360 msgid "apply changes matching the given path" msgstr "tillämpa ändringar som motsvarar given sökväg" -#: builtin/apply.c:4358 +#: builtin/apply.c:4362 msgid "num" msgstr "antal" -#: builtin/apply.c:4359 +#: builtin/apply.c:4363 msgid "remove <num> leading slashes from traditional diff paths" msgstr "ta bort <antal> inledande snedstreck frÃ¥n traditionella diff-sökvägar" -#: builtin/apply.c:4362 +#: builtin/apply.c:4366 msgid "ignore additions made by the patch" msgstr "ignorera tillägg gjorda av patchen" -#: builtin/apply.c:4364 +#: builtin/apply.c:4368 msgid "instead of applying the patch, output diffstat for the input" msgstr "istället för att tillämpa patchen, skriv ut diffstat för indata" -#: builtin/apply.c:4368 +#: builtin/apply.c:4372 msgid "show number of added and deleted lines in decimal notation" msgstr "visa antal tillagda och borttagna rader decimalt" -#: builtin/apply.c:4370 +#: builtin/apply.c:4374 msgid "instead of applying the patch, output a summary for the input" msgstr "istället för att tillämpa patchen, skriv ut en summering av indata" -#: builtin/apply.c:4372 +#: builtin/apply.c:4376 msgid "instead of applying the patch, see if the patch is applicable" msgstr "istället för att tillämpa patchen, se om patchen kan tillämpas" -#: builtin/apply.c:4374 +#: builtin/apply.c:4378 msgid "make sure the patch is applicable to the current index" msgstr "se till att patchen kan tillämpas pÃ¥ aktuellt index" -#: builtin/apply.c:4376 +#: builtin/apply.c:4380 msgid "apply a patch without touching the working tree" msgstr "tillämpa en patch utan att röra arbetskatalogen" -#: builtin/apply.c:4378 +#: builtin/apply.c:4382 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "tillämpa ocksÃ¥ patchen (använd med --stat/--summary/--check)" -#: builtin/apply.c:4380 +#: builtin/apply.c:4384 msgid "attempt three-way merge if a patch does not apply" msgstr "försök en trevägssammanslagning om patchen inte kan tillämpas" -#: builtin/apply.c:4382 +#: builtin/apply.c:4386 msgid "build a temporary index based on embedded index information" msgstr "bygg ett temporärt index baserat pÃ¥ inbyggd indexinformation" -#: builtin/apply.c:4384 builtin/checkout-index.c:197 builtin/ls-files.c:463 +#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 msgid "paths are separated with NUL character" msgstr "sökvägar avdelas med NUL-tecken" -#: builtin/apply.c:4387 +#: builtin/apply.c:4391 msgid "ensure at least <n> lines of context match" msgstr "se till att Ã¥tminstone <n> rader sammanhang är lika" -#: builtin/apply.c:4388 +#: builtin/apply.c:4392 msgid "action" msgstr "Ã¥tgärd" -#: builtin/apply.c:4389 +#: builtin/apply.c:4393 msgid "detect new or modified lines that have whitespace errors" msgstr "detektera nya eller ändrade rader som har fel i blanktecken" -#: builtin/apply.c:4392 builtin/apply.c:4395 +#: builtin/apply.c:4396 builtin/apply.c:4399 msgid "ignore changes in whitespace when finding context" msgstr "ignorera ändringar i blanktecken för sammanhang" -#: builtin/apply.c:4398 +#: builtin/apply.c:4402 msgid "apply the patch in reverse" msgstr "tillämpa patchen baklänges" -#: builtin/apply.c:4400 +#: builtin/apply.c:4404 msgid "don't expect at least one line of context" msgstr "förvänta inte minst en rad sammanhang" -#: builtin/apply.c:4402 +#: builtin/apply.c:4406 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "lämna refuserade stycken i motsvarande *.rej-filer" -#: builtin/apply.c:4404 +#: builtin/apply.c:4408 msgid "allow overlapping hunks" msgstr "tillÃ¥t överlappande stycken" -#: builtin/apply.c:4407 +#: builtin/apply.c:4411 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "tolerera felaktigt detekterade saknade nyradstecken vid filslut" -#: builtin/apply.c:4410 +#: builtin/apply.c:4414 msgid "do not trust the line counts in the hunk headers" msgstr "lite inte pÃ¥ antalet linjer i styckehuvuden" -#: builtin/apply.c:4412 +#: builtin/apply.c:4416 msgid "root" msgstr "rot" -#: builtin/apply.c:4413 +#: builtin/apply.c:4417 msgid "prepend <root> to all filenames" msgstr "lägg till <rot> i alla filnamn" -#: builtin/apply.c:4435 +#: builtin/apply.c:4439 msgid "--3way outside a repository" msgstr "--3way utanför arkiv" -#: builtin/apply.c:4443 +#: builtin/apply.c:4447 msgid "--index outside a repository" msgstr "--index utanför arkiv" -#: builtin/apply.c:4446 +#: builtin/apply.c:4450 msgid "--cached outside a repository" msgstr "--cached utanför arkiv" -#: builtin/apply.c:4462 +#: builtin/apply.c:4466 #, c-format msgid "can't open patch '%s'" msgstr "kan inte öppna patchen \"%s\"" -#: builtin/apply.c:4476 +#: builtin/apply.c:4480 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "undertryckte %d fel i blanksteg" msgstr[1] "undertryckte %d fel i blanksteg" -#: builtin/apply.c:4482 builtin/apply.c:4492 +#: builtin/apply.c:4486 builtin/apply.c:4496 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -2116,21 +2324,21 @@ msgstr "git archive: Fjärr utan URL" msgid "git archive: expected ACK/NAK, got EOF" msgstr "git archive: förväntade ACK/NAK, fick EOF" -#: builtin/archive.c:63 +#: builtin/archive.c:61 #, c-format msgid "git archive: NACK %s" msgstr "git archive: NACK %s" -#: builtin/archive.c:65 +#: builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "fjärrfel: %s" -#: builtin/archive.c:66 +#: builtin/archive.c:64 msgid "git archive: protocol error" msgstr "git archive: protokollfel" -#: builtin/archive.c:71 +#: builtin/archive.c:68 msgid "git archive: expected a flush" msgstr "git archive: förväntade en tömning (flush)" @@ -2150,119 +2358,119 @@ msgstr "uppdatera BISECT_HEAD istället för att checka ut aktuell incheckning" msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "git blame [flaggor] [rev-flaggor] [rev] [--] fil" -#: builtin/blame.c:30 builtin/shortlog.c:15 +#: builtin/blame.c:30 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-flaggor] dokumenteras i git-rev-list(1)" -#: builtin/blame.c:2350 +#: builtin/blame.c:2355 msgid "Show blame entries as we find them, incrementally" msgstr "Visa klandringsposter när vi hittar dem, interaktivt" -#: builtin/blame.c:2351 +#: builtin/blame.c:2356 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "Visa blank SHA-1 för gränsincheckningar (Standard: av)" -#: builtin/blame.c:2352 +#: builtin/blame.c:2357 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "Behandla inte rotincheckningar som gränser (Standard: av)" -#: builtin/blame.c:2353 +#: builtin/blame.c:2358 msgid "Show work cost statistics" msgstr "Visa statistik över arbetskostnad" -#: builtin/blame.c:2354 +#: builtin/blame.c:2359 msgid "Show output score for blame entries" msgstr "Visa utdatapoäng för klandringsposter" -#: builtin/blame.c:2355 +#: builtin/blame.c:2360 msgid "Show original filename (Default: auto)" msgstr "Visa originalfilnamn (Standard: auto)" -#: builtin/blame.c:2356 +#: builtin/blame.c:2361 msgid "Show original linenumber (Default: off)" msgstr "Visa ursprungligt radnummer (Standard: av)" -#: builtin/blame.c:2357 +#: builtin/blame.c:2362 msgid "Show in a format designed for machine consumption" msgstr "Visa i ett format avsett för maskinkonsumtion" -#: builtin/blame.c:2358 +#: builtin/blame.c:2363 msgid "Show porcelain format with per-line commit information" msgstr "Visa porslinsformat med per-rad-incheckningsinformation" -#: builtin/blame.c:2359 +#: builtin/blame.c:2364 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "Använd samma utdataläge som git-annotate (Standard: av)" -#: builtin/blame.c:2360 +#: builtin/blame.c:2365 msgid "Show raw timestamp (Default: off)" msgstr "Visa rÃ¥ tidsstämpel (Standard: av)" -#: builtin/blame.c:2361 +#: builtin/blame.c:2366 msgid "Show long commit SHA1 (Default: off)" msgstr "Visa lÃ¥ng inchecknings-SHA1 (Standard: av)" -#: builtin/blame.c:2362 +#: builtin/blame.c:2367 msgid "Suppress author name and timestamp (Default: off)" msgstr "Undertryck författarnamn och tidsstämpel (Standard: av)" -#: builtin/blame.c:2363 +#: builtin/blame.c:2368 msgid "Show author email instead of name (Default: off)" msgstr "Visa författarens e-post istället för namn (Standard: av)" -#: builtin/blame.c:2364 +#: builtin/blame.c:2369 msgid "Ignore whitespace differences" msgstr "Ignorera ändringar i blanksteg" -#: builtin/blame.c:2365 +#: builtin/blame.c:2370 msgid "Spend extra cycles to find better match" msgstr "Slösa extra cykler med att hitta bättre träff" -#: builtin/blame.c:2366 +#: builtin/blame.c:2371 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "Använd revisioner frÃ¥n <fil> istället för att anropa git-rev-list" -#: builtin/blame.c:2367 +#: builtin/blame.c:2372 msgid "Use <file>'s contents as the final image" msgstr "Använd <fil>s innehÃ¥ll som slutgiltig bild" -#: builtin/blame.c:2368 builtin/blame.c:2369 +#: builtin/blame.c:2373 builtin/blame.c:2374 msgid "score" msgstr "poäng" -#: builtin/blame.c:2368 +#: builtin/blame.c:2373 msgid "Find line copies within and across files" msgstr "Hitta kopierade rader inuti och mellan filer" -#: builtin/blame.c:2369 +#: builtin/blame.c:2374 msgid "Find line movements within and across files" msgstr "Hitta flyttade rader inuti och mellan filer" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "Process only line range n,m, counting from 1" msgstr "Behandla endast radintervallet n,m, med början pÃ¥ 1" -#: builtin/branch.c:23 +#: builtin/branch.c:24 msgid "git branch [options] [-r | -a] [--merged | --no-merged]" msgstr "git branch [flaggor] [-r | -a] [--merged | --no-merged]" -#: builtin/branch.c:24 +#: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" msgstr "git branch [flaggor] [-l] [-f] <grennamn> [<startpunkt>]" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) <branchname>..." msgstr "git branch [flaggor] [-r] (-d | -D) <grennamn>..." -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" msgstr "git branch [flaggor] (-m | -M) [<gammal_gren>] <ny_gren>" -#: builtin/branch.c:145 +#: builtin/branch.c:150 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -2271,7 +2479,7 @@ msgstr "" "tar bort grenen \"%s\" som har slagits ihop med\n" " \"%s\", men ännu inte slagits ihop med HEAD." -#: builtin/branch.c:149 +#: builtin/branch.c:154 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -2280,12 +2488,12 @@ msgstr "" "tar inte bort grenen \"%s\" som inte har slagits ihop med\n" " \"%s\", trots att den har slagits ihop med HEAD." -#: builtin/branch.c:163 +#: builtin/branch.c:168 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för \"%s\"" -#: builtin/branch.c:167 +#: builtin/branch.c:172 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -2294,288 +2502,332 @@ msgstr "" "Grenen \"%s\" har inte slagits samman i sin helhet.\n" "Om du är säker pÃ¥ att du vill ta bort den, kör \"git branch -D %s\"." -#: builtin/branch.c:180 +#: builtin/branch.c:185 msgid "Update of config-file failed" msgstr "Misslyckades uppdatera konfigurationsfil" -#: builtin/branch.c:208 +#: builtin/branch.c:213 msgid "cannot use -a with -d" msgstr "kan inte ange -a med -d" -#: builtin/branch.c:214 +#: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" msgstr "Kunde inte slÃ¥ upp incheckningsobjekt för HEAD" -#: builtin/branch.c:222 +#: builtin/branch.c:227 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "Kan inte ta bort grenen \"%s\" som du befinner dig pÃ¥ för närvarande." -#: builtin/branch.c:235 +#: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." msgstr "fjärrgrenen \"%s\" hittades inte." -#: builtin/branch.c:236 +#: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." msgstr "grenen \"%s\" hittades inte." -#: builtin/branch.c:250 +#: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" msgstr "Fel vid borttagning av fjärrgrenen \"%s\"" -#: builtin/branch.c:251 +#: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" msgstr "Fel vid borttagning av grenen \"%s\"" -#: builtin/branch.c:258 +#: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Tog bort fjärrgrenen %s (var %s).\n" -#: builtin/branch.c:259 +#: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "Tog bort grenen %s (var %s).\n" -#: builtin/branch.c:361 +#: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" msgstr "grenen \"%s\" pekar inte pÃ¥ en incheckning" -#: builtin/branch.c:433 +#: builtin/branch.c:453 #, c-format msgid "[%s: behind %d]" msgstr "[%s: bakom %d] " -#: builtin/branch.c:435 +#: builtin/branch.c:455 #, c-format msgid "[behind %d]" msgstr "[bakom %d] " -#: builtin/branch.c:439 +#: builtin/branch.c:459 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: före %d] " -#: builtin/branch.c:441 +#: builtin/branch.c:461 #, c-format msgid "[ahead %d]" msgstr "[före %d] " -#: builtin/branch.c:444 +#: builtin/branch.c:464 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: före %d, bakom %d] " -#: builtin/branch.c:447 +#: builtin/branch.c:467 #, c-format msgid "[ahead %d, behind %d]" msgstr "[före %d, bakom %d] " -#: builtin/branch.c:469 +#: builtin/branch.c:490 msgid " **** invalid ref ****" msgstr " **** ogiltig ref ****" -#: builtin/branch.c:560 +#: builtin/branch.c:582 +#, c-format +msgid "(no branch, rebasing %s)" +msgstr "(ingen gren, ombaserar %s)" + +#: builtin/branch.c:585 +#, c-format +msgid "(no branch, bisect started on %s)" +msgstr "(ingen gren, \"bisect\" startad pÃ¥ %s)" + +#: builtin/branch.c:588 +#, c-format +msgid "(detached from %s)" +msgstr "(frÃ¥nkopplad frÃ¥n %s)" + +#: builtin/branch.c:591 msgid "(no branch)" msgstr "(ingen gren)" -#: builtin/branch.c:593 +#: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" msgstr "objektet \"%s\" pekar pÃ¥ en incheckning" -#: builtin/branch.c:625 +#: builtin/branch.c:669 msgid "some refs could not be read" msgstr "vissa referenser kunde inte läsas" -#: builtin/branch.c:638 +#: builtin/branch.c:682 msgid "cannot rename the current branch while not on any." msgstr "" "kunde inte byta namn pÃ¥ aktuell gren när du inte befinner dig pÃ¥ nÃ¥gon." -#: builtin/branch.c:648 +#: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" msgstr "Felaktigt namn pÃ¥ gren: \"%s\"" -#: builtin/branch.c:663 +#: builtin/branch.c:707 msgid "Branch rename failed" msgstr "Misslyckades byta namn pÃ¥ gren" -#: builtin/branch.c:667 +#: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "Bytte bort namn pÃ¥ en felaktigt namngiven gren \"%s\"" -#: builtin/branch.c:671 +#: builtin/branch.c:715 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "Grenen namnbytt till %s, men HEAD har inte uppdaterats!" -#: builtin/branch.c:678 +#: builtin/branch.c:722 msgid "Branch is renamed, but update of config-file failed" msgstr "Grenen namnbytt, men misslyckades uppdatera konfigurationsfilen" -#: builtin/branch.c:693 +#: builtin/branch.c:737 #, c-format msgid "malformed object name %s" msgstr "felformat objektnamn %s" -#: builtin/branch.c:717 +#: builtin/branch.c:761 #, c-format msgid "could not write branch description template: %s" msgstr "kunde inte skriva grenbeskrivningsmall: %s" -#: builtin/branch.c:747 +#: builtin/branch.c:791 msgid "Generic options" msgstr "Allmänna flaggor" -#: builtin/branch.c:749 +#: builtin/branch.c:793 msgid "show hash and subject, give twice for upstream branch" msgstr "visa hash och ärenderad, ange tvÃ¥ gÃ¥nger för uppströmsgren" -#: builtin/branch.c:750 +#: builtin/branch.c:794 msgid "suppress informational messages" msgstr "undertryck informationsmeddelanden" -#: builtin/branch.c:751 +#: builtin/branch.c:795 msgid "set up tracking mode (see git-pull(1))" msgstr "ställ in spÃ¥rningsläge (se git-pull(1))" -#: builtin/branch.c:753 +#: builtin/branch.c:797 msgid "change upstream info" msgstr "ändra uppströmsinformation" -#: builtin/branch.c:757 +#: builtin/branch.c:801 msgid "use colored output" msgstr "använd färgad utdata" -#: builtin/branch.c:758 +#: builtin/branch.c:802 msgid "act on remote-tracking branches" msgstr "arbeta pÃ¥ fjärrspÃ¥rande grenar" -#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 -#: builtin/branch.c:794 builtin/commit.c:1366 builtin/commit.c:1367 -#: builtin/commit.c:1368 builtin/commit.c:1369 builtin/tag.c:468 +#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 +#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 +#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 msgid "commit" msgstr "incheckning" -#: builtin/branch.c:762 builtin/branch.c:768 +#: builtin/branch.c:806 builtin/branch.c:812 msgid "print only branches that contain the commit" msgstr "visa endast grenar som innehÃ¥ller incheckningen" -#: builtin/branch.c:774 +#: builtin/branch.c:818 msgid "Specific git-branch actions:" msgstr "Specifika git-branch-Ã¥tgärder:" -#: builtin/branch.c:775 +#: builtin/branch.c:819 msgid "list both remote-tracking and local branches" msgstr "visa bÃ¥de fjärrspÃ¥rande och lokala grenar" -#: builtin/branch.c:777 +#: builtin/branch.c:821 msgid "delete fully merged branch" msgstr "ta bort helt sammanslagen gren" -#: builtin/branch.c:778 +#: builtin/branch.c:822 msgid "delete branch (even if not merged)" msgstr "ta bort gren (även om inte helt sammanslagen)" -#: builtin/branch.c:779 +#: builtin/branch.c:823 msgid "move/rename a branch and its reflog" msgstr "flytta/ta bort en gren och dess reflogg" -#: builtin/branch.c:780 +#: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "flytta/ta bort en gren, även om mÃ¥let finns" -#: builtin/branch.c:781 +#: builtin/branch.c:825 msgid "list branch names" msgstr "lista namn pÃ¥ grenar" -#: builtin/branch.c:782 +#: builtin/branch.c:826 msgid "create the branch's reflog" msgstr "skapa grenens reflogg" -#: builtin/branch.c:784 +#: builtin/branch.c:828 msgid "edit the description for the branch" msgstr "redigera beskrivning för grenen" -#: builtin/branch.c:785 +#: builtin/branch.c:829 msgid "force creation (when already exists)" msgstr "tvinga skapande (när den redan finns)" -#: builtin/branch.c:788 +#: builtin/branch.c:832 msgid "print only not merged branches" msgstr "visa endast ej sammanslagna grenar" -#: builtin/branch.c:794 +#: builtin/branch.c:838 msgid "print only merged branches" msgstr "visa endast sammanslagna grenar" -#: builtin/branch.c:798 +#: builtin/branch.c:842 msgid "list branches in columns" msgstr "visa grenar i spalter" -#: builtin/branch.c:811 +#: builtin/branch.c:855 msgid "Failed to resolve HEAD as a valid ref." msgstr "Misslyckades slÃ¥ upp HEAD som giltig referens" -#: builtin/branch.c:816 builtin/clone.c:561 +#: builtin/branch.c:860 builtin/clone.c:619 msgid "HEAD not found below refs/heads!" msgstr "HEAD hittades inte under refs/heads!" -#: builtin/branch.c:839 +#: builtin/branch.c:883 msgid "--column and --verbose are incompatible" msgstr "--column och --verbose är inkompatibla" -#: builtin/branch.c:845 +#: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" msgstr "grennamn krävs" -#: builtin/branch.c:860 +#: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" msgstr "Kan inte beskriva frÃ¥nkopplad HEAD" -#: builtin/branch.c:865 +#: builtin/branch.c:909 msgid "cannot edit description of more than one branch" msgstr "kan inte redigera beskrivning för mer än en gren" -#: builtin/branch.c:872 +#: builtin/branch.c:916 #, c-format msgid "No commit on branch '%s' yet." msgstr "Inga incheckningar pÃ¥ grenen \"%s\" ännu" -#: builtin/branch.c:875 +#: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." msgstr "Ingen gren vid namnet \"%s\"." -#: builtin/branch.c:888 +#: builtin/branch.c:934 msgid "too many branches for a rename operation" msgstr "för mÃ¥nga grenar för namnbyte" -#: builtin/branch.c:893 +#: builtin/branch.c:939 +msgid "too many branches to set new upstream" +msgstr "för mÃ¥nga grenar för att byta uppström" + +#: builtin/branch.c:943 +#, c-format +msgid "" +"could not set upstream of HEAD to %s when it does not point to any branch." +msgstr "" +"kunde inte sätta uppström för HEAD till %s när det inte pekar mot nÃ¥gon gren." + +#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 +#, c-format +msgid "no such branch '%s'" +msgstr "okänd gren \"%s\"" + +#: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" msgstr "grenen \"%s\" finns inte" -#: builtin/branch.c:905 +#: builtin/branch.c:962 +msgid "too many branches to unset upstream" +msgstr "för mÃ¥nga grenar för att ta bort uppström" + +#: builtin/branch.c:966 +msgid "could not unset upstream of HEAD when it does not point to any branch." +msgstr "" +"kunde inte ta bort uppström för HEAD när det inte pekar mot nÃ¥gon gren." + +#: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Grenen \"%s\" har ingen uppströmsinformation" -#: builtin/branch.c:920 +#: builtin/branch.c:987 +msgid "it does not make sense to create 'HEAD' manually" +msgstr "kan inte skapa \"HEAD\" manuellt" + +#: builtin/branch.c:993 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "" "flaggorna -a och -r pÃ¥ \"git branch\" kan inte anges tillsammans med ett " "grennamn" -#: builtin/branch.c:923 +#: builtin/branch.c:996 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2584,7 +2836,7 @@ msgstr "" "Flaggan --set-upstream rekommenderas ej och kommer tas bort. Använd --track " "eller --set-upstream-to\n" -#: builtin/branch.c:940 +#: builtin/branch.c:1013 #, c-format msgid "" "\n" @@ -2595,12 +2847,12 @@ msgstr "" "Om du vill göra sÃ¥ att \"%s\" spÃ¥rar \"%s\" gör du sÃ¥ här:\n" "\n" -#: builtin/branch.c:941 +#: builtin/branch.c:1014 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:942 +#: builtin/branch.c:1015 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2618,43 +2870,43 @@ msgstr "Behöver ett arkiv för att skapa ett paket (bundle)." msgid "Need a repository to unbundle." msgstr "Behöver ett arkiv för att packa upp ett paket (bundle)." -#: builtin/cat-file.c:247 +#: builtin/cat-file.c:176 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>" msgstr "git cat-file (-t|-s|-e|-p|<typ>|--textconv) <objekt>" -#: builtin/cat-file.c:248 +#: builtin/cat-file.c:177 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>" msgstr "git cat-file (--batch|--batch-check) < <objektlista>" -#: builtin/cat-file.c:266 +#: builtin/cat-file.c:195 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "<typ> kan vara en av: blob, tree, commit, tag" -#: builtin/cat-file.c:267 +#: builtin/cat-file.c:196 msgid "show object type" msgstr "visa objekttyp" -#: builtin/cat-file.c:268 +#: builtin/cat-file.c:197 msgid "show object size" msgstr "visa objektstorlek" -#: builtin/cat-file.c:270 +#: builtin/cat-file.c:199 msgid "exit with zero when there's no error" msgstr "avsluta med noll när det inte uppstÃ¥tt nÃ¥got fel" -#: builtin/cat-file.c:271 +#: builtin/cat-file.c:200 msgid "pretty-print object's content" msgstr "visa objektets innehÃ¥ll snyggt" -#: builtin/cat-file.c:273 +#: builtin/cat-file.c:202 msgid "for blob objects, run textconv on object's content" msgstr "för blob-objekt, kör textconv pÃ¥ objektets innehÃ¥ll" -#: builtin/cat-file.c:275 +#: builtin/cat-file.c:204 msgid "show info and content of objects fed from the standard input" msgstr "visa information och innehÃ¥ll för objekt som listas pÃ¥ standard in" -#: builtin/cat-file.c:278 +#: builtin/cat-file.c:207 msgid "show info about objects fed from the standard input" msgstr "visa information för objekt som listas pÃ¥ standard in" @@ -2682,27 +2934,27 @@ msgstr "läs filnamn frÃ¥n standard in" msgid "input paths are terminated by a null character" msgstr "sökvägar avdelas med null-tecken" -#: builtin/check-ignore.c:18 builtin/checkout.c:1012 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "undertryck förloppsrapportering" -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:146 msgid "cannot specify pathnames with --stdin" msgstr "kan inte ange sökvägsnamn med --stdin" -#: builtin/check-ignore.c:154 +#: builtin/check-ignore.c:149 msgid "-z only makes sense with --stdin" msgstr "-z kan endast användas tillsammans med --stdin" -#: builtin/check-ignore.c:156 +#: builtin/check-ignore.c:151 msgid "no path specified" msgstr "ingen sökväg angavs" -#: builtin/check-ignore.c:160 +#: builtin/check-ignore.c:155 msgid "--quiet is only valid with a single pathname" msgstr "--quiet kan endast användas med ett enkelt sökvägsnamn" -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:157 msgid "cannot have both --quiet and --verbose" msgstr "kan inte använda bÃ¥de --quiet och --verbose" @@ -2758,106 +3010,106 @@ msgstr "git checkout [flaggor] <gren>" msgid "git checkout [options] [<branch>] -- <file>..." msgstr "git checkout [flaggor] [<gren>] -- <fil>..." -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format msgid "path '%s' does not have our version" msgstr "sökvägen \"%s\" har inte vÃ¥r version" -#: builtin/checkout.c:118 builtin/checkout.c:151 +#: builtin/checkout.c:119 builtin/checkout.c:152 #, c-format msgid "path '%s' does not have their version" msgstr "sökvägen \"%s\" har inte deras version" -#: builtin/checkout.c:134 +#: builtin/checkout.c:135 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "sökvägen \"%s\" innehÃ¥ller inte alla nödvändiga versioner" -#: builtin/checkout.c:178 +#: builtin/checkout.c:179 #, c-format msgid "path '%s' does not have necessary versions" msgstr "sökvägen \"%s\" innehÃ¥ller inte nödvändiga versioner" -#: builtin/checkout.c:195 +#: builtin/checkout.c:196 #, c-format msgid "path '%s': cannot merge" msgstr "sökväg \"%s\": kan inte slÃ¥ ihop" -#: builtin/checkout.c:212 +#: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Kunde inte lägga till sammanslagningsresultat för \"%s\"" -#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 -#: builtin/checkout.c:245 +#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 +#: builtin/checkout.c:246 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "\"%s\" kan inte användas vid uppdatering av sökvägar" -#: builtin/checkout.c:248 builtin/checkout.c:251 +#: builtin/checkout.c:249 builtin/checkout.c:252 #, c-format msgid "'%s' cannot be used with %s" msgstr "\"%s\" kan inte användas med %s" -#: builtin/checkout.c:254 +#: builtin/checkout.c:255 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt." -#: builtin/checkout.c:265 builtin/checkout.c:426 +#: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" msgstr "indexfilen är trasig" -#: builtin/checkout.c:295 builtin/checkout.c:302 +#: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format msgid "path '%s' is unmerged" msgstr "sökvägen \"%s\" har inte slagits ihop" -#: builtin/checkout.c:448 +#: builtin/checkout.c:480 msgid "you need to resolve your current index first" msgstr "du mÃ¥ste lösa ditt befintliga index först" -#: builtin/checkout.c:569 +#: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "Kan inte skapa referenslog för \"%s\"\n" -#: builtin/checkout.c:602 +#: builtin/checkout.c:634 msgid "HEAD is now at" msgstr "HEAD är nu pÃ¥" -#: builtin/checkout.c:609 +#: builtin/checkout.c:641 #, c-format msgid "Reset branch '%s'\n" msgstr "Ã…terställ gren \"%s\"\n" -#: builtin/checkout.c:612 +#: builtin/checkout.c:644 #, c-format msgid "Already on '%s'\n" msgstr "Redan pÃ¥ \"%s\"\n" -#: builtin/checkout.c:616 +#: builtin/checkout.c:648 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Växlade till och nollställde grenen \"%s\"\n" -#: builtin/checkout.c:618 builtin/checkout.c:955 +#: builtin/checkout.c:650 builtin/checkout.c:987 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Växlade till en ny gren \"%s\"\n" -#: builtin/checkout.c:620 +#: builtin/checkout.c:652 #, c-format msgid "Switched to branch '%s'\n" msgstr "Växlade till grenen \"%s\"\n" -#: builtin/checkout.c:676 +#: builtin/checkout.c:708 #, c-format msgid " ... and %d more.\n" msgstr " ... och %d till.\n" #. The singular version -#: builtin/checkout.c:682 +#: builtin/checkout.c:714 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2880,7 +3132,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:700 +#: builtin/checkout.c:732 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2895,132 +3147,136 @@ msgstr "" " git branch nytt_grennamn %s\n" "\n" -#: builtin/checkout.c:730 +#: builtin/checkout.c:762 msgid "internal error in revision walk" msgstr "internt fel vid genomgÃ¥ng av revisioner (revision walk)" -#: builtin/checkout.c:734 +#: builtin/checkout.c:766 msgid "Previous HEAD position was" msgstr "Tidigare position för HEAD var" -#: builtin/checkout.c:761 builtin/checkout.c:950 +#: builtin/checkout.c:793 builtin/checkout.c:982 msgid "You are on a branch yet to be born" msgstr "Du är pÃ¥ en gren som ännu inte är född" #. case (1) -#: builtin/checkout.c:886 +#: builtin/checkout.c:918 #, c-format msgid "invalid reference: %s" msgstr "felaktig referens: %s" #. case (1): want a tree -#: builtin/checkout.c:925 +#: builtin/checkout.c:957 #, c-format msgid "reference is not a tree: %s" msgstr "referensen är inte ett träd: %s" -#: builtin/checkout.c:964 +#: builtin/checkout.c:996 msgid "paths cannot be used with switching branches" msgstr "sökvägar kan inte användas vid byte av gren" -#: builtin/checkout.c:967 builtin/checkout.c:971 +#: builtin/checkout.c:999 builtin/checkout.c:1003 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "\"%s\" kan inte användas vid byte av gren" -#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 -#: builtin/checkout.c:986 +#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 +#: builtin/checkout.c:1018 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "\"%s\" kan inte användas med \"%s\"" -#: builtin/checkout.c:991 +#: builtin/checkout.c:1023 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "Kan inte växla gren till icke-incheckningen \"%s\"" -#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "gren" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1046 msgid "create and checkout a new branch" msgstr "skapa och checka ut en ny gren" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1048 msgid "create/reset and checkout a branch" msgstr "skapa/nollställ och checka ut en gren" -#: builtin/checkout.c:1017 +#: builtin/checkout.c:1049 msgid "create reflog for new branch" msgstr "skapa reflogg för ny gren" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1050 msgid "detach the HEAD at named commit" msgstr "koppla frÃ¥n HEAD vid namngiven incheckning" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1051 msgid "set upstream info for new branch" msgstr "sätt uppströmsinformation för ny gren" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new branch" msgstr "ny gren" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new unparented branch" msgstr "ny gren utan förälder" -#: builtin/checkout.c:1022 +#: builtin/checkout.c:1054 msgid "checkout our version for unmerged files" msgstr "checka ut vÃ¥r version för ej sammanslagna filer" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1056 msgid "checkout their version for unmerged files" msgstr "checka ut deras version för ej sammanslagna filer" -#: builtin/checkout.c:1026 +#: builtin/checkout.c:1058 msgid "force checkout (throw away local modifications)" msgstr "tvinga utcheckning (kasta bort lokala ändringar)" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1059 msgid "perform a 3-way merge with the new branch" msgstr "utför en 3-vägssammanslagning för den nya grenen" -#: builtin/checkout.c:1028 builtin/merge.c:215 +#: builtin/checkout.c:1060 builtin/merge.c:217 msgid "update ignored files (default)" msgstr "uppdatera ignorerade filer (standard)" -#: builtin/checkout.c:1029 builtin/log.c:1147 parse-options.h:245 +#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 msgid "style" msgstr "stil" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1062 msgid "conflict style (merge or diff3)" msgstr "konfliktstil (merge eller diff3)" -#: builtin/checkout.c:1033 +#: builtin/checkout.c:1065 +msgid "do not limit pathspecs to sparse entries only" +msgstr "begränsa inte sökvägar till endast glesa poster" + +#: builtin/checkout.c:1067 msgid "second guess 'git checkout no-such-branch'" msgstr "förutspÃ¥ \"git checkout gren-saknas\"" -#: builtin/checkout.c:1057 +#: builtin/checkout.c:1091 msgid "-b, -B and --orphan are mutually exclusive" msgstr "-b, -B och --orphan är ömsesidigt uteslutande" -#: builtin/checkout.c:1074 +#: builtin/checkout.c:1108 msgid "--track needs a branch name" msgstr "--track behöver ett namn pÃ¥ en gren" -#: builtin/checkout.c:1081 +#: builtin/checkout.c:1115 msgid "Missing branch name; try -b" msgstr "Grennamn saknas; försök med -b" -#: builtin/checkout.c:1116 +#: builtin/checkout.c:1150 msgid "invalid path specification" msgstr "felaktig sökvägsangivelse" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1157 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -3029,12 +3285,12 @@ msgstr "" "Kan inte uppdatera sökvägar och växla till grenen \"%s\" samtidigt.\n" "Ville du checka ut \"%s\" som inte kan lösas som en utcheckning?" -#: builtin/checkout.c:1128 +#: builtin/checkout.c:1162 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout: --detach tar inte en sökväg som argument \"%s\"" -#: builtin/checkout.c:1132 +#: builtin/checkout.c:1166 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -3084,8 +3340,8 @@ msgstr "tvinga" msgid "remove whole directories" msgstr "ta bort hela kataloger" -#: builtin/clean.c:165 builtin/describe.c:413 builtin/grep.c:717 -#: builtin/ls-files.c:494 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 +#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "mönster" @@ -3120,216 +3376,234 @@ msgstr "" "clean.requireForce har standardvärdet true, men varken -n eller -f angavs; " "vägrar städa" -#: builtin/clone.c:36 +#: builtin/clone.c:37 msgid "git clone [options] [--] <repo> [<dir>]" msgstr "git clone [flaggor] [--] <arkiv> [<kat>]" -#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:212 +#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 #: builtin/push.c:436 msgid "force progress reporting" msgstr "tvinga förloppsrapportering" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "don't create a checkout" msgstr "skapa inte nÃ¥gon utcheckning" -#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 msgid "create a bare repository" msgstr "skapa ett naket (\"bare\") arkiv" -#: builtin/clone.c:72 +#: builtin/clone.c:73 msgid "create a mirror repository (implies bare)" msgstr "skapa ett spegelarkiv (implicerar \"bare\")" -#: builtin/clone.c:74 +#: builtin/clone.c:75 msgid "to clone from a local repository" msgstr "för att klona frÃ¥n ett lokalt arkiv" -#: builtin/clone.c:76 +#: builtin/clone.c:77 msgid "don't use local hardlinks, always copy" msgstr "skapa inte lokala hÃ¥rda länkar, kopiera alltid" -#: builtin/clone.c:78 +#: builtin/clone.c:79 msgid "setup as shared repository" msgstr "skapa som ett delat arkiv" -#: builtin/clone.c:80 builtin/clone.c:82 +#: builtin/clone.c:81 builtin/clone.c:83 msgid "initialize submodules in the clone" msgstr "initiera undermoduler i klonen" -#: builtin/clone.c:83 builtin/init-db.c:485 +#: builtin/clone.c:84 builtin/init-db.c:485 msgid "template-directory" msgstr "mallkatalog" -#: builtin/clone.c:84 builtin/init-db.c:486 +#: builtin/clone.c:85 builtin/init-db.c:486 msgid "directory from which templates will be used" msgstr "katalog att använda mallar frÃ¥n" -#: builtin/clone.c:86 +#: builtin/clone.c:87 msgid "reference repository" msgstr "referensarkiv" -#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "namn" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "use <name> instead of 'origin' to track upstream" msgstr "använd <namn> istället för \"origin\" för att spÃ¥ra uppströms" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "checkout <branch> instead of the remote's HEAD" msgstr "checka ut <gren> istället för fjärrens HEAD" -#: builtin/clone.c:92 +#: builtin/clone.c:93 msgid "path to git-upload-pack on the remote" msgstr "sökväg till git-upload-pack pÃ¥ fjärren" -#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "djup" -#: builtin/clone.c:94 +#: builtin/clone.c:95 msgid "create a shallow clone of that depth" msgstr "skapa en grund klon pÃ¥ detta djup" -#: builtin/clone.c:96 +#: builtin/clone.c:97 msgid "clone only one branch, HEAD or --branch" msgstr "klona endast en gren, HEAD eller --branch" -#: builtin/clone.c:97 builtin/init-db.c:494 +#: builtin/clone.c:98 builtin/init-db.c:494 msgid "gitdir" msgstr "gitkat" -#: builtin/clone.c:98 builtin/init-db.c:495 +#: builtin/clone.c:99 builtin/init-db.c:495 msgid "separate git dir from working tree" msgstr "separera gitkatalogen frÃ¥n arbetskatalogen" -#: builtin/clone.c:99 +#: builtin/clone.c:100 msgid "key=value" msgstr "nyckel=värde" -#: builtin/clone.c:100 +#: builtin/clone.c:101 msgid "set config inside the new repository" msgstr "ställ in konfiguration i det nya arkivet" -#: builtin/clone.c:243 +#: builtin/clone.c:254 #, c-format -msgid "reference repository '%s' is not a local directory." -msgstr "referensarkivet \"%s\" är inte en lokal katalog." +msgid "reference repository '%s' is not a local repository." +msgstr "referensarkivet \"%s\" är inte ett lokalt arkiv." -#: builtin/clone.c:306 +#: builtin/clone.c:317 #, c-format msgid "failed to create directory '%s'" msgstr "misslyckades skapa katalogen \"%s\"" -#: builtin/clone.c:308 builtin/diff.c:77 +#: builtin/clone.c:319 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "misslyckades ta status pÃ¥ \"%s\"" -#: builtin/clone.c:310 +#: builtin/clone.c:321 #, c-format msgid "%s exists and is not a directory" msgstr "%s finns och är ingen katalog" -#: builtin/clone.c:324 +#: builtin/clone.c:335 #, c-format msgid "failed to stat %s\n" msgstr "misslyckades ta status pÃ¥ %s\n" -#: builtin/clone.c:346 +#: builtin/clone.c:357 #, c-format msgid "failed to create link '%s'" msgstr "misslyckades skapa länken \"%s\"" -#: builtin/clone.c:350 +#: builtin/clone.c:361 #, c-format msgid "failed to copy file to '%s'" msgstr "misslyckades kopiera filen till \"%s\"" -#: builtin/clone.c:373 +#: builtin/clone.c:384 #, c-format msgid "done.\n" msgstr "klart.\n" -#: builtin/clone.c:443 +#: builtin/clone.c:397 +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 "" +"Klonen lyckades, men utcheckningen misslyckades.\n" +"Du kan inspektera det som checkades ut med \"git status\"\n" +"och försöka checka ut igen med \"git checkout -f HEAD\"\n" + +#: builtin/clone.c:476 #, c-format msgid "Could not find remote branch %s to clone." msgstr "Kunde inte hitta fjärrgrenen %s för att klona." -#: builtin/clone.c:552 +#: builtin/clone.c:550 +msgid "remote did not send all necessary objects" +msgstr "fjärren sände inte alla nödvändiga objekt" + +#: builtin/clone.c:610 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "" "HEAD hos fjärren pekar pÃ¥ en obefintlig referens, kan inte checka ut.\n" -#: builtin/clone.c:690 +#: builtin/clone.c:641 +msgid "unable to checkout working tree" +msgstr "kunde inte checka ut arbetskatalogen" + +#: builtin/clone.c:749 msgid "Too many arguments." msgstr "För mÃ¥nga argument." -#: builtin/clone.c:694 +#: builtin/clone.c:753 msgid "You must specify a repository to clone." msgstr "Du mÃ¥ste ange ett arkiv att klona." -#: builtin/clone.c:705 +#: builtin/clone.c:764 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "flaggorna --bare och --origin %s är inkompatibla." -#: builtin/clone.c:708 +#: builtin/clone.c:767 msgid "--bare and --separate-git-dir are incompatible." msgstr "flaggorna --bare och --separate-git-dir är inkompatibla." -#: builtin/clone.c:721 +#: builtin/clone.c:780 #, c-format msgid "repository '%s' does not exist" msgstr "arkivet \"%s\" finns inte" -#: builtin/clone.c:726 +#: builtin/clone.c:785 msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth ignoreras i lokala kloningar; använd file:// istället" -#: builtin/clone.c:736 +#: builtin/clone.c:795 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "destinationssökvägen \"%s\" finns redan och är inte en tom katalog." -#: builtin/clone.c:746 +#: builtin/clone.c:805 #, c-format msgid "working tree '%s' already exists." msgstr "arbetsträdet \"%s\" finns redan." -#: builtin/clone.c:759 builtin/clone.c:771 +#: builtin/clone.c:818 builtin/clone.c:830 #, c-format msgid "could not create leading directories of '%s'" msgstr "kunde inte skapa inledande kataloger för \"%s\"" -#: builtin/clone.c:762 +#: builtin/clone.c:821 #, c-format msgid "could not create work tree dir '%s'." msgstr "kunde inte skapa arbetskatalogen \"%s\"" -#: builtin/clone.c:781 +#: builtin/clone.c:840 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "Klonar till ett naket arkiv \"%s\"...\n" -#: builtin/clone.c:783 +#: builtin/clone.c:842 #, c-format msgid "Cloning into '%s'...\n" msgstr "Klonar till \"%s\"...\n" -#: builtin/clone.c:818 +#: builtin/clone.c:877 #, c-format msgid "Don't know how to clone %s" msgstr "Vet inte hur man klonar %s" -#: builtin/clone.c:867 +#: builtin/clone.c:926 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "Fjärrgrenen %s hittades inte i uppströmsarkivet %s" -#: builtin/clone.c:874 +#: builtin/clone.c:933 msgid "You appear to have cloned an empty repository." msgstr "Du verkar ha klonat ett tomt arkiv." @@ -3424,93 +3698,93 @@ msgstr "" "\n" "Annars använder du \"git reset\"\n" -#: builtin/commit.c:258 +#: builtin/commit.c:260 msgid "failed to unpack HEAD tree object" msgstr "misslyckades packa upp HEAD:s trädobjekt" -#: builtin/commit.c:300 +#: builtin/commit.c:302 msgid "unable to create temporary index" msgstr "kunde inte skapa temporär indexfil" -#: builtin/commit.c:306 +#: builtin/commit.c:308 msgid "interactive add failed" msgstr "interaktiv tilläggning misslyckades" -#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 +#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 msgid "unable to write new_index file" msgstr "kunde inte skriva filen new_index" -#: builtin/commit.c:391 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a merge." msgstr "kan inte utföra en delvis incheckning under en sammanslagning." -#: builtin/commit.c:393 +#: builtin/commit.c:395 msgid "cannot do a partial commit during a cherry-pick." msgstr "kan inte utföra en delvis incheckning under en cherry-pick." -#: builtin/commit.c:403 +#: builtin/commit.c:405 msgid "cannot read the index" msgstr "kan inte läsa indexet" -#: builtin/commit.c:423 +#: builtin/commit.c:425 msgid "unable to write temporary index file" msgstr "kunde inte skriva temporär indexfil" -#: builtin/commit.c:511 builtin/commit.c:517 +#: builtin/commit.c:513 builtin/commit.c:519 #, c-format msgid "invalid commit: %s" msgstr "felaktig incheckning: %s" -#: builtin/commit.c:540 +#: builtin/commit.c:542 msgid "malformed --author parameter" msgstr "felformad \"--author\"-flagga" -#: builtin/commit.c:560 +#: builtin/commit.c:562 #, c-format msgid "Malformed ident string: '%s'" msgstr "Felaktig indragningssträng: \"%s\"" -#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 +#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 #, c-format msgid "could not lookup commit %s" msgstr "kunde inte slÃ¥ upp incheckningen %s" -#: builtin/commit.c:610 builtin/shortlog.c:272 +#: builtin/commit.c:612 builtin/shortlog.c:270 #, c-format msgid "(reading log message from standard input)\n" msgstr "(läser loggmeddelande frÃ¥n standard in)\n" -#: builtin/commit.c:612 +#: builtin/commit.c:614 msgid "could not read log from standard input" msgstr "kunde inte läsa logg frÃ¥n standard in" -#: builtin/commit.c:616 +#: builtin/commit.c:618 #, c-format msgid "could not read log file '%s'" msgstr "kunde inte läsa loggfilen \"%s\"" -#: builtin/commit.c:622 +#: builtin/commit.c:624 msgid "commit has empty message" msgstr "incheckningen har ett tomt meddelande" -#: builtin/commit.c:638 +#: builtin/commit.c:640 msgid "could not read MERGE_MSG" msgstr "kunde inte läsa MERGE_MSG" -#: builtin/commit.c:642 +#: builtin/commit.c:644 msgid "could not read SQUASH_MSG" msgstr "kunde inte läsa SQUASH_MSG" -#: builtin/commit.c:646 +#: builtin/commit.c:648 #, c-format msgid "could not read '%s'" msgstr "kunde inte läsa \"%s\"" -#: builtin/commit.c:707 +#: builtin/commit.c:709 msgid "could not write commit template" msgstr "kunde inte skriva incheckningsmall" -#: builtin/commit.c:718 +#: builtin/commit.c:720 #, c-format msgid "" "\n" @@ -3525,7 +3799,7 @@ msgstr "" "\t%s\n" "och försöker igen.\n" -#: builtin/commit.c:723 +#: builtin/commit.c:725 #, c-format msgid "" "\n" @@ -3540,7 +3814,7 @@ msgstr "" "\t%s\n" "och försöker igen.\n" -#: builtin/commit.c:735 +#: builtin/commit.c:737 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3550,7 +3824,7 @@ msgstr "" "med \"%c\" kommer ignoreras, och ett tomt meddelande avbryter " "incheckningen.\n" -#: builtin/commit.c:740 +#: builtin/commit.c:742 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3561,139 +3835,139 @@ msgstr "" "med \"%c\" kommer behÃ¥llas; du kan själv ta bort dem om du vill.\n" "Ett tomt meddelande avbryter incheckningen.\n" -#: builtin/commit.c:753 +#: builtin/commit.c:755 #, c-format msgid "%sAuthor: %s" msgstr "%sFörfattare: %s" -#: builtin/commit.c:760 +#: builtin/commit.c:762 #, c-format msgid "%sCommitter: %s" msgstr "%sIncheckare: %s" -#: builtin/commit.c:780 +#: builtin/commit.c:782 msgid "Cannot read index" msgstr "Kan inte läsa indexet" -#: builtin/commit.c:817 +#: builtin/commit.c:819 msgid "Error building trees" msgstr "Fel vid byggande av träd" -#: builtin/commit.c:832 builtin/tag.c:359 +#: builtin/commit.c:834 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Ange meddelandet en av flaggorna -m eller -F.\n" -#: builtin/commit.c:929 +#: builtin/commit.c:931 #, c-format msgid "No existing author found with '%s'" msgstr "Hittade ingen befintlig författare med \"%s\"" -#: builtin/commit.c:944 builtin/commit.c:1138 +#: builtin/commit.c:946 builtin/commit.c:1140 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Ogiltigt läge för ospÃ¥rade filer: \"%s\"" -#: builtin/commit.c:974 +#: builtin/commit.c:976 msgid "Using both --reset-author and --author does not make sense" msgstr "Kan inte använda bÃ¥de --reset-author och --author" -#: builtin/commit.c:985 +#: builtin/commit.c:987 msgid "You have nothing to amend." msgstr "Du har inget att utöka." -#: builtin/commit.c:988 +#: builtin/commit.c:990 msgid "You are in the middle of a merge -- cannot amend." msgstr "Du är i mitten av en sammanslagning -- kan inte utöka." -#: builtin/commit.c:990 +#: builtin/commit.c:992 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "Du är i mitten av en cherry-pick -- kan inte utöka." -#: builtin/commit.c:993 +#: builtin/commit.c:995 msgid "Options --squash and --fixup cannot be used together" msgstr "Flaggorna --squash och --fixup kan inte användas samtidigt" -#: builtin/commit.c:1003 +#: builtin/commit.c:1005 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Endast en av -c/-C/-F/--fixup kan användas." -#: builtin/commit.c:1005 +#: builtin/commit.c:1007 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "Flaggan -m kan inte kombineras med -c/-C/-F/--fixup." -#: builtin/commit.c:1013 +#: builtin/commit.c:1015 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "--reset-author kan endast användas med -C, -c eller --amend." -#: builtin/commit.c:1030 +#: builtin/commit.c:1032 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "" "Endast en av --include/--only/--all/--interactive/--patch kan användas." -#: builtin/commit.c:1032 +#: builtin/commit.c:1034 msgid "No paths with --include/--only does not make sense." msgstr "Du mÃ¥ste ange sökvägar tillsammans med --include/--only." -#: builtin/commit.c:1034 +#: builtin/commit.c:1036 msgid "Clever... amending the last one with dirty index." msgstr "Smart... utöka den senaste med smutsigt index." -#: builtin/commit.c:1036 +#: builtin/commit.c:1038 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "Explicita sökvägar angavs utan -i eller -o; antar --only sökvägar..." -#: builtin/commit.c:1046 builtin/tag.c:575 +#: builtin/commit.c:1048 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "Felaktigt städningsläge %s" -#: builtin/commit.c:1051 +#: builtin/commit.c:1053 msgid "Paths with -a does not make sense." msgstr "Kan inte ange sökvägar med -a." -#: builtin/commit.c:1057 builtin/commit.c:1192 +#: builtin/commit.c:1059 builtin/commit.c:1194 msgid "--long and -z are incompatible" msgstr "--long och -z är inkompatibla" -#: builtin/commit.c:1152 builtin/commit.c:1388 +#: builtin/commit.c:1154 builtin/commit.c:1390 msgid "show status concisely" msgstr "vis koncis status" -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1156 builtin/commit.c:1392 msgid "show branch information" msgstr "visa information om gren" -#: builtin/commit.c:1156 builtin/commit.c:1392 builtin/push.c:426 +#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 msgid "machine-readable output" msgstr "maskinläsbar utdata" -#: builtin/commit.c:1159 builtin/commit.c:1394 +#: builtin/commit.c:1161 builtin/commit.c:1396 msgid "show status in long format (default)" msgstr "visa status i lÃ¥ngt format (standard)" -#: builtin/commit.c:1162 builtin/commit.c:1397 +#: builtin/commit.c:1164 builtin/commit.c:1399 msgid "terminate entries with NUL" msgstr "terminera poster med NUL" -#: builtin/commit.c:1164 builtin/commit.c:1400 builtin/fast-export.c:647 -#: builtin/fast-export.c:650 builtin/tag.c:459 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 +#: builtin/fast-export.c:662 builtin/tag.c:459 msgid "mode" msgstr "läge" -#: builtin/commit.c:1165 builtin/commit.c:1400 +#: builtin/commit.c:1167 builtin/commit.c:1402 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "visa ospÃ¥rade filer, valfria lägen: alla, normal, no. (Standard: all)" -#: builtin/commit.c:1168 +#: builtin/commit.c:1170 msgid "show ignored files" msgstr "visa ignorerade filer" -#: builtin/commit.c:1169 parse-options.h:151 +#: builtin/commit.c:1171 parse-options.h:151 msgid "when" msgstr "när" -#: builtin/commit.c:1170 +#: builtin/commit.c:1172 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -3701,217 +3975,217 @@ msgstr "" "ignorera ändringar i undermoduler, valfritt när: all, dirty, untracked. " "(Default: all)" -#: builtin/commit.c:1172 +#: builtin/commit.c:1174 msgid "list untracked files in columns" msgstr "visa ospÃ¥rade filer i spalter" -#: builtin/commit.c:1246 +#: builtin/commit.c:1248 msgid "couldn't look up newly created commit" msgstr "kunde inte slÃ¥ upp en precis skapad incheckning" -#: builtin/commit.c:1248 +#: builtin/commit.c:1250 msgid "could not parse newly created commit" msgstr "kunde inte tolka en precis skapad incheckning" -#: builtin/commit.c:1289 +#: builtin/commit.c:1291 msgid "detached HEAD" msgstr "frÃ¥nkopplad HEAD" -#: builtin/commit.c:1291 +#: builtin/commit.c:1293 msgid " (root-commit)" msgstr " (rotincheckning)" -#: builtin/commit.c:1358 +#: builtin/commit.c:1360 msgid "suppress summary after successful commit" msgstr "undertryck sammanfattning efter framgÃ¥ngsrik incheckning" -#: builtin/commit.c:1359 +#: builtin/commit.c:1361 msgid "show diff in commit message template" msgstr "visa diff i mallen för incheckningsmeddelandet" -#: builtin/commit.c:1361 +#: builtin/commit.c:1363 msgid "Commit message options" msgstr "Alternativ för incheckningsmeddelande" -#: builtin/commit.c:1362 builtin/tag.c:457 +#: builtin/commit.c:1364 builtin/tag.c:457 msgid "read message from file" msgstr "läs meddelande frÃ¥n fil" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "author" msgstr "författare" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "override author for commit" msgstr "överstyr författare för incheckningen" -#: builtin/commit.c:1364 builtin/gc.c:178 +#: builtin/commit.c:1366 builtin/gc.c:178 msgid "date" msgstr "datum" -#: builtin/commit.c:1364 +#: builtin/commit.c:1366 msgid "override date for commit" msgstr "överstyr datum för inchecknignen" -#: builtin/commit.c:1365 builtin/merge.c:206 builtin/notes.c:533 +#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 #: builtin/notes.c:690 builtin/tag.c:455 msgid "message" msgstr "meddelande" -#: builtin/commit.c:1365 +#: builtin/commit.c:1367 msgid "commit message" msgstr "incheckningsmeddelande" -#: builtin/commit.c:1366 +#: builtin/commit.c:1368 msgid "reuse and edit message from specified commit" msgstr "Ã¥teranvänd och redigera meddelande frÃ¥n angiven incheckning" -#: builtin/commit.c:1367 +#: builtin/commit.c:1369 msgid "reuse message from specified commit" msgstr "Ã¥teranvänd meddelande frÃ¥n angiven incheckning" -#: builtin/commit.c:1368 +#: builtin/commit.c:1370 msgid "use autosquash formatted message to fixup specified commit" msgstr "" "använd autosquash-formaterat meddelande för att fixa angiven incheckning" -#: builtin/commit.c:1369 +#: builtin/commit.c:1371 msgid "use autosquash formatted message to squash specified commit" msgstr "" "använd autosquash-formaterat meddelande för att slÃ¥ ihop med angiven " "incheckning" -#: builtin/commit.c:1370 +#: builtin/commit.c:1372 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "jag är nu författare av incheckningen (används med -C/-c/--amend)" -#: builtin/commit.c:1371 builtin/log.c:1102 builtin/revert.c:109 +#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "lägg till Signed-off-by:" -#: builtin/commit.c:1372 +#: builtin/commit.c:1374 msgid "use specified template file" msgstr "använd angiven mallfil" -#: builtin/commit.c:1373 +#: builtin/commit.c:1375 msgid "force edit of commit" msgstr "tvinga redigering av incheckning" -#: builtin/commit.c:1374 +#: builtin/commit.c:1376 msgid "default" msgstr "standard" -#: builtin/commit.c:1374 builtin/tag.c:460 +#: builtin/commit.c:1376 builtin/tag.c:460 msgid "how to strip spaces and #comments from message" msgstr "hur blanksteg och #kommentarer skall tas bort frÃ¥n meddelande" -#: builtin/commit.c:1375 +#: builtin/commit.c:1377 msgid "include status in commit message template" msgstr "inkludera status i mallen för incheckningsmeddelandet" -#: builtin/commit.c:1376 builtin/merge.c:213 builtin/tag.c:461 +#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 msgid "key id" msgstr "nyckel-id" -#: builtin/commit.c:1377 builtin/merge.c:214 +#: builtin/commit.c:1379 builtin/merge.c:216 msgid "GPG sign commit" msgstr "GPG-signera incheckning" #. end commit message options -#: builtin/commit.c:1380 +#: builtin/commit.c:1382 msgid "Commit contents options" msgstr "Alternativ för incheckningens innehÃ¥ll" -#: builtin/commit.c:1381 +#: builtin/commit.c:1383 msgid "commit all changed files" msgstr "checka in alla ändrade filer" -#: builtin/commit.c:1382 +#: builtin/commit.c:1384 msgid "add specified files to index for commit" msgstr "lägg till angivna filer till indexet för incheckning" -#: builtin/commit.c:1383 +#: builtin/commit.c:1385 msgid "interactively add files" msgstr "lägg till filer interaktivt" -#: builtin/commit.c:1384 +#: builtin/commit.c:1386 msgid "interactively add changes" msgstr "lägg till ändringar interaktivt" -#: builtin/commit.c:1385 +#: builtin/commit.c:1387 msgid "commit only specified files" msgstr "checka endast in angivna filer" -#: builtin/commit.c:1386 +#: builtin/commit.c:1388 msgid "bypass pre-commit hook" msgstr "förbigÃ¥ pre-commit-krok" -#: builtin/commit.c:1387 +#: builtin/commit.c:1389 msgid "show what would be committed" msgstr "visa vad som skulle checkas in" -#: builtin/commit.c:1398 +#: builtin/commit.c:1400 msgid "amend previous commit" msgstr "lägg till föregÃ¥ende incheckning" -#: builtin/commit.c:1399 +#: builtin/commit.c:1401 msgid "bypass post-rewrite hook" msgstr "förbigÃ¥ post-rewrite-krok" -#: builtin/commit.c:1404 +#: builtin/commit.c:1406 msgid "ok to record an empty change" msgstr "ok att registrera en tom ändring" -#: builtin/commit.c:1407 +#: builtin/commit.c:1409 msgid "ok to record a change with an empty message" msgstr "ok att registrera en ändring med tomt meddelande" -#: builtin/commit.c:1439 +#: builtin/commit.c:1441 msgid "could not parse HEAD commit" msgstr "kunde inte tolka HEAD:s incheckning" -#: builtin/commit.c:1477 builtin/merge.c:508 +#: builtin/commit.c:1479 builtin/merge.c:510 #, c-format msgid "could not open '%s' for reading" msgstr "kunde inte öppna \"%s\" för läsning" -#: builtin/commit.c:1484 +#: builtin/commit.c:1486 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Trasig MERGE_HEAD-fil (%s)" -#: builtin/commit.c:1491 +#: builtin/commit.c:1493 msgid "could not read MERGE_MODE" msgstr "kunde inte läsa MERGE_MODE" -#: builtin/commit.c:1510 +#: builtin/commit.c:1512 #, c-format msgid "could not read commit message: %s" msgstr "kunde inte läsa incheckningsmeddelande: %s" -#: builtin/commit.c:1524 +#: builtin/commit.c:1526 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "Avbryter incheckning; meddelandet inte redigerat.\n" -#: builtin/commit.c:1529 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "Avbryter pÃ¥ grund av tomt incheckningsmeddelande.\n" -#: builtin/commit.c:1544 builtin/merge.c:832 builtin/merge.c:857 +#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 msgid "failed to write commit object" msgstr "kunde inte skriva incheckningsobjekt" -#: builtin/commit.c:1565 +#: builtin/commit.c:1567 msgid "cannot lock HEAD ref" msgstr "kunde inte lÃ¥sa HEAD-referens" -#: builtin/commit.c:1569 +#: builtin/commit.c:1571 msgid "cannot update HEAD ref" msgstr "kunde inte uppdatera HEAD-referens" -#: builtin/commit.c:1580 +#: builtin/commit.c:1582 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -4038,9 +4312,13 @@ msgstr "terminera värden med NUL-byte" msgid "respect include directives on lookup" msgstr "respektera inkluderingsdirektiv vid uppslag" -#: builtin/count-objects.c:69 -msgid "git count-objects [-v]" -msgstr "git count-objects [-v]" +#: builtin/count-objects.c:82 +msgid "git count-objects [-v] [-H | --human-readable]" +msgstr "git count-objects [-v] [-H | --human-readable]" + +#: builtin/count-objects.c:97 +msgid "print sizes in human readable format" +msgstr "skriv storlekar i människoläsbart format" #: builtin/describe.c:15 msgid "git describe [options] <committish>*" @@ -4050,47 +4328,47 @@ msgstr "git describe [flaggor] <incheckning-igt>*" msgid "git describe [options] --dirty" msgstr "git describe [flaggor] --dirty" -#: builtin/describe.c:234 +#: builtin/describe.c:233 #, c-format msgid "annotated tag %s not available" msgstr "den annoterade taggen %s inte tillgänglig" -#: builtin/describe.c:238 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s has no embedded name" msgstr "den annoterade taggen %s har inget inbäddat namn" -#: builtin/describe.c:240 +#: builtin/describe.c:239 #, c-format msgid "tag '%s' is really '%s' here" msgstr "taggen \"%s\" är i verkligheten \"%s\" här" -#: builtin/describe.c:267 +#: builtin/describe.c:266 #, c-format msgid "Not a valid object name %s" msgstr "Objektnamnet är inte giltigt: %s" -#: builtin/describe.c:270 +#: builtin/describe.c:269 #, c-format msgid "%s is not a valid '%s' object" msgstr "%s är inte ett giltigt \"%s\"-objekt" -#: builtin/describe.c:287 +#: builtin/describe.c:286 #, c-format msgid "no tag exactly matches '%s'" msgstr "ingen tagg motsvarar \"%s\" exakt" -#: builtin/describe.c:289 +#: builtin/describe.c:288 #, c-format msgid "searching to describe %s\n" msgstr "söker för att beskriva %s\n" -#: builtin/describe.c:329 +#: builtin/describe.c:328 #, c-format msgid "finished search at %s\n" msgstr "avslutade sökning pÃ¥ %s\n" -#: builtin/describe.c:353 +#: builtin/describe.c:352 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -4099,7 +4377,7 @@ msgstr "" "Inga annoterade taggar kan beskriva \"%s\".\n" "Det finns dock oannoterade taggar: testa --tags." -#: builtin/describe.c:357 +#: builtin/describe.c:356 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -4108,12 +4386,12 @@ msgstr "" "Inga taggar kan beskriva \"%s\".\n" "Testa --always, eller skapa nÃ¥gra taggar." -#: builtin/describe.c:378 +#: builtin/describe.c:377 #, c-format msgid "traversed %lu commits\n" msgstr "traverserade %lu incheckningar\n" -#: builtin/describe.c:381 +#: builtin/describe.c:380 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -4122,59 +4400,59 @@ msgstr "" "mer än %i taggar hittades; listar de %i senaste\n" "gav upp sökningen vid %s\n" -#: builtin/describe.c:403 +#: builtin/describe.c:402 msgid "find the tag that comes after the commit" msgstr "hitta taggen som kommer efter incheckningen" -#: builtin/describe.c:404 +#: builtin/describe.c:403 msgid "debug search strategy on stderr" msgstr "felsök sökstrategin pÃ¥ standard fel" +#: builtin/describe.c:404 +msgid "use any ref" +msgstr "använd alla referenser" + #: builtin/describe.c:405 -msgid "use any ref in .git/refs" -msgstr "använd alla referenser i .git/refs" +msgid "use any tag, even unannotated" +msgstr "använd alla taggar, även oannoterade" #: builtin/describe.c:406 -msgid "use any tag in .git/refs/tags" -msgstr "använd alla taggar i .git/refs/tags" - -#: builtin/describe.c:407 msgid "always use long format" msgstr "använd alltid lÃ¥ngt format" -#: builtin/describe.c:410 +#: builtin/describe.c:409 msgid "only output exact matches" msgstr "skriv endast ut exakta träffar" -#: builtin/describe.c:412 +#: builtin/describe.c:411 msgid "consider <n> most recent tags (default: 10)" msgstr "överväg de <n> nyaste taggarna (standard: 10)" -#: builtin/describe.c:414 +#: builtin/describe.c:413 msgid "only consider tags matching <pattern>" msgstr "överväg endast taggar som motsvarar <mönster>" -#: builtin/describe.c:416 builtin/name-rev.c:238 +#: builtin/describe.c:415 builtin/name-rev.c:238 msgid "show abbreviated commit object as fallback" msgstr "visa förkortade incheckningsobjekt som standard" -#: builtin/describe.c:417 +#: builtin/describe.c:416 msgid "mark" msgstr "märke" -#: builtin/describe.c:418 +#: builtin/describe.c:417 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "lägg till <märke> pÃ¥ lortigt arbetsträd (standard: \"-dirty\")" -#: builtin/describe.c:436 +#: builtin/describe.c:435 msgid "--long is incompatible with --abbrev=0" msgstr "--long är inkompatibel med --abbrev=0" -#: builtin/describe.c:462 +#: builtin/describe.c:461 msgid "No names found, cannot describe anything." msgstr "Inga namn hittades, kan inte beskriva nÃ¥got." -#: builtin/describe.c:482 +#: builtin/describe.c:481 msgid "--dirty is incompatible with committishes" msgstr "--dirty är inkompatibelt med \"committish\"-värden" @@ -4216,39 +4494,39 @@ msgstr "ej hanterat objekt \"%s\" angavs." msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-flaggor]" -#: builtin/fast-export.c:646 +#: builtin/fast-export.c:658 msgid "show progress after <n> objects" msgstr "visa förlopp efter <n> objekt" -#: builtin/fast-export.c:648 +#: builtin/fast-export.c:660 msgid "select handling of signed tags" msgstr "välj hantering av signerade taggar" -#: builtin/fast-export.c:651 +#: builtin/fast-export.c:663 msgid "select handling of tags that tag filtered objects" msgstr "välj hantering av taggar som har taggfiltrerade objekt" -#: builtin/fast-export.c:654 +#: builtin/fast-export.c:666 msgid "Dump marks to this file" msgstr "Dump märken till filen" -#: builtin/fast-export.c:656 +#: builtin/fast-export.c:668 msgid "Import marks from this file" msgstr "Importera märken frÃ¥n filen" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:670 msgid "Fake a tagger when tags lack one" msgstr "Fejka taggare när taggen saknar en" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:672 msgid "Output full tree for each commit" msgstr "Skriv ut hela trädet för varje incheckning" -#: builtin/fast-export.c:662 +#: builtin/fast-export.c:674 msgid "Use the done feature to terminate the stream" msgstr "Använd done-funktionen för att avsluta strömmen" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:675 msgid "Skip output of blob data" msgstr "Hoppa över skrivning av blob-data" @@ -4324,7 +4602,7 @@ msgstr "fördjupa historik för grund klon" msgid "convert to a complete repository" msgstr "konvertera till komplett arkiv" -#: builtin/fetch.c:88 builtin/log.c:1119 +#: builtin/fetch.c:88 builtin/log.c:1130 msgid "dir" msgstr "kat" @@ -4504,29 +4782,29 @@ msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" "git fmt-merge-msg [-m <meddelande>] [--log[=<n>]|--no-log] [--file <fil>]" -#: builtin/fmt-merge-msg.c:659 builtin/fmt-merge-msg.c:662 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 #: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 msgid "n" msgstr "n" -#: builtin/fmt-merge-msg.c:660 +#: builtin/fmt-merge-msg.c:664 msgid "populate log with at most <n> entries from shortlog" msgstr "fyll i loggen med som mest <n> poster frÃ¥n shortlog" -#: builtin/fmt-merge-msg.c:663 +#: builtin/fmt-merge-msg.c:667 msgid "alias for --log (deprecated)" msgstr "alias för --log (avrÃ¥ds)" -#: builtin/fmt-merge-msg.c:666 +#: builtin/fmt-merge-msg.c:670 msgid "text" msgstr "text" -#: builtin/fmt-merge-msg.c:667 +#: builtin/fmt-merge-msg.c:671 msgid "use <text> as start of message" msgstr "inled meddelande med <text>" -#: builtin/fmt-merge-msg.c:668 +#: builtin/fmt-merge-msg.c:672 msgid "file to read from" msgstr "fil att läsa frÃ¥n" @@ -4862,28 +5140,23 @@ msgstr "visa användning" msgid "no pattern given." msgstr "inget mönster angavs." -#: builtin/grep.c:825 -#, c-format -msgid "bad object %s" -msgstr "felaktigt objekt %s" - -#: builtin/grep.c:868 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager fungerar endast i arbetskatalogen" -#: builtin/grep.c:891 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "--cached och --untracked kan inte användas med --no-index." -#: builtin/grep.c:896 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "--no-index och --untracked kan inte användas med revisioner." -#: builtin/grep.c:899 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "--[no-]exclude-standard kan inte användas för spÃ¥rat innehÃ¥ll." -#: builtin/grep.c:907 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "bÃ¥de --cached och träd angavs." @@ -4923,50 +5196,54 @@ msgstr "spara filen som den är utan filer" msgid "process file as it were from this path" msgstr "hantera filen som om den kom frÃ¥n sökvägen" -#: builtin/help.c:42 +#: builtin/help.c:43 msgid "print all available commands" msgstr "visa alla tillgängliga kommandon" -#: builtin/help.c:43 +#: builtin/help.c:44 +msgid "print list of useful guides" +msgstr "lista användbara vägledningar" + +#: builtin/help.c:45 msgid "show man page" msgstr "visa manualsida" -#: builtin/help.c:44 +#: builtin/help.c:46 msgid "show manual in web browser" msgstr "visa manual i webbläsare" -#: builtin/help.c:46 +#: builtin/help.c:48 msgid "show info page" msgstr "visa info-sida" -#: builtin/help.c:52 -msgid "git help [--all] [--man|--web|--info] [command]" -msgstr "git help [--all] [--man|--web|--info] [kommando]" +#: builtin/help.c:54 +msgid "git help [--all] [--guides] [--man|--web|--info] [command]" +msgstr "git help [--all] [--guides] [--man|--web|--info] [kommando]" -#: builtin/help.c:64 +#: builtin/help.c:66 #, c-format msgid "unrecognized help format '%s'" msgstr "okänt hjälpformat: %s" -#: builtin/help.c:92 +#: builtin/help.c:94 msgid "Failed to start emacsclient." msgstr "Misslyckades starta emacsclient." -#: builtin/help.c:105 +#: builtin/help.c:107 msgid "Failed to parse emacsclient version." msgstr "Kunde inte tolka emacsclient-version." -#: builtin/help.c:113 +#: builtin/help.c:115 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "emacsclient version \"%d\" för gammal (< 22)." -#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 +#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 #, c-format msgid "failed to exec '%s': %s" msgstr "exec misslyckades för \"%s\": %s" -#: builtin/help.c:216 +#: builtin/help.c:218 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -4975,7 +5252,7 @@ msgstr "" "\"%s\": sökväg för man-visare som ej stöds.\n" "Använd \"man.<verktyg>.cmd\" istället." -#: builtin/help.c:228 +#: builtin/help.c:230 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -4984,303 +5261,335 @@ msgstr "" "\"%s\": kommando för man-visare som stöds.\n" "Använd \"man.<verktyg>.path\" istället." -#: builtin/help.c:349 +#: builtin/help.c:351 #, c-format msgid "'%s': unknown man viewer." msgstr "\"%s\": okänd man-visare." -#: builtin/help.c:366 +#: builtin/help.c:368 msgid "no man viewer handled the request" msgstr "ingen man-visare hanterade förfrÃ¥gan" -#: builtin/help.c:374 +#: builtin/help.c:376 msgid "no info viewer handled the request" msgstr "ingen info-visare hanterade förfrÃ¥gan" -#: builtin/help.c:429 builtin/help.c:436 +#: builtin/help.c:422 +msgid "Defining attributes per path" +msgstr "Definierar attribut per sökväg" + +#: builtin/help.c:423 +msgid "A Git glossary" +msgstr "En Git-ordlista" + +#: builtin/help.c:424 +msgid "Specifies intentionally untracked files to ignore" +msgstr "Ange avsiktligen ospÃ¥rade filer att ignorera" + +#: builtin/help.c:425 +msgid "Defining submodule properties" +msgstr "Ange egenskaper för undermoduler" + +#: builtin/help.c:426 +msgid "Specifying revisions and ranges for Git" +msgstr "Ange versioner och intervall i Git" + +#: builtin/help.c:427 +msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" +msgstr "Introduktion till Git (för version 1.5.1 och senare)" + +#: builtin/help.c:428 +msgid "An overview of recommended workflows with Git" +msgstr "Översikt över rekommenderade arbetsflöden med Git" + +#: builtin/help.c:440 +msgid "The common Git guides are:\n" +msgstr "De vanliga Git-vägledningarna är:\n" + +#: builtin/help.c:462 builtin/help.c:478 #, c-format msgid "usage: %s%s" msgstr "användning: %s%s" -#: builtin/help.c:452 +#: builtin/help.c:494 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "\"git %s\" är ett alias för \"%s\"" -#: builtin/index-pack.c:170 +#: builtin/index-pack.c:182 #, c-format msgid "object type mismatch at %s" msgstr "objekttyp stämmer inte överens vid %s" -#: builtin/index-pack.c:190 +#: builtin/index-pack.c:202 msgid "object of unexpected type" msgstr "objekt av oväntad typ" -#: builtin/index-pack.c:227 +#: builtin/index-pack.c:239 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "kan inte fylla %d byte" msgstr[1] "kan inte fylla %d byte" -#: builtin/index-pack.c:237 +#: builtin/index-pack.c:249 msgid "early EOF" msgstr "tidigt filslut" -#: builtin/index-pack.c:238 +#: builtin/index-pack.c:250 msgid "read error on input" msgstr "indataläsfel" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:262 msgid "used more bytes than were available" msgstr "använde fler byte än tillgängligt" -#: builtin/index-pack.c:257 +#: builtin/index-pack.c:269 msgid "pack too large for current definition of off_t" msgstr "paket för stort för nuvarande definition av off_t" -#: builtin/index-pack.c:273 +#: builtin/index-pack.c:285 #, c-format msgid "unable to create '%s'" msgstr "kunde inte skapa \"%s\"" -#: builtin/index-pack.c:278 +#: builtin/index-pack.c:290 #, c-format msgid "cannot open packfile '%s'" msgstr "kan inte öppna paketfilen \"%s\"" -#: builtin/index-pack.c:292 +#: builtin/index-pack.c:304 msgid "pack signature mismatch" msgstr "paketsignatur stämmer inte överens" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:306 #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "paketversion %<PRIu32> stöds ej" -#: builtin/index-pack.c:312 +#: builtin/index-pack.c:324 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "paketet har felaktigt objekt vid index %lu: %s" -#: builtin/index-pack.c:434 +#: builtin/index-pack.c:446 #, c-format msgid "inflate returned %d" msgstr "inflate returnerade %d" -#: builtin/index-pack.c:483 +#: builtin/index-pack.c:495 msgid "offset value overflow for delta base object" msgstr "indexvärdespill för deltabasobjekt" -#: builtin/index-pack.c:491 +#: builtin/index-pack.c:503 msgid "delta base offset is out of bound" msgstr "deltabasindex utanför gränsen" -#: builtin/index-pack.c:499 +#: builtin/index-pack.c:511 #, c-format msgid "unknown object type %d" msgstr "okänd objekttyp %d" -#: builtin/index-pack.c:530 +#: builtin/index-pack.c:542 msgid "cannot pread pack file" msgstr "kan inte utföra \"pread\" pÃ¥ paketfil" -#: builtin/index-pack.c:532 +#: builtin/index-pack.c:544 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "för tidigt slut pÃ¥ paketfilen, %lu byte saknas" msgstr[1] "för tidigt slut pÃ¥ paketfilen, %lu byte saknas" -#: builtin/index-pack.c:558 +#: builtin/index-pack.c:570 msgid "serious inflate inconsistency" msgstr "allvarlig inflate-inkonsekvens" -#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678 -#: builtin/index-pack.c:712 builtin/index-pack.c:721 +#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 +#: builtin/index-pack.c:724 builtin/index-pack.c:733 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "SHA1-KOLLISION UPPTÄCKT VID %s !" -#: builtin/index-pack.c:652 builtin/pack-objects.c:170 +#: builtin/index-pack.c:664 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "kunde inte läsa %s" -#: builtin/index-pack.c:718 +#: builtin/index-pack.c:730 #, c-format msgid "cannot read existing object %s" msgstr "kan inte läsa befintligt objekt %s" -#: builtin/index-pack.c:732 +#: builtin/index-pack.c:744 #, c-format msgid "invalid blob object %s" msgstr "ogiltigt blob-objekt %s" -#: builtin/index-pack.c:747 +#: builtin/index-pack.c:759 #, c-format msgid "invalid %s" msgstr "ogiltigt %s" -#: builtin/index-pack.c:749 +#: builtin/index-pack.c:761 msgid "Error in object" msgstr "Fel i objekt" -#: builtin/index-pack.c:751 +#: builtin/index-pack.c:763 #, c-format msgid "Not all child objects of %s are reachable" msgstr "Inte alla barnobjekt för %s kan nÃ¥s" -#: builtin/index-pack.c:821 builtin/index-pack.c:847 +#: builtin/index-pack.c:833 builtin/index-pack.c:863 msgid "failed to apply delta" msgstr "misslyckades tillämpa delta" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Receiving objects" msgstr "Tar emot objekt" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Indexing objects" msgstr "Skapar index för objekt" -#: builtin/index-pack.c:1012 +#: builtin/index-pack.c:1030 msgid "pack is corrupted (SHA1 mismatch)" msgstr "paketet är trasigt (SHA1 stämmer inte)" -#: builtin/index-pack.c:1017 +#: builtin/index-pack.c:1035 msgid "cannot fstat packfile" msgstr "kan inte utföra \"fstat\" pÃ¥ paketfil" -#: builtin/index-pack.c:1020 +#: builtin/index-pack.c:1038 msgid "pack has junk at the end" msgstr "paket har skräp i slutet" -#: builtin/index-pack.c:1031 +#: builtin/index-pack.c:1049 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "förvirrad bortom vanvett i parse_pack_objects()" -#: builtin/index-pack.c:1054 +#: builtin/index-pack.c:1072 msgid "Resolving deltas" msgstr "Analyserar delta" -#: builtin/index-pack.c:1064 +#: builtin/index-pack.c:1082 #, c-format msgid "unable to create thread: %s" msgstr "kunde inte skapa trÃ¥d: %s" -#: builtin/index-pack.c:1106 +#: builtin/index-pack.c:1124 msgid "confusion beyond insanity" msgstr "förvirrad bortom vanvett" -#: builtin/index-pack.c:1112 +#: builtin/index-pack.c:1132 #, c-format msgid "completed with %d local objects" msgstr "slutfördes med %d lokala objekt" -#: builtin/index-pack.c:1121 +#: builtin/index-pack.c:1142 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "Oväntad svanschecksumma för %s (trasig disk?)" -#: builtin/index-pack.c:1125 +#: builtin/index-pack.c:1146 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "paketet har %d oanalyserat delta" msgstr[1] "paketet har %d oanalyserade delta" -#: builtin/index-pack.c:1150 +#: builtin/index-pack.c:1171 #, c-format msgid "unable to deflate appended object (%d)" msgstr "kunde inte utföra \"deflate\" pÃ¥ tillagt objekt (%d)" -#: builtin/index-pack.c:1229 +#: builtin/index-pack.c:1250 #, c-format msgid "local object %s is corrupt" msgstr "lokalt objekt %s är trasigt" -#: builtin/index-pack.c:1253 +#: builtin/index-pack.c:1274 msgid "error while closing pack file" msgstr "fel vid stängning av paketfil" -#: builtin/index-pack.c:1266 +#: builtin/index-pack.c:1287 #, c-format msgid "cannot write keep file '%s'" msgstr "kan inte ta skriva \"keep\"-fil \"%s\"" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1295 #, c-format msgid "cannot close written keep file '%s'" msgstr "akn inte stänga skriven \"keep\"-fil \"%s\"" -#: builtin/index-pack.c:1287 +#: builtin/index-pack.c:1308 msgid "cannot store pack file" msgstr "kan inte spara paketfil" -#: builtin/index-pack.c:1298 +#: builtin/index-pack.c:1319 msgid "cannot store index file" msgstr "kan inte spara indexfil" -#: builtin/index-pack.c:1331 +#: builtin/index-pack.c:1352 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "felaktig pack.indexversion=%<PRIu32>" -#: builtin/index-pack.c:1337 +#: builtin/index-pack.c:1358 #, c-format msgid "invalid number of threads specified (%d)" msgstr "felaktigt antal trÃ¥dar angivet (%d)" -#: builtin/index-pack.c:1341 builtin/index-pack.c:1514 +#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 #, c-format msgid "no threads support, ignoring %s" msgstr "trÃ¥dstöd saknas, ignorerar %s" -#: builtin/index-pack.c:1399 +#: builtin/index-pack.c:1420 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Kan inte öppna befintlig paketfil \"%s\"" -#: builtin/index-pack.c:1401 +#: builtin/index-pack.c:1422 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "Kan inte öppna befintligt paket-idx-fil för \"%s\"" -#: builtin/index-pack.c:1448 +#: builtin/index-pack.c:1469 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "icke-delta: %d objekt" msgstr[1] "icke-delta: %d objekt" -#: builtin/index-pack.c:1455 +#: builtin/index-pack.c:1476 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "kedjelängd = %d: %lu objekt" msgstr[1] "kedjelängd = %d: %lu objekt" -#: builtin/index-pack.c:1482 +#: builtin/index-pack.c:1503 msgid "Cannot come back to cwd" msgstr "Kan inte gÃ¥ tillbaka till arbetskatalogen (cwd)" -#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 -#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 +#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 +#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 #, c-format msgid "bad %s" msgstr "felaktig %s" -#: builtin/index-pack.c:1559 +#: builtin/index-pack.c:1580 msgid "--fix-thin cannot be used without --stdin" msgstr "--fix-thin kan inte användas med --stdin" -#: builtin/index-pack.c:1563 builtin/index-pack.c:1573 +#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "paketfilnamnet \"%s\" slutar inte med \".pack\"" -#: builtin/index-pack.c:1582 +#: builtin/index-pack.c:1603 msgid "--verify with no packfile name given" msgstr "--verify angavs utan paketfilnamn" @@ -5448,345 +5757,340 @@ msgstr "Kan inte komma Ã¥t aktuell arbetskatalog" msgid "Cannot access work tree '%s'" msgstr "Kan inte komma Ã¥t arbetskatalogen \"%s\"" -#: builtin/log.c:39 -msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" -msgstr "git log [<flaggor>] [<sedan>..<till>] [[--] <sökväg>...]\n" - #: builtin/log.c:40 +msgid "git log [<options>] [<revision range>] [[--] <path>...]\n" +msgstr "git log [<flaggor>] [<versionsintervall>] [[--] <sökväg>...]\n" + +#: builtin/log.c:41 msgid " or: git show [options] <object>..." msgstr " eller: git show [flaggor] <objekt>..." -#: builtin/log.c:102 +#: builtin/log.c:103 msgid "suppress diff output" msgstr "undertryck diff-utdata" -#: builtin/log.c:103 +#: builtin/log.c:104 msgid "show source" msgstr "visa källkod" -#: builtin/log.c:104 +#: builtin/log.c:105 msgid "Use mail map file" msgstr "Använd e-postmappningsfil" -#: builtin/log.c:105 +#: builtin/log.c:106 msgid "decorate options" msgstr "dekoreringsflaggor" -#: builtin/log.c:198 +#: builtin/log.c:199 #, c-format msgid "Final output: %d %s\n" msgstr "Slututdata: %d %s\n" -#: builtin/log.c:419 builtin/log.c:511 +#: builtin/log.c:422 builtin/log.c:514 #, c-format msgid "Could not read object %s" msgstr "Kunde inte läsa objektet %s" -#: builtin/log.c:535 +#: builtin/log.c:538 #, c-format msgid "Unknown type: %d" msgstr "Okänd typ: %d" -#: builtin/log.c:627 +#: builtin/log.c:638 msgid "format.headers without value" msgstr "format.headers utan värde" -#: builtin/log.c:701 +#: builtin/log.c:720 msgid "name of output directory is too long" msgstr "namnet pÃ¥ utdatakatalogen är för lÃ¥ngt" -#: builtin/log.c:717 +#: builtin/log.c:736 #, c-format msgid "Cannot open patch file %s" msgstr "Kan inte öppna patchfilen %s" -#: builtin/log.c:731 +#: builtin/log.c:750 msgid "Need exactly one range." msgstr "Behöver precis ett intervall." -#: builtin/log.c:739 +#: builtin/log.c:758 msgid "Not a range." msgstr "Inte ett intervall." -#: builtin/log.c:812 +#: builtin/log.c:860 msgid "Cover letter needs email format" msgstr "Omslagsbrevet behöver e-postformat" -#: builtin/log.c:885 +#: builtin/log.c:936 #, c-format msgid "insane in-reply-to: %s" msgstr "tokigt in-reply-to: %s" -#: builtin/log.c:913 +#: builtin/log.c:964 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "git format-patch [flaggor] [<sedan> | <revisionsintervall>]" -#: builtin/log.c:958 +#: builtin/log.c:1009 msgid "Two output directories?" msgstr "TvÃ¥ utdatakataloger?" -#: builtin/log.c:1097 +#: builtin/log.c:1108 msgid "use [PATCH n/m] even with a single patch" msgstr "använd [PATCH n/m] även för en ensam patch" -#: builtin/log.c:1100 +#: builtin/log.c:1111 msgid "use [PATCH] even with multiple patches" msgstr "använd [PATCH] även för flera patchar" -#: builtin/log.c:1104 +#: builtin/log.c:1115 msgid "print patches to standard out" msgstr "skriv patcharna pÃ¥ stnadard ut" -#: builtin/log.c:1106 +#: builtin/log.c:1117 msgid "generate a cover letter" msgstr "generera ett följebrev" -#: builtin/log.c:1108 +#: builtin/log.c:1119 msgid "use simple number sequence for output file names" msgstr "använd enkel nummersekvens för utdatafilnamn" -#: builtin/log.c:1109 +#: builtin/log.c:1120 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1110 +#: builtin/log.c:1121 msgid "use <sfx> instead of '.patch'" msgstr "använd <sfx> istället för \".patch\"" -#: builtin/log.c:1112 +#: builtin/log.c:1123 msgid "start numbering patches at <n> instead of 1" msgstr "börja numrera patchar pÃ¥ <n> istället för 1" -#: builtin/log.c:1114 +#: builtin/log.c:1125 msgid "mark the series as Nth re-roll" msgstr "markera serien som N:te försök" -#: builtin/log.c:1116 +#: builtin/log.c:1127 msgid "Use [<prefix>] instead of [PATCH]" msgstr "Använd [<prefix>] istället för [PATCH]" -#: builtin/log.c:1119 +#: builtin/log.c:1130 msgid "store resulting files in <dir>" msgstr "spara filerna i <katalog>" -#: builtin/log.c:1122 +#: builtin/log.c:1133 msgid "don't strip/add [PATCH]" msgstr "ta inte bort eller lägg till [PATCH]" -#: builtin/log.c:1125 +#: builtin/log.c:1136 msgid "don't output binary diffs" msgstr "skriv inte binära diffar" -#: builtin/log.c:1127 +#: builtin/log.c:1138 msgid "don't include a patch matching a commit upstream" msgstr "ta inte med patchar som motsvarar en uppströmsincheckning" -#: builtin/log.c:1129 +#: builtin/log.c:1140 msgid "show patch format instead of default (patch + stat)" msgstr "visa patchformat istället för standard (patch + stat)" -#: builtin/log.c:1131 +#: builtin/log.c:1142 msgid "Messaging" msgstr "E-post" -#: builtin/log.c:1132 +#: builtin/log.c:1143 msgid "header" msgstr "huvud" -#: builtin/log.c:1133 +#: builtin/log.c:1144 msgid "add email header" msgstr "lägg till e-posthuvud" -#: builtin/log.c:1134 builtin/log.c:1136 +#: builtin/log.c:1145 builtin/log.c:1147 msgid "email" msgstr "epost" -#: builtin/log.c:1134 +#: builtin/log.c:1145 msgid "add To: header" msgstr "Lägg till mottagarhuvud (\"To:\")" -#: builtin/log.c:1136 +#: builtin/log.c:1147 msgid "add Cc: header" msgstr "Lägg till kopiehuvud (\"Cc:\")" -#: builtin/log.c:1138 +#: builtin/log.c:1149 msgid "message-id" msgstr "meddelande-id" -#: builtin/log.c:1139 +#: builtin/log.c:1150 msgid "make first mail a reply to <message-id>" msgstr "Gör det första brevet ett svar till <meddelande-id>" -#: builtin/log.c:1140 builtin/log.c:1143 +#: builtin/log.c:1151 builtin/log.c:1154 msgid "boundary" msgstr "gräns" -#: builtin/log.c:1141 +#: builtin/log.c:1152 msgid "attach the patch" msgstr "bifoga patchen" -#: builtin/log.c:1144 +#: builtin/log.c:1155 msgid "inline the patch" msgstr "gör patchen ett inline-objekt" -#: builtin/log.c:1148 +#: builtin/log.c:1159 msgid "enable message threading, styles: shallow, deep" msgstr "aktivera brevtrÃ¥dning, typer: shallow, deep" -#: builtin/log.c:1150 +#: builtin/log.c:1161 msgid "signature" msgstr "signatur" -#: builtin/log.c:1151 +#: builtin/log.c:1162 msgid "add a signature" msgstr "lägg till signatur" -#: builtin/log.c:1153 +#: builtin/log.c:1164 msgid "don't print the patch filenames" msgstr "visa inte filnamn för patchar" -#: builtin/log.c:1202 -#, c-format -msgid "bogus committer info %s" -msgstr "felaktig incheckarinformation %s" - -#: builtin/log.c:1247 +#: builtin/log.c:1248 msgid "-n and -k are mutually exclusive." msgstr "-n och -k kan inte användas samtidigt." -#: builtin/log.c:1249 +#: builtin/log.c:1250 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix och -k kan inte användas samtidigt." -#: builtin/log.c:1257 +#: builtin/log.c:1258 msgid "--name-only does not make sense" msgstr "kan inte använda --name-only" -#: builtin/log.c:1259 +#: builtin/log.c:1260 msgid "--name-status does not make sense" msgstr "kan inte använda --name-status" -#: builtin/log.c:1261 +#: builtin/log.c:1262 msgid "--check does not make sense" msgstr "kan inte använda --check" -#: builtin/log.c:1284 +#: builtin/log.c:1285 msgid "standard output, or directory, which one?" msgstr "standard ut, eller katalog, vilken skall det vara?" -#: builtin/log.c:1286 +#: builtin/log.c:1287 #, c-format msgid "Could not create directory '%s'" msgstr "Kunde inte skapa katalogen \"%s\"" -#: builtin/log.c:1439 +#: builtin/log.c:1435 msgid "Failed to create output files" msgstr "Misslyckades skapa utdatafiler" -#: builtin/log.c:1488 +#: builtin/log.c:1484 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<uppström> [<huvud> [<gräns>]]]" -#: builtin/log.c:1543 +#: builtin/log.c:1539 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" msgstr "Kunde inte hitta en spÃ¥rad fjärrgren, ange <uppström> manuellt.\n" -#: builtin/log.c:1556 builtin/log.c:1558 builtin/log.c:1570 +#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 #, c-format msgid "Unknown commit %s" msgstr "Okänd incheckning %s" -#: builtin/ls-files.c:409 +#: builtin/ls-files.c:402 msgid "git ls-files [options] [<file>...]" msgstr "git ls-files [flaggor] [<fil>...]" -#: builtin/ls-files.c:466 +#: builtin/ls-files.c:459 msgid "identify the file status with tags" msgstr "identifiera filstatus med taggar" -#: builtin/ls-files.c:468 +#: builtin/ls-files.c:461 msgid "use lowercase letters for 'assume unchanged' files" msgstr "använd smÃ¥ bokstäver för \"anta oförändrade\"-filer" -#: builtin/ls-files.c:470 +#: builtin/ls-files.c:463 msgid "show cached files in the output (default)" msgstr "visa cachade filer i utdata (standard)" -#: builtin/ls-files.c:472 +#: builtin/ls-files.c:465 msgid "show deleted files in the output" msgstr "visa borttagna filer i utdata" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:467 msgid "show modified files in the output" msgstr "visa modifierade filer i utdata" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:469 msgid "show other files in the output" msgstr "visa andra filer i utdata" -#: builtin/ls-files.c:478 +#: builtin/ls-files.c:471 msgid "show ignored files in the output" msgstr "visa ignorerade filer i utdata" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:474 msgid "show staged contents' object name in the output" msgstr "visa köat innehÃ¥lls objektnamn i utdata" -#: builtin/ls-files.c:483 +#: builtin/ls-files.c:476 msgid "show files on the filesystem that need to be removed" msgstr "visa filer i filsystemet som behöver tas bort" -#: builtin/ls-files.c:485 +#: builtin/ls-files.c:478 msgid "show 'other' directories' name only" msgstr "visa endast namn för \"andra\" kataloger" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:481 msgid "don't show empty directories" msgstr "visa inte tomma kataloger" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:484 msgid "show unmerged files in the output" msgstr "visa ej sammanslagna filer i utdata" -#: builtin/ls-files.c:493 +#: builtin/ls-files.c:486 msgid "show resolve-undo information" msgstr "visa \"resolve-undo\"-information" -#: builtin/ls-files.c:495 +#: builtin/ls-files.c:488 msgid "skip files matching pattern" msgstr "hoppa över filer som motsvarar mönster" -#: builtin/ls-files.c:498 +#: builtin/ls-files.c:491 msgid "exclude patterns are read from <file>" msgstr "exkludera mönster som läses frÃ¥n <fil>" -#: builtin/ls-files.c:501 +#: builtin/ls-files.c:494 msgid "read additional per-directory exclude patterns in <file>" msgstr "läs ytterligare per-katalog-exkluderingsmönster frÃ¥n <fil>" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:496 msgid "add the standard git exclusions" msgstr "lägg till git:s standardexkluderingar" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:499 msgid "make the output relative to the project top directory" msgstr "gör utdata relativ till projektets toppkatalog" -#: builtin/ls-files.c:509 +#: builtin/ls-files.c:502 msgid "if any <file> is not in the index, treat this as an error" msgstr "om en <fil> inte är indexet, betrakta det som ett fel" -#: builtin/ls-files.c:510 +#: builtin/ls-files.c:503 msgid "tree-ish" msgstr "träd-igt" -#: builtin/ls-files.c:511 +#: builtin/ls-files.c:504 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "lÃ¥tsas att sökvägar borttagna sedan <träd-igt> fortfarande finns" -#: builtin/ls-files.c:513 +#: builtin/ls-files.c:506 msgid "show debugging data" msgstr "visa felsökningsutdata" @@ -5894,110 +6198,114 @@ msgstr "tillÃ¥t snabbspolning (standard)" msgid "abort if fast-forward is not possible" msgstr "avbryt om snabbspolning inte är möjlig" -#: builtin/merge.c:202 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:203 +msgid "Verify that the named commit has a valid GPG signature" +msgstr "Bekräfta att den namngivna incheckningen har en giltig GPG-signatur" + +#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112 msgid "strategy" msgstr "strategi" -#: builtin/merge.c:203 +#: builtin/merge.c:205 msgid "merge strategy to use" msgstr "sammanslagninsstrategi att använda" -#: builtin/merge.c:204 +#: builtin/merge.c:206 msgid "option=value" msgstr "alternativ=värde" -#: builtin/merge.c:205 +#: builtin/merge.c:207 msgid "option for selected merge strategy" msgstr "alternativ för vald sammanslagningsstrategi" -#: builtin/merge.c:207 +#: builtin/merge.c:209 msgid "merge commit message (for a non-fast-forward merge)" msgstr "incheckningsmeddelande för (icke snabbspolande) sammanslagning" -#: builtin/merge.c:211 +#: builtin/merge.c:213 msgid "abort the current in-progress merge" msgstr "avbryt den pÃ¥gÃ¥ende sammanslagningen" -#: builtin/merge.c:240 +#: builtin/merge.c:242 msgid "could not run stash." msgstr "kunde köra stash." -#: builtin/merge.c:245 +#: builtin/merge.c:247 msgid "stash failed" msgstr "stash misslyckades" -#: builtin/merge.c:250 +#: builtin/merge.c:252 #, c-format msgid "not a valid object: %s" msgstr "inte ett giltigt objekt: %s" -#: builtin/merge.c:269 builtin/merge.c:286 +#: builtin/merge.c:271 builtin/merge.c:288 msgid "read-tree failed" msgstr "read-tree misslyckades" -#: builtin/merge.c:316 +#: builtin/merge.c:318 msgid " (nothing to squash)" msgstr " (inget att platta till)" -#: builtin/merge.c:329 +#: builtin/merge.c:331 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Tillplattningsincheckning -- uppdaterar inte HEAD\n" -#: builtin/merge.c:361 +#: builtin/merge.c:363 msgid "Writing SQUASH_MSG" msgstr "Skriver SQUASH_MSG" -#: builtin/merge.c:363 +#: builtin/merge.c:365 msgid "Finishing SQUASH_MSG" msgstr "Avslutar SQUASH_MSG" -#: builtin/merge.c:386 +#: builtin/merge.c:388 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "Inget sammanslagningsmeddelande -- uppdaterar inte HEAD\n" -#: builtin/merge.c:436 +#: builtin/merge.c:438 #, c-format msgid "'%s' does not point to a commit" msgstr "\"%s\" verkar inte peka pÃ¥ en incheckning" -#: builtin/merge.c:535 +#: builtin/merge.c:550 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Felaktig branch.%s.mergeoptions-sträng: %s" -#: builtin/merge.c:628 +#: builtin/merge.c:643 msgid "git write-tree failed to write a tree" msgstr "git write-tree misslyckades skriva ett träd" -#: builtin/merge.c:656 +#: builtin/merge.c:671 msgid "Not handling anything other than two heads merge." msgstr "Hanterar inte nÃ¥got annat än en sammanslagning av tvÃ¥ huvuden." -#: builtin/merge.c:670 +#: builtin/merge.c:685 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "Felaktig flagga för merge-recursive: -X%s" -#: builtin/merge.c:684 +#: builtin/merge.c:699 #, c-format msgid "unable to write %s" msgstr "kunde inte skriva %s" -#: builtin/merge.c:773 +#: builtin/merge.c:788 #, c-format msgid "Could not read from '%s'" msgstr "Kunde inte läsa frÃ¥n \"%s\"" -#: builtin/merge.c:782 +#: builtin/merge.c:797 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "" "Checkar inte in sammanslagningen; använd \"git commit\" för att slutföra " "den.\n" -#: builtin/merge.c:788 +#: builtin/merge.c:803 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6013,53 +6321,53 @@ msgstr "" "Rader som inleds med \"%c\" kommer ignoreras, och ett tomt meddelande\n" "avbryter incheckningen.\n" -#: builtin/merge.c:812 +#: builtin/merge.c:827 msgid "Empty commit message." msgstr "Tomt incheckningsmeddelande." -#: builtin/merge.c:824 +#: builtin/merge.c:839 #, c-format msgid "Wonderful.\n" msgstr "Underbart.\n" -#: builtin/merge.c:889 +#: builtin/merge.c:904 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "" "Kunde inte slÃ¥ ihop automatiskt; fixa konflikter och checka in resultatet.\n" -#: builtin/merge.c:905 +#: builtin/merge.c:920 #, c-format msgid "'%s' is not a commit" msgstr "\"%s\" är inte en incheckning" -#: builtin/merge.c:946 +#: builtin/merge.c:961 msgid "No current branch." msgstr "Inte pÃ¥ nÃ¥gon gren." -#: builtin/merge.c:948 +#: builtin/merge.c:963 msgid "No remote for the current branch." msgstr "Ingen fjärr för aktuell gren." -#: builtin/merge.c:950 +#: builtin/merge.c:965 msgid "No default upstream defined for the current branch." msgstr "Ingen standarduppström angiven för aktuell gren." -#: builtin/merge.c:955 +#: builtin/merge.c:970 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "Ingen fjärrspÃ¥rande gren för %s frÃ¥n %s" -#: builtin/merge.c:1042 builtin/merge.c:1199 +#: builtin/merge.c:1057 builtin/merge.c:1214 #, c-format msgid "%s - not something we can merge" msgstr "%s - inte nÃ¥got vi kan slÃ¥ ihop" -#: builtin/merge.c:1110 +#: builtin/merge.c:1125 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "Det finns ingen sammanslagning att avbryta (MERGE_HEAD saknas)." -#: builtin/merge.c:1126 git-pull.sh:31 +#: builtin/merge.c:1141 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6067,11 +6375,11 @@ msgstr "" "Du har inte avslutat sammanslagningen (MERGE_HEAD finns).\n" "Checka in dina ändringar innan du kan slÃ¥ ihop." -#: builtin/merge.c:1129 git-pull.sh:34 +#: builtin/merge.c:1144 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Du har inte avslutat sammanslagningen (MERGE_HEAD finns)." -#: builtin/merge.c:1133 +#: builtin/merge.c:1148 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6079,79 +6387,102 @@ msgstr "" "Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns).\n" "Checka in dina ändringar innan du kan slÃ¥ ihop." -#: builtin/merge.c:1136 +#: builtin/merge.c:1151 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "Du har inte avslutat din \"cherry-pick\" (CHERRY_PICK_HEAD finns)." -#: builtin/merge.c:1145 +#: builtin/merge.c:1160 msgid "You cannot combine --squash with --no-ff." msgstr "Du kan inte kombinera --squash med --no-ff." -#: builtin/merge.c:1150 +#: builtin/merge.c:1165 msgid "You cannot combine --no-ff with --ff-only." msgstr "Du kan inte kombinera --no-ff med --ff-only." -#: builtin/merge.c:1157 +#: builtin/merge.c:1172 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "Ingen incheckning angiven och merge.defaultToUpstream är ej satt." -#: builtin/merge.c:1189 +#: builtin/merge.c:1204 msgid "Can merge only exactly one commit into empty head" msgstr "Kan endast slÃ¥ ihop en enda incheckning i ett tomt huvud." -#: builtin/merge.c:1192 +#: builtin/merge.c:1207 msgid "Squash commit into empty head not supported yet" msgstr "Stöder inte en tillplattningsincheckning pÃ¥ ett tomt huvud ännu" -#: builtin/merge.c:1194 +#: builtin/merge.c:1209 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "Icke-snabbspolad incheckning kan inte användas med ett tomt huvud" -#: builtin/merge.c:1310 +#: builtin/merge.c:1265 +#, c-format +msgid "Commit %s has an untrusted GPG signature, allegedly by %s." +msgstr "" +"Incheckningen %s har en obetrodd GPG-signatur som pÃ¥stÃ¥s vara gjord av %s." + +#: builtin/merge.c:1268 +#, c-format +msgid "Commit %s has a bad GPG signature allegedly by %s." +msgstr "" +"Incheckningen %s har en felaktig GPG-signatur som pÃ¥stÃ¥s vara gjord av %s." + +#. 'N' +#: builtin/merge.c:1271 +#, c-format +msgid "Commit %s does not have a GPG signature." +msgstr "Incheckning %s har inte nÃ¥gon GPG-signatur." + +#: builtin/merge.c:1274 +#, c-format +msgid "Commit %s has a good GPG signature by %s\n" +msgstr "Incheckningen %s har en korrekt GPG-signatur av %s\n" + +#: builtin/merge.c:1358 #, c-format msgid "Updating %s..%s\n" msgstr "Uppdaterar %s..%s\n" -#: builtin/merge.c:1349 +#: builtin/merge.c:1397 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "Försöker riktigt enkel sammanslagning i indexet...\n" -#: builtin/merge.c:1356 +#: builtin/merge.c:1404 #, c-format msgid "Nope.\n" msgstr "Nej.\n" -#: builtin/merge.c:1388 +#: builtin/merge.c:1436 msgid "Not possible to fast-forward, aborting." msgstr "Kan inte snabbspola, avbryter." -#: builtin/merge.c:1411 builtin/merge.c:1490 +#: builtin/merge.c:1459 builtin/merge.c:1538 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "Ã…terspolar trädet till orört...\n" -#: builtin/merge.c:1415 +#: builtin/merge.c:1463 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Försöker sammanslagninsstrategin %s...\n" -#: builtin/merge.c:1481 +#: builtin/merge.c:1529 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "Ingen sammanslagningsstrategi hanterade sammanslagningen.\n" -#: builtin/merge.c:1483 +#: builtin/merge.c:1531 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "Sammanslagning med strategin %s misslyckades.\n" -#: builtin/merge.c:1492 +#: builtin/merge.c:1540 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "Använder %s för att förbereda lösning för hand.\n" -#: builtin/merge.c:1504 +#: builtin/merge.c:1552 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -7193,11 +7524,15 @@ msgstr "ta bort lokalt borttagna referenser" msgid "bypass pre-push hook" msgstr "förbigÃ¥ pre-push-krok" -#: builtin/push.c:448 +#: builtin/push.c:440 +msgid "push missing but relevant tags" +msgstr "sänd in saknade men relevanta taggar" + +#: builtin/push.c:450 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "--delete är imkompatibel med --all, --mirror och --tags" -#: builtin/push.c:450 +#: builtin/push.c:452 msgid "--delete doesn't make sense without any refs" msgstr "--delete kan inte användas utan referenser" @@ -7953,16 +8288,16 @@ msgstr "" "varianten." #: builtin/revert.c:22 -msgid "git revert [options] <commit-ish>" -msgstr "git revert [flaggor] <incheckning-igt>" +msgid "git revert [options] <commit-ish>..." +msgstr "git revert [flaggor] <incheckning-igt>..." #: builtin/revert.c:23 msgid "git revert <subcommand>" msgstr "git revert <underkommando>" #: builtin/revert.c:28 -msgid "git cherry-pick [options] <commit-ish>" -msgstr "git cherry-pick [flaggor] <incheckning-igt>" +msgid "git cherry-pick [options] <commit-ish>..." +msgstr "git cherry-pick [flaggor] <incheckning-igt>..." #: builtin/revert.c:29 msgid "git cherry-pick <subcommand>" @@ -8113,32 +8448,31 @@ msgid "git rm: unable to remove %s" msgstr "git rm: kan inte ta bort %s" #: builtin/shortlog.c:13 -msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" -msgstr "" -"git shortlog [-n] [-s] [-e] [-w] [rev-flaggor] [--] [<incheckning-id>... ]" +msgid "git shortlog [<options>] [<revision range>] [[--] [<path>...]]" +msgstr "git shortlog [<flaggor>] [<versionsintervall>] [[--] <sökväg>...]" -#: builtin/shortlog.c:133 +#: builtin/shortlog.c:131 #, c-format msgid "Missing author: %s" msgstr "Författare saknas: %s" -#: builtin/shortlog.c:229 +#: builtin/shortlog.c:227 msgid "sort output according to the number of commits per author" msgstr "sortera utdata enligt antal incheckningar per författare" -#: builtin/shortlog.c:231 +#: builtin/shortlog.c:229 msgid "Suppress commit descriptions, only provides commit count" msgstr "Undertryck beskrivningar, visa bara antal incheckningar" -#: builtin/shortlog.c:233 +#: builtin/shortlog.c:231 msgid "Show the email address of each author" msgstr "Visa e-postadress för varje författare" -#: builtin/shortlog.c:234 +#: builtin/shortlog.c:232 msgid "w[,i1[,i2]]" msgstr "w[,i1[,i2]]" -#: builtin/shortlog.c:235 +#: builtin/shortlog.c:233 msgid "Linewrap output" msgstr "Radbryt utdata" @@ -8158,67 +8492,67 @@ msgstr "" msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "git show-branch (-g|--reflog)[=<n>[,<bas>]] [--list] [<ref>]" -#: builtin/show-branch.c:651 +#: builtin/show-branch.c:650 msgid "show remote-tracking and local branches" msgstr "visa fjärrspÃ¥rande och lokala grenar" -#: builtin/show-branch.c:653 +#: builtin/show-branch.c:652 msgid "show remote-tracking branches" msgstr "visa fjärrspÃ¥rande grenar" -#: builtin/show-branch.c:655 +#: builtin/show-branch.c:654 msgid "color '*!+-' corresponding to the branch" msgstr "färga \"*!+-\" enligt grenen" -#: builtin/show-branch.c:657 +#: builtin/show-branch.c:656 msgid "show <n> more commits after the common ancestor" msgstr "visa <n> ytterligare incheckningar efter gemensam anfader" -#: builtin/show-branch.c:659 +#: builtin/show-branch.c:658 msgid "synonym to more=-1" msgstr "synonym till more=-1" -#: builtin/show-branch.c:660 +#: builtin/show-branch.c:659 msgid "suppress naming strings" msgstr "undertyck namnsträngar" -#: builtin/show-branch.c:662 +#: builtin/show-branch.c:661 msgid "include the current branch" msgstr "inkludera aktuell gren" -#: builtin/show-branch.c:664 +#: builtin/show-branch.c:663 msgid "name commits with their object names" msgstr "namnge incheckningar med deras objektnamn" -#: builtin/show-branch.c:666 +#: builtin/show-branch.c:665 msgid "show possible merge bases" msgstr "visa möjliga sammanslaningsbaser" -#: builtin/show-branch.c:668 +#: builtin/show-branch.c:667 msgid "show refs unreachable from any other ref" msgstr "visa referenser som inte kan nÃ¥s frÃ¥n nÃ¥gon annan referens" -#: builtin/show-branch.c:670 +#: builtin/show-branch.c:669 msgid "show commits in topological order" msgstr "visa incheckningar i topologisk ordning" -#: builtin/show-branch.c:672 +#: builtin/show-branch.c:671 msgid "show only commits not on the first branch" msgstr "visa endast incheckningar inte pÃ¥ den första grenen" -#: builtin/show-branch.c:674 +#: builtin/show-branch.c:673 msgid "show merges reachable from only one tip" msgstr "visa sammanslagningar som endast kan nÃ¥s frÃ¥n en spets" -#: builtin/show-branch.c:676 +#: builtin/show-branch.c:675 msgid "show commits where no parent comes before its children" msgstr "visa incheckningar där ingen förälder kommer före dess barn" -#: builtin/show-branch.c:678 +#: builtin/show-branch.c:677 msgid "<n>[,<base>]" msgstr "<n>[,<bas>]" -#: builtin/show-branch.c:679 +#: builtin/show-branch.c:678 msgid "show <n> most recent ref-log entries starting at base" msgstr "visa <n> nyaste refloggposter med början pÃ¥ bas" @@ -8678,9 +9012,14 @@ msgid "only useful for debugging" msgstr "endast användbart vid felsökning" #: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." +msgid "" +"'git help -a' and 'git help -g' lists available subcommands and some\n" +"concept guides. See 'git help <command>' or 'git help <concept>'\n" +"to read about a specific subcommand or concept." msgstr "" -"Se \"git help <kommando>\" för mer information om ett specifikt kommando." +"\"git help -a\" och \"git help -g\" visar tillgängliga underkommandon och\n" +"nÃ¥gra konceptvägledningar. Se \"git help <kommando>\" eller \"git help\n" +"<koncept>\" för att läsa mer om specifika underkommandon och koncept." #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -9047,16 +9386,16 @@ msgstr "" "Du mÃ¥ste sedan ange Ã¥tminstone en bra och en dÃ¥lig version.\n" "(Du kan använda \"git bisect bad\" och \"git bisect good\" för detta.)" -#: git-bisect.sh:347 git-bisect.sh:474 +#: git-bisect.sh:363 git-bisect.sh:490 msgid "We are not bisecting." msgstr "Vi utför ingen bisect för tillfället." -#: git-bisect.sh:354 +#: git-bisect.sh:370 #, sh-format msgid "'$invalid' is not a valid commit" msgstr "\"$invalid\" är inte en giltig incheckning" -#: git-bisect.sh:363 +#: git-bisect.sh:379 #, sh-format msgid "" "Could not check out original HEAD '$branch'.\n" @@ -9065,25 +9404,25 @@ msgstr "" "Kunde inte checka ut original-HEAD \"$branch\".\n" "Försök \"git bisect reset <incheckning>\"." -#: git-bisect.sh:390 +#: git-bisect.sh:406 msgid "No logfile given" msgstr "Ingen loggfil angiven" -#: git-bisect.sh:391 +#: git-bisect.sh:407 #, sh-format msgid "cannot read $file for replaying" msgstr "kan inte läsa $file för uppspelning" -#: git-bisect.sh:408 +#: git-bisect.sh:424 msgid "?? what are you talking about?" msgstr "?? vad menar du?" -#: git-bisect.sh:420 +#: git-bisect.sh:436 #, sh-format msgid "running $command" msgstr "kör $command" -#: git-bisect.sh:427 +#: git-bisect.sh:443 #, sh-format msgid "" "bisect run failed:\n" @@ -9092,11 +9431,11 @@ msgstr "" "\"bisect\"-körningen misslyckades:\n" "felkod $res frÃ¥n \"$command\" är < 0 eller >= 128" -#: git-bisect.sh:453 +#: git-bisect.sh:469 msgid "bisect run cannot continue any more" msgstr "\"bisect\"-körningen kan inte fortsätta längre" -#: git-bisect.sh:459 +#: git-bisect.sh:475 #, sh-format msgid "" "bisect run failed:\n" @@ -9105,7 +9444,7 @@ msgstr "" "\"bisect\"-körningen misslyckades:\n" "\"bisect_state $state\" avslutades med felkoden $res" -#: git-bisect.sh:466 +#: git-bisect.sh:482 msgid "bisect run success" msgstr "\"bisect\"-körningen lyckades" @@ -9123,7 +9462,7 @@ msgstr "" msgid "Pull is not possible because you have unmerged files." msgstr "Du kan inte göra en \"pull\" dÃ¥ du har ändringar som inte checkats in." -#: git-pull.sh:197 +#: git-pull.sh:203 msgid "updating an unborn branch with changes added to the index" msgstr "uppdaterar en ofödd gren med ändringar som lagts till i indexet" @@ -9131,7 +9470,7 @@ msgstr "uppdaterar en ofödd gren med ändringar som lagts till i indexet" #. The working tree and the index file is still based on the #. $orig_head commit, but we are merging into $curr_head. #. First update the working tree to match $curr_head. -#: git-pull.sh:229 +#: git-pull.sh:235 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -9142,11 +9481,11 @@ msgstr "" "Varning: snabbspolar din arbetskatalog frÃ¥n\n" "Varning: incheckningen $orig_head." -#: git-pull.sh:254 +#: git-pull.sh:260 msgid "Cannot merge multiple branches into empty head" msgstr "Kan inte slÃ¥ ihop flera grenar i ett tomt huvud." -#: git-pull.sh:258 +#: git-pull.sh:264 msgid "Cannot rebase onto multiple branches" msgstr "Kan inte utföra en \"rebase\" ovanpÃ¥ flera grenar" @@ -9403,38 +9742,38 @@ msgstr "Inget grennamn angavs" msgid "(To restore them type \"git stash apply\")" msgstr "(För att Ã¥terställa dem, skriv \"git stash apply\")" -#: git-submodule.sh:90 +#: git-submodule.sh:91 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "kan inte ta bort en komponent frÃ¥n url:en \"$remoteurl\"" -#: git-submodule.sh:195 +#: git-submodule.sh:196 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" "Hittade ingen undermodulmappning i .gitmodules för sökvägen \"$sm_path\"" -#: git-submodule.sh:238 +#: git-submodule.sh:239 #, sh-format msgid "Clone of '$url' into submodule path '$sm_path' failed" msgstr "Misslyckades klona \"$url\" till undermodulsökvägen \"$sm_path\"" -#: git-submodule.sh:250 +#: git-submodule.sh:251 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "Gitkatalog \"$a\" ingÃ¥r i underkatalogsökvägen \"$b\" eller omvänt" -#: git-submodule.sh:343 +#: git-submodule.sh:349 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "arkiv-URL: \"$repo\" mÃ¥ste vara absolut eller börja med ./|../" -#: git-submodule.sh:360 +#: git-submodule.sh:366 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "\"$sm_path\" finns redan i indexet" -#: git-submodule.sh:364 +#: git-submodule.sh:370 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9445,22 +9784,22 @@ msgstr "" "$sm_path\n" "Använd -f om du verkligen vill lägga till den" -#: git-submodule.sh:382 +#: git-submodule.sh:388 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "Lägger till befintligt arkiv i \"$sm_path\" i indexet" -#: git-submodule.sh:384 +#: git-submodule.sh:390 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "\"$sm_path\" finns redan och är inte ett giltigt git-arkiv" -#: git-submodule.sh:392 +#: git-submodule.sh:398 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "En git-katalog för \"$sm_name\" hittades lokalt med fjärr(ar):" -#: git-submodule.sh:394 +#: git-submodule.sh:400 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" @@ -9468,14 +9807,14 @@ msgstr "" "För att Ã¥teranvända den lokala git-katalogen istället för att pÃ¥ nytt klona " "frÃ¥n" -#: git-submodule.sh:396 +#: git-submodule.sh:402 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" msgstr "" "använd flaggan \"--force\". Om den lokala git-katalogen inte är riktigt arkiv" -#: git-submodule.sh:397 +#: git-submodule.sh:403 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " @@ -9484,154 +9823,240 @@ msgstr "" "eller om du är osäker pÃ¥ vad det innebär, välj nytt namn med flaggan \"--name" "\"." -#: git-submodule.sh:399 +#: git-submodule.sh:405 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "Aktiverar lokal git-katalog för undermodulen \"$sm_name\" pÃ¥ nytt." -#: git-submodule.sh:411 +#: git-submodule.sh:417 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "Kan inte checka ut undermodulen \"$sm_path\"" -#: git-submodule.sh:416 +#: git-submodule.sh:422 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "Misslyckades lägga till undermodulen \"$sm_path\"" -#: git-submodule.sh:425 +#: git-submodule.sh:431 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "Misslyckades registrera undermodulen \"$sm_path\"" -#: git-submodule.sh:468 +#: git-submodule.sh:474 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "GÃ¥r in i \"$prefix$sm_path\"" -#: git-submodule.sh:482 +#: git-submodule.sh:488 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "" "Stoppar pÃ¥ \"$sm_path\"; skriptet returnerade en status skild frÃ¥n noll." -#: git-submodule.sh:526 +#: git-submodule.sh:532 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "Hittade ingen url för undermodulsökvägen \"$sm_path\" i .gitmodules" -#: git-submodule.sh:535 +#: git-submodule.sh:541 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "Misslyckades registrera url för underkatalogsökväg \"$sm_path\"" -#: git-submodule.sh:537 +#: git-submodule.sh:543 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "Undermodulen \"$name\" ($url) registrerad för sökvägen \"$sm_path\"" -#: git-submodule.sh:545 +#: git-submodule.sh:551 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" "Misslyckades registrera uppdateringsläge för undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:649 +#: git-submodule.sh:588 +#, sh-format +msgid "Use '.' if you really want to deinitialize all submodules" +msgstr "Använd \".\" om du verkligen vill avinitiera alla undermoduler" + +#: git-submodule.sh:603 +#, sh-format +msgid "Submodule work tree '$sm_path' contains a .git directory" +msgstr "Undermodulens arbetskatalog \"$sm_path\" innehÃ¥ller katalogen \".git\"" + +#: git-submodule.sh:604 +#, sh-format +msgid "" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "" +"(använd \"rm -rf\" om du verkligen vill ta bort den och all dess historik)" + +#: git-submodule.sh:610 +#, sh-format +msgid "" +"Submodule work tree '$sm_path' contains local modifications; use '-f' to " +"discard them" +msgstr "" +"Undermodulens arbetskatalog \"$sm_path\" har lokala ändringar; \"-f\" kastar " +"bort dem" + +#: git-submodule.sh:613 +#, sh-format +msgid "Cleared directory '$sm_path'" +msgstr "Rensade katalogen \"$sm_path\"" + +#: git-submodule.sh:614 +#, sh-format +msgid "Could not remove submodule work tree '$sm_path'" +msgstr "Kunde inte ta bort underkatalogens arbetskatalog \"$sm_path\"" + +#: git-submodule.sh:617 +#, sh-format +msgid "Could not create empty submodule directory '$sm_path'" +msgstr "Kunde inte skapa tom undermodulskatalog \"$sm_path\"" + +#: git-submodule.sh:626 +#, sh-format +msgid "Submodule '$name' ($url) unregistered for path '$sm_path'" +msgstr "Undermodulen \"$name\" ($url) avregistrerad för sökvägen \"$sm_path\"" + +#: git-submodule.sh:731 #, sh-format msgid "" -"Submodule path '$sm_path' not initialized\n" +"Submodule path '$prefix$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -"Undermodulen \"$sm_path\" har inte initierats\n" +"Undermodulen \"$prefix$sm_path\" har inte initierats\n" "Kanske du vill köra \"update --init\"?" -#: git-submodule.sh:662 +#: git-submodule.sh:744 #, sh-format -msgid "Unable to find current revision in submodule path '$sm_path'" -msgstr "Kan inte hitta aktuell revision i undermodulsökväg \"$sm_path\"" +msgid "Unable to find current revision in submodule path '$prefix$sm_path'" +msgstr "" +"Kan inte hitta aktuell revision i undermodulsökvägen \"$prefix$sm_path\"" -#: git-submodule.sh:671 git-submodule.sh:695 +#: git-submodule.sh:753 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "Kan inte hämta i undermodulsökväg \"$sm_path\"" -#: git-submodule.sh:709 +#: git-submodule.sh:777 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" -msgstr "Kan inte ombasera \"$sha1\" i undermodulsökväg \"$sm_path\"" +msgid "Unable to fetch in submodule path '$prefix$sm_path'" +msgstr "Kan inte hämta i undermodulsökväg \"$prefix$sm_path\"" -#: git-submodule.sh:710 +#: git-submodule.sh:791 #, sh-format -msgid "Submodule path '$sm_path': rebased into '$sha1'" -msgstr "Undermodulsökvägen \"$sm_path\": ombaserade in i \"$sha1\"" +msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'" +msgstr "Kan inte ombasera \"$sha1\" i undermodulsökvägen \"$prefix$sm_path\"" -#: git-submodule.sh:715 +#: git-submodule.sh:792 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$sm_path'" -msgstr "Kan inte slÃ¥ ihop \"$sha1\" i undermodulsökvägen \"$sm_path\"" +msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'" +msgstr "Undermodulsökvägen \"$prefix$sm_path\": ombaserade in i \"$sha1\"" -#: git-submodule.sh:716 +#: git-submodule.sh:797 #, sh-format -msgid "Submodule path '$sm_path': merged in '$sha1'" -msgstr "Undermodulsökvägen \"$sm_path\": sammanslagen i \"$sha1\"" +msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'" +msgstr "Kan inte slÃ¥ ihop \"$sha1\" i undermodulsökvägen \"$prefix$sm_path\"" -#: git-submodule.sh:721 +#: git-submodule.sh:798 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" -msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$sm_path\"" +msgid "Submodule path '$prefix$sm_path': merged in '$sha1'" +msgstr "Undermodulsökvägen \"$prefix$sm_path\": sammanslagen i \"$sha1\"" -#: git-submodule.sh:722 +#: git-submodule.sh:803 #, sh-format -msgid "Submodule path '$sm_path': checked out '$sha1'" -msgstr "Undermodulsökvägen \"$sm_path\": checkade ut \"$sha1\"" +msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'" +msgstr "Kan inte checka ut \"$sha1\" i undermodulsökvägen \"$prefix$sm_path\"" -#: git-submodule.sh:744 git-submodule.sh:1066 +#: git-submodule.sh:804 #, sh-format -msgid "Failed to recurse into submodule path '$sm_path'" -msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\"" +msgid "Submodule path '$prefix$sm_path': checked out '$sha1'" +msgstr "Undermodulsökvägen \"$prefix$sm_path\": checkade ut \"$sha1\"" + +#: git-submodule.sh:831 +#, sh-format +msgid "Failed to recurse into submodule path '$prefix$sm_path'" +msgstr "Misslyckades rekursera in i undermodulsökvägen \"$prefix$sm_path\"" -#: git-submodule.sh:852 +#: git-submodule.sh:939 msgid "The --cached option cannot be used with the --files option" msgstr "Flaggan --cached kan inte användas med flaggan --files" #. unexpected type -#: git-submodule.sh:892 +#: git-submodule.sh:979 #, sh-format msgid "unexpected mode $mod_dst" msgstr "oväntat läge $mod_dst" -#: git-submodule.sh:910 +#: git-submodule.sh:997 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_src" -#: git-submodule.sh:913 +#: git-submodule.sh:1000 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Varning: $name innehÃ¥ller inte incheckning $sha1_dst" -#: git-submodule.sh:916 +#: git-submodule.sh:1003 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr " Varning: $name innehÃ¥ller inte incheckningar $sha1_src och $sha1_dst" -#: git-submodule.sh:941 +#: git-submodule.sh:1028 msgid "blob" msgstr "blob" -#: git-submodule.sh:979 +#: git-submodule.sh:1066 msgid "Submodules changed but not updated:" msgstr "Undermoduler ändrade men inte uppdaterade:" -#: git-submodule.sh:981 +#: git-submodule.sh:1068 msgid "Submodule changes to be committed:" msgstr "Undermodulers ändringar att checka in:" -#: git-submodule.sh:1129 +#: git-submodule.sh:1153 +#, sh-format +msgid "Failed to recurse into submodule path '$sm_path'" +msgstr "Misslyckades rekursera in i undermodulsökvägen \"$sm_path\"" + +#: git-submodule.sh:1216 #, sh-format msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "Synkroniserar undermodul-url för \"$prefix$sm_path\"" +#~ msgid "It took %.2f seconds to enumerate untracked files. 'status -uno'" +#~ msgstr "Det tog %.2f sekunder att räkna ospÃ¥rade filer. \"status -uno\"" + +#~ msgid "may speed it up, but you have to be careful not to forget to add" +#~ msgstr "kanske gör det snabbare, men du mÃ¥ste vara försiktig sÃ¥ att du" + +#~ msgid "new files yourself (see 'git help status')." +#~ msgstr "inte glömmer lägga till filer själv (se \"git help status\")" + +#~ msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +#~ msgstr "" +#~ "git shortlog [-n] [-s] [-e] [-w] [rev-flaggor] [--] [<incheckning-id>... ]" + +#~ msgid "See 'git help <command>' for more information on a specific command." +#~ msgstr "" +#~ "Se \"git help <kommando>\" för mer information om ett specifikt kommando." + +#~ msgid "use any ref in .git/refs" +#~ msgstr "använd alla referenser i .git/refs" + +#~ msgid "use any tag in .git/refs/tags" +#~ msgstr "använd alla taggar i .git/refs/tags" + +#~ msgid "bad object %s" +#~ msgstr "felaktigt objekt %s" + +#~ msgid "bogus committer info %s" +#~ msgstr "felaktig incheckarinformation %s" + #~ msgid "can't fdopen 'show' output fd" #~ msgstr "kunde inte öppna (fdopen) \"show\"-utdata-filhandtag" @@ -9739,9 +10164,6 @@ msgstr "Synkroniserar undermodul-url för \"$prefix$sm_path\"" #~ msgid "# Changed but not updated:" #~ msgstr "# Ändrade men inte uppdaterade:" -#~ msgid "A branch named '%s' already exists." -#~ msgstr "Det finns redan en gren som heter \"%s\"" - #~ msgid "path '%s' does not have all 3 versions" #~ msgstr "sökvägen \"%s\" har inte alla 3 versionerna" @@ -9804,9 +10226,6 @@ msgstr "Synkroniserar undermodul-url för \"$prefix$sm_path\"" #~ msgid "Could not extract author time from %s" #~ msgstr "Kunde inte hämta författartid frÃ¥n %s" -#~ msgid "No author information found in %s" -#~ msgstr "Hittade ingen författarinformation i %s" - #~ msgid "cherry-pick --ff cannot be used with --signoff" #~ msgstr "cherry-pick --ff kan inte användas med --signoff" @@ -6,10 +6,10 @@ # msgid "" msgstr "" -"Project-Id-Version: git-v1.8.2-rc2-4-g77995\n" +"Project-Id-Version: git-v1.8.3-rc0-20-gc6bc7\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2013-03-05 12:36+0800\n" -"PO-Revision-Date: 2013-03-06 13:55+0700\n" +"POT-Creation-Date: 2013-04-30 08:25+0800\n" +"PO-Revision-Date: 2013-05-01 14:26+0700\n" "Last-Translator: Trần Ngá»c Quân <vnwildman@gmail.com>\n" "Language-Team: Vietnamese <translation-team-vi@lists.sourceforge.net>\n" "Language: vi\n" @@ -20,8 +20,9 @@ msgstr "" "Plural-Forms: nplurals=2; plural=1;\n" "X-Poedit-SourceCharset: UTF-8\n" "X-Poedit-Basepath: ../\n" +"X-Generator: Poedit 1.5.5\n" -#: advice.c:49 +#: advice.c:53 #, c-format msgid "hint: %.*s\n" msgstr "gợi ý: %.*s\n" @@ -30,7 +31,7 @@ msgstr "gợi ý: %.*s\n" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:79 +#: advice.c:83 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm <file>' as\n" @@ -69,7 +70,7 @@ msgstr "fmt" msgid "archive format" msgstr "định dạng lÆ°u trữ" -#: archive.c:324 builtin/log.c:1115 +#: archive.c:324 builtin/log.c:1126 msgid "prefix" msgstr "tiá»n tố" @@ -77,15 +78,15 @@ 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:326 builtin/archive.c:91 builtin/blame.c:2366 -#: builtin/blame.c:2367 builtin/config.c:55 builtin/fast-export.c:653 -#: builtin/fast-export.c:655 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:497 builtin/ls-files.c:500 builtin/notes.c:536 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 +#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 +#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 #: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 msgid "file" msgstr "táºp-tin" -#: archive.c:327 builtin/archive.c:92 +#: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" msgstr "ghi kho lÆ°u và o táºp tin nà y" @@ -95,7 +96,7 @@ msgstr "Ä‘á»c .gitattributes trong thÆ° mục là m việc" #: archive.c:330 msgid "report archived files on stderr" -msgstr "liệt kê các táºp tin được lÆ°u trữ và o stderr (đầu ra lá»—i chuẩn)" +msgstr "liệt kê các táºp tin được lÆ°u trữ và o stderr (đầu ra lá»—i tiêu chuẩn)" #: archive.c:331 msgid "store only" @@ -113,19 +114,19 @@ 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:345 builtin/archive.c:93 builtin/clone.c:85 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 msgid "repo" msgstr "kho" -#: archive.c:346 builtin/archive.c:94 +#: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository <repo>" msgstr "nháºn kho lÆ°u từ kho chứa <kho> trên máy chủ" -#: archive.c:347 builtin/archive.c:95 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 msgid "command" msgstr "lệnh" -#: archive.c:348 builtin/archive.c:96 +#: archive.c:348 builtin/archive.c:93 msgid "path to the remote git-upload-archive command" msgstr "Ä‘Æ°á»ng dẫn đến lệnh git-upload-pack trên máy chủ" @@ -137,6 +138,132 @@ msgstr "" "Các mẫu dạng phủ định bị cấm dùng cho các thuá»™c tÃnh của git\n" "Dùng “\\!†cho các chuá»—i văn bản có dấu chấm than dẫn đầu." +#: branch.c:60 +#, c-format +msgid "Not setting branch %s as its own upstream." +msgstr "ChÆ°a cà i đặt nhánh %s nhÆ° là thượng nguồn (upstream) của nó." + +#: branch.c:82 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s by rebasing." +msgstr "" +"Nhánh %s cà i đặt để theo dõi vết nhánh máy chủ %s từ %s bằng cách rebase." + +#: branch.c:83 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s." +msgstr "Nhánh %s cà i đặt để theo vết nhánh máy chủ %s từ %s." + +#: branch.c:87 +#, c-format +msgid "Branch %s set up to track local branch %s by rebasing." +msgstr "Nhánh %s cà i đặt để theo vết nhánh ná»™i bá»™ %s bằng cách rebase." + +#: branch.c:88 +#, c-format +msgid "Branch %s set up to track local branch %s." +msgstr "Nhánh %s cà i đặt để theo vết nhánh ná»™i bá»™ %s." + +#: branch.c:92 +#, c-format +msgid "Branch %s set up to track remote ref %s by rebasing." +msgstr "Nhánh %s cà i đặt để theo vết nhánh máy chủ %s bằng cách rebase." + +#: branch.c:93 +#, c-format +msgid "Branch %s set up to track remote ref %s." +msgstr "Nhánh %s cà i đặt để theo vết tham chiếu máy chủ %s." + +#: branch.c:97 +#, c-format +msgid "Branch %s set up to track local ref %s by rebasing." +msgstr "" +"Nhánh %s cà i đặt để theo dõi vết tham chiếu ná»™i bá»™ %s bằng cách rebase." + +#: branch.c:98 +#, c-format +msgid "Branch %s set up to track local ref %s." +msgstr "Nhánh %s cà i đặt để theo dõi tham chiếu ná»™i bá»™ %s." + +#: branch.c:118 +#, c-format +msgid "Tracking not set up: name too long: %s" +msgstr "Theo vết chÆ°a được cà i đặt: tên quá dà i: %s" + +#: branch.c:137 +#, c-format +msgid "Not tracking: ambiguous information for ref %s" +msgstr "Không theo vết: thông tin chÆ°a rõ rà ng cho tham chiếu %s" + +#: branch.c:182 +#, c-format +msgid "'%s' is not a valid branch name." +msgstr "“%s†không phải là má»™t tên nhánh hợp lệ." + +#: branch.c:187 +#, c-format +msgid "A branch named '%s' already exists." +msgstr "Äã có nhánh mang tên “%sâ€." + +#: branch.c:195 +msgid "Cannot force update the current branch." +msgstr "Không thể ép buá»™c cáºp nháºt nhánh hiện hà nh." + +#: branch.c:201 +#, c-format +msgid "Cannot setup tracking information; starting point '%s' is not a branch." +msgstr "" +"Không thể cà i đặt thông tin theo vết; Ä‘iểm bắt đầu “%s†không phải là má»™t " +"nhánh." + +#: branch.c:203 +#, c-format +msgid "the requested upstream branch '%s' does not exist" +msgstr "nhánh dòng ngược đã yêu cầu “%s†chÆ°a sẵn có" + +#: branch.c:205 +msgid "" +"\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push." +msgstr "" +"\n" +"Nếu bạn có ý định trên cÆ¡ sở công việc của bạn trên nhánh dòng ngược\n" +"(upstream) cái mà đã sẵn có trên máy chủ, bạn cần chạy\n" +"lệnh \"git fetch\" để lấy nó vá».\n" +"\n" +"Nếu bạn có ý định push lênh má»™t nhánh ná»™i bá»™ má»›i cái mà \n" +"sẽ theo dõi bản đối chiếu máy chủ của nó, bạn cần dùng lệnh\n" +"\"git push -u\" để đặt cấu hình dòng ngược bạn muốn push." + +#: branch.c:250 +#, c-format +msgid "Not a valid object name: '%s'." +msgstr "Không phải tên đối tượng hợp lệ: “%sâ€." + +#: branch.c:270 +#, c-format +msgid "Ambiguous object name: '%s'." +msgstr "Tên đối tượng chÆ°a rõ rà ng: “%sâ€." + +#: branch.c:275 +#, c-format +msgid "Not a valid branch point: '%s'." +msgstr "Nhánh không hợp lệ: “%sâ€." + +#: branch.c:281 +msgid "Failed to lock ref for update" +msgstr "Gặp lá»—i khi khóa tham chiếu (ref) để cáºp nháºt" + +#: branch.c:299 +msgid "Failed to write ref" +msgstr "Gặp lá»—i khi ghi tham chiếu (ref)" + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -147,7 +274,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 (header) không được thừa nháºn: %s%s (%d)" -#: bundle.c:89 builtin/commit.c:674 +#: bundle.c:89 builtin/commit.c:676 #, c-format msgid "could not open '%s'" msgstr "không thể mở “%sâ€" @@ -156,35 +283,35 @@ 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 (commit) cần trÆ°á»›c hết nà y:" -#: bundle.c:164 sequencer.c:566 sequencer.c:998 builtin/log.c:299 -#: builtin/log.c:751 builtin/log.c:1358 builtin/log.c:1574 builtin/merge.c:347 -#: builtin/shortlog.c:157 +#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 +#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 +#: builtin/shortlog.c:155 msgid "revision walk setup failed" msgstr "cà i đặt việc di chuyển qua các Ä‘iểm xét lại gặp lá»—i" #: bundle.c:186 #, c-format -msgid "The bundle contains %d ref" -msgid_plural "The bundle contains %d refs" -msgstr[0] "Bundle chứa %d tham chiếu (refs)" -msgstr[1] "Bundle chứa %d tham chiếu (refs)" +msgid "The bundle contains this ref:" +msgid_plural "The bundle contains these %d refs:" +msgstr[0] "Bundle chứa tham chiếu (ref) nà y:" +msgstr[1] "Bundle chứa %d tham chiếu (ref):" -#: bundle.c:192 +#: bundle.c:193 msgid "The bundle records a complete history." msgstr "Lệnh bundle ghi lại toà n bá»™ lịch sá»." #: bundle.c:195 #, c-format -msgid "The bundle requires this ref" -msgid_plural "The bundle requires these %d refs" -msgstr[0] "Lệnh bundle yêu cầu tham chiếu (refs) nà y" -msgstr[1] "Lệnh bundle yêu cầu %d tham chiếu (refs) nà y" +msgid "The bundle requires this ref:" +msgid_plural "The bundle requires these %d refs:" +msgstr[0] "Lệnh bundle yêu cầu tham chiếu nà y:" +msgstr[1] "Lệnh bundle yêu cầu %d tham chiếu (refs) nà y:" #: bundle.c:294 msgid "rev-list died" msgstr "rev-list đã chết" -#: bundle.c:300 builtin/log.c:1254 builtin/shortlog.c:260 +#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 #, c-format msgid "unrecognized argument: %s" msgstr "đối số không được thừa nháºn: %s" @@ -334,7 +461,7 @@ msgstr "" "Tìm thấy các lá»—i trong biến cấu hình “diff.dirstatâ€:\n" "%s" -#: diff.c:3468 +#: diff.c:3481 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -343,12 +470,12 @@ msgstr "" "Gặp lá»—i khi phân tÃch đối số tùy chá»n --dirstat/-X:\n" "%s" -#: diff.c:3482 +#: diff.c:3495 #, 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â€" -#: gpg-interface.c:59 gpg-interface.c:127 +#: gpg-interface.c:59 gpg-interface.c:131 msgid "could not run gpg." msgstr "không thể chạy gpg." @@ -360,27 +487,27 @@ msgstr "gpg đã không chấp nháºn dữ liệu" msgid "gpg failed to sign the data" msgstr "gpg gặp lá»—i khi ký dữ liệu" -#: gpg-interface.c:112 +#: gpg-interface.c:115 #, 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" -#: gpg-interface.c:115 +#: gpg-interface.c:118 #, 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" -#: grep.c:1622 +#: grep.c:1623 #, c-format msgid "'%s': unable to read %s" msgstr "“%sâ€: không thể Ä‘á»c %s" -#: grep.c:1639 +#: grep.c:1640 #, c-format msgid "'%s': %s" msgstr "“%sâ€: %s" -#: grep.c:1650 +#: grep.c:1651 #, c-format msgid "'%s': short read %s" msgstr "“%sâ€: Ä‘á»c ngắn %s" @@ -448,8 +575,8 @@ msgstr[1] "" msgid "failed to read the cache" msgstr "gặp lá»—i khi Ä‘á»c bá»™ nhá»› tạm" -#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 -#: builtin/clone.c:586 +#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 +#: builtin/clone.c:645 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" @@ -498,7 +625,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:773 builtin/clone.c:302 +#: merge-recursive.c:773 builtin/clone.c:313 #, c-format msgid "failed to open '%s'" msgstr "gặp lá»—i khi mở “%sâ€" @@ -633,7 +760,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:1633 git-submodule.sh:942 +#: merge-recursive.c:1633 git-submodule.sh:1029 msgid "submodule" msgstr "mô-Ä‘un-con" @@ -705,10 +832,15 @@ msgstr "hòa trá»™n không trả vá» lần chuyển giao (commit) nà o" msgid "Could not parse object '%s'" msgstr "Không thể phân tÃch đối tượng “%sâ€" -#: merge-recursive.c:2009 builtin/merge.c:643 +#: merge-recursive.c:2009 builtin/merge.c:658 msgid "Unable to write index." msgstr "Không thể ghi bảng mục lục" +#: object.c:195 +#, c-format +msgid "unable to parse object: %s" +msgstr "không thể phân tÃch đối tượng: “%sâ€" + #: parse-options.c:489 msgid "..." msgstr "..." @@ -744,18 +876,18 @@ msgstr "ÄÆ°á»ng dẫn “%s†thì ở trong mô-Ä‘un-con “%.*sâ€" msgid "'%s' is beyond a symbolic link" msgstr "“%s†nằm ngoà i má»™t liên kết tượng trÆ°ng" -#: remote.c:1653 +#: remote.c:1781 #, 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 là đầu của “%s†bởi %d lần chuyển giao (commit).\n" msgstr[1] "Nhánh của bạn là đầu của “%s†bởi %d lần chuyển giao (commit).\n" -#: remote.c:1659 +#: remote.c:1787 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:1662 +#: remote.c:1790 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -767,11 +899,11 @@ msgstr[1] "" "Nhánh của bạn thì ở đằng sau “%s†bởi %d lần chuyển giao (commit), và có thể " "được fast-forward.\n" -#: remote.c:1670 +#: remote.c:1798 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:1673 +#: remote.c:1801 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -787,25 +919,25 @@ msgstr[1] "" "Your branch and “%s†have diverged,\n" "and have %d and %d different commit each, respectively.\n" -#: remote.c:1683 +#: remote.c:1811 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" -#: sequencer.c:123 builtin/merge.c:761 builtin/merge.c:874 builtin/merge.c:984 -#: builtin/merge.c:994 +#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 +#: builtin/merge.c:1009 #, c-format msgid "Could not open '%s' for writing" msgstr "Không thể mở “%s†để ghi" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 -#: builtin/merge.c:999 +#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 +#: builtin/merge.c:1001 builtin/merge.c:1014 #, c-format msgid "Could not write to '%s'" msgstr "Không thể ghi và o “%sâ€" -#: sequencer.c:146 +#: sequencer.c:229 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -813,7 +945,7 @@ msgstr "" "sau khi giải quyết các xung Ä‘á»™t, đánh dấu Ä‘Æ°á»ng dẫn đã sá»a\n" "vá»›i lệnh “git add <Ä‘Æ°á»ng_dẫn>†hoặc “git rm <Ä‘Æ°á»ng_dẫn>â€" -#: sequencer.c:149 +#: sequencer.c:232 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -823,232 +955,242 @@ msgstr "" "vá»›i lệnh “git add <Ä‘Æ°á»ng_dẫn>†hoặc “git rm <Ä‘Æ°á»ng_dẫn>â€\n" "và chuyển giao (commit) kết quả bằng lệnh “git commitâ€" -#: sequencer.c:162 sequencer.c:774 sequencer.c:857 +#: sequencer.c:245 sequencer.c:859 sequencer.c:942 #, c-format msgid "Could not write to %s" msgstr "Không thể ghi và o %s" -#: sequencer.c:165 +#: sequencer.c:248 #, c-format msgid "Error wrapping up %s" msgstr "Lá»—i bao bá»c %s" -#: sequencer.c:180 +#: sequencer.c:263 msgid "Your local changes would be overwritten by cherry-pick." msgstr "Các thay đổi ná»™i bá»™ của bạn có thể bị ghi đè bởi lệnh cherry-pick." -#: sequencer.c:182 +#: sequencer.c:265 msgid "Your local changes would be overwritten by revert." msgstr "Các thay đổi ná»™i bá»™ của bạn có thể bị ghi đè bởi lệnh revert." -#: sequencer.c:185 +#: sequencer.c:268 msgid "Commit your changes or stash them to proceed." msgstr "Chuyển giao (commit) các thay đổi của bạn hay stash chúng để xá» lý." #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:236 +#: sequencer.c:319 #, c-format msgid "%s: Unable to write new index file" msgstr "%s: Không thể ghi táºp tin lÆ°u bảng mục lục má»›i" -#: sequencer.c:267 +#: sequencer.c:350 msgid "Could not resolve HEAD commit\n" msgstr "Không thể phân giải commit (lần chuyển giao) HEAD\n" -#: sequencer.c:288 +#: sequencer.c:371 msgid "Unable to update cache tree\n" msgstr "Không thể cáºp nháºt cây bá»™ nhá»› đệm\n" -#: sequencer.c:333 +#: sequencer.c:416 #, c-format msgid "Could not parse commit %s\n" msgstr "Không thể phân tÃch commit (lần chuyển giao) %s\n" -#: sequencer.c:338 +#: sequencer.c:421 #, c-format msgid "Could not parse parent commit %s\n" msgstr "Không thể phân tÃch commit (lần chuyển giao) cha mẹ %s\n" -#: sequencer.c:404 +#: sequencer.c:487 msgid "Your index file is unmerged." msgstr "Táºp tin lÆ°u mục lục của bạn không được hòa trá»™n." -#: sequencer.c:423 +#: sequencer.c:506 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "" "Lần chuyển giao (commit) %s là má»™t lần hòa trá»™n nhÆ°ng không Ä‘Æ°a ra tùy chá»n -" "m." -#: sequencer.c:431 +#: sequencer.c:514 #, c-format msgid "Commit %s does not have parent %d" msgstr "Lần chuyển giao (commit) %s không có cha mẹ %d" -#: sequencer.c:435 +#: sequencer.c:518 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "" -"Luồng chÃnh được chỉ ra nhÆ°ng lần chuyển giao (commit) %s không phải là má»™t " -"lần hòa trá»™n." +"Luồng chÃnh đã được chỉ ra nhÆ°ng lần chuyển giao (commit) %s không phải là " +"má»™t lần hòa trá»™n." #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:448 +#: sequencer.c:531 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s: không thể phân tÃch lần chuyển giao mẹ của %s" -#: sequencer.c:452 +#: sequencer.c:535 #, c-format msgid "Cannot get commit message for %s" msgstr "Không thể lấy thông Ä‘iệp lần chuyển giao (commit) cho %s" -#: sequencer.c:536 +#: sequencer.c:621 #, c-format msgid "could not revert %s... %s" msgstr "không thể revert %s... %s" -#: sequencer.c:537 +#: sequencer.c:622 #, c-format msgid "could not apply %s... %s" msgstr "không thể apply (áp dụng miếng vá) %s... %s" -#: sequencer.c:569 +#: sequencer.c:654 msgid "empty commit set passed" msgstr "lần chuyển giao (commit) trống rá»—ng đặt là hợp quy cách" -#: sequencer.c:577 +#: sequencer.c:662 #, c-format msgid "git %s: failed to read the index" msgstr "git %s: gặp lá»—i Ä‘á»c bảng mục lục" -#: sequencer.c:582 +#: sequencer.c:667 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %s: gặp lá»—i khi là m tÆ°Æ¡i má»›i bảng mục lục" -#: sequencer.c:640 +#: sequencer.c:725 #, c-format msgid "Cannot %s during a %s" msgstr "Không thể %s trong khi %s" -#: sequencer.c:662 +#: sequencer.c:747 #, c-format msgid "Could not parse line %d." msgstr "Không phân tÃch được dòng %d." -#: sequencer.c:667 +#: sequencer.c:752 msgid "No commits parsed." msgstr "Không có lần chuyển giao (commit) nà o được phân tÃch." -#: sequencer.c:680 +#: sequencer.c:765 #, c-format msgid "Could not open %s" msgstr "Không thể mở %s" -#: sequencer.c:684 +#: sequencer.c:769 #, c-format msgid "Could not read %s." msgstr "Không thể Ä‘á»c %s." -#: sequencer.c:691 +#: sequencer.c:776 #, c-format msgid "Unusable instruction sheet: %s" msgstr "Bảng chỉ thị không thể dùng được: %s" -#: sequencer.c:719 +#: sequencer.c:804 #, c-format msgid "Invalid key: %s" msgstr "Khóa không đúng: %s" -#: sequencer.c:722 +#: sequencer.c:807 #, c-format msgid "Invalid value for %s: %s" msgstr "Giá trị không hợp lệ %s: %s" -#: sequencer.c:734 +#: sequencer.c:819 #, c-format msgid "Malformed options sheet: %s" msgstr "Bảng tùy chá»n dị hình: %s" -#: sequencer.c:755 +#: sequencer.c:840 msgid "a cherry-pick or revert is already in progress" msgstr "má»™t thao tác cherry-pick hoặc revert Ä‘ang được thá»±c hiện" -#: sequencer.c:756 +#: sequencer.c:841 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "hãy thá» \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:760 +#: sequencer.c:845 #, c-format msgid "Could not create sequencer directory %s" msgstr "Không thể tạo thÆ° mục xếp dãy %s" -#: sequencer.c:776 sequencer.c:861 +#: sequencer.c:861 sequencer.c:946 #, c-format msgid "Error wrapping up %s." msgstr "Lá»—i bao bá»c %s." -#: sequencer.c:795 sequencer.c:929 +#: sequencer.c:880 sequencer.c:1014 msgid "no cherry-pick or revert in progress" msgstr "không cherry-pick hay revert trong tiến trình" -#: sequencer.c:797 +#: sequencer.c:882 msgid "cannot resolve HEAD" msgstr "không thể phân giải HEAD" -#: sequencer.c:799 +#: sequencer.c:884 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:821 builtin/apply.c:4056 +#: sequencer.c:906 builtin/apply.c:4060 #, c-format msgid "cannot open %s: %s" msgstr "không thể mở %s: %s" -#: sequencer.c:824 +#: sequencer.c:909 #, c-format msgid "cannot read %s: %s" msgstr "không thể Ä‘á»c %s: %s" -#: sequencer.c:825 +#: sequencer.c:910 msgid "unexpected end of file" msgstr "kết thúc táºp tin Ä‘á»™t xuất" -#: sequencer.c:831 +#: sequencer.c:916 #, 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:854 +#: sequencer.c:939 #, c-format msgid "Could not format %s." msgstr "Không thể định dạng %s." -#: sequencer.c:1016 +#: sequencer.c:1083 +#, c-format +msgid "%s: can't cherry-pick a %s" +msgstr "%s: không thể cherry-pick má»™t %s" + +#: sequencer.c:1085 +#, c-format +msgid "%s: bad revision" +msgstr "%s: Ä‘iểm xét duyệt sai" + +#: sequencer.c:1119 msgid "Can't revert as initial commit" msgstr "Không thể revert má»™t lần chuyển giao (commit) khởi tạo" -#: sequencer.c:1017 +#: sequencer.c:1120 msgid "Can't cherry-pick into empty head" msgstr "Không thể cherry-pick và o má»™t đầu (head) trống rá»—ng" -#: sha1_name.c:1044 +#: sha1_name.c:1036 msgid "HEAD does not point to a branch" msgstr "HEAD không chỉ đến má»™t nhánh nà o cả" -#: sha1_name.c:1047 +#: sha1_name.c:1039 #, c-format msgid "No such branch: '%s'" msgstr "Không có nhánh nà o nhÆ° thế: “%sâ€" -#: sha1_name.c:1049 +#: sha1_name.c:1041 #, c-format msgid "No upstream configured for branch '%s'" msgstr "Không có thượng nguồn (upstream) được cấu hình cho nhánh “%sâ€" -#: sha1_name.c:1052 +#: sha1_name.c:1044 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "" @@ -1185,114 +1327,114 @@ msgstr "ná»™i dung bị sá»a đổi, " msgid "untracked content, " msgstr "ná»™i dung chÆ°a được theo dõi, " -#: wt-status.c:303 +#: wt-status.c:306 #, c-format msgid "new file: %s" msgstr "táºp tin má»›i: %s" -#: wt-status.c:306 +#: wt-status.c:309 #, c-format msgid "copied: %s -> %s" msgstr "đã sao chép: %s -> %s" -#: wt-status.c:309 +#: wt-status.c:312 #, c-format msgid "deleted: %s" msgstr "đã xóa: %s" -#: wt-status.c:312 +#: wt-status.c:315 #, c-format msgid "modified: %s" msgstr "đã sá»a đổi: %s" -#: wt-status.c:315 +#: wt-status.c:318 #, c-format msgid "renamed: %s -> %s" msgstr "đã đổi tên: %s -> %s" -#: wt-status.c:318 +#: wt-status.c:321 #, c-format msgid "typechange: %s" msgstr "đổi-kiểu: %s" -#: wt-status.c:321 +#: wt-status.c:324 #, c-format msgid "unknown: %s" msgstr "không hiểu: %s" -#: wt-status.c:324 +#: wt-status.c:327 #, c-format msgid "unmerged: %s" msgstr "chÆ°a hòa trá»™n: %s" -#: wt-status.c:327 +#: wt-status.c:330 #, c-format msgid "bug: unhandled diff status %c" msgstr "lá»—i: không lấy được trạng thái lệnh diff %c" -#: wt-status.c:789 +#: wt-status.c:803 msgid "You have unmerged paths." msgstr "Bạn có những Ä‘Æ°á»ng dẫn chÆ°a được hòa trá»™n." -#: wt-status.c:792 wt-status.c:944 +#: wt-status.c:806 wt-status.c:958 msgid " (fix conflicts and run \"git commit\")" msgstr " (sá»a các xung Ä‘á»™t sau đó chạy \"git commit\")" -#: wt-status.c:795 +#: wt-status.c:809 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:798 +#: wt-status.c:812 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:808 +#: wt-status.c:822 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:811 +#: wt-status.c:825 msgid "The current patch is empty." msgstr "Miếng vá hiện tại bị trống rá»—ng." -#: wt-status.c:815 +#: wt-status.c:829 msgid " (fix conflicts and then run \"git am --resolved\")" msgstr " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git am --resolved\")" -#: wt-status.c:817 +#: wt-status.c:831 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:819 +#: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr " (dùng \"git am --abort\" để phục hồi lại nhánh nguyên thủy)" -#: wt-status.c:879 wt-status.c:896 +#: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc rebase nhánh “%s†trên “%sâ€." -#: wt-status.c:884 wt-status.c:901 +#: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc rebase (tái cấu trúc)." -#: wt-status.c:887 +#: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git rebase --continue\")" -#: wt-status.c:889 +#: wt-status.c:903 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (dùng \"git rebase --skip\" để bá» qua lần vá nà y)" -#: wt-status.c:891 +#: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr " (dùng \"git rebase --abort\" để check-out nhánh nguyên thủy)" -#: wt-status.c:904 +#: wt-status.c:918 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr "" " (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh \"git rebase --continue\")" -#: wt-status.c:908 +#: wt-status.c:922 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." @@ -1300,110 +1442,148 @@ msgstr "" "Bạn hiện nay Ä‘ang thá»±c hiện việc chia tách má»™t lần chuyển giao (commit) " "trong khi Ä‘ang rebase nhánh “%s†trên “%sâ€." -#: wt-status.c:913 +#: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." msgstr "" "Bạn hiện tại Ä‘ang cắt đôi má»™t lần chuyển giao trong khi Ä‘ang thá»±c hiện việc " "rebase." -#: wt-status.c:916 +#: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr "" " (Má»™t khi thÆ° mục là m việc của bạn đã gá»n gà ng, chạy \"git rebase --continue" "\")" -#: wt-status.c:920 +#: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "" "Bạn hiện nay Ä‘ang thá»±c hiện việc sá»a chữa má»™t lần chuyển giao (commit) trong " "khi Ä‘ang rebase nhánh “%s†trên “%sâ€." -#: wt-status.c:925 +#: wt-status.c:939 msgid "You are currently editing a commit during a rebase." msgstr "Bạn hiện Ä‘ang sá»a má»™t lần chuyển giao trong khi bạn thá»±c hiện rebase." -#: wt-status.c:928 +#: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr "" " (dùng \"git commit --amend\" để tu bổ lần chuyển giao (commit) hiện tại)" -#: wt-status.c:930 +#: wt-status.c:944 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr "" " (dùng \"git rebase --continue\" má»™t khi bạn cảm thấy hà i lòng vá» những " "thay đổi của mình)" -#: wt-status.c:940 +#: wt-status.c:954 msgid "You are currently cherry-picking." msgstr "Bạn hiện nay Ä‘ang thá»±c hiện việc cherry-pick." -#: wt-status.c:947 +#: wt-status.c:961 msgid " (all conflicts fixed: run \"git commit\")" msgstr " (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh \"git commit\")" -#: wt-status.c:958 +#: wt-status.c:970 +#, c-format +msgid "You are currently reverting commit %s." +msgstr "Bạn hiện nay Ä‘ang thá»±c hiện thao tác revert lần chuyển giao “%sâ€." + +#: wt-status.c:975 +msgid " (fix conflicts and run \"git revert --continue\")" +msgstr " (sá»a các xung Ä‘á»™t và sau đó chạy lệnh \"git revert --continue\")" + +#: wt-status.c:978 +msgid " (all conflicts fixed: run \"git revert --continue\")" +msgstr "" +" (khi tất cả các xung Ä‘á»™t đã sá»a xong: chạy lệnh \"git revert --continue\")" + +#: wt-status.c:980 +msgid " (use \"git revert --abort\" to cancel the revert operation)" +msgstr " (dùng \"git revert --abort\" để hủy bá» thao tác revert)" + +#: wt-status.c:991 #, c-format -msgid "You are currently bisecting branch '%s'." +msgid "You are currently bisecting, started from branch '%s'." msgstr "" -"Bạn hiện nay Ä‘ang thá»±c hiện thao tác di chuyển ná»a bÆ°á»›c (bisect) trên nhánh " -"“%sâ€." +"Bạn hiện nay Ä‘ang thá»±c hiện thao tác di chuyển ná»a bÆ°á»›c (bisect), bắt đầu từ " +"nhánh “%sâ€." -#: wt-status.c:962 +#: wt-status.c:995 msgid "You are currently bisecting." msgstr "Bạn hiện tại Ä‘ang thá»±c hiện việc bisect (chia đôi)." -#: wt-status.c:965 +#: wt-status.c:998 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:1064 +#: wt-status.c:1173 msgid "On branch " msgstr "Trên nhánh " -#: wt-status.c:1071 +#: wt-status.c:1184 +msgid "HEAD detached at " +msgstr "HEAD được tách rá»i tại" + +#: wt-status.c:1186 +msgid "HEAD detached from " +msgstr "HEAD được tách rá»i từ" + +#: wt-status.c:1189 msgid "Not currently on any branch." msgstr "Hiện tại chẳng ở nhánh nà o cả." -#: wt-status.c:1083 +#: wt-status.c:1206 msgid "Initial commit" msgstr "Lần chuyển giao (commit) khởi đầu" -#: wt-status.c:1097 +#: wt-status.c:1220 msgid "Untracked files" msgstr "Những táºp tin chÆ°a được theo dõi" -#: wt-status.c:1099 +#: wt-status.c:1222 msgid "Ignored files" msgstr "Những táºp tin bị lá» Ä‘i" -#: wt-status.c:1101 +#: wt-status.c:1226 +#, c-format +msgid "" +"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" +"may speed it up, but you have to be careful not to forget to add\n" +"new files yourself (see 'git help status')." +msgstr "" +"Cần %.2f giây để liệt kê tất cả các táºp tin chÆ°a được theo dõi. “status -" +"unoâ€\n" +"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:1232 #, c-format msgid "Untracked files not listed%s" msgstr "Những táºp tin không bị theo vết không được liệt kê ra %s" -#: wt-status.c:1103 +#: wt-status.c:1234 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:1109 +#: wt-status.c:1240 msgid "No changes" msgstr "Không có thay đổi nà o" -#: wt-status.c:1114 +#: wt-status.c:1245 #, 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 commit (dùng \"git add\" và /hoặc \"git " "commit -a\")\n" -#: wt-status.c:1117 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit\n" msgstr "không có thay đổi nà o được thêm và o lần chuyển giao (commit)\n" -#: wt-status.c:1120 +#: wt-status.c:1251 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " @@ -1412,58 +1592,58 @@ msgstr "" "không có gì được thêm và o lần chuyển giao (commit) nhÆ°ng có những táºp tin " "không được theo dấu vết hiện diện (dùng \"git add\" để Ä‘Æ°a và o theo dõi)\n" -#: wt-status.c:1123 +#: wt-status.c:1254 #, 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 (commit) nhÆ°ng có những táºp tin " "không được theo dấu vết hiện diện\n" -#: wt-status.c:1126 +#: wt-status.c:1257 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "" " không có gì để commit (tạo/sao-chép các táºp tin và dùng \"git add\" để theo " "dõi dấu vết)\n" -#: wt-status.c:1129 wt-status.c:1134 +#: wt-status.c:1260 wt-status.c:1265 #, c-format msgid "nothing to commit\n" msgstr "không có gì để chuyển giao (commit)\n" -#: wt-status.c:1132 +#: wt-status.c:1263 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "" "không có gì để chuyển giao (commit) (dùng -u để bá» các táºp tin cần theo dấu " "vết)\n" -#: wt-status.c:1136 +#: wt-status.c:1267 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "không có gì để chuyển giao (commit), thÆ° mục là m việc sạch sẽ\n" -#: wt-status.c:1244 +#: wt-status.c:1375 msgid "HEAD (no branch)" msgstr "HEAD (không nhánh)" -#: wt-status.c:1250 +#: wt-status.c:1381 msgid "Initial commit on " msgstr "Lần chuyển giao (commit) khởi tạo trên " -#: wt-status.c:1265 +#: wt-status.c:1396 msgid "behind " msgstr "đằng sau " -#: wt-status.c:1268 wt-status.c:1271 +#: wt-status.c:1399 wt-status.c:1402 msgid "ahead " msgstr "phÃa trÆ°á»›c " -#: wt-status.c:1273 +#: wt-status.c:1404 msgid ", behind " msgstr ", đằng sau " -#: compat/precompose_utf8.c:58 builtin/clone.c:341 +#: compat/precompose_utf8.c:58 builtin/clone.c:352 #, c-format msgid "failed to unlink '%s'" msgstr "bá» liên kết (unlink) %s không thà nh công" @@ -1472,200 +1652,235 @@ msgstr "bá» liên kết (unlink) %s không thà nh công" msgid "git add [options] [--] <pathspec>..." msgstr "git add [các-tùy-chá»n] [--] <pathspec>..." -#: builtin/add.c:63 +#. +#. * To be consistent with "git add -p" and most Git +#. * commands, we should default to being tree-wide, but +#. * this is not the original behavior and can't be +#. * changed until users trained themselves not to type +#. * "git add -u" or "git add -A". For now, we warn and +#. * keep the old behavior. Later, the behavior can be changed +#. * to tree-wide, keeping the warning for a while, and +#. * eventually we can drop the warning. +#. +#: builtin/add.c:58 +#, c-format +msgid "" +"The behavior of 'git add %s (or %s)' with no path argument from a\n" +"subdirectory of the tree will change in Git 2.0 and should not be used " +"anymore.\n" +"To add content for the whole tree, run:\n" +"\n" +" git add %s :/\n" +" (or git add %s :/)\n" +"\n" +"To restrict the command to the current directory, run:\n" +"\n" +" git add %s .\n" +" (or git add %s .)\n" +"\n" +"With the current Git version, the command is restricted to the current " +"directory.\n" +msgstr "" +"Cách ứng xá» của lệnh “git add %s (hay %s)†khi không có tham số Ä‘Æ°á»ng dẫn " +"từ\n" +"thÆ°-mục con của cây sẽ thay đổi kể từ Git 2.0 và không thể sá» dụng nhÆ° thế " +"nữa.\n" +"Äể thêm ná»™i dung cho toà n bá»™ cây, chạy:\n" +"\n" +" git add %s :/\n" +" (hay git add %s :/)\n" +"\n" +"Äể hạn chế lệnh cho thÆ°-mục hiện tại, chạy:\n" +"\n" +" git add %s .\n" +" (hay git add %s .)\n" +"\n" +"Vá»›i phiên bản hiện tại của Git, lệnh bị hạn chế cho thÆ°-mục hiện tại.\n" + +#: builtin/add.c:100 +#, c-format +msgid "" +"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n" +msgstr "" +"Bạn chạy “git add†mà không có “-A (--all)†cÅ©ng không “--ignore-removalâ€,\n" +"cách ứng xá» của nó sẽ thay đổi kể từ Git 2.0: nó quan tâm đến các Ä‘Æ°á»ng dẫn " +"mà \n" +"bạn đã gỡ bá». Các Ä‘Æ°á»ng dẫn nhÆ° là “%s†cái mà \n" +"bị gỡ bá» từ cây là m việc của bạn thì bị bá» qua vá»›i phiên bản nà y của Git.\n" +"\n" +"* “git add --ignore-removal <pathspec>â€, cái hiện tại là mặc định,\n" +" bá» qua các Ä‘Æ°á»ng dẫn bạn đã gỡ bá» từ cây là m việc của bạn.\n" +"\n" +"* “git add --all <pathspec>†sẽ đồng thá»i giúp bạn ghi lại việc dá»i Ä‘i.\n" +"\n" +"Chạy “git status†để kiểm tra các Ä‘Æ°á»ng dẫn bạn đã gỡ bá» từ cây là m việc của " +"bạn.\n" + +#: builtin/add.c:144 #, c-format msgid "unexpected diff status %c" msgstr "trạng thái lệnh diff không nhÆ° mong đợi %c" -#: builtin/add.c:68 builtin/commit.c:231 +#: builtin/add.c:149 builtin/commit.c:233 msgid "updating files failed" msgstr "Cáºp nháºt táºp tin gặp lá»—i" -#: builtin/add.c:78 +#: builtin/add.c:163 #, c-format msgid "remove '%s'\n" msgstr "gỡ bỠ“%sâ€\n" -#: builtin/add.c:148 +#: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "" "Các thay đổi không được lÆ°u trạng thái sau khi là m tÆ°Æ¡i má»›i lại bảng mục lục:" -#: builtin/add.c:151 builtin/add.c:460 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "pathspec “%s†không khá»›p vá»›i bất kỳ táºp tin nà o" -#: builtin/add.c:234 +#: builtin/add.c:339 msgid "Could not read the index" msgstr "Không thể Ä‘á»c bảng mục lục" -#: builtin/add.c:244 +#: builtin/add.c:349 #, c-format msgid "Could not open '%s' for writing." msgstr "Không thể mở “%s†để ghi." -#: builtin/add.c:248 +#: builtin/add.c:353 msgid "Could not write patch" msgstr "Không thể ghi ra miếng vá" -#: builtin/add.c:253 +#: builtin/add.c:358 #, c-format msgid "Could not stat '%s'" msgstr "không thể lấy trạng thái vỠ“%sâ€" -#: builtin/add.c:255 +#: builtin/add.c:360 msgid "Empty patch. Aborted." msgstr "Miếng vá trống rá»—ng. Äã bá» qua." -#: builtin/add.c:261 +#: builtin/add.c:366 #, c-format msgid "Could not apply '%s'" msgstr "Không thể apply (áp dụng miếng vá) “%sâ€" -#: builtin/add.c:271 +#: builtin/add.c:376 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "" "Các Ä‘Æ°á»ng dẫn theo sau đây sẽ bị lá» Ä‘i bởi má»™t trong các táºp tin .gitignore " "của bạn:\n" -#: builtin/add.c:277 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 #: builtin/rm.c:206 msgid "dry run" msgstr "chạy thá»" -#: builtin/add.c:278 builtin/apply.c:4405 builtin/check-ignore.c:19 -#: builtin/commit.c:1150 builtin/count-objects.c:82 builtin/fsck.c:613 -#: builtin/log.c:1522 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 +#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "chi tiết" -#: builtin/add.c:280 +#: builtin/add.c:396 msgid "interactive picking" msgstr "sá»a bằng cách tÆ°Æ¡ng tác" -#: builtin/add.c:281 builtin/checkout.c:1031 builtin/reset.c:258 +#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 msgid "select hunks interactively" msgstr "chá»n “hunks†má»™t cách tÆ°Æ¡ng tác" -#: builtin/add.c:282 +#: builtin/add.c:398 msgid "edit current diff and apply" msgstr "sá»a diff hiện nay và áp dụng nó" -#: builtin/add.c:283 +#: builtin/add.c:399 msgid "allow adding otherwise ignored files" msgstr "cho phép thêm các táºp tin bị bá» qua khác" -#: builtin/add.c:284 +#: builtin/add.c:400 msgid "update tracked files" msgstr "cáºp nháºt các táºp tin được theo vết" -#: builtin/add.c:285 +#: builtin/add.c:401 msgid "record only the fact that the path will be added later" msgstr "chỉ ghi lại sá»± việc mà đưá»ng dẫn sẽ được thêm và o sau" -#: builtin/add.c:286 +#: builtin/add.c:402 msgid "add changes from all tracked and untracked files" msgstr "" "thêm các thay đổi từ tất cả các táºp tin có cÅ©ng nhÆ° không được theo dõi dấu " "vết" -#: builtin/add.c:287 +#. takes no arguments +#: builtin/add.c:405 +msgid "ignore paths removed in the working tree (same as --no-all)" +msgstr "" +"lá» Ä‘i các Ä‘Æ°á»ng dẫn bị gỡ bá» trong cây thÆ° mục là m việc (giống vá»›i --no-all)" + +#: builtin/add.c:407 msgid "don't add, only refresh the index" msgstr "không thêm, chỉ là m tÆ°Æ¡i má»›i bảng mục lục" -#: builtin/add.c:288 +#: builtin/add.c:408 msgid "just skip files which cannot be added because of errors" msgstr "chie bá» qua những táºp tin mà nó không thể được thêm và o bởi vì gặp lá»—i" -#: builtin/add.c:289 +#: builtin/add.c:409 msgid "check if - even missing - files are ignored in dry run" msgstr "" "kiểm tra xem - tháºm chà thiếu - táºp tin bị bá» qua trong quá trình chạy thá»" -#: builtin/add.c:311 +#: builtin/add.c:431 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "Sá» dụng tùy chá»n -f nếu bạn thá»±c sá»± muốn thêm chúng và o.\n" -#: builtin/add.c:312 +#: builtin/add.c:432 msgid "no files added" msgstr "chÆ°a có táºp tin nà o được thêm và o" -#: builtin/add.c:318 +#: builtin/add.c:438 msgid "adding files failed" msgstr "thêm táºp tin gặp lá»—i" -#. -#. * To be consistent with "git add -p" and most Git -#. * commands, we should default to being tree-wide, but -#. * this is not the original behavior and can't be -#. * changed until users trained themselves not to type -#. * "git add -u" or "git add -A". For now, we warn and -#. * keep the old behavior. Later, this warning can be -#. * turned into a die(...), and eventually we may -#. * reallow the command with a new behavior. -#. -#: builtin/add.c:335 -#, c-format -msgid "" -"The behavior of 'git add %s (or %s)' with no path argument from a\n" -"subdirectory of the tree will change in Git 2.0 and should not be used " -"anymore.\n" -"To add content for the whole tree, run:\n" -"\n" -" git add %s :/\n" -" (or git add %s :/)\n" -"\n" -"To restrict the command to the current directory, run:\n" -"\n" -" git add %s .\n" -" (or git add %s .)\n" -"\n" -"With the current Git version, the command is restricted to the current " -"directory." -msgstr "" -"Cách ứng xá» của lệnh “git add %s (hay %s)†khi không có tham số Ä‘Æ°á»ng dẫn " -"từ\n" -"thÆ°-mục con của cây sẽ thay đổi kể từ Git 2.0 và không thể sá» dụng nhÆ° thế " -"nữa.\n" -"Äể thêm ná»™i dung cho toà n bá»™ cây, chạy:\n" -"\n" -" git add %s :/\n" -" (hay git add %s :/)\n" -"\n" -"Äể hạn chế lệnh cho thÆ°-mục hiện tại, chạy:\n" -"\n" -" git add %s .\n" -" (hay git add %s .)\n" -"\n" -"Vá»›i phiên bản hiện tại của Git, lệnh bị hạn chế cho thÆ°-mục hiện tại." - -#: builtin/add.c:381 +#: builtin/add.c:477 msgid "-A and -u are mutually incompatible" msgstr "-A và -u xung khắc nhau" -#: builtin/add.c:383 +#: builtin/add.c:495 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "Tùy chá»n --ignore-missing chỉ có thể được dùng cùng vá»›i --dry-run" -#: builtin/add.c:414 +#: builtin/add.c:525 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "Không có gì được chỉ ra, không có gì được thêm và o.\n" -#: builtin/add.c:415 +#: builtin/add.c:526 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "Có lẽ bạn muốn là “git add .†phải không?\n" -#: builtin/add.c:421 builtin/check-ignore.c:67 builtin/clean.c:204 -#: builtin/commit.c:291 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 +#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 msgid "index file corrupt" msgstr "táºp tin ghi bảng mục lục bị há»ng" -#: builtin/add.c:481 builtin/apply.c:4501 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 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" @@ -1799,24 +2014,24 @@ msgstr "không thể Ä‘á»c liên kết tượng trÆ°ng %s" msgid "unable to open or read %s" msgstr "không thể mở hay Ä‘á»c %s" -#: builtin/apply.c:2684 +#: builtin/apply.c:2688 #, c-format msgid "invalid start of line: '%c'" msgstr "sai khởi đầu dòng: “%câ€" -#: builtin/apply.c:2802 +#: builtin/apply.c:2806 #, 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)." msgstr[1] "Khối dữ liệu #%d thà nh công tại %d (offset %d dòng)." -#: builtin/apply.c:2814 +#: builtin/apply.c:2818 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "Ná»™i dung bị giảm xuống (%ld/%ld) để áp dụng mảnh dữ liệu tại %d" -#: builtin/apply.c:2820 +#: builtin/apply.c:2824 #, c-format msgid "" "while searching for:\n" @@ -1825,325 +2040,325 @@ msgstr "" "Trong khi Ä‘ang tìm kiếm cho:\n" "%.*s" -#: builtin/apply.c:2839 +#: builtin/apply.c:2843 #, 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:2942 +#: builtin/apply.c:2946 #, 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:2948 +#: builtin/apply.c:2952 #, 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:2969 +#: builtin/apply.c:2973 #, c-format msgid "patch failed: %s:%ld" msgstr "vá gặp lá»—i: %s:%ld" -#: builtin/apply.c:3091 +#: builtin/apply.c:3095 #, c-format msgid "cannot checkout %s" msgstr "không thể \"checkout\" %s" -#: builtin/apply.c:3136 builtin/apply.c:3145 builtin/apply.c:3189 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 #, c-format msgid "read of %s failed" msgstr "Ä‘á»c %s gặp lá»—i" -#: builtin/apply.c:3169 builtin/apply.c:3391 +#: builtin/apply.c:3173 builtin/apply.c:3395 #, c-format msgid "path %s has been renamed/deleted" msgstr "Ä‘Æ°á»ng dẫn %s đã bị xóa/đổi tên" -#: builtin/apply.c:3250 builtin/apply.c:3405 +#: builtin/apply.c:3254 builtin/apply.c:3409 #, 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:3254 builtin/apply.c:3397 builtin/apply.c:3419 +#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 #, c-format msgid "%s: %s" msgstr "%s: %s" -#: builtin/apply.c:3259 builtin/apply.c:3413 +#: builtin/apply.c:3263 builtin/apply.c:3417 #, c-format msgid "%s: does not match index" msgstr "%s: không khá»›p trong mục lục" -#: builtin/apply.c:3361 +#: builtin/apply.c:3365 msgid "removal patch leaves file contents" msgstr "loại bá» miếng vá để lại ná»™i dung táºp tin" -#: builtin/apply.c:3430 +#: builtin/apply.c:3434 #, c-format msgid "%s: wrong type" msgstr "%s: sai kiểu" -#: builtin/apply.c:3432 +#: builtin/apply.c:3436 #, c-format msgid "%s has type %o, expected %o" msgstr "%s có kiểu %o, mong chá» %o" -#: builtin/apply.c:3533 +#: builtin/apply.c:3537 #, c-format msgid "%s: already exists in index" msgstr "%s: đã có từ trÆ°á»›c trong bảng mục lục" -#: builtin/apply.c:3536 +#: builtin/apply.c:3540 #, 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:3556 +#: builtin/apply.c:3560 #, 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:3561 +#: builtin/apply.c:3565 #, 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:3569 +#: builtin/apply.c:3573 #, c-format msgid "%s: patch does not apply" msgstr "%s: miếng vá không được áp dụng" -#: builtin/apply.c:3582 +#: builtin/apply.c:3586 #, c-format msgid "Checking patch %s..." msgstr "Äang kiểm tra miếng vá %s..." -#: builtin/apply.c:3675 builtin/checkout.c:215 builtin/reset.c:124 +#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 #, 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:3818 +#: builtin/apply.c:3822 #, c-format msgid "unable to remove %s from index" msgstr "không thể gỡ bá» %s từ mục lục" -#: builtin/apply.c:3846 +#: builtin/apply.c:3850 #, c-format msgid "corrupt patch for subproject %s" msgstr "miếng vá sai há»ng cho dá»± án con (subproject) %s" -#: builtin/apply.c:3850 +#: builtin/apply.c:3854 #, c-format msgid "unable to stat newly created file '%s'" msgstr "không thể lấy trạng thái vá» táºp tin %s má»›i hÆ¡n đã được tạo" -#: builtin/apply.c:3855 +#: builtin/apply.c:3859 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "không thể tạo “backing store†cho táºp tin được tạo má»›i hÆ¡n %s" -#: builtin/apply.c:3858 builtin/apply.c:3966 +#: builtin/apply.c:3862 builtin/apply.c:3970 #, c-format msgid "unable to add cache entry for %s" msgstr "không thể thêm mục nhá»› tạm cho %s" -#: builtin/apply.c:3891 +#: builtin/apply.c:3895 #, c-format msgid "closing file '%s'" msgstr "Ä‘ang đóng táºp tin “%sâ€" -#: builtin/apply.c:3940 +#: builtin/apply.c:3944 #, c-format msgid "unable to write file '%s' mode %o" msgstr "không thể ghi và o táºp tin “%s†chế Ä‘á»™ (mode) %o" -#: builtin/apply.c:4027 +#: builtin/apply.c:4031 #, 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:4035 +#: builtin/apply.c:4039 msgid "internal error" msgstr "lá»—i ná»™i bá»™" #. Say this even without --verbose -#: builtin/apply.c:4038 +#: builtin/apply.c:4042 #, 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..." msgstr[1] "Äang áp dụng miếng vá %%s vá»›i %d lần từ chối..." -#: builtin/apply.c:4048 +#: builtin/apply.c:4052 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "Ä‘ang cắt cụt tên táºp tin .rej thà nh %.*s.rej" -#: builtin/apply.c:4069 +#: builtin/apply.c:4073 #, c-format msgid "Hunk #%d applied cleanly." msgstr "Khối nhá»› #%d được áp dụng gá»n gà ng." -#: builtin/apply.c:4072 +#: builtin/apply.c:4076 #, c-format msgid "Rejected hunk #%d." msgstr "hunk #%d bị từ chối." -#: builtin/apply.c:4222 +#: builtin/apply.c:4226 msgid "unrecognized input" msgstr "không thừa nháºn đầu và o" -#: builtin/apply.c:4233 +#: builtin/apply.c:4237 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:4352 builtin/apply.c:4355 builtin/clone.c:91 +#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 #: builtin/fetch.c:63 msgid "path" msgstr "Ä‘Æ°á»ng-dẫn" -#: builtin/apply.c:4353 +#: builtin/apply.c:4357 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:4356 +#: builtin/apply.c:4360 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:4358 +#: builtin/apply.c:4362 msgid "num" msgstr "số" -#: builtin/apply.c:4359 +#: builtin/apply.c:4363 msgid "remove <num> leading slashes from traditional diff paths" msgstr "gỡ bá» <số> phần dẫn đầu (slashe) từ Ä‘Æ°á»ng dẫn diff cổ Ä‘iển" -#: builtin/apply.c:4362 +#: builtin/apply.c:4366 msgid "ignore additions made by the patch" msgstr "lá» Ä‘i phần phụ thêm tạo ra bởi miếng vá" -#: builtin/apply.c:4364 +#: builtin/apply.c:4368 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:4368 +#: builtin/apply.c:4372 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:4370 +#: builtin/apply.c:4374 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:4372 +#: builtin/apply.c:4376 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:4374 +#: builtin/apply.c:4378 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:4376 +#: builtin/apply.c:4380 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:4378 +#: builtin/apply.c:4382 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:4380 +#: builtin/apply.c:4384 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:4382 +#: builtin/apply.c:4386 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:4384 builtin/checkout-index.c:197 builtin/ls-files.c:463 +#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 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:4387 +#: builtin/apply.c:4391 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:4388 +#: builtin/apply.c:4392 msgid "action" msgstr "hà nh Ä‘á»™ng" -#: builtin/apply.c:4389 +#: builtin/apply.c:4393 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:4392 builtin/apply.c:4395 +#: builtin/apply.c:4396 builtin/apply.c:4399 msgid "ignore changes in whitespace when finding context" msgstr "lá» Ä‘i sá»± thay đổi do khoảng trắng khi quét ná»™i dung" -#: builtin/apply.c:4398 +#: builtin/apply.c:4402 msgid "apply the patch in reverse" msgstr "áp dụng miếng vá theo chiá»u ngược" -#: builtin/apply.c:4400 +#: builtin/apply.c:4404 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:4402 +#: builtin/apply.c:4406 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:4404 +#: builtin/apply.c:4408 msgid "allow overlapping hunks" msgstr "cho phép chồng khối nhá»›" -#: builtin/apply.c:4407 +#: builtin/apply.c:4411 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:4410 +#: builtin/apply.c:4414 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:4412 +#: builtin/apply.c:4416 msgid "root" msgstr "root" -#: builtin/apply.c:4413 +#: builtin/apply.c:4417 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:4435 +#: builtin/apply.c:4439 msgid "--3way outside a repository" msgstr "--3way ở ngoà i má»™t kho chứa" -#: builtin/apply.c:4443 +#: builtin/apply.c:4447 msgid "--index outside a repository" msgstr "--index ở ngoà i má»™t kho chứa" -#: builtin/apply.c:4446 +#: builtin/apply.c:4450 msgid "--cached outside a repository" msgstr "--cached ở ngoà i má»™t kho chứa" -#: builtin/apply.c:4462 +#: builtin/apply.c:4466 #, c-format msgid "can't open patch '%s'" msgstr "không thể mở miếng vá “%sâ€" -#: builtin/apply.c:4476 +#: builtin/apply.c:4480 #, 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" msgstr[1] "đã chấm dứt %d lá»—i khoảng trắng" -#: builtin/apply.c:4482 builtin/apply.c:4492 +#: builtin/apply.c:4486 builtin/apply.c:4496 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -2167,21 +2382,21 @@ msgstr "git archive: Máy chủ không có địa chỉ URL" msgid "git archive: expected ACK/NAK, got EOF" msgstr "git archive: mong đợi ACK/NAK, nháºn EOF" -#: builtin/archive.c:63 +#: builtin/archive.c:61 #, c-format msgid "git archive: NACK %s" msgstr "git archive: NACK %s" -#: builtin/archive.c:65 +#: builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "lá»—i máy chủ: %s" -#: builtin/archive.c:66 +#: builtin/archive.c:64 msgid "git archive: protocol error" msgstr "git archive: lá»—i giao thức" -#: builtin/archive.c:71 +#: builtin/archive.c:68 msgid "git archive: expected a flush" msgstr "git archive: đã mong chá» má»™t flush" @@ -2203,121 +2418,121 @@ msgstr "" msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "git blame [các-tùy-chá»n] [rev-opts] [rev] [--] táºp-tin" -#: builtin/blame.c:30 builtin/shortlog.c:15 +#: builtin/blame.c:30 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[rev-opts] được mô tả trong git-rev-list(1)" -#: builtin/blame.c:2350 +#: builtin/blame.c:2355 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:2351 +#: builtin/blame.c:2356 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:2352 +#: builtin/blame.c:2357 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:2353 +#: builtin/blame.c:2358 msgid "Show work cost statistics" msgstr "Hiển thị thống kê công sức là m việc" -#: builtin/blame.c:2354 +#: builtin/blame.c:2359 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:2355 +#: builtin/blame.c:2360 msgid "Show original filename (Default: auto)" msgstr "Hiển thị tên táºp tin gốc (Mặc định: auto)" -#: builtin/blame.c:2356 +#: builtin/blame.c:2361 msgid "Show original linenumber (Default: off)" msgstr "Hiển thị số dòng gốc (Mặc định: off)" -#: builtin/blame.c:2357 +#: builtin/blame.c:2362 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:2358 +#: builtin/blame.c:2363 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:2359 +#: builtin/blame.c:2364 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "Dùng cùng chế Ä‘á»™ xuất ra vóigit-annotate (Mặc định: off)" -#: builtin/blame.c:2360 +#: builtin/blame.c:2365 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:2361 +#: builtin/blame.c:2366 msgid "Show long commit SHA1 (Default: off)" msgstr "Hiển thị SHA1 của lần chuyển giao (commit) dạng dà i (Mặc định: off)" -#: builtin/blame.c:2362 +#: builtin/blame.c:2367 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:2363 +#: builtin/blame.c:2368 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:2364 +#: builtin/blame.c:2369 msgid "Ignore whitespace differences" msgstr "Bá» qua các khác biệt do khoảng trắng gây ra" -#: builtin/blame.c:2365 +#: builtin/blame.c:2370 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:2366 +#: builtin/blame.c:2371 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:2367 +#: builtin/blame.c:2372 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:2368 builtin/blame.c:2369 +#: builtin/blame.c:2373 builtin/blame.c:2374 msgid "score" msgstr "Ä‘iểm số" -#: builtin/blame.c:2368 +#: builtin/blame.c:2373 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:2369 +#: builtin/blame.c:2374 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:2370 +#: builtin/blame.c:2375 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "Process only line range n,m, counting from 1" msgstr "Xá» lý chỉ dòng vùng n,m, tÃnh từ 1" -#: builtin/branch.c:23 +#: builtin/branch.c:24 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:24 +#: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" msgstr "git branch [các-tùy-chá»n] [-l] [-f] <tên-nhánh> [<Ä‘iểm-đầu>]" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) <branchname>..." msgstr "git branch [các-tùy-chá»n] [-r] (-d | -D) <tên-nhánh> ..." -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" msgstr "git branch [các-tùy-chá»n] (-m | -M) [<nhánh-cÅ©>] <nhánh-má»›i>" -#: builtin/branch.c:145 +#: builtin/branch.c:150 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -2326,7 +2541,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:149 +#: builtin/branch.c:154 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -2335,12 +2550,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:163 +#: builtin/branch.c:168 #, 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 (commit) cho “%sâ€" -#: builtin/branch.c:167 +#: builtin/branch.c:172 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -2349,287 +2564,333 @@ 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:180 +#: builtin/branch.c:185 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:208 +#: builtin/branch.c:213 msgid "cannot use -a with -d" msgstr "không thể dùng tùy chá»n -a vá»›i -d" -#: builtin/branch.c:214 +#: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" msgstr "Không thể tìm kiếm đối tượng chuyển giao (commit) cho HEAD" -#: builtin/branch.c:222 +#: builtin/branch.c:227 #, 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 ở." -#: builtin/branch.c:235 +#: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." msgstr "không tìm thấy nhánh máy chủ “%sâ€." -#: builtin/branch.c:236 +#: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." msgstr "không tìm thấy nhánh “%sâ€." -#: builtin/branch.c:250 +#: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" msgstr "Gặp lá»—i khi Ä‘ang xóa nhánh trên máy chủ “%sâ€" -#: builtin/branch.c:251 +#: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" msgstr "Lá»—i khi xoá bá» nhánh “%sâ€" -#: builtin/branch.c:258 +#: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "Nhánh trên máy chủ \"%s\" đã bị xóa (từng là %s).\n" -#: builtin/branch.c:259 +#: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "Nhánh “%s†đã bị xóa (từng là %s)\n" -#: builtin/branch.c:361 +#: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" msgstr "nhánh “%s†không chỉ đến má»™t lần chuyển giao (commit) nà o cả" -#: builtin/branch.c:433 +#: builtin/branch.c:453 #, c-format msgid "[%s: behind %d]" msgstr "[%s: đằng sau %d]" -#: builtin/branch.c:435 +#: builtin/branch.c:455 #, c-format msgid "[behind %d]" msgstr "[đằng sau %d]" -#: builtin/branch.c:439 +#: builtin/branch.c:459 #, c-format msgid "[%s: ahead %d]" msgstr "[%s: phÃa trÆ°á»›c %d]" -#: builtin/branch.c:441 +#: builtin/branch.c:461 #, c-format msgid "[ahead %d]" msgstr "[phÃa trÆ°á»›c %d]" -#: builtin/branch.c:444 +#: builtin/branch.c:464 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s: trÆ°á»›c %d, sau %d]" -#: builtin/branch.c:447 +#: builtin/branch.c:467 #, c-format msgid "[ahead %d, behind %d]" msgstr "[trÆ°á»›c %d, sau %d]" -#: builtin/branch.c:469 +#: builtin/branch.c:490 msgid " **** invalid ref ****" msgstr " **** tham chiếu sai ****" -#: builtin/branch.c:560 +#: builtin/branch.c:582 +#, c-format +msgid "(no branch, rebasing %s)" +msgstr "(không nhánh, Ä‘ang rebase %s)" + +#: builtin/branch.c:585 +#, c-format +msgid "(no branch, bisect started on %s)" +msgstr "(không nhánh, bisect được bắt đầu tại %s)" + +#: builtin/branch.c:588 +#, c-format +msgid "(detached from %s)" +msgstr "(được tách rá»i từ %s)" + +#: builtin/branch.c:591 msgid "(no branch)" msgstr "(không nhánh)" -#: builtin/branch.c:593 +#: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" msgstr "đối tượng “%s†không chỉ đến má»™t lần chuyển giao (commit) nà o cả" -#: builtin/branch.c:625 +#: builtin/branch.c:669 msgid "some refs could not be read" msgstr "má»™t số tham chiếu đã không thể Ä‘á»c được" -#: builtin/branch.c:638 +#: builtin/branch.c:682 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:648 +#: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" msgstr "Sai tên nhánh: “%sâ€" -#: builtin/branch.c:663 +#: builtin/branch.c:707 msgid "Branch rename failed" msgstr "Äổi tên nhánh gặp lá»—i" -#: builtin/branch.c:667 +#: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "Äã đổi tên nhánh khuyết danh “%s†đi" -#: builtin/branch.c:671 +#: builtin/branch.c:715 #, 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:678 +#: builtin/branch.c:722 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:693 +#: builtin/branch.c:737 #, c-format msgid "malformed object name %s" msgstr "tên đối tượng dị hình %s" -#: builtin/branch.c:717 +#: builtin/branch.c:761 #, 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:747 +#: builtin/branch.c:791 msgid "Generic options" msgstr "Tùy chá»n chung" -#: builtin/branch.c:749 +#: builtin/branch.c:793 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:750 +#: builtin/branch.c:794 msgid "suppress informational messages" msgstr "Thu hồi các thông Ä‘iệp thông tin" -#: builtin/branch.c:751 +#: builtin/branch.c:795 msgid "set up tracking mode (see git-pull(1))" msgstr "cà i đặt chế Ä‘á»™ theo vết (xem git-pull(1))" -#: builtin/branch.c:753 +#: builtin/branch.c:797 msgid "change upstream info" msgstr "thay đổi thông tin thượng nguồn (upstream)" -#: builtin/branch.c:757 +#: builtin/branch.c:801 msgid "use colored output" msgstr "sá» dụng kết xuất có tô mà u" -#: builtin/branch.c:758 +#: builtin/branch.c:802 msgid "act on remote-tracking branches" msgstr "thao tác trên nhánh “remote-trackingâ€" -#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 -#: builtin/branch.c:794 builtin/commit.c:1366 builtin/commit.c:1367 -#: builtin/commit.c:1368 builtin/commit.c:1369 builtin/tag.c:468 +#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 +#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 +#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 msgid "commit" msgstr "commit" -#: builtin/branch.c:762 builtin/branch.c:768 +#: builtin/branch.c:806 builtin/branch.c:812 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:774 +#: builtin/branch.c:818 msgid "Specific git-branch actions:" msgstr "Hà nh Ä‘á»™ng git-branch:" -#: builtin/branch.c:775 +#: builtin/branch.c:819 msgid "list both remote-tracking and local branches" msgstr "liệt kê cả nhánh “remote-tracking†và ná»™i bá»™" -#: builtin/branch.c:777 +#: builtin/branch.c:821 msgid "delete fully merged branch" msgstr "xóa má»™t cách đầy đủ nhánh đã hòa trá»™n" -#: builtin/branch.c:778 +#: builtin/branch.c:822 msgid "delete branch (even if not merged)" msgstr "xoá nhánh (cho dù là chÆ°a được hòa trá»™n)" -#: builtin/branch.c:779 +#: builtin/branch.c:823 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:780 +#: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "di chuyển hoặc đổi tên má»™t nhánh, tháºm chà cả khi Ä‘Ãch đã có sẵn" -#: builtin/branch.c:781 +#: builtin/branch.c:825 msgid "list branch names" msgstr "liệt kê các tên nhánh" -#: builtin/branch.c:782 +#: builtin/branch.c:826 msgid "create the branch's reflog" msgstr "tạo reflog của nhánh" -#: builtin/branch.c:784 +#: builtin/branch.c:828 msgid "edit the description for the branch" msgstr "sá»a mô tả cho nhánh" -#: builtin/branch.c:785 +#: builtin/branch.c:829 msgid "force creation (when already exists)" msgstr "ép buá»™c tạo (khi đã sẵn tồn tại rồi)" -#: builtin/branch.c:788 +#: builtin/branch.c:832 msgid "print only not merged branches" msgstr "chỉ hiển thị các nhánh chÆ°a được hòa trá»™n" -#: builtin/branch.c:794 +#: builtin/branch.c:838 msgid "print only merged branches" msgstr "chỉ hiển thị các nhánh được hòa trá»™n" -#: builtin/branch.c:798 +#: builtin/branch.c:842 msgid "list branches in columns" msgstr "liệt kê các nhánh trong các cá»™t" -#: builtin/branch.c:811 +#: builtin/branch.c:855 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 (ref) hợp lệ." -#: builtin/branch.c:816 builtin/clone.c:561 +#: builtin/branch.c:860 builtin/clone.c:619 msgid "HEAD not found below refs/heads!" msgstr "không tìm thấy HEAD ở dÆ°á»›i refs/heads!" -#: builtin/branch.c:839 +#: builtin/branch.c:883 msgid "--column and --verbose are incompatible" msgstr "--column và --verbose xung khắc nhau" -#: builtin/branch.c:845 +#: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" msgstr "cần tên nhánh" -#: builtin/branch.c:860 +#: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" msgstr "Không thể Ä‘Æ°a ra mô tả HEAD đã tách rá»i" -#: builtin/branch.c:865 +#: builtin/branch.c:909 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:872 +#: builtin/branch.c:916 #, 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:875 +#: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." msgstr "Không có nhánh nà o có tên “%sâ€." -#: builtin/branch.c:888 +#: builtin/branch.c:934 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:893 +#: builtin/branch.c:939 +msgid "too many branches to set new upstream" +msgstr "quá nhiá»u nhánh được đặt cho dòng ngược (upstream) má»›i" + +#: builtin/branch.c:943 +#, c-format +msgid "" +"could not set upstream of HEAD to %s when it does not point to any branch." +msgstr "" +"không thể đặt dòng ngược (upstream) của HEAD thà nh %s khi mà nó chẳng chỉ " +"đến nhánh nà o cả." + +#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 +#, c-format +msgid "no such branch '%s'" +msgstr "không có nhánh nà o nhÆ° thế “%sâ€" + +#: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" msgstr "nhánh “%s†chÆ°a sẵn có" -#: builtin/branch.c:905 +#: builtin/branch.c:962 +msgid "too many branches to unset upstream" +msgstr "quá nhiá»u nhánh để bỠđặt ngược dòng (upstream)" + +#: builtin/branch.c:966 +msgid "could not unset upstream of HEAD when it does not point to any branch." +msgstr "" +"không thể bỠđặt ngược dòng (upstream) của HEAD không chỉ đến má»™t nhánh nà o " +"cả." + +#: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" msgstr "Nhánh “%s†không có thông tin thượng nguồn (upstream)" -#: builtin/branch.c:920 +#: builtin/branch.c:987 +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:993 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:923 +#: builtin/branch.c:996 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2638,7 +2899,7 @@ msgstr "" "Cá» --set-upstream bị phản đối và sẽ bị xóa bá». Nên dùng --track hoặc --set-" "upstream-to\n" -#: builtin/branch.c:940 +#: builtin/branch.c:1013 #, c-format msgid "" "\n" @@ -2649,12 +2910,12 @@ msgstr "" "Nếu bạn muốn “%s†theo dõi “%sâ€, thá»±c hiện lệnh sau:\n" "\n" -#: builtin/branch.c:941 +#: builtin/branch.c:1014 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:942 +#: builtin/branch.c:1015 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2672,44 +2933,44 @@ msgstr "Cần má»™t kho chứa để mà tạo má»™t bundle." msgid "Need a repository to unbundle." msgstr "Cần má»™t kho chứa để mà bung má»™t bundle." -#: builtin/cat-file.c:247 +#: builtin/cat-file.c:176 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>" msgstr "git cat-file (-t|-s|-e|-p|<kiểu>|--textconv) <đối tượng>" -#: builtin/cat-file.c:248 +#: builtin/cat-file.c:177 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>" msgstr "git cat-file (--batch|--batch-check) < <danh-sách-đối-tượng>" -#: builtin/cat-file.c:266 +#: builtin/cat-file.c:195 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "<kiểu> là má»™t trong số: blob, tree, commit, tag" -#: builtin/cat-file.c:267 +#: builtin/cat-file.c:196 msgid "show object type" msgstr "hiển thị kiểu đối tượng" -#: builtin/cat-file.c:268 +#: builtin/cat-file.c:197 msgid "show object size" msgstr "hiển thị kÃch thÆ°á»›c đối tượng" -#: builtin/cat-file.c:270 +#: builtin/cat-file.c:199 msgid "exit with zero when there's no error" msgstr "thoát vá»›i 0 khi không có lá»—i" -#: builtin/cat-file.c:271 +#: builtin/cat-file.c:200 msgid "pretty-print object's content" msgstr "in ná»™i dung đối tượng dạng dá»… Ä‘á»c" -#: builtin/cat-file.c:273 +#: builtin/cat-file.c:202 msgid "for blob objects, run textconv on object's content" msgstr "vá»›i đối tượng blob, chạy lệnh textconv trên ná»™i dung của đối tượng" -#: builtin/cat-file.c:275 +#: builtin/cat-file.c:204 msgid "show info and content of objects fed from the standard input" msgstr "" "hiển thị thông tin và ná»™i dung của các đối tượng lấy từ đầu và o tiêu chuẩn" -#: builtin/cat-file.c:278 +#: builtin/cat-file.c:207 msgid "show info about objects fed from the standard input" msgstr "hiển thị các thông tin vỠđối tượng fed từ đầu và o tiêu chuẩn" @@ -2738,27 +2999,27 @@ msgstr "Ä‘á»c tên táºp tin từ đầu và o tiêu chuẩn" msgid "input paths are terminated by a null character" msgstr "các Ä‘Æ°á»ng dẫn được ngăn cách bởi ký tá»± null" -#: builtin/check-ignore.c:18 builtin/checkout.c:1012 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "chặn các báo cáo tiến trình hoạt Ä‘á»™ng" -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:146 msgid "cannot specify pathnames with --stdin" msgstr "không thể chỉ định các tên Ä‘Æ°á»ng dẫn vá»›i --stdin" -#: builtin/check-ignore.c:154 +#: builtin/check-ignore.c:149 msgid "-z only makes sense with --stdin" msgstr "-z chỉ hợp lý vá»›i --stdin" -#: builtin/check-ignore.c:156 +#: builtin/check-ignore.c:151 msgid "no path specified" msgstr "chÆ°a ghi rõ Ä‘Æ°á»ng dẫn" -#: builtin/check-ignore.c:160 +#: builtin/check-ignore.c:155 msgid "--quiet is only valid with a single pathname" msgstr "--quiet chỉ hợp lệ vá»›i tên Ä‘Æ°á»ng dẫn Ä‘Æ¡n" -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:157 msgid "cannot have both --quiet and --verbose" msgstr "không thể dùng cả hai tùy chá»n --quiet và --verbose" @@ -2815,107 +3076,107 @@ msgstr "git checkout [các-tùy-chá»n] <nhánh>" msgid "git checkout [options] [<branch>] -- <file>..." msgstr "git checkout [các-tùy-chá»n] [<nhánh>] -- <táºp-tin>..." -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format msgid "path '%s' does not have our version" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản của chúng ta" -#: builtin/checkout.c:118 builtin/checkout.c:151 +#: builtin/checkout.c:119 builtin/checkout.c:152 #, c-format msgid "path '%s' does not have their version" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản của chúng" -#: builtin/checkout.c:134 +#: builtin/checkout.c:135 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "Ä‘Æ°á»ng dẫn “%s†không có tất cả các phiên bản cần thiết" -#: builtin/checkout.c:178 +#: builtin/checkout.c:179 #, c-format msgid "path '%s' does not have necessary versions" msgstr "Ä‘Æ°á»ng dẫn “%s†không có các phiên bản cần thiết" -#: builtin/checkout.c:195 +#: builtin/checkout.c:196 #, c-format msgid "path '%s': cannot merge" msgstr "Ä‘Æ°á»ng dẫn “%sâ€: không thể hòa trá»™n" -#: builtin/checkout.c:212 +#: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" msgstr "Không thể thêm kết quả hòa trá»™n cho “%sâ€" -#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 -#: builtin/checkout.c:245 +#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 +#: builtin/checkout.c:246 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "“%s†không thể được sá» dụng vá»›i các Ä‘Æ°á»ng dẫn cáºp nháºt" -#: builtin/checkout.c:248 builtin/checkout.c:251 +#: builtin/checkout.c:249 builtin/checkout.c:252 #, c-format msgid "'%s' cannot be used with %s" msgstr "“%s†không thể được sá» dụng vá»›i %s" -#: builtin/checkout.c:254 +#: builtin/checkout.c:255 #, 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:265 builtin/checkout.c:426 +#: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" msgstr "táºp tin ghi bảng mục lục bị há»ng" -#: builtin/checkout.c:295 builtin/checkout.c:302 +#: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format msgid "path '%s' is unmerged" msgstr "Ä‘Æ°á»ng dẫn “%s†không được hòa trá»™n" -#: builtin/checkout.c:448 +#: builtin/checkout.c:480 msgid "you need to resolve your current index first" msgstr "bạn cần phải phân giải bảng mục lục hiện tại của bạn trÆ°á»›c đã" -#: builtin/checkout.c:569 +#: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "Không thể thá»±c hiện reflog cho “%sâ€\n" -#: builtin/checkout.c:602 +#: builtin/checkout.c:634 msgid "HEAD is now at" msgstr "HEAD hiện giá» tại" -#: builtin/checkout.c:609 +#: builtin/checkout.c:641 #, c-format msgid "Reset branch '%s'\n" msgstr "Äặt lại nhánh “%sâ€\n" -#: builtin/checkout.c:612 +#: builtin/checkout.c:644 #, c-format msgid "Already on '%s'\n" msgstr "Äã sẵn sà ng trên “%sâ€\n" -#: builtin/checkout.c:616 +#: builtin/checkout.c:648 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "Äã chuyển tá»›i và reset nhánh “%sâ€\n" -#: builtin/checkout.c:618 builtin/checkout.c:955 +#: builtin/checkout.c:650 builtin/checkout.c:987 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "Äã chuyển đến nhánh má»›i “%sâ€\n" -#: builtin/checkout.c:620 +#: builtin/checkout.c:652 #, c-format msgid "Switched to branch '%s'\n" msgstr "Äã chuyển đến nhánh “%sâ€\n" -#: builtin/checkout.c:676 +#: builtin/checkout.c:708 #, c-format msgid " ... and %d more.\n" msgstr " ... và nhiá»u hÆ¡n %d.\n" #. The singular version -#: builtin/checkout.c:682 +#: builtin/checkout.c:714 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2940,7 +3201,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:700 +#: builtin/checkout.c:732 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2956,134 +3217,138 @@ msgstr "" " git branch tên_nhánh_má»›i %s\n" "\n" -#: builtin/checkout.c:730 +#: builtin/checkout.c:762 msgid "internal error in revision walk" msgstr "lá»—i ná»™i bá»™ trong khi di chuyển qua các Ä‘iểm xét lại" -#: builtin/checkout.c:734 +#: builtin/checkout.c:766 msgid "Previous HEAD position was" msgstr "Vị trà kế trÆ°á»›c của HEAD là " -#: builtin/checkout.c:761 builtin/checkout.c:950 +#: builtin/checkout.c:793 builtin/checkout.c:982 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" #. case (1) -#: builtin/checkout.c:886 +#: builtin/checkout.c:918 #, c-format msgid "invalid reference: %s" msgstr "tham chiếu sai: %s" #. case (1): want a tree -#: builtin/checkout.c:925 +#: builtin/checkout.c:957 #, c-format msgid "reference is not a tree: %s" msgstr "tham chiếu không phải là má»™t cây (tree):%s" -#: builtin/checkout.c:964 +#: builtin/checkout.c:996 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:967 builtin/checkout.c:971 +#: builtin/checkout.c:999 builtin/checkout.c:1003 #, 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:975 builtin/checkout.c:978 builtin/checkout.c:983 -#: builtin/checkout.c:986 +#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 +#: builtin/checkout.c:1018 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "“%s†không thể được sá» dụng vá»›i “%sâ€" -#: builtin/checkout.c:991 +#: builtin/checkout.c:1023 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "Không thể chuyển nhánh đến má»™t non-commit “%sâ€" -#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "nhánh" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1046 msgid "create and checkout a new branch" msgstr "tạo và checkout má»™t nhánh má»›i" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1048 msgid "create/reset and checkout a branch" msgstr "create/reset và checkout má»™t nhánh" -#: builtin/checkout.c:1017 +#: builtin/checkout.c:1049 msgid "create reflog for new branch" msgstr "tạo reflog cho nhánh má»›i" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1050 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:1019 +#: builtin/checkout.c:1051 msgid "set upstream info for new branch" msgstr "đặt thông tin thượng nguồn (upstream) cho nhánh má»›i" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new branch" msgstr "nhánh má»›i" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new unparented branch" msgstr "nhánh mồ côi má»›i" -#: builtin/checkout.c:1022 +#: builtin/checkout.c:1054 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:1024 +#: builtin/checkout.c:1056 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:1026 +#: builtin/checkout.c:1058 msgid "force checkout (throw away local modifications)" msgstr "ép buá»™c lấy ra (checkout) (bá» Ä‘i những thay đổi ná»™i bá»™)" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1059 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:1028 builtin/merge.c:215 +#: builtin/checkout.c:1060 builtin/merge.c:217 msgid "update ignored files (default)" msgstr "cáºp nháºt các táºp tin bị bá» qua (mặc định)" -#: builtin/checkout.c:1029 builtin/log.c:1147 parse-options.h:245 +#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 msgid "style" msgstr "kiểu" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1062 msgid "conflict style (merge or diff3)" msgstr "xung Ä‘á»™t kiểu (hòa trá»™n hay diff3)" -#: builtin/checkout.c:1033 +#: builtin/checkout.c:1065 +msgid "do not limit pathspecs to sparse entries only" +msgstr "không giá»›i hạn pathspecs chỉ thà nh các mục thÆ°a thá»›t" + +#: builtin/checkout.c:1067 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:1057 +#: builtin/checkout.c:1091 msgid "-b, -B and --orphan are mutually exclusive" msgstr "Tùy chá»n -b|-B và --orphan loại từ lẫn nhau" -#: builtin/checkout.c:1074 +#: builtin/checkout.c:1108 msgid "--track needs a branch name" msgstr "--track cần tên má»™t nhánh" -#: builtin/checkout.c:1081 +#: builtin/checkout.c:1115 msgid "Missing branch name; try -b" msgstr "Thiếu tên nhánh; hãy thá» -b" -#: builtin/checkout.c:1116 +#: builtin/checkout.c:1150 msgid "invalid path specification" msgstr "Ä‘Æ°á»ng dẫn đã cho không hợp lệ" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1157 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -3093,12 +3358,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 (commit)?" -#: builtin/checkout.c:1128 +#: builtin/checkout.c:1162 #, 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:1132 +#: builtin/checkout.c:1166 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -3147,8 +3412,8 @@ msgstr "ép buá»™c" msgid "remove whole directories" msgstr "gỡ bá» toà n bá»™ thÆ° mục" -#: builtin/clean.c:165 builtin/describe.c:413 builtin/grep.c:717 -#: builtin/ls-files.c:494 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 +#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "mẫu" @@ -3183,215 +3448,233 @@ msgstr "" "clean.requireForce mặc định được đặt thà nh true và không Ä‘Æ°a ra tùy chá»n -n " "mà cÅ©ng không -f; từ chối lệnh dá»n dẹp (clean)" -#: builtin/clone.c:36 +#: builtin/clone.c:37 msgid "git clone [options] [--] <repo> [<dir>]" msgstr "git clone [các-tùy-chá»n] [--] <kho> [<t.mục>]" -#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:212 +#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 #: builtin/push.c:436 msgid "force progress reporting" msgstr "ép buá»™c báo cáo tiến trình" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "don't create a checkout" msgstr "không tạo má»™t checkout" -#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 msgid "create a bare repository" msgstr "tạo kho chứa bare" -#: builtin/clone.c:72 +#: builtin/clone.c:73 msgid "create a mirror repository (implies bare)" msgstr "tạo kho bản sao (mirror) (ngụ ý là bare)" -#: builtin/clone.c:74 +#: builtin/clone.c:75 msgid "to clone from a local repository" msgstr "để nhân bản từ kho ná»™i bá»™" -#: builtin/clone.c:76 +#: builtin/clone.c:77 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:78 +#: builtin/clone.c:79 msgid "setup as shared repository" msgstr "cà i đặt đây là kho chia sẻ" -#: builtin/clone.c:80 builtin/clone.c:82 +#: builtin/clone.c:81 builtin/clone.c:83 msgid "initialize submodules in the clone" msgstr "khởi tạo mô-Ä‘un-con trong bản sao" -#: builtin/clone.c:83 builtin/init-db.c:485 +#: builtin/clone.c:84 builtin/init-db.c:485 msgid "template-directory" msgstr "thÆ°-mục-tạm" -#: builtin/clone.c:84 builtin/init-db.c:486 +#: builtin/clone.c:85 builtin/init-db.c:486 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:86 +#: builtin/clone.c:87 msgid "reference repository" msgstr "kho tham chiếu" -#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "tên" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "use <name> instead of 'origin' to track upstream" msgstr "dùng <tên> thay vì “origin†để theo dõi thượng nguồn (uptream)" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "checkout <branch> instead of the remote's HEAD" msgstr "lấy ra nhánh (checkout <nhánh>) thay vì HEAD của máy chủ" -#: builtin/clone.c:92 +#: builtin/clone.c:93 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:93 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "Ä‘á»™ sâu" -#: builtin/clone.c:94 +#: builtin/clone.c:95 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:96 +#: builtin/clone.c:97 msgid "clone only one branch, HEAD or --branch" msgstr "nhân bản (clone) chỉ má»™t nhánh, HEAD hoặc --branch" -#: builtin/clone.c:97 builtin/init-db.c:494 +#: builtin/clone.c:98 builtin/init-db.c:494 msgid "gitdir" msgstr "gitdir" -#: builtin/clone.c:98 builtin/init-db.c:495 +#: builtin/clone.c:99 builtin/init-db.c:495 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:99 +#: builtin/clone.c:100 msgid "key=value" msgstr "khóa=giá trị" -#: builtin/clone.c:100 +#: 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:243 +#: builtin/clone.c:254 #, c-format -msgid "reference repository '%s' is not a local directory." -msgstr "kho tham chiếu “%s†không phải là má»™t thÆ° mục ná»™i bá»™." +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:306 +#: builtin/clone.c:317 #, c-format msgid "failed to create directory '%s'" msgstr "tạo thÆ° mục \"%s\" gặp lá»—i" -#: builtin/clone.c:308 builtin/diff.c:77 +#: builtin/clone.c:319 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "gặp lá»—i stat (lấy trạng thái vá») “%sâ€" -#: builtin/clone.c:310 +#: builtin/clone.c:321 #, c-format msgid "%s exists and is not a directory" msgstr "%s tồn tại nhÆ°ng không phải là má»™t thÆ° mục" -#: builtin/clone.c:324 +#: builtin/clone.c:335 #, c-format msgid "failed to stat %s\n" msgstr "lá»—i stat (lấy trạng thái vá») %s\n" -#: builtin/clone.c:346 +#: builtin/clone.c:357 #, 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:350 +#: builtin/clone.c:361 #, c-format msgid "failed to copy file to '%s'" msgstr "gặp lá»—i khi chép táºp tin tá»›i “%sâ€" -#: builtin/clone.c:373 +#: builtin/clone.c:384 #, c-format msgid "done.\n" msgstr "hoà n tất.\n" -#: builtin/clone.c:443 +#: builtin/clone.c:397 +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 "" +"Việc nhân bản thà nh công, nhÆ°ng checkout gặp lá»—i.\n" +"Bạn kiểm tra kỹ xem cái gì được lấy ra bằng lệnh “git statusâ€\n" +"và thá» checkout vá»›i lệnh “git checkout -f HEADâ€\n" + +#: builtin/clone.c:476 #, 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:552 +#: builtin/clone.c:550 +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:610 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ể checkout.\n" -#: builtin/clone.c:690 +#: builtin/clone.c:641 +msgid "unable to checkout working tree" +msgstr "không thể lấy ra (checkout) cây là m việc" + +#: builtin/clone.c:749 msgid "Too many arguments." msgstr "Có quá nhiá»u đối số." -#: builtin/clone.c:694 +#: builtin/clone.c:753 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:705 +#: builtin/clone.c:764 #, 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:708 +#: builtin/clone.c:767 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:721 +#: builtin/clone.c:780 #, c-format msgid "repository '%s' does not exist" msgstr "kho chứa “%s†chÆ°a tồn tại" -#: builtin/clone.c:726 +#: builtin/clone.c:785 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:736 +#: builtin/clone.c:795 #, 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:746 +#: builtin/clone.c:805 #, 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:759 builtin/clone.c:771 +#: builtin/clone.c:818 builtin/clone.c:830 #, 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:762 +#: builtin/clone.c:821 #, 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:781 +#: builtin/clone.c:840 #, 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:783 +#: builtin/clone.c:842 #, c-format msgid "Cloning into '%s'...\n" msgstr "Äang nhân bản thà nh “%sâ€...\n" -#: builtin/clone.c:818 +#: builtin/clone.c:877 #, 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:867 +#: builtin/clone.c:926 #, 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 (upstream) %s" -#: builtin/clone.c:874 +#: builtin/clone.c:933 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." @@ -3493,97 +3776,97 @@ msgstr "" "\n" "Nếu không, hãy thá» dùng “git resetâ€\n" -#: builtin/commit.c:258 +#: builtin/commit.c:260 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:300 +#: builtin/commit.c:302 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:306 +#: builtin/commit.c:308 msgid "interactive add failed" msgstr "việc thêm tÆ°Æ¡ng tác gặp lá»—i" -#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 +#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 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:391 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a merge." msgstr "" "không thể thá»±c hiện việc chuyển giao (commit) cục bá»™ trong khi Ä‘ang được hòa " "trá»™n." -#: builtin/commit.c:393 +#: builtin/commit.c:395 msgid "cannot do a partial commit during a cherry-pick." msgstr "" "không thể thá»±c hiện việc chuyển giao (commit) bá»™ pháºn trong khi Ä‘ang cherry-" "pick." -#: builtin/commit.c:403 +#: builtin/commit.c:405 msgid "cannot read the index" msgstr "không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:423 +#: builtin/commit.c:425 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:511 builtin/commit.c:517 +#: builtin/commit.c:513 builtin/commit.c:519 #, c-format msgid "invalid commit: %s" msgstr "lần chuyển giao (commit) không hợp lệ: %s" -#: builtin/commit.c:540 +#: builtin/commit.c:542 msgid "malformed --author parameter" msgstr "đối số --author bị dị hình" -#: builtin/commit.c:560 +#: builtin/commit.c:562 #, c-format msgid "Malformed ident string: '%s'" msgstr "Chuá»—i thụt lỠđầu dòng dị hình: “%sâ€" -#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 +#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 #, 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:610 builtin/shortlog.c:272 +#: builtin/commit.c:612 builtin/shortlog.c:270 #, 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:612 +#: builtin/commit.c:614 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:616 +#: builtin/commit.c:618 #, c-format msgid "could not read log file '%s'" msgstr "không Ä‘á»c được tệp nháºt ký “%sâ€" -#: builtin/commit.c:622 +#: builtin/commit.c:624 msgid "commit has empty message" msgstr "lần chuyển giao (commit) có ghi chú trống rá»—ng" -#: builtin/commit.c:638 +#: builtin/commit.c:640 msgid "could not read MERGE_MSG" msgstr "không thể Ä‘á»c MERGE_MSG" -#: builtin/commit.c:642 +#: builtin/commit.c:644 msgid "could not read SQUASH_MSG" msgstr "không thể Ä‘á»c SQUASH_MSG" -#: builtin/commit.c:646 +#: builtin/commit.c:648 #, c-format msgid "could not read '%s'" msgstr "Không thể Ä‘á»c “%sâ€." -#: builtin/commit.c:707 +#: builtin/commit.c:709 msgid "could not write commit template" msgstr "không thể ghi mẫu commit" -#: builtin/commit.c:718 +#: builtin/commit.c:720 #, c-format msgid "" "\n" @@ -3598,7 +3881,7 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:723 +#: builtin/commit.c:725 #, c-format msgid "" "\n" @@ -3613,7 +3896,7 @@ msgstr "" "\t%s\n" "và thá» lại.\n" -#: builtin/commit.c:735 +#: builtin/commit.c:737 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3624,7 +3907,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 (commit).\n" -#: builtin/commit.c:740 +#: builtin/commit.c:742 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3636,148 +3919,148 @@ 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 (commit).\n" -#: builtin/commit.c:753 +#: builtin/commit.c:755 #, c-format msgid "%sAuthor: %s" msgstr "%sTác giả: %s" -#: builtin/commit.c:760 +#: builtin/commit.c:762 #, c-format msgid "%sCommitter: %s" msgstr "%sNgÆ°á»i chuyển giao (commit): %s" -#: builtin/commit.c:780 +#: builtin/commit.c:782 msgid "Cannot read index" msgstr "không Ä‘á»c được bảng mục lục" -#: builtin/commit.c:817 +#: builtin/commit.c:819 msgid "Error building trees" msgstr "Gặp lá»—i khi xây dá»±ng cây" -#: builtin/commit.c:832 builtin/tag.c:359 +#: builtin/commit.c:834 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "Xin hãy áp dụng thông Ä‘iệp sá» dụng hoặc là tùy chá»n -m hoặc là -F.\n" -#: builtin/commit.c:929 +#: builtin/commit.c:931 #, c-format msgid "No existing author found with '%s'" msgstr "Không tìm thấy tác giả có sẵn vá»›i “%sâ€" -#: builtin/commit.c:944 builtin/commit.c:1138 +#: builtin/commit.c:946 builtin/commit.c:1140 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "Chế Ä‘á»™ cho các táºp tin không bị theo vết không hợp lệ “%sâ€" -#: builtin/commit.c:974 +#: builtin/commit.c:976 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:985 +#: builtin/commit.c:987 msgid "You have nothing to amend." msgstr "Không có gì để amend (tu bổ) cả." -#: builtin/commit.c:988 +#: builtin/commit.c:990 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 amend (tu bổ)." -#: builtin/commit.c:990 +#: builtin/commit.c:992 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 amend (tu " "bổ)." -#: builtin/commit.c:993 +#: builtin/commit.c:995 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:1003 +#: builtin/commit.c:1005 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "Chỉ má»™t tùy chá»n trong số -c/-C/-F/--fixup được sá» dụng" -#: builtin/commit.c:1005 +#: builtin/commit.c:1007 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:1013 +#: builtin/commit.c:1015 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:1030 +#: builtin/commit.c:1032 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:1032 +#: builtin/commit.c:1034 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:1034 +#: builtin/commit.c:1036 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 phi nghÄ©a." -#: builtin/commit.c:1036 +#: builtin/commit.c:1038 msgid "Explicit paths specified without -i nor -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; Ä‘ang " "giả định --only những-Ä‘Æ°á»ng-dẫn..." -#: builtin/commit.c:1046 builtin/tag.c:575 +#: builtin/commit.c:1048 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "Chế Ä‘á»™ dá»n dẹp không hợp lệ %s" -#: builtin/commit.c:1051 +#: builtin/commit.c:1053 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:1057 builtin/commit.c:1192 +#: builtin/commit.c:1059 builtin/commit.c:1194 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:1152 builtin/commit.c:1388 +#: builtin/commit.c:1154 builtin/commit.c:1390 msgid "show status concisely" msgstr "hiển thị trạng thái ở dạng súc tÃch" -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1156 builtin/commit.c:1392 msgid "show branch information" msgstr "hiển thị thông tin nhánh" -#: builtin/commit.c:1156 builtin/commit.c:1392 builtin/push.c:426 +#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 msgid "machine-readable output" msgstr "kết xuất dạng máy-có-thể-Ä‘á»c" -#: builtin/commit.c:1159 builtin/commit.c:1394 +#: builtin/commit.c:1161 builtin/commit.c:1396 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:1162 builtin/commit.c:1397 +#: builtin/commit.c:1164 builtin/commit.c:1399 msgid "terminate entries with NUL" msgstr "chấm dứt các mục bằng NUL" -#: builtin/commit.c:1164 builtin/commit.c:1400 builtin/fast-export.c:647 -#: builtin/fast-export.c:650 builtin/tag.c:459 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 +#: builtin/fast-export.c:662 builtin/tag.c:459 msgid "mode" msgstr "chế Ä‘á»™" -#: builtin/commit.c:1165 builtin/commit.c:1400 +#: builtin/commit.c:1167 builtin/commit.c:1402 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:1168 +#: builtin/commit.c:1170 msgid "show ignored files" msgstr "hiển thị các táºp tin ẩn" -#: builtin/commit.c:1169 parse-options.h:151 +#: builtin/commit.c:1171 parse-options.h:151 msgid "when" msgstr "khi" -#: builtin/commit.c:1170 +#: builtin/commit.c:1172 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" @@ -3785,223 +4068,223 @@ 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:1172 +#: builtin/commit.c:1174 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:1246 +#: builtin/commit.c:1248 msgid "couldn't look up newly created commit" msgstr "không thể tìm thấy lần chuyển giao (commit) má»›i hÆ¡n đã được tạo" -#: builtin/commit.c:1248 +#: builtin/commit.c:1250 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:1289 +#: builtin/commit.c:1291 msgid "detached HEAD" msgstr "đã rá»i khá»i HEAD" -#: builtin/commit.c:1291 +#: builtin/commit.c:1293 msgid " (root-commit)" msgstr " (root-commit)" -#: builtin/commit.c:1358 +#: builtin/commit.c:1360 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:1359 +#: builtin/commit.c:1361 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:1361 +#: builtin/commit.c:1363 msgid "Commit message options" msgstr "Các tùy chá»n ghi chú commit" -#: builtin/commit.c:1362 builtin/tag.c:457 +#: builtin/commit.c:1364 builtin/tag.c:457 msgid "read message from file" msgstr "Ä‘á»c chú thÃch từ táºp tin" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "author" msgstr "tác giả" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "override author for commit" msgstr "ghi đè tác giả cho commit" -#: builtin/commit.c:1364 builtin/gc.c:178 +#: builtin/commit.c:1366 builtin/gc.c:178 msgid "date" msgstr "ngà y tháng" -#: builtin/commit.c:1364 +#: builtin/commit.c:1366 msgid "override date for commit" msgstr "ghi đè ngà y tháng cho commit" -#: builtin/commit.c:1365 builtin/merge.c:206 builtin/notes.c:533 +#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 #: builtin/notes.c:690 builtin/tag.c:455 msgid "message" msgstr "thông Ä‘iệp" -#: builtin/commit.c:1365 +#: builtin/commit.c:1367 msgid "commit message" msgstr "chú thÃch của lần commit" -#: builtin/commit.c:1366 +#: builtin/commit.c:1368 msgid "reuse and edit message from specified commit" msgstr "" "dùng lại các ghi chú từ lần chuyển giao (commit) đã cho nhÆ°ng có cho sá»a chữa" -#: builtin/commit.c:1367 +#: builtin/commit.c:1369 msgid "reuse message from specified commit" msgstr "dùng lại các ghi chú từ lần chuyển giao (commit) đã cho" -#: builtin/commit.c:1368 +#: builtin/commit.c:1370 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:1369 +#: builtin/commit.c:1371 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:1370 +#: builtin/commit.c:1372 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:1371 builtin/log.c:1102 builtin/revert.c:109 +#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "thêm dòng Signed-off-by:" -#: builtin/commit.c:1372 +#: builtin/commit.c:1374 msgid "use specified template file" msgstr "sá» dụng táºp tin mẫu đã cho" -#: builtin/commit.c:1373 +#: builtin/commit.c:1375 msgid "force edit of commit" msgstr "ép buá»™c sá»a lần commit" -#: builtin/commit.c:1374 +#: builtin/commit.c:1376 msgid "default" msgstr "mặc định" -#: builtin/commit.c:1374 builtin/tag.c:460 +#: builtin/commit.c:1376 builtin/tag.c:460 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:1375 +#: builtin/commit.c:1377 msgid "include status in commit message template" msgstr "bao gồm các trạng thái ghi mẫu ghi chú chuyển giao (commit)" -#: builtin/commit.c:1376 builtin/merge.c:213 builtin/tag.c:461 +#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 msgid "key id" msgstr "id khóa" -#: builtin/commit.c:1377 builtin/merge.c:214 +#: builtin/commit.c:1379 builtin/merge.c:216 msgid "GPG sign commit" msgstr "ký lần commit dùng GPG" #. end commit message options -#: builtin/commit.c:1380 +#: builtin/commit.c:1382 msgid "Commit contents options" msgstr "Các tùy ná»™i dung ghi chú commit" -#: builtin/commit.c:1381 +#: builtin/commit.c:1383 msgid "commit all changed files" msgstr "chuyển giao tất cả các táºp tin có thay đổi" -#: builtin/commit.c:1382 +#: builtin/commit.c:1384 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 (commit)" -#: builtin/commit.c:1383 +#: builtin/commit.c:1385 msgid "interactively add files" msgstr "thêm các táºp-tin bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1384 +#: builtin/commit.c:1386 msgid "interactively add changes" msgstr "thêm các thay đổi bằng tÆ°Æ¡ng tác" -#: builtin/commit.c:1385 +#: builtin/commit.c:1387 msgid "commit only specified files" msgstr "chỉ chuyển giao các táºp tin đã chỉ ra" -#: builtin/commit.c:1386 +#: builtin/commit.c:1388 msgid "bypass pre-commit hook" msgstr "vòng qua móc (hook) pre-commit" -#: builtin/commit.c:1387 +#: builtin/commit.c:1389 msgid "show what would be committed" msgstr "hiển thị xem cái gì có thể được chuyển giao" -#: builtin/commit.c:1398 +#: builtin/commit.c:1400 msgid "amend previous commit" msgstr "tu bổ (amend) lần commit trÆ°á»›c" -#: builtin/commit.c:1399 +#: builtin/commit.c:1401 msgid "bypass post-rewrite hook" msgstr "vòng qua móc (hook) post-rewrite" -#: builtin/commit.c:1404 +#: builtin/commit.c:1406 msgid "ok to record an empty change" msgstr "ok để ghi lại má»™t thay đổi trống rá»—ng" -#: builtin/commit.c:1407 +#: builtin/commit.c:1409 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:1439 +#: builtin/commit.c:1441 msgid "could not parse HEAD commit" msgstr "không thể phân tÃch commit (lần chuyển giao) HEAD" -#: builtin/commit.c:1477 builtin/merge.c:508 +#: builtin/commit.c:1479 builtin/merge.c:510 #, c-format msgid "could not open '%s' for reading" msgstr "không thể mở “%s†để Ä‘á»c" -#: builtin/commit.c:1484 +#: builtin/commit.c:1486 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "Táºp tin MERGE_HEAD sai há»ng (%s)" -#: builtin/commit.c:1491 +#: builtin/commit.c:1493 msgid "could not read MERGE_MODE" msgstr "không thể Ä‘á»c MERGE_MODE" -#: builtin/commit.c:1510 +#: builtin/commit.c:1512 #, c-format msgid "could not read commit message: %s" msgstr "không thể Ä‘á»c thông Ä‘iệp (message) commit (lần chuyển giao): %s" -#: builtin/commit.c:1524 +#: builtin/commit.c:1526 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "" "Äang bá» qua việc chuyển giao (commit); bạn đã không biên soạn thông Ä‘iệp " "(message).\n" -#: builtin/commit.c:1529 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "" "Äang bá» qua lần chuyển giao (commit) bởi vì thông Ä‘iệp của nó trống rá»—ng.\n" -#: builtin/commit.c:1544 builtin/merge.c:832 builtin/merge.c:857 +#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 msgid "failed to write commit object" msgstr "gặp lá»—i khi ghi đối tượng chuyển giao (commit)" -#: builtin/commit.c:1565 +#: builtin/commit.c:1567 msgid "cannot lock HEAD ref" msgstr "không thể khóa HEAD ref (tham chiếu)" -#: builtin/commit.c:1569 +#: builtin/commit.c:1571 msgid "cannot update HEAD ref" msgstr "không thể cáºp nháºt ref (tham chiếu) HEAD" -#: builtin/commit.c:1580 +#: builtin/commit.c:1582 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -4128,9 +4411,13 @@ msgstr "chấm dứt giá trị vá»›i byte NUL" msgid "respect include directives on lookup" msgstr "tôn trá»ng kể cà các hÆ°á»›ng trong tìm kiếm" -#: builtin/count-objects.c:69 -msgid "git count-objects [-v]" -msgstr "git count-objects [-v]" +#: builtin/count-objects.c:82 +msgid "git count-objects [-v] [-H | --human-readable]" +msgstr "git count-objects [-v] [-H | --human-readable]" + +#: builtin/count-objects.c:97 +msgid "print sizes in human readable format" +msgstr "hiển thị kÃch cỡ theo định dạng dà nh cho ngÆ°á»i Ä‘á»c" #: builtin/describe.c:15 msgid "git describe [options] <committish>*" @@ -4140,47 +4427,47 @@ msgstr "git describe [các-tùy-chá»n] <committish>*" msgid "git describe [options] --dirty" msgstr "git describe [các-tùy-chá»n] --dirty" -#: builtin/describe.c:234 +#: builtin/describe.c:233 #, c-format msgid "annotated tag %s not available" msgstr "thẻ đã được ghi chú %s không sẵn để dùng" -#: builtin/describe.c:238 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s has no embedded name" msgstr "thẻ được chú giải %s không có tên nhúng" -#: builtin/describe.c:240 +#: builtin/describe.c:239 #, c-format msgid "tag '%s' is really '%s' here" msgstr "thẻ “%s†đã thá»±c sá»± ở đây “%s†rồi" -#: builtin/describe.c:267 +#: builtin/describe.c:266 #, c-format msgid "Not a valid object name %s" msgstr "Không phải tên đối tượng %s hợp lệ" -#: builtin/describe.c:270 +#: builtin/describe.c:269 #, c-format msgid "%s is not a valid '%s' object" msgstr "%s không phải là má»™t đối tượng “%s†hợp lệ" -#: builtin/describe.c:287 +#: builtin/describe.c:286 #, c-format msgid "no tag exactly matches '%s'" msgstr "không có thẻ nà o khá»›p chÃnh xác vá»›i “%sâ€" -#: builtin/describe.c:289 +#: builtin/describe.c:288 #, c-format msgid "searching to describe %s\n" msgstr "Äang tìm kiếm để mô tả %s\n" -#: builtin/describe.c:329 +#: builtin/describe.c:328 #, c-format msgid "finished search at %s\n" msgstr "việc tìm kiếm đã kết thúc tại %s\n" -#: builtin/describe.c:353 +#: builtin/describe.c:352 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -4189,7 +4476,7 @@ msgstr "" "Không có thẻ được chú giải nà o được mô tả là “%sâ€.\n" "Tuy nhiên, ở đây có những thẻ không được chú giải: hãy thá» --tags." -#: builtin/describe.c:357 +#: builtin/describe.c:356 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -4198,12 +4485,12 @@ msgstr "" "Không có thẻ (tag) có thể mô tả “%sâ€.\n" "Hãy thá» --always, hoặt tạo má»™t số thẻ." -#: builtin/describe.c:378 +#: builtin/describe.c:377 #, c-format msgid "traversed %lu commits\n" msgstr "đã xuyên %lu qua lần chuyển giao (commit)\n" -#: builtin/describe.c:381 +#: builtin/describe.c:380 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -4212,59 +4499,59 @@ msgstr "" "tìm thấy nhiá»u hÆ¡n %i thẻ (tag); đã liệt kê %i gần đây nhất\n" "bá» Ä‘i tìm kiếm tại %s\n" -#: builtin/describe.c:403 +#: builtin/describe.c:402 msgid "find the tag that comes after the commit" msgstr "tìm các thẻ mà nó đến trÆ°á»›c lần chuyển giao" -#: builtin/describe.c:404 +#: builtin/describe.c:403 msgid "debug search strategy on stderr" msgstr "chiến lược tìm kiếm trên đầu ra lá»—i chuẩn stderr" +#: builtin/describe.c:404 +msgid "use any ref" +msgstr "dùng ref bất kỳ" + #: builtin/describe.c:405 -msgid "use any ref in .git/refs" -msgstr "sá» dụng bất kỳ ref nà o trong .git/refs" +msgid "use any tag, even unannotated" +msgstr "dùng thẻ bất kỳ, cả khi “unannotatedâ€" #: builtin/describe.c:406 -msgid "use any tag in .git/refs/tags" -msgstr "sá» dụng bất kỳ thẻ nà o trong .git/refs/tags" - -#: builtin/describe.c:407 msgid "always use long format" msgstr "luôn dùng định dạng dà i" -#: builtin/describe.c:410 +#: builtin/describe.c:409 msgid "only output exact matches" msgstr "chỉ xuất những gì khá»›p chÃnh xác" -#: builtin/describe.c:412 +#: builtin/describe.c:411 msgid "consider <n> most recent tags (default: 10)" msgstr "coi nhÆ° <n> thẻ gần đây nhất (mặc định: 10)" -#: builtin/describe.c:414 +#: builtin/describe.c:413 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:416 builtin/name-rev.c:238 +#: builtin/describe.c:415 builtin/name-rev.c:238 msgid "show abbreviated commit object as fallback" msgstr "hiển thị đối tượng chuyển giao vắn tắt nhÆ° là fallback" -#: builtin/describe.c:417 +#: builtin/describe.c:416 msgid "mark" msgstr "dấu" -#: builtin/describe.c:418 +#: builtin/describe.c:417 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "thêm <dấu> trên cây thÆ° mục là m việc bẩn (mặc định \"-dirty\")" -#: builtin/describe.c:436 +#: builtin/describe.c:435 msgid "--long is incompatible with --abbrev=0" msgstr "--long là xung khắc vá»›i tùy chá»n --abbrev=0" -#: builtin/describe.c:462 +#: builtin/describe.c:461 msgid "No names found, cannot describe anything." msgstr "Không tìm thấy các tên, không thể mô tả gì cả." -#: builtin/describe.c:482 +#: builtin/describe.c:481 msgid "--dirty is incompatible with committishes" msgstr "--dirty là xung khắc vá»›i các tùy chá»n dà nh cho chuyển giao (commit)" @@ -4306,39 +4593,39 @@ msgstr "đã cho đối tượng không thể nắm giữ “%sâ€." msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-opts]" -#: builtin/fast-export.c:646 +#: builtin/fast-export.c:658 msgid "show progress after <n> objects" msgstr "hiển thị tiến triển sau <n> đối tượng" -#: builtin/fast-export.c:648 +#: builtin/fast-export.c:660 msgid "select handling of signed tags" msgstr "chá»n Ä‘iá»u khiển của thẻ đã ký" -#: builtin/fast-export.c:651 +#: builtin/fast-export.c:663 msgid "select handling of tags that tag filtered objects" msgstr "chá»n sá»± xá» lý của các thẻ, cái mà đánh thẻ các đối tượng được lá»c ra" -#: builtin/fast-export.c:654 +#: builtin/fast-export.c:666 msgid "Dump marks to this file" msgstr "Äổ các đánh dấu nà y và o táºp-tin" -#: builtin/fast-export.c:656 +#: builtin/fast-export.c:668 msgid "Import marks from this file" msgstr "nháºp và o đánh dấu từ táºp tin nà y" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:670 msgid "Fake a tagger when tags lack one" msgstr "Là m giả má»™t cái thẻ khi thẻ bị thiếu má»™t cái" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:672 msgid "Output full tree for each commit" msgstr "Xuất ra toà n bá»™ cây cho má»—i lần chuyển giao" -#: builtin/fast-export.c:662 +#: builtin/fast-export.c:674 msgid "Use the done feature to terminate the stream" msgstr "Sá» dụng tÃnh năng done để chấm dứt luồng dữ liệu" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:675 msgid "Skip output of blob data" msgstr "Bá» qua kết xuất của dữ liệu blob" @@ -4416,7 +4703,7 @@ msgstr "là m sâu hÆ¡n lịch sá» của bản sao" msgid "convert to a complete repository" msgstr "chuyển đổi hoà n toà n sang kho git" -#: builtin/fetch.c:88 builtin/log.c:1119 +#: builtin/fetch.c:88 builtin/log.c:1130 msgid "dir" msgstr "tmục" @@ -4598,29 +4885,29 @@ msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" "git fmt-merge-msg [-m <thông Ä‘iệp>] [--log[=<n>]|--no-log] [--file <táºp-tin>]" -#: builtin/fmt-merge-msg.c:659 builtin/fmt-merge-msg.c:662 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 #: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 msgid "n" msgstr "n" -#: builtin/fmt-merge-msg.c:660 +#: builtin/fmt-merge-msg.c:664 msgid "populate log with at most <n> entries from shortlog" msgstr "gắn nháºt ký vá»›i Ãt nhất <n> mục từ lệnh “shortlogâ€" -#: builtin/fmt-merge-msg.c:663 +#: builtin/fmt-merge-msg.c:667 msgid "alias for --log (deprecated)" msgstr "bà danh cho --log (không được dùng)" -#: builtin/fmt-merge-msg.c:666 +#: builtin/fmt-merge-msg.c:670 msgid "text" msgstr "văn bản" -#: builtin/fmt-merge-msg.c:667 +#: builtin/fmt-merge-msg.c:671 msgid "use <text> as start of message" msgstr "dùng <văn bản thÆ°á»ng> để bắt đầu ghi chú" -#: builtin/fmt-merge-msg.c:668 +#: builtin/fmt-merge-msg.c:672 msgid "file to read from" msgstr "táºp tin để Ä‘á»c dữ liệu từ đó" @@ -4958,30 +5245,25 @@ msgstr "hiển thị cách dùng" msgid "no pattern given." msgstr "chÆ°a chỉ ra mẫu." -#: builtin/grep.c:825 -#, c-format -msgid "bad object %s" -msgstr "đối tượng sai %s" - -#: builtin/grep.c:868 +#: builtin/grep.c:866 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:891 +#: builtin/grep.c:889 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:896 +#: builtin/grep.c:894 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:899 +#: builtin/grep.c:897 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:907 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "cả hai --cached và các cây phải được chỉ ra." @@ -5021,50 +5303,54 @@ msgstr "lÆ°u các táºp tin mà nó không có các bá»™ lá»c" msgid "process file as it were from this path" msgstr "xá» lý táºp tin nhÆ° là nó Ä‘ang ở thÆ° mục nà y" -#: builtin/help.c:42 +#: builtin/help.c:43 msgid "print all available commands" msgstr "hiển thị danh sách các câu lệnh ngÆ°á»i dùng có thể sá» dụng" -#: builtin/help.c:43 +#: builtin/help.c:44 +msgid "print list of useful guides" +msgstr "hiển thị danh sách các hÆ°á»›ng dẫn hữu dụng" + +#: builtin/help.c:45 msgid "show man page" msgstr "hiển thị trang man" -#: builtin/help.c:44 +#: builtin/help.c:46 msgid "show manual in web browser" msgstr "hiển thị hÆ°á»›ng dẫn sá» dụng trong trình duyệt web" -#: builtin/help.c:46 +#: builtin/help.c:48 msgid "show info page" msgstr "hiện trang info" -#: builtin/help.c:52 -msgid "git help [--all] [--man|--web|--info] [command]" -msgstr "git help [--all] [--man|--web|--info] [lệnh]" +#: builtin/help.c:54 +msgid "git help [--all] [--guides] [--man|--web|--info] [command]" +msgstr "git help [--all] [--guides] [--man|--web|--info] [lệnh]" -#: builtin/help.c:64 +#: builtin/help.c:66 #, c-format msgid "unrecognized help format '%s'" msgstr "không nháºn ra định dạng trợ giúp “%sâ€" -#: builtin/help.c:92 +#: builtin/help.c:94 msgid "Failed to start emacsclient." msgstr "Lá»—i khởi chạy emacsclient." -#: builtin/help.c:105 +#: builtin/help.c:107 msgid "Failed to parse emacsclient version." msgstr "Gặp lá»—i khi phân tÃch phiên bản emacsclient." -#: builtin/help.c:113 +#: builtin/help.c:115 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "phiên bản của emacsclient “%d†quá cÅ© (< 22)." -#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 +#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 #, c-format msgid "failed to exec '%s': %s" msgstr "gặp lá»—i khi thá»±c thi “%sâ€: %s" -#: builtin/help.c:216 +#: builtin/help.c:218 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -5073,7 +5359,7 @@ msgstr "" "“%sâ€: Ä‘Æ°á»ng dẫn không há»— trợ bá»™ trình chiếu man.\n" "Hãy cân nhắc đến việc sá» dụng “man.<tool>.cmd†để thay thế." -#: builtin/help.c:228 +#: builtin/help.c:230 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -5082,303 +5368,335 @@ msgstr "" "“%sâ€: cmd (lệnh) há»— trợ bá»™ trình chiếu man.\n" "Hãy cân nhắc đến việc sá» dụng “man.<tool>.path†để thay thế." -#: builtin/help.c:349 +#: builtin/help.c:351 #, c-format msgid "'%s': unknown man viewer." msgstr "“%sâ€: không rõ chÆ°Æ¡ng trình xem man." -#: builtin/help.c:366 +#: builtin/help.c:368 msgid "no man viewer handled the request" msgstr "không có trình xem trợ giúp dạng manpage tiếp hợp vá»›i yêu cầu" -#: builtin/help.c:374 +#: builtin/help.c:376 msgid "no info viewer handled the request" msgstr "không có trình xem trợ giúp dạng info tiếp hợp vá»›i yêu cầu" -#: builtin/help.c:429 builtin/help.c:436 +#: builtin/help.c:422 +msgid "Defining attributes per path" +msgstr "Äịnh nghÄ©a các thuá»™c tÃnh cho má»—i Ä‘Æ°á»ng dẫn" + +#: builtin/help.c:423 +msgid "A Git glossary" +msgstr "Thuáºt ngữ chuyên môn Git" + +#: builtin/help.c:424 +msgid "Specifies intentionally untracked files to ignore" +msgstr "Chỉ định các táºp tin chÆ°a theo dõi dấu vết bị bá» qua má»™t cách cố ý" + +#: builtin/help.c:425 +msgid "Defining submodule properties" +msgstr "Äịnh nghÄ©a thuá»™c tÃnh mô-Ä‘un-con" + +#: builtin/help.c:426 +msgid "Specifying revisions and ranges for Git" +msgstr "Chỉ định Ä‘iểm xét duyệt và vùng cho Git" + +#: builtin/help.c:427 +msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" +msgstr "HÆ°á»›ng dẫn cách dùng Git ở mức cÆ¡ bản (dà nh cho bản 1.5.1 hay má»›i hÆ¡n)" + +#: builtin/help.c:428 +msgid "An overview of recommended workflows with Git" +msgstr "Tổng quan vá» luồng công việc khuyến nghị nên dùng vá»›i Git." + +#: builtin/help.c:440 +msgid "The common Git guides are:\n" +msgstr "Các chỉ dẫn chung vá» cách dùng Git là :\n" + +#: builtin/help.c:462 builtin/help.c:478 #, c-format msgid "usage: %s%s" msgstr "cách sá» dụng: %s%s" -#: builtin/help.c:452 +#: builtin/help.c:494 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "“git %s†được đặt bà danh thà nh “%sâ€" -#: builtin/index-pack.c:170 +#: builtin/index-pack.c:182 #, c-format msgid "object type mismatch at %s" msgstr "kiểu đối tượng không khá»›p tại %s" -#: builtin/index-pack.c:190 +#: builtin/index-pack.c:202 msgid "object of unexpected type" msgstr "đối tượng của kiểu không mong đợi" -#: builtin/index-pack.c:227 +#: builtin/index-pack.c:239 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "không thể Ä‘iá»n và o %d byte" msgstr[1] "không thể Ä‘iá»n và o %d byte" -#: builtin/index-pack.c:237 +#: builtin/index-pack.c:249 msgid "early EOF" msgstr "vừa đúng lúc EOF" -#: builtin/index-pack.c:238 +#: builtin/index-pack.c:250 msgid "read error on input" msgstr "lá»—i Ä‘á»c ở đầu và o" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:262 msgid "used more bytes than were available" msgstr "sá» dụng nhiá»u hÆ¡n số lượng byte mà nó sẵn có" -#: builtin/index-pack.c:257 +#: builtin/index-pack.c:269 msgid "pack too large for current definition of off_t" msgstr "pack quá lá»›n so vá»›i định nghÄ©a hiện tại của kiểu off_t" -#: builtin/index-pack.c:273 +#: builtin/index-pack.c:285 #, c-format msgid "unable to create '%s'" msgstr "không thể tạo “%sâ€" -#: builtin/index-pack.c:278 +#: builtin/index-pack.c:290 #, c-format msgid "cannot open packfile '%s'" msgstr "không thể mở packfile “%sâ€" -#: builtin/index-pack.c:292 +#: builtin/index-pack.c:304 msgid "pack signature mismatch" msgstr "chữ ký cho pack không khá»›p" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:306 #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "không há»— trợ phiên bản pack %<PRIu32>" -#: builtin/index-pack.c:312 +#: builtin/index-pack.c:324 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "pack có đối tượng sai khoảng bù (offset) %lu: %s" -#: builtin/index-pack.c:434 +#: builtin/index-pack.c:446 #, c-format msgid "inflate returned %d" msgstr "xả nén trả vá» %d" -#: builtin/index-pack.c:483 +#: builtin/index-pack.c:495 msgid "offset value overflow for delta base object" msgstr "trà n giá trị khoảng bù cho đối tượng delta cÆ¡ sở" -#: builtin/index-pack.c:491 +#: builtin/index-pack.c:503 msgid "delta base offset is out of bound" msgstr "khoảng bù cÆ¡ sở cho delta nằm ngoà i phạm vi" -#: builtin/index-pack.c:499 +#: builtin/index-pack.c:511 #, c-format msgid "unknown object type %d" msgstr "không hiểu kiểu đối tượng %d" -#: builtin/index-pack.c:530 +#: builtin/index-pack.c:542 msgid "cannot pread pack file" msgstr "không thể chạy hà m pread cho táºp tin pack" -#: builtin/index-pack.c:532 +#: builtin/index-pack.c:544 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "táºp tin pack bị kết thúc sá»›m, %lu byte bị thiếu" msgstr[1] "táºp tin pack bị kết thúc sá»›m, %lu byte bị thiếu" -#: builtin/index-pack.c:558 +#: builtin/index-pack.c:570 msgid "serious inflate inconsistency" msgstr "sá»± mâu thuẫn xả nén nghiêm trá»ng" -#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678 -#: builtin/index-pack.c:712 builtin/index-pack.c:721 +#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 +#: builtin/index-pack.c:724 builtin/index-pack.c:733 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "Sá»° VA CHẠM SHA1 Äà XẢY RA VỚI %s!" -#: builtin/index-pack.c:652 builtin/pack-objects.c:170 +#: builtin/index-pack.c:664 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "không thể Ä‘á»c %s" -#: builtin/index-pack.c:718 +#: builtin/index-pack.c:730 #, c-format msgid "cannot read existing object %s" msgstr "không thể Ä‘á»c đối tượng đã tồn tại %s" -#: builtin/index-pack.c:732 +#: builtin/index-pack.c:744 #, c-format msgid "invalid blob object %s" msgstr "đối tượng blob không hợp lệ %s" -#: builtin/index-pack.c:747 +#: builtin/index-pack.c:759 #, c-format msgid "invalid %s" msgstr "%s không hợp lệ" -#: builtin/index-pack.c:749 +#: builtin/index-pack.c:761 msgid "Error in object" msgstr "Lá»—i trong đối tượng" -#: builtin/index-pack.c:751 +#: builtin/index-pack.c:763 #, c-format msgid "Not all child objects of %s are reachable" msgstr "Không phải tất cả các đối tượng con của %s là có thể vá»›i tá»›i được" -#: builtin/index-pack.c:821 builtin/index-pack.c:847 +#: builtin/index-pack.c:833 builtin/index-pack.c:863 msgid "failed to apply delta" msgstr "gặp lá»—i khi áp dụng delta" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Receiving objects" msgstr "Äang nháºn vá» các đối tượng" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Indexing objects" msgstr "Các đối tượng bảng mục lục" -#: builtin/index-pack.c:1012 +#: builtin/index-pack.c:1030 msgid "pack is corrupted (SHA1 mismatch)" msgstr "pack bị sai há»ng (SHA1 không khá»›p)" -#: builtin/index-pack.c:1017 +#: builtin/index-pack.c:1035 msgid "cannot fstat packfile" msgstr "không thể fstat packfile" -#: builtin/index-pack.c:1020 +#: builtin/index-pack.c:1038 msgid "pack has junk at the end" msgstr "pack có phần thừa ở cuối" -#: builtin/index-pack.c:1031 +#: builtin/index-pack.c:1049 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "lá»™n xá»™n hÆ¡n cả Ä‘iên rồ khi chạy hà m parse_pack_objects()" -#: builtin/index-pack.c:1054 +#: builtin/index-pack.c:1072 msgid "Resolving deltas" msgstr "Äang phân giải các delta" -#: builtin/index-pack.c:1064 +#: builtin/index-pack.c:1082 #, c-format msgid "unable to create thread: %s" msgstr "không thể tạo tuyến: %s" -#: builtin/index-pack.c:1106 +#: builtin/index-pack.c:1124 msgid "confusion beyond insanity" msgstr "lá»™n xá»™n hÆ¡n cả Ä‘iên rồ" -#: builtin/index-pack.c:1112 +#: builtin/index-pack.c:1132 #, c-format msgid "completed with %d local objects" msgstr "đầy đủ vá»›i %d đối tượng ná»™i bá»™" -#: builtin/index-pack.c:1121 +#: builtin/index-pack.c:1142 #, 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?)" -#: builtin/index-pack.c:1125 +#: builtin/index-pack.c:1146 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "pack có %d delta chÆ°a được giải quyết" msgstr[1] "pack có %d delta chÆ°a được giải quyết" -#: builtin/index-pack.c:1150 +#: builtin/index-pack.c:1171 #, c-format msgid "unable to deflate appended object (%d)" msgstr "không thể xả đối tượng nối thêm (%d)" -#: builtin/index-pack.c:1229 +#: builtin/index-pack.c:1250 #, c-format msgid "local object %s is corrupt" msgstr "đối tượng ná»™i bá»™ %s bị há»ng" -#: builtin/index-pack.c:1253 +#: builtin/index-pack.c:1274 msgid "error while closing pack file" msgstr "gặp lá»—i trong khi đóng táºp tin pack" -#: builtin/index-pack.c:1266 +#: builtin/index-pack.c:1287 #, c-format msgid "cannot write keep file '%s'" msgstr "không thể ghi táºp tin giữ lại “%sâ€" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1295 #, 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:1287 +#: builtin/index-pack.c:1308 msgid "cannot store pack file" msgstr "không thể lÆ°u táºp tin pack" -#: builtin/index-pack.c:1298 +#: builtin/index-pack.c:1319 msgid "cannot store index file" msgstr "không thể lÆ°u trữ táºp tin ghi mục lục" -#: builtin/index-pack.c:1331 +#: builtin/index-pack.c:1352 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "sai pack.indexversion=%<PRIu32>" -#: builtin/index-pack.c:1337 +#: builtin/index-pack.c:1358 #, c-format msgid "invalid number of threads specified (%d)" msgstr "số tuyến chỉ ra không hợp lệ (%d)" -#: builtin/index-pack.c:1341 builtin/index-pack.c:1514 +#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 #, c-format msgid "no threads support, ignoring %s" msgstr "không há»— trợ Ä‘a tuyến, bá» qua %s" -#: builtin/index-pack.c:1399 +#: builtin/index-pack.c:1420 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "Không thể mở táºp tin pack đã sẵn có “%sâ€" -#: builtin/index-pack.c:1401 +#: builtin/index-pack.c:1422 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "Không thể mở táºp tin “pack idx†cho “%sâ€" -#: builtin/index-pack.c:1448 +#: builtin/index-pack.c:1469 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "không delta: %d đối tượng" msgstr[1] "không delta: %d đối tượng" -#: builtin/index-pack.c:1455 +#: builtin/index-pack.c:1476 #, 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" msgstr[1] "chiá»u dà i xÃch = %d: %lu đối tượng" -#: builtin/index-pack.c:1482 +#: builtin/index-pack.c:1503 msgid "Cannot come back to cwd" msgstr "Không thể quay lại cwd" -#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 -#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 +#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 +#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 #, c-format msgid "bad %s" msgstr "%s sai" -#: builtin/index-pack.c:1559 +#: builtin/index-pack.c:1580 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:1563 builtin/index-pack.c:1573 +#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "tên táºp tin packfile “%s†không được kết thúc bằng Ä‘uôi “.packâ€" -#: builtin/index-pack.c:1582 +#: builtin/index-pack.c:1603 msgid "--verify with no packfile name given" msgstr "dùng tùy chá»n --verify mà không Ä‘Æ°a ra tên packfile" @@ -5546,246 +5864,241 @@ msgstr "Không thể truy cáºp thÆ° mục là m việc hiện hà nh" msgid "Cannot access work tree '%s'" msgstr "không thể truy cáºp cây (tree) là m việc “%sâ€" -#: builtin/log.c:39 -msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" -msgstr "git log [<các-tùy-chá»n>] [<kể-từ>..<cho-đến>] [[--] <Ä‘Æ°á»ng-dẫn>...]\n" - #: builtin/log.c:40 +msgid "git log [<options>] [<revision range>] [[--] <path>...]\n" +msgstr "git log [<các-tùy-chá»n>] [<vùng xem xét>] [[--] <Ä‘Æ°á»ng-dẫn>...]\n" + +#: builtin/log.c:41 msgid " or: git show [options] <object>..." -msgstr " or: git show [các-tùy-chá»n] <đối-tượng>..." +msgstr " hay: git show [các-tùy-chá»n] <đối-tượng>..." -#: builtin/log.c:102 +#: builtin/log.c:103 msgid "suppress diff output" msgstr "chặn má»i kết xuất từ diff" -#: builtin/log.c:103 +#: builtin/log.c:104 msgid "show source" msgstr "hiển thị mã nguồn" -#: builtin/log.c:104 +#: builtin/log.c:105 msgid "Use mail map file" msgstr "Sá» dụng táºp tin ánh xạ thÆ°" -#: builtin/log.c:105 +#: builtin/log.c:106 msgid "decorate options" msgstr "các tùy chá»n trang trÃ" -#: builtin/log.c:198 +#: builtin/log.c:199 #, c-format msgid "Final output: %d %s\n" msgstr "Kết xuất cuối cùng: %d %s\n" -#: builtin/log.c:419 builtin/log.c:511 +#: builtin/log.c:422 builtin/log.c:514 #, c-format msgid "Could not read object %s" msgstr "Không thể Ä‘á»c đối tượng %s" -#: builtin/log.c:535 +#: builtin/log.c:538 #, c-format msgid "Unknown type: %d" msgstr "Không nháºn ra kiểu: %d" -#: builtin/log.c:627 +#: builtin/log.c:638 msgid "format.headers without value" msgstr "format.headers không có giá trị cụ thể" -#: builtin/log.c:701 +#: builtin/log.c:720 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:717 +#: builtin/log.c:736 #, c-format msgid "Cannot open patch file %s" msgstr "Không thể mở táºp tin miếng vá: %s" -#: builtin/log.c:731 +#: builtin/log.c:750 msgid "Need exactly one range." msgstr "Cần chÃnh xác má»™t vùng." -#: builtin/log.c:739 +#: builtin/log.c:758 msgid "Not a range." msgstr "Không phải là má»™t vùng." -#: builtin/log.c:812 +#: builtin/log.c:860 msgid "Cover letter needs email format" msgstr "â€Cover letter†cần cho định dạng thÆ°" -#: builtin/log.c:885 +#: builtin/log.c:936 #, c-format msgid "insane in-reply-to: %s" msgstr "in-reply-to Ä‘iên rồ: %s" -#: builtin/log.c:913 +#: builtin/log.c:964 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:958 +#: builtin/log.c:1009 msgid "Two output directories?" msgstr "Hai thÆ° mục kết xuất?" -#: builtin/log.c:1097 +#: builtin/log.c:1108 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:1100 +#: builtin/log.c:1111 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:1104 +#: builtin/log.c:1115 msgid "print patches to standard out" msgstr "hiển thị miếng vá ra đầu ra chuẩn" -#: builtin/log.c:1106 +#: builtin/log.c:1117 msgid "generate a cover letter" msgstr "tạo bì thÆ°" -#: builtin/log.c:1108 +#: builtin/log.c:1119 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:1109 +#: builtin/log.c:1120 msgid "sfx" msgstr "sfx" -#: builtin/log.c:1110 +#: builtin/log.c:1121 msgid "use <sfx> instead of '.patch'" msgstr "sá» dụng <sfx> thay cho “.patchâ€" -#: builtin/log.c:1112 +#: builtin/log.c:1123 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:1114 +#: builtin/log.c:1125 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:1116 +#: builtin/log.c:1127 msgid "Use [<prefix>] instead of [PATCH]" msgstr "Dùng [<tiá»n-tố>] thay cho [VÃ]" -#: builtin/log.c:1119 +#: builtin/log.c:1130 msgid "store resulting files in <dir>" msgstr "lÆ°u các táºp tin kết quả trong <t.mục>" -#: builtin/log.c:1122 +#: builtin/log.c:1133 msgid "don't strip/add [PATCH]" msgstr "không strip/add [VÃ]" -#: builtin/log.c:1125 +#: builtin/log.c:1136 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:1127 +#: builtin/log.c:1138 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:1129 +#: builtin/log.c:1140 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:1131 +#: builtin/log.c:1142 msgid "Messaging" msgstr "Lá»i nhắn" -#: builtin/log.c:1132 +#: builtin/log.c:1143 msgid "header" msgstr "đầu Ä‘á» thÆ°" -#: builtin/log.c:1133 +#: builtin/log.c:1144 msgid "add email header" msgstr "thêm đầu Ä‘á» thÆ°" -#: builtin/log.c:1134 builtin/log.c:1136 +#: builtin/log.c:1145 builtin/log.c:1147 msgid "email" msgstr "thÆ° Ä‘iện tá»" -#: builtin/log.c:1134 +#: builtin/log.c:1145 msgid "add To: header" msgstr "thêm To: đầu Ä‘á» thÆ°" -#: builtin/log.c:1136 +#: builtin/log.c:1147 msgid "add Cc: header" msgstr "thêm Cc: đầu Ä‘á» thÆ°" -#: builtin/log.c:1138 +#: builtin/log.c:1149 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1139 +#: builtin/log.c:1150 msgid "make first mail a reply to <message-id>" msgstr "dùng thÆ° đầu tiên để trả lá»i <message-id>" -#: builtin/log.c:1140 builtin/log.c:1143 +#: builtin/log.c:1151 builtin/log.c:1154 msgid "boundary" msgstr "ranh giá»›i" -#: builtin/log.c:1141 +#: builtin/log.c:1152 msgid "attach the patch" msgstr "Ä‘Ãnh kèm miếng vá" -#: builtin/log.c:1144 +#: builtin/log.c:1155 msgid "inline the patch" msgstr "dùng miếng vá là m ná»™i dung" -#: builtin/log.c:1148 +#: builtin/log.c:1159 msgid "enable message threading, styles: shallow, deep" msgstr "cho phép luồng lá»i nhắn, kiểu: “shallowâ€, “deepâ€" -#: builtin/log.c:1150 +#: builtin/log.c:1161 msgid "signature" msgstr "chữ ký" -#: builtin/log.c:1151 +#: builtin/log.c:1162 msgid "add a signature" msgstr "thêm chữ ký" -#: builtin/log.c:1153 +#: builtin/log.c:1164 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:1202 -#, c-format -msgid "bogus committer info %s" -msgstr "thông tin ngÆ°á»i chuyển giao không có thá»±c %s" - -#: builtin/log.c:1247 +#: builtin/log.c:1248 msgid "-n and -k are mutually exclusive." msgstr "-n và -k loại từ lẫn nhau." -#: builtin/log.c:1249 +#: builtin/log.c:1250 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix và -k xung khắc nhau." -#: builtin/log.c:1257 +#: builtin/log.c:1258 msgid "--name-only does not make sense" msgstr "--name-only không hợp lý" -#: builtin/log.c:1259 +#: builtin/log.c:1260 msgid "--name-status does not make sense" msgstr "--name-status không hợp lý" -#: builtin/log.c:1261 +#: builtin/log.c:1262 msgid "--check does not make sense" msgstr "--check không hợp lý" -#: builtin/log.c:1284 +#: builtin/log.c:1285 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:1286 +#: builtin/log.c:1287 #, c-format msgid "Could not create directory '%s'" msgstr "Không thể tạo thÆ° mục “%sâ€" -#: builtin/log.c:1439 +#: builtin/log.c:1435 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:1488 +#: builtin/log.c:1484 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<thượng-nguồn> [<head> [<giá»›i-hạn>]]]" -#: builtin/log.c:1543 +#: builtin/log.c:1539 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" @@ -5793,103 +6106,103 @@ msgstr "" "Không tìm thấy nhánh mạng bị theo vết, hãy chỉ định <thượng-nguồn> má»™t cách " "thủ công.\n" -#: builtin/log.c:1556 builtin/log.c:1558 builtin/log.c:1570 +#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 #, c-format msgid "Unknown commit %s" msgstr "Không hiểu lần chuyển giao (commit) %s" -#: builtin/ls-files.c:409 +#: builtin/ls-files.c:402 msgid "git ls-files [options] [<file>...]" msgstr "git ls-files [các-tùy-chá»n] [<táºp-tin>...]" -#: builtin/ls-files.c:466 +#: builtin/ls-files.c:459 msgid "identify the file status with tags" msgstr "nháºn dạng các trạng thái táºp tin vá»›i thẻ" -#: builtin/ls-files.c:468 +#: builtin/ls-files.c:461 msgid "use lowercase letters for 'assume unchanged' files" msgstr "" "dùng chữ cái viết thÆ°á»ng cho các táºp tin “assume unchanged†(giả định không " "thay đổi)" -#: builtin/ls-files.c:470 +#: builtin/ls-files.c:463 msgid "show cached files in the output (default)" msgstr "hiển thị các táºp tin được nhá»› tạm và o đầu ra (mặc định)" -#: builtin/ls-files.c:472 +#: builtin/ls-files.c:465 msgid "show deleted files in the output" msgstr "hiển thị các táºp tin đã xóa trong kết xuất" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:467 msgid "show modified files in the output" msgstr "hiển thị các táºp tin đã bị sá»a đổi ra kết xuất" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:469 msgid "show other files in the output" msgstr "hiển thị các táºp tin khác trong kết xuất" -#: builtin/ls-files.c:478 +#: builtin/ls-files.c:471 msgid "show ignored files in the output" msgstr "hiển thị các táºp tin bị bá» qua trong kết xuất" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:474 msgid "show staged contents' object name in the output" msgstr "hiển thị tên đối tượng của ná»™i dung được lÆ°u trạng thái ở kết xuất" -#: builtin/ls-files.c:483 +#: builtin/ls-files.c:476 msgid "show files on the filesystem that need to be removed" msgstr "hiển thị các táºp tin trên hệ thống táºp tin mà nó cần được gỡ bá»" -#: builtin/ls-files.c:485 +#: builtin/ls-files.c:478 msgid "show 'other' directories' name only" msgstr "chỉ hiển thị tên của các thÆ° mục “khácâ€" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:481 msgid "don't show empty directories" msgstr "không hiển thị thÆ° mục rá»—ng" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:484 msgid "show unmerged files in the output" msgstr "hiển thị các táºp tin chÆ°a hòa trá»™n trong kết xuất" -#: builtin/ls-files.c:493 +#: builtin/ls-files.c:486 msgid "show resolve-undo information" msgstr "hiển thị thông tin resolve-undo" -#: builtin/ls-files.c:495 +#: builtin/ls-files.c:488 msgid "skip files matching pattern" msgstr "bá» qua những táºp tin khá»›p vá»›i má»™t mẫu" -#: builtin/ls-files.c:498 +#: builtin/ls-files.c:491 msgid "exclude patterns are read from <file>" msgstr "mẫu loại trừ được Ä‘á»c từ <táºp tin>" -#: builtin/ls-files.c:501 +#: builtin/ls-files.c:494 msgid "read additional per-directory exclude patterns in <file>" msgstr "Ä‘á»c thêm các mẫu ngoại trừ má»—i thÆ° mục trong <táºp tin>" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:496 msgid "add the standard git exclusions" msgstr "thêm loại trừ tiêu chuẩn kiểu git" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:499 msgid "make the output relative to the project top directory" msgstr "là m cho kết xuất liên quan đến thÆ° mục ở mức cao nhất (gốc) của dá»± án" -#: builtin/ls-files.c:509 +#: builtin/ls-files.c:502 msgid "if any <file> is not in the index, treat this as an error" msgstr "nếu <táºp tin> bất kỳ không ở trong bảng mục lục, xá» lý nó nhÆ° má»™t lá»—i" -#: builtin/ls-files.c:510 +#: builtin/ls-files.c:503 msgid "tree-ish" msgstr "tree-ish" -#: builtin/ls-files.c:511 +#: builtin/ls-files.c:504 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "" "giả định rằng các Ä‘Æ°á»ng dẫn đã bị gỡ bá» kể từ <tree-ish> nay vẫn hiện diện" -#: builtin/ls-files.c:513 +#: builtin/ls-files.c:506 msgid "show debugging data" msgstr "hiển thị dữ liệu gỡ lá»—i" @@ -5996,111 +6309,115 @@ msgstr "cho phép fast-forward (mặc định)" msgid "abort if fast-forward is not possible" msgstr "bá» qua nếu fast-forward không thể được" -#: builtin/merge.c:202 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:203 +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:204 builtin/notes.c:866 builtin/revert.c:112 msgid "strategy" msgstr "chiến lược" -#: builtin/merge.c:203 +#: builtin/merge.c:205 msgid "merge strategy to use" msgstr "chiến lược hòa trá»™n sẽ dùng" -#: builtin/merge.c:204 +#: builtin/merge.c:206 msgid "option=value" msgstr "tùy_chá»n=giá_trị" -#: builtin/merge.c:205 +#: builtin/merge.c:207 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:207 +#: builtin/merge.c:209 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 non-fast-forward)" -#: builtin/merge.c:211 +#: builtin/merge.c:213 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:240 +#: builtin/merge.c:242 msgid "could not run stash." msgstr "không thể chạy stash." -#: builtin/merge.c:245 +#: builtin/merge.c:247 msgid "stash failed" msgstr "stash gặp lá»—i" -#: builtin/merge.c:250 +#: builtin/merge.c:252 #, 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:269 builtin/merge.c:286 +#: builtin/merge.c:271 builtin/merge.c:288 msgid "read-tree failed" msgstr "read-tree gặp lá»—i" -#: builtin/merge.c:316 +#: builtin/merge.c:318 msgid " (nothing to squash)" msgstr " (không có gì để squash)" -#: builtin/merge.c:329 +#: builtin/merge.c:331 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "Squash commit -- không cáºp nháºt HEAD\n" -#: builtin/merge.c:361 +#: builtin/merge.c:363 msgid "Writing SQUASH_MSG" msgstr "Äang ghi SQUASH_MSG" -#: builtin/merge.c:363 +#: builtin/merge.c:365 msgid "Finishing SQUASH_MSG" msgstr "Hoà n thà nh SQUASH_MSG" -#: builtin/merge.c:386 +#: builtin/merge.c:388 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "Không thông Ä‘iệp hòa trá»™n -- không cáºp nháºt HEAD\n" -#: builtin/merge.c:436 +#: builtin/merge.c:438 #, c-format msgid "'%s' does not point to a commit" msgstr "“%s†không chỉ đến má»™t lần chuyển giao (commit) nà o cả" -#: builtin/merge.c:535 +#: builtin/merge.c:550 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "Chuá»—i branch.%s.mergeoptions sai: %s" -#: builtin/merge.c:628 +#: builtin/merge.c:643 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/merge.c:656 +#: builtin/merge.c:671 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:670 +#: builtin/merge.c:685 #, 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:699 #, c-format msgid "unable to write %s" msgstr "không thể ghi %s" -#: builtin/merge.c:773 +#: builtin/merge.c:788 #, c-format msgid "Could not read from '%s'" msgstr "Không thể Ä‘á»c từ “%sâ€" -#: builtin/merge.c:782 +#: builtin/merge.c:797 #, 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 (commit); 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:803 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6118,55 +6435,55 @@ msgstr "" "rá»—ng\n" "sẽ hủy bá» lần chuyển giao (commit).\n" -#: builtin/merge.c:812 +#: builtin/merge.c:827 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:839 #, c-format msgid "Wonderful.\n" msgstr "Thần kỳ.\n" -#: builtin/merge.c:889 +#: builtin/merge.c:904 #, 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 " "(commit) kết quả.\n" -#: builtin/merge.c:905 +#: builtin/merge.c:920 #, 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:946 +#: builtin/merge.c:961 msgid "No current branch." msgstr "không phải nhánh hiện hà nh" -#: builtin/merge.c:948 +#: builtin/merge.c:963 msgid "No remote for the current branch." msgstr "Không có máy chủ cho nhánh hiện hà nh." -#: builtin/merge.c:950 +#: builtin/merge.c:965 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:955 +#: builtin/merge.c:970 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "Không nhánh mạng theo vết cho %s từ %s" -#: builtin/merge.c:1042 builtin/merge.c:1199 +#: builtin/merge.c:1057 builtin/merge.c:1214 #, 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:1110 +#: builtin/merge.c:1125 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:1126 git-pull.sh:31 +#: builtin/merge.c:1141 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6174,11 +6491,11 @@ msgstr "" "Bạn chÆ°a kết thúc việc hòa trá»™ng (MERGE_HEAD vẫn tồn tại).\n" "Hãy chuyển giao (commit) các thay đổi trÆ°á»›c khi bạn có thể hòa trá»™n." -#: builtin/merge.c:1129 git-pull.sh:34 +#: builtin/merge.c:1144 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "Bạn chÆ°a kết thúc việc hòa trá»™ng (MERGE_HEAD vẫn tồn tại)." -#: builtin/merge.c:1133 +#: builtin/merge.c:1148 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6186,85 +6503,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 (commit) các thay đổi trÆ°á»›c khi bạn có thể hòa trá»™n." -#: builtin/merge.c:1136 +#: builtin/merge.c:1151 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:1145 +#: builtin/merge.c:1160 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:1150 +#: builtin/merge.c:1165 msgid "You cannot combine --no-ff with --ff-only." msgstr "Bạn không thể kết hợp --no-ff vá»›i --ff-only." -#: builtin/merge.c:1157 +#: builtin/merge.c:1172 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "" "Không chỉ ra lần chuyển giao (commit) và merge.defaultToUpstream chÆ°a được " "đặt." -#: builtin/merge.c:1189 +#: builtin/merge.c:1204 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 (commit) và o má»™t " "head rá»—ng" -#: builtin/merge.c:1192 +#: builtin/merge.c:1207 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:1194 +#: builtin/merge.c:1209 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "" "Chuyển giao (commit) không-fast-forward không hợp lý ở trong má»™t head trống " "rá»—ng" -#: builtin/merge.c:1310 +#: builtin/merge.c:1265 +#, 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:1268 +#, 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." + +#. 'N' +#: builtin/merge.c:1271 +#, c-format +msgid "Commit %s does not have a GPG signature." +msgstr "Lần chuyển giao (commit) %s không có chữ ký GPG." + +#: builtin/merge.c:1274 +#, 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:1358 #, c-format msgid "Updating %s..%s\n" msgstr "Äang cáºp nháºt %s..%s\n" -#: builtin/merge.c:1349 +#: builtin/merge.c:1397 #, 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:1356 +#: builtin/merge.c:1404 #, c-format msgid "Nope.\n" msgstr "Không.\n" -#: builtin/merge.c:1388 +#: builtin/merge.c:1436 msgid "Not possible to fast-forward, aborting." msgstr "Thá»±c hiện lệnh fast-forward là không thể được, Ä‘ang bá» qua." -#: builtin/merge.c:1411 builtin/merge.c:1490 +#: builtin/merge.c:1459 builtin/merge.c:1538 #, 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:1415 +#: builtin/merge.c:1463 #, c-format msgid "Trying merge strategy %s...\n" msgstr "Äang thá» chiến lược hòa trá»™n %s...\n" -#: builtin/merge.c:1481 +#: builtin/merge.c:1529 #, 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:1483 +#: builtin/merge.c:1531 #, 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:1492 +#: builtin/merge.c:1540 #, 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:1504 +#: builtin/merge.c:1552 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "" @@ -7325,11 +7664,15 @@ msgstr "prune (cắt cụt) những tham chiếu (refs) bị gỡ bá»" msgid "bypass pre-push hook" msgstr "vòng qua “pre-push hookâ€" -#: builtin/push.c:448 +#: builtin/push.c:440 +msgid "push missing but relevant tags" +msgstr "push bị trượt nhÆ°ng các thẻ thÃch hợp" + +#: builtin/push.c:450 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "--delete là xung khắc vá»›i các tùy chá»n --all, --mirror và --tags" -#: builtin/push.c:450 +#: builtin/push.c:452 msgid "--delete doesn't make sense without any refs" msgstr "--delete không hợp lý nếu không có bất kỳ tham chiếu (refs) nà o" @@ -7852,7 +8195,7 @@ msgstr " * [nên xén bá»›t] %s" #: builtin/remote.c:1298 #, c-format msgid " * [pruned] %s" -msgstr " *[đã xén bá»›] %s" +msgstr " *[đã bị xén] %s" #: builtin/remote.c:1321 msgid "prune remotes after fetching" @@ -8089,16 +8432,16 @@ msgstr "" "Chạy lệnh \"git rev-parse --parseopt -h\" để có thêm thông tin vá» cách dùng." #: builtin/revert.c:22 -msgid "git revert [options] <commit-ish>" -msgstr "git revert [các-tùy-chá»n] <commit-ish>" +msgid "git revert [options] <commit-ish>..." +msgstr "git revert [các-tùy-chá»n] <commit-ish>..." #: builtin/revert.c:23 msgid "git revert <subcommand>" msgstr "git revert <lệnh-con>" #: builtin/revert.c:28 -msgid "git cherry-pick [options] <commit-ish>" -msgstr "git cherry-pick [các-tùy-chá»n] <commit-ish>" +msgid "git cherry-pick [options] <commit-ish>..." +msgstr "git cherry-pick [các-tùy-chá»n] <commit-ish>..." #: builtin/revert.c:29 msgid "git cherry-pick <subcommand>" @@ -8249,31 +8592,31 @@ msgid "git rm: unable to remove %s" msgstr "git rm: không thể gỡ bá» %s" #: builtin/shortlog.c:13 -msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" -msgstr "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +msgid "git shortlog [<options>] [<revision range>] [[--] [<path>...]]" +msgstr "git shortlog [các-tùy-chá»n] [<vùng-xem-xét>] [[--] [<Ä‘Æ°á»ng-dẫn>...]]" -#: builtin/shortlog.c:133 +#: builtin/shortlog.c:131 #, c-format msgid "Missing author: %s" msgstr "Thiếu tên tác giả: %s" -#: builtin/shortlog.c:229 +#: builtin/shortlog.c:227 msgid "sort output according to the number of commits per author" msgstr "sắp xếp kết xuất tuân theo số lượng chuyển giao trên má»—i tác giả" -#: builtin/shortlog.c:231 +#: builtin/shortlog.c:229 msgid "Suppress commit descriptions, only provides commit count" msgstr "Chặn má»i mô tả lần chuyển giao, chỉ Ä‘Æ°a ra số lượng lần chuyển giao" -#: builtin/shortlog.c:233 +#: builtin/shortlog.c:231 msgid "Show the email address of each author" msgstr "Hiển thị thÆ° Ä‘iện tá» cho từng tác giả" -#: builtin/shortlog.c:234 +#: builtin/shortlog.c:232 msgid "w[,i1[,i2]]" msgstr "w[,i1[,i2]]" -#: builtin/shortlog.c:235 +#: builtin/shortlog.c:233 msgid "Linewrap output" msgstr "Ngắt dòng khi quá dà i" @@ -8293,67 +8636,67 @@ msgstr "" msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "git show-branch (-g|--reflog)[=<n>[,<ná»n>]] [--list] [<ref>]" -#: builtin/show-branch.c:651 +#: builtin/show-branch.c:650 msgid "show remote-tracking and local branches" msgstr "hiển thị các nhánh remote-tracking và ná»™i bá»™" -#: builtin/show-branch.c:653 +#: builtin/show-branch.c:652 msgid "show remote-tracking branches" msgstr "hiển thị các nhánh remote-tracking" -#: builtin/show-branch.c:655 +#: builtin/show-branch.c:654 msgid "color '*!+-' corresponding to the branch" msgstr "mà u “*!+-†tÆ°Æ¡ng ứng vá»›i nhánh" -#: builtin/show-branch.c:657 +#: builtin/show-branch.c:656 msgid "show <n> more commits after the common ancestor" msgstr "hiển thị thêm <n> lần chuyển giao sau cha mẹ chung" -#: builtin/show-branch.c:659 +#: builtin/show-branch.c:658 msgid "synonym to more=-1" msgstr "đồng nghÄ©a vá»›i more=-1" -#: builtin/show-branch.c:660 +#: builtin/show-branch.c:659 msgid "suppress naming strings" msgstr "chặn các chuá»—i đặt tên" -#: builtin/show-branch.c:662 +#: builtin/show-branch.c:661 msgid "include the current branch" msgstr "bao gồm nhánh hiện hà nh" -#: builtin/show-branch.c:664 +#: builtin/show-branch.c:663 msgid "name commits with their object names" msgstr "đặt tên các lần chuyển giao bằng các tên của đối tượng của chúng" -#: builtin/show-branch.c:666 +#: builtin/show-branch.c:665 msgid "show possible merge bases" msgstr "hiển thị má»i cÆ¡ sở có thể dùng để hòa trá»™n" -#: builtin/show-branch.c:668 +#: builtin/show-branch.c:667 msgid "show refs unreachable from any other ref" msgstr "hiển thị các tham chiếu không thể được Ä‘á»c bởi bất kỳ tham chiếu khác" -#: builtin/show-branch.c:670 +#: builtin/show-branch.c:669 msgid "show commits in topological order" msgstr "hiển thị các lần chuyển giao theo thứ tá»± tôpô" -#: builtin/show-branch.c:672 +#: builtin/show-branch.c:671 msgid "show only commits not on the first branch" msgstr "chỉ hiển thị các lần chuyển giao không nằm trên nhánh đầu tiên" -#: builtin/show-branch.c:674 +#: builtin/show-branch.c:673 msgid "show merges reachable from only one tip" msgstr "hiển thị các lần hòa trá»™n có thể Ä‘á»c được chỉ từ má»™t đầu mút" -#: builtin/show-branch.c:676 +#: builtin/show-branch.c:675 msgid "show commits where no parent comes before its children" msgstr "hiển thị các lần chuyển giao nÆ¡i mà cha mẹ đến trÆ°á»›c con của nó" -#: builtin/show-branch.c:678 +#: builtin/show-branch.c:677 msgid "<n>[,<base>]" msgstr "<n>[,<cÆ¡ sở>]" -#: builtin/show-branch.c:679 +#: builtin/show-branch.c:678 msgid "show <n> most recent ref-log entries starting at base" msgstr "hiển thị <n> các mục “ref-log†gần nhất kể từ ná»n (base)" @@ -8822,9 +9165,15 @@ msgid "only useful for debugging" msgstr "chỉ hữu Ãch khi cần gỡ lá»—i" #: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." +msgid "" +"'git help -a' and 'git help -g' lists available subcommands and some\n" +"concept guides. See 'git help <command>' or 'git help <concept>'\n" +"to read about a specific subcommand or concept." msgstr "" -"Chạy lệnh “git help <tên-lệnh>†để có thêm thông tin vá» lệnh được chỉ ra." +"“git help -a†và “git help -g†liệt kê các câu lệnh con sẵn có và má»™t số\n" +"hÆ°á»›ng dẫn khái niệm cÆ¡ bản. Xem “git help <lệnh>†hay “git help <khái " +"niệm>â€\n" +"để Ä‘á»c các đặc tả cho lệnh hay khái niệm đó." #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -9206,16 +9555,16 @@ msgstr "" "sai.\n" "(Bạn có thể sá» dụng \"git bisect bad\" và \"git bisect good\" cho chúng.)" -#: git-bisect.sh:347 git-bisect.sh:474 +#: git-bisect.sh:363 git-bisect.sh:490 msgid "We are not bisecting." msgstr "Chúng tôi không bisect." -#: git-bisect.sh:354 +#: git-bisect.sh:370 #, sh-format msgid "'$invalid' is not a valid commit" msgstr "â€$invalid†không phải là lần chuyển giao (commit) hợp lệ" -#: git-bisect.sh:363 +#: git-bisect.sh:379 #, sh-format msgid "" "Could not check out original HEAD '$branch'.\n" @@ -9224,25 +9573,25 @@ msgstr "" "Không thể check-out HEAD nguyên thủy của “$branchâ€.\n" "Hãy thỠ“git bisect reset <lần-chuyển-giao>â€." -#: git-bisect.sh:390 +#: git-bisect.sh:406 msgid "No logfile given" msgstr "ChÆ°a chỉ ra táºp tin ghi nháºt ký" -#: git-bisect.sh:391 +#: git-bisect.sh:407 #, sh-format msgid "cannot read $file for replaying" msgstr "không thể Ä‘á»c $file để thao diá»…n lại" -#: git-bisect.sh:408 +#: git-bisect.sh:424 msgid "?? what are you talking about?" msgstr "?? bạn Ä‘ang nói gì thế?" -#: git-bisect.sh:420 +#: git-bisect.sh:436 #, sh-format msgid "running $command" msgstr "Ä‘ang chạy lệnh $command" -#: git-bisect.sh:427 +#: git-bisect.sh:443 #, sh-format msgid "" "bisect run failed:\n" @@ -9251,11 +9600,11 @@ msgstr "" "chạy bisect gặp lá»—i:\n" "mã trả vá» $res từ lệnh “$command†là < 0 hoặc >= 128" -#: git-bisect.sh:453 +#: git-bisect.sh:469 msgid "bisect run cannot continue any more" msgstr "bisect không thể tiếp tục thêm được nữa" -#: git-bisect.sh:459 +#: git-bisect.sh:475 #, sh-format msgid "" "bisect run failed:\n" @@ -9264,7 +9613,7 @@ msgstr "" "chạy bisect gặp lá»—i:\n" "â€bisect_state $state†đã thoát ra vá»›i mã lá»—i $res" -#: git-bisect.sh:466 +#: git-bisect.sh:482 msgid "bisect run success" msgstr "bisect chạy thà nh công" @@ -9284,7 +9633,7 @@ msgid "Pull is not possible because you have unmerged files." msgstr "" "Full là không thể thá»±c hiện bởi vì bạn có những táºp tin chÆ°a được hòa trá»™n." -#: git-pull.sh:197 +#: git-pull.sh:203 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 " @@ -9294,7 +9643,7 @@ msgstr "" #. The working tree and the index file is still based on the #. $orig_head commit, but we are merging into $curr_head. #. First update the working tree to match $curr_head. -#: git-pull.sh:229 +#: git-pull.sh:235 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -9305,11 +9654,11 @@ msgstr "" "Cảnh báo: Ä‘ang fast-forward cây là m việc của bạn từ\n" "Cảnh báo: commit $orig_head." -#: git-pull.sh:254 +#: git-pull.sh:260 msgid "Cannot merge multiple branches into empty head" msgstr "Không thể hòa trá»™n nhiá»u nhánh và trong má»™t head trống rá»—ng" -#: git-pull.sh:258 +#: git-pull.sh:264 msgid "Cannot rebase onto multiple branches" msgstr "Không thể thá»±c hiện lệnh rebase (cÆ¡ cấu lại) trên nhiá»u nhánh" @@ -9575,41 +9924,41 @@ 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:90 +#: git-submodule.sh:91 #, 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:195 +#: git-submodule.sh:196 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "" "Không tìm thấy ánh xạ (mapping) mô-Ä‘un-con trong .gitmodules cho Ä‘Æ°á»ng dẫn " "“$sm_pathâ€" -#: git-submodule.sh:238 +#: git-submodule.sh:239 #, sh-format msgid "Clone of '$url' into submodule path '$sm_path' failed" msgstr "Nhân bản “$url†và o Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_path†gặp lá»—i" -#: git-submodule.sh:250 +#: git-submodule.sh:251 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "" "Gitdir “$a†là bá»™ pháºn của Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$b†hoặc \"vice versa\"" -#: git-submodule.sh:343 +#: git-submodule.sh:349 #, 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:360 +#: git-submodule.sh:366 #, 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:364 +#: git-submodule.sh:370 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9621,36 +9970,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:382 +#: git-submodule.sh:388 #, 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:384 +#: git-submodule.sh:390 #, 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:392 +#: git-submodule.sh:398 #, 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:394 +#: git-submodule.sh:400 #, 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:396 +#: git-submodule.sh:402 #, 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:397 +#: git-submodule.sh:403 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " @@ -9659,159 +10008,248 @@ 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:399 +#: git-submodule.sh:405 #, 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:411 +#: git-submodule.sh:417 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "Không thể checkout mô-Ä‘un con “$sm_pathâ€" -#: git-submodule.sh:416 +#: git-submodule.sh:422 #, 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:425 +#: git-submodule.sh:431 #, 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:468 +#: git-submodule.sh:474 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "Äang nháºp “$prefix$sm_pathâ€" -#: git-submodule.sh:482 +#: git-submodule.sh:488 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "Dừng lại tại “$sm_pathâ€; script trả vá» trạng thái khác không." -#: git-submodule.sh:526 +#: git-submodule.sh:532 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "" "Không tìm thấy url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_path†trong .gitmodules" -#: git-submodule.sh:535 +#: git-submodule.sh:541 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "Gặp lá»—i khi đăng ký url cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:537 +#: git-submodule.sh:543 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "Mô-Ä‘un-con “$name†($url) được đăng ký cho Ä‘Æ°á»ng dẫn “$sm_pathâ€" -#: git-submodule.sh:545 +#: git-submodule.sh:551 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "" "Gặp lá»—i khi đăng ký chế Ä‘á»™ cáºp nháºt cho Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:649 +#: git-submodule.sh:588 +#, 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" + +#: git-submodule.sh:603 +#, sh-format +msgid "Submodule work tree '$sm_path' contains a .git directory" +msgstr "Cây là m việc mô-Ä‘un-con “$sm_path†có chứa thÆ° mục .git" + +#: git-submodule.sh:604 +#, sh-format +msgid "" +"(use 'rm -rf' if you really want to remove it including all of its history)" +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:610 +#, sh-format +msgid "" +"Submodule work tree '$sm_path' contains local modifications; use '-f' to " +"discard them" +msgstr "" +"Cây là m việc mô-Ä‘un-con “$sm_path†chứa các thay đổi ná»™i bá»™; hãy dùng “-f†" +"để loại bá» chúng Ä‘i" + +#: git-submodule.sh:613 +#, sh-format +msgid "Cleared directory '$sm_path'" +msgstr "ThÆ° mục được dá»n “$sm_pathâ€" + +#: git-submodule.sh:614 +#, sh-format +msgid "Could not remove submodule work tree '$sm_path'" +msgstr "Không thể gỡ bá» cây là m việc mô-Ä‘un con “$sm_pathâ€" + +#: git-submodule.sh:617 +#, sh-format +msgid "Could not create empty submodule directory '$sm_path'" +msgstr "Không thể tạo thÆ° mục mô-Ä‘un-con rá»—ng “$sm_pathâ€" + +#: git-submodule.sh:626 +#, sh-format +msgid "Submodule '$name' ($url) unregistered for path '$sm_path'" +msgstr "Mô-Ä‘un-con “$name†($url) được bỠđăng ký cho Ä‘Æ°á»ng dẫn “$sm_pathâ€" + +#: git-submodule.sh:731 #, sh-format msgid "" -"Submodule path '$sm_path' not initialized\n" +"Submodule path '$prefix$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -"ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_path†chÆ°a được khởi tạo\n" +"ÄÆ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_path†chÆ°a được khởi tạo\n" "Có lẽ bạn muốn sá» dụng lệnh “update --initâ€?" -#: git-submodule.sh:662 +#: git-submodule.sh:744 #, sh-format -msgid "Unable to find current revision in submodule path '$sm_path'" +msgid "Unable to find current revision in submodule path '$prefix$sm_path'" msgstr "" -"Không tìm thấy Ä‘iểm xét lại hiện hà nh trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" +"Không tìm thấy Ä‘iểm xét lại hiện hà nh trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix" +"$sm_pathâ€" -#: git-submodule.sh:671 git-submodule.sh:695 +#: git-submodule.sh:753 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "Không thể lấy vá» (fetch) trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" -#: git-submodule.sh:709 +#: git-submodule.sh:777 +#, sh-format +msgid "Unable to fetch in submodule path '$prefix$sm_path'" +msgstr "Không thể lấy vá» (fetch) trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€" + +#: git-submodule.sh:791 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" -msgstr "Không thể rebase “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" +msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'" +msgstr "Không thể rebase “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€" -#: git-submodule.sh:710 +#: git-submodule.sh:792 #, sh-format -msgid "Submodule path '$sm_path': rebased into '$sha1'" -msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được rebase và o trong “$sha1â€" +msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€: được rebase và o trong “$sha1â€" -#: git-submodule.sh:715 +#: git-submodule.sh:797 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$sm_path'" +msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'" msgstr "" -"Không thể hòa trá»™n (merge) “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" +"Không thể hòa trá»™n (merge) “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix" +"$sm_pathâ€" -#: git-submodule.sh:716 +#: git-submodule.sh:798 #, sh-format -msgid "Submodule path '$sm_path': merged in '$sha1'" -msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được hòa trá»™n và o “$sha1â€" +msgid "Submodule path '$prefix$sm_path': merged in '$sha1'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€: được hòa trá»™n và o “$sha1â€" -#: git-submodule.sh:721 +#: git-submodule.sh:803 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" -msgstr "Không thể checkout “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€" +msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'" +msgstr "" +"Không thể checkout “$sha1†trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€" -#: git-submodule.sh:722 +#: git-submodule.sh:804 #, sh-format -msgid "Submodule path '$sm_path': checked out '$sha1'" -msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$sm_pathâ€: được checkout “$sha1â€" +msgid "Submodule path '$prefix$sm_path': checked out '$sha1'" +msgstr "ÄÆ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€: được checkout “$sha1â€" -#: git-submodule.sh:744 git-submodule.sh:1066 +#: git-submodule.sh:831 #, 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â€" +msgid "Failed to recurse into submodule path '$prefix$sm_path'" +msgstr "Gặp lá»—i khi đệ quy và o trong Ä‘Æ°á»ng dẫn mô-Ä‘un-con “$prefix$sm_pathâ€" -#: git-submodule.sh:852 +#: git-submodule.sh:939 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" #. unexpected type -#: git-submodule.sh:892 +#: git-submodule.sh:979 #, sh-format msgid "unexpected mode $mod_dst" msgstr "chế Ä‘á»™ không nhÆ° mong chá» $mod_dst" -#: git-submodule.sh:910 +#: git-submodule.sh:997 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_src" -#: git-submodule.sh:913 +#: git-submodule.sh:1000 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " Cảnh báo: $name không chứa lần chuyển giao (commit) $sha1_dst" -#: git-submodule.sh:916 +#: git-submodule.sh:1003 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr "" " Cảnh báo: $name không chứa những lần chuyển giao (commit) $sha1_src và " "$sha1_dst" -#: git-submodule.sh:941 +#: git-submodule.sh:1028 msgid "blob" msgstr "blob" -#: git-submodule.sh:979 +#: git-submodule.sh:1066 msgid "Submodules changed but not updated:" msgstr "Những mô-Ä‘un-con đã bị thay đổi nhÆ°ng chÆ°a được cáºp nháºt:" -#: git-submodule.sh:981 +#: git-submodule.sh:1068 msgid "Submodule changes to be committed:" msgstr "Những mô-Ä‘un-con thay đổi đã được chuyển giao (commit):" -#: git-submodule.sh:1129 +#: git-submodule.sh:1153 +#, 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:1216 #, sh-format msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "Url Mô-Ä‘un-con đồng bá»™ hóa cho “$prefix$sm_pathâ€" +#~ msgid "It took %.2f seconds to enumerate untracked files. 'status -uno'" +#~ msgstr "Cần %.2f giây để đếm các táºp tin chÆ°a được theo vết. “status -unoâ€" + +#~ msgid "may speed it up, but you have to be careful not to forget to add" +#~ msgstr "" +#~ "có thể là m nó nhanh lên, nhÆ°ng bạn phải cẩn trá»ng đừng quên thêm nó và o" + +#~ msgid "new files yourself (see 'git help status')." +#~ msgstr "táºp tin má»›i của chÃnh bạn (xem “git help statusâ€.." + +#~ msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +#~ msgstr "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" + +#~ msgid "See 'git help <command>' for more information on a specific command." +#~ msgstr "" +#~ "Chạy lệnh “git help <tên-lệnh>†để có thêm thông tin vá» lệnh được chỉ ra." + +#~ msgid "use any ref in .git/refs" +#~ msgstr "sá» dụng bất kỳ ref nà o trong .git/refs" + +#~ msgid "use any tag in .git/refs/tags" +#~ msgstr "sá» dụng bất kỳ thẻ nà o trong .git/refs/tags" + +#~ msgid "bad object %s" +#~ msgstr "đối tượng sai %s" + +#~ msgid "bogus committer info %s" +#~ msgstr "thông tin ngÆ°á»i chuyển giao không có thá»±c %s" + #~ msgid "can't fdopen 'show' output fd" #~ msgstr "không thể fdopen “show†(lệnh hiển thị) mô tả táºp tin (fd) kết xuất" diff --git a/po/zh_CN.po b/po/zh_CN.po index c48ae10d78..ba757d9afd 100644 --- a/po/zh_CN.po +++ b/po/zh_CN.po @@ -12,8 +12,8 @@ msgid "" msgstr "" "Project-Id-Version: Git\n" "Report-Msgid-Bugs-To: Git Mailing List <git@vger.kernel.org>\n" -"POT-Creation-Date: 2013-03-05 12:36+0800\n" -"PO-Revision-Date: 2013-03-05 13:07+0800\n" +"POT-Creation-Date: 2013-04-30 08:25+0800\n" +"PO-Revision-Date: 2013-04-12 09:23+0800\n" "Last-Translator: Jiang Xin <worldhello.net@gmail.com>\n" "Language-Team: GitHub <https://github.com/gotgit/git/>\n" "Language: zh_CN\n" @@ -22,7 +22,7 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n" -#: advice.c:49 +#: advice.c:53 #, c-format msgid "hint: %.*s\n" msgstr "æ示:%.*s\n" @@ -31,7 +31,7 @@ msgstr "æ示:%.*s\n" #. * Message used both when 'git commit' fails and when #. * other commands doing a merge do. #. -#: advice.c:79 +#: advice.c:83 msgid "" "Fix them up in the work tree,\n" "and then use 'git add/rm <file>' as\n" @@ -68,7 +68,7 @@ msgstr "æ ¼å¼" msgid "archive format" msgstr "å½’æ¡£æ ¼å¼" -#: archive.c:324 builtin/log.c:1115 +#: archive.c:324 builtin/log.c:1126 msgid "prefix" msgstr "å‰ç¼€" @@ -76,15 +76,15 @@ msgstr "å‰ç¼€" msgid "prepend prefix to each pathname in the archive" msgstr "为归档ä¸æ¯ä¸ªè·¯å¾„ååŠ ä¸Šå‰ç¼€" -#: archive.c:326 builtin/archive.c:91 builtin/blame.c:2366 -#: builtin/blame.c:2367 builtin/config.c:55 builtin/fast-export.c:653 -#: builtin/fast-export.c:655 builtin/grep.c:715 builtin/hash-object.c:77 -#: builtin/ls-files.c:497 builtin/ls-files.c:500 builtin/notes.c:536 +#: archive.c:326 builtin/archive.c:88 builtin/blame.c:2371 +#: builtin/blame.c:2372 builtin/config.c:55 builtin/fast-export.c:665 +#: builtin/fast-export.c:667 builtin/grep.c:715 builtin/hash-object.c:77 +#: builtin/ls-files.c:490 builtin/ls-files.c:493 builtin/notes.c:536 #: builtin/notes.c:693 builtin/read-tree.c:107 parse-options.h:149 msgid "file" msgstr "文件" -#: archive.c:327 builtin/archive.c:92 +#: archive.c:327 builtin/archive.c:89 msgid "write the archive to this file" msgstr "归档写入æ¤æ–‡ä»¶" @@ -112,19 +112,19 @@ msgstr "压缩效果更好" msgid "list supported archive formats" msgstr "列出支æŒçš„å½’æ¡£æ ¼å¼" -#: archive.c:345 builtin/archive.c:93 builtin/clone.c:85 +#: archive.c:345 builtin/archive.c:90 builtin/clone.c:86 msgid "repo" msgstr "版本库" -#: archive.c:346 builtin/archive.c:94 +#: archive.c:346 builtin/archive.c:91 msgid "retrieve the archive from remote repository <repo>" msgstr "从远程版本库(<版本库>)æå–归档文件" -#: archive.c:347 builtin/archive.c:95 builtin/notes.c:615 +#: archive.c:347 builtin/archive.c:92 builtin/notes.c:615 msgid "command" msgstr "命令" -#: archive.c:348 builtin/archive.c:96 +#: archive.c:348 builtin/archive.c:93 msgid "path to the remote git-upload-archive command" msgstr "远程 git-upload-archive 命令的路径" @@ -136,6 +136,126 @@ msgstr "" "负值模版在 git attributes ä¸è¢«å¿½ç•¥\n" "当å—符串确实è¦ä»¥æ„Ÿå¹å·å¼€å§‹æ—¶ï¼Œä½¿ç”¨ '\\!'。" +#: branch.c:60 +#, c-format +msgid "Not setting branch %s as its own upstream." +msgstr "未设置分支 %s 作为它自己的上游。" + +#: branch.c:82 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s by rebasing." +msgstr "分支 %1$s 设置为使用å˜åŸºæ¥è·Ÿè¸ªæ¥è‡ª %3$s 的远程分支 %2$s。" + +#: branch.c:83 +#, c-format +msgid "Branch %s set up to track remote branch %s from %s." +msgstr "分支 %1$s 设置为跟踪æ¥è‡ª %3$s 的远程分支 %2$s。" + +#: branch.c:87 +#, c-format +msgid "Branch %s set up to track local branch %s by rebasing." +msgstr "分支 %s 设置为使用å˜åŸºæ¥è·Ÿè¸ªæœ¬åœ°åˆ†æ”¯ %s。" + +#: branch.c:88 +#, c-format +msgid "Branch %s set up to track local branch %s." +msgstr "分支 %s 设置为跟踪本地分支 %s。" + +#: branch.c:92 +#, c-format +msgid "Branch %s set up to track remote ref %s by rebasing." +msgstr "分支 %s 设置为使用å˜åŸºæ¥è·Ÿè¸ªè¿œç¨‹å¼•ç”¨ %s。" + +#: branch.c:93 +#, c-format +msgid "Branch %s set up to track remote ref %s." +msgstr "分支 %s 设置为跟踪远程引用 %s。" + +#: branch.c:97 +#, c-format +msgid "Branch %s set up to track local ref %s by rebasing." +msgstr "分支 %s 设置为使用å˜åŸºæ¥è·Ÿè¸ªæœ¬åœ°å¼•ç”¨ %s。" + +#: branch.c:98 +#, c-format +msgid "Branch %s set up to track local ref %s." +msgstr "分支 %s 设置为跟踪本地引用 %s。" + +#: branch.c:118 +#, c-format +msgid "Tracking not set up: name too long: %s" +msgstr "跟踪未设置:åå—太长:%s" + +#: branch.c:137 +#, c-format +msgid "Not tracking: ambiguous information for ref %s" +msgstr "未跟踪:引用 %s 有æ§ä¹‰" + +#: branch.c:182 +#, c-format +msgid "'%s' is not a valid branch name." +msgstr "'%s' ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„分支å称。" + +#: branch.c:187 +#, c-format +msgid "A branch named '%s' already exists." +msgstr "一个分支å '%s' å·²ç»å˜åœ¨ã€‚" + +#: branch.c:195 +msgid "Cannot force update the current branch." +msgstr "æ— æ³•å¼ºåˆ¶æ›´æ–°å½“å‰åˆ†æ”¯ã€‚" + +#: branch.c:201 +#, c-format +msgid "Cannot setup tracking information; starting point '%s' is not a branch." +msgstr "æ— æ³•è®¾ç½®è·Ÿè¸ªä¿¡æ¯ï¼›èµ·å§‹ç‚¹ '%s' ä¸æ˜¯ä¸€ä¸ªåˆ†æ”¯ã€‚" + +#: branch.c:203 +#, c-format +msgid "the requested upstream branch '%s' does not exist" +msgstr "请求的上游分支 '%s' ä¸å˜åœ¨" + +#: branch.c:205 +msgid "" +"\n" +"If you are planning on basing your work on an upstream\n" +"branch that already exists at the remote, you may need to\n" +"run \"git fetch\" to retrieve it.\n" +"\n" +"If you are planning to push out a new local branch that\n" +"will track its remote counterpart, you may want to use\n" +"\"git push -u\" to set the upstream config as you push." +msgstr "" +"\n" +"如果您æ£è®¡åˆ’基于远程一个现å˜çš„ä¸Šæ¸¸åˆ†æ”¯å¼€å§‹ä½ çš„å·¥ä½œï¼Œ\n" +"您å¯èƒ½éœ€è¦æ‰§è¡Œ \"git fetch\" æ¥èŽ·å–分支。\n" +"\n" +"如果您æ£è®¡åˆ’推é€ä¸€ä¸ªèƒ½ä¸Žå¯¹åº”远程分支建立跟踪的新的本地分支,\n" +"您å¯èƒ½éœ€è¦ä½¿ç”¨ \"git push -u\" 推é€åˆ†æ”¯å¹¶é…置和上游的关è”。" + +#: branch.c:250 +#, c-format +msgid "Not a valid object name: '%s'." +msgstr "ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„对象å:'%s'。" + +#: branch.c:270 +#, c-format +msgid "Ambiguous object name: '%s'." +msgstr "æ§ä¹‰çš„对象å:'%s'。" + +#: branch.c:275 +#, c-format +msgid "Not a valid branch point: '%s'." +msgstr "æ— æ•ˆçš„åˆ†æ”¯ç‚¹ï¼š'%s'。" + +#: branch.c:281 +msgid "Failed to lock ref for update" +msgstr "æ— æ³•ä¸ºæ›´æ–°é”定引用" + +#: branch.c:299 +msgid "Failed to write ref" +msgstr "ä¸èƒ½å†™å¼•ç”¨" + #: bundle.c:36 #, c-format msgid "'%s' does not look like a v2 bundle file" @@ -146,7 +266,7 @@ msgstr "'%s' ä¸åƒæ˜¯ä¸€ä¸ª v2 版本的包文件" msgid "unrecognized header: %s%s (%d)" msgstr "未能识别的包头:%s%s (%d)" -#: bundle.c:89 builtin/commit.c:674 +#: bundle.c:89 builtin/commit.c:676 #, c-format msgid "could not open '%s'" msgstr "ä¸èƒ½æ‰“å¼€ '%s'" @@ -155,35 +275,35 @@ msgstr "ä¸èƒ½æ‰“å¼€ '%s'" msgid "Repository lacks these prerequisite commits:" msgstr "版本库缺少这些必备的æ交:" -#: bundle.c:164 sequencer.c:566 sequencer.c:998 builtin/log.c:299 -#: builtin/log.c:751 builtin/log.c:1358 builtin/log.c:1574 builtin/merge.c:347 -#: builtin/shortlog.c:157 +#: bundle.c:164 sequencer.c:651 sequencer.c:1101 builtin/log.c:300 +#: builtin/log.c:770 builtin/log.c:1344 builtin/log.c:1570 builtin/merge.c:349 +#: builtin/shortlog.c:155 msgid "revision walk setup failed" msgstr "版本é历设置失败" #: bundle.c:186 #, c-format -msgid "The bundle contains %d ref" -msgid_plural "The bundle contains %d refs" -msgstr[0] "这个包ä¸å«æœ‰ %d 个引用" -msgstr[1] "这个包ä¸å«æœ‰ %d 个引用" +msgid "The bundle contains this ref:" +msgid_plural "The bundle contains these %d refs:" +msgstr[0] "这个包ä¸å«æœ‰è¿™ä¸ªå¼•ç”¨ï¼š" +msgstr[1] "这个包ä¸å«æœ‰ %d 个引用:" -#: bundle.c:192 +#: bundle.c:193 msgid "The bundle records a complete history." msgstr "这个包记录一个完整历å²ã€‚" #: bundle.c:195 #, c-format -msgid "The bundle requires this ref" -msgid_plural "The bundle requires these %d refs" -msgstr[0] "这个包需è¦è¿™ä¸ªå¼•ç”¨" -msgstr[1] "è¿™ä¸ªåŒ…éœ€è¦ %d 个这些引用" +msgid "The bundle requires this ref:" +msgid_plural "The bundle requires these %d refs:" +msgstr[0] "这个包需è¦è¿™ä¸ªå¼•ç”¨ï¼š" +msgstr[1] "è¿™ä¸ªåŒ…éœ€è¦ %d 个引用:" #: bundle.c:294 msgid "rev-list died" msgstr "rev-list 终æ¢" -#: bundle.c:300 builtin/log.c:1254 builtin/shortlog.c:260 +#: bundle.c:300 builtin/log.c:1255 builtin/shortlog.c:258 #, c-format msgid "unrecognized argument: %s" msgstr "未能识别的å‚数:%s" @@ -335,7 +455,7 @@ msgstr "" "å‘现é…ç½®å˜é‡ 'diff.dirstat' ä¸çš„错误:\n" "%s" -#: diff.c:3468 +#: diff.c:3481 #, c-format msgid "" "Failed to parse --dirstat/-X option parameter:\n" @@ -344,12 +464,12 @@ msgstr "" "æ— æ³•è§£æž --dirstat/-X 选项的å‚数:\n" "%s" -#: diff.c:3482 +#: diff.c:3495 #, c-format msgid "Failed to parse --submodule option parameter: '%s'" msgstr "æ— æ³•è§£æž --submodule 选项的å‚数:'%s'" -#: gpg-interface.c:59 gpg-interface.c:127 +#: gpg-interface.c:59 gpg-interface.c:131 msgid "could not run gpg." msgstr "ä¸èƒ½æ‰§è¡Œ gpg。" @@ -361,27 +481,27 @@ msgstr "gpg 没有接å—æ•°æ®" msgid "gpg failed to sign the data" msgstr "gpg æ— æ³•ä¸ºæ•°æ®ç¾å" -#: gpg-interface.c:112 +#: gpg-interface.c:115 #, c-format msgid "could not create temporary file '%s': %s" msgstr "ä¸èƒ½åˆ›å»ºä¸´æ—¶æ–‡ä»¶ '%s':%s" -#: gpg-interface.c:115 +#: gpg-interface.c:118 #, c-format msgid "failed writing detached signature to '%s': %s" msgstr "æ— æ³•å°†åˆ†ç¦»å¼ç¾å写入 '%s':%s" -#: grep.c:1622 +#: grep.c:1623 #, c-format msgid "'%s': unable to read %s" msgstr "'%s'ï¼šæ— æ³•è¯»å– %s" -#: grep.c:1639 +#: grep.c:1640 #, c-format msgid "'%s': %s" msgstr "'%s':%s" -#: grep.c:1650 +#: grep.c:1651 #, c-format msgid "'%s': short read %s" msgstr "'%s':读å–ä¸å®Œæ•´ %s" @@ -449,8 +569,8 @@ msgstr[1] "" msgid "failed to read the cache" msgstr "æ— æ³•è¯»å–缓å˜" -#: merge.c:110 builtin/checkout.c:333 builtin/checkout.c:534 -#: builtin/clone.c:586 +#: merge.c:110 builtin/checkout.c:365 builtin/checkout.c:566 +#: builtin/clone.c:645 msgid "unable to write new index file" msgstr "æ— æ³•å†™æ–°çš„ç´¢å¼•æ–‡ä»¶" @@ -499,7 +619,7 @@ msgstr "ä¸èƒ½è¯»å–对象 %s '%s'" msgid "blob expected for %s '%s'" msgstr "%s '%s' 应为数æ®ï¼ˆblob)对象" -#: merge-recursive.c:773 builtin/clone.c:302 +#: merge-recursive.c:773 builtin/clone.c:313 #, c-format msgid "failed to open '%s'" msgstr "æ— æ³•æ‰“å¼€ '%s'" @@ -634,7 +754,7 @@ msgstr "略过 %s(已ç»åšè¿‡ç›¸åŒåˆå¹¶ï¼‰" msgid "Auto-merging %s" msgstr "自动åˆå¹¶ %s" -#: merge-recursive.c:1633 git-submodule.sh:942 +#: merge-recursive.c:1633 git-submodule.sh:1029 msgid "submodule" msgstr "å模组" @@ -704,10 +824,15 @@ msgstr "åˆå¹¶æœªè¿”回æ交" msgid "Could not parse object '%s'" msgstr "ä¸èƒ½è§£æžå¯¹è±¡ '%s'" -#: merge-recursive.c:2009 builtin/merge.c:643 +#: merge-recursive.c:2009 builtin/merge.c:658 msgid "Unable to write index." msgstr "ä¸èƒ½å†™å…¥ç´¢å¼•ã€‚" +#: object.c:195 +#, c-format +msgid "unable to parse object: %s" +msgstr "ä¸èƒ½è§£æžå¯¹è±¡ï¼š%s" + #: parse-options.c:489 msgid "..." msgstr "..." @@ -744,18 +869,18 @@ msgstr "路径 '%s' 属于模组 '%.*s'" msgid "'%s' is beyond a symbolic link" msgstr "'%s' ä½äºŽç¬¦å·é“¾æŽ¥ä¸" -#: remote.c:1653 +#: remote.c:1781 #, 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] "您的分支领先 '%s' å…± %d 个æ交。\n" msgstr[1] "您的分支领先 '%s' å…± %d 个æ交。\n" -#: remote.c:1659 +#: remote.c:1787 msgid " (use \"git push\" to publish your local commits)\n" msgstr " (使用 \"git push\" æ¥å‘布您的本地æ交)\n" -#: remote.c:1662 +#: remote.c:1790 #, c-format msgid "Your branch is behind '%s' by %d commit, and can be fast-forwarded.\n" msgid_plural "" @@ -764,11 +889,11 @@ msgstr[0] "您的分支è½åŽ '%s' å…± %d 个æ交,并且å¯ä»¥å¿«è¿›ã€‚\n" msgstr[1] "您的分支è½åŽ '%s' å…± %d 个æ交,并且å¯ä»¥å¿«è¿›ã€‚\n" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: remote.c:1670 +#: remote.c:1798 msgid " (use \"git pull\" to update your local branch)\n" msgstr " (使用 \"git pull\" æ¥æ›´æ–°æ‚¨çš„本地分支)\n" -#: remote.c:1673 +#: remote.c:1801 #, c-format msgid "" "Your branch and '%s' have diverged,\n" @@ -784,23 +909,23 @@ msgstr[1] "" "并且分别有 %d å’Œ %d 处ä¸åŒçš„æ交。\n" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: remote.c:1683 +#: remote.c:1811 msgid " (use \"git pull\" to merge the remote branch into yours)\n" msgstr " (使用 \"git pull\" æ¥åˆå¹¶è¿œç¨‹åˆ†æ”¯ï¼‰\n" -#: sequencer.c:123 builtin/merge.c:761 builtin/merge.c:874 builtin/merge.c:984 -#: builtin/merge.c:994 +#: sequencer.c:206 builtin/merge.c:776 builtin/merge.c:889 builtin/merge.c:999 +#: builtin/merge.c:1009 #, c-format msgid "Could not open '%s' for writing" msgstr "ä¸èƒ½ä¸ºå†™å…¥æ‰“å¼€ '%s'" -#: sequencer.c:125 builtin/merge.c:333 builtin/merge.c:764 builtin/merge.c:986 -#: builtin/merge.c:999 +#: sequencer.c:208 builtin/merge.c:335 builtin/merge.c:779 +#: builtin/merge.c:1001 builtin/merge.c:1014 #, c-format msgid "Could not write to '%s'" msgstr "ä¸èƒ½å†™å…¥ '%s'" -#: sequencer.c:146 +#: sequencer.c:229 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'" @@ -808,7 +933,7 @@ msgstr "" "冲çªè§£å†³å®Œæ¯•åŽï¼Œç”¨ 'git add <paths>' 或 'git rm <paths>'\n" "å‘½ä»¤æ ‡è®°ä¿®æ£åŽçš„文件" -#: sequencer.c:149 +#: sequencer.c:232 msgid "" "after resolving the conflicts, mark the corrected paths\n" "with 'git add <paths>' or 'git rm <paths>'\n" @@ -817,228 +942,238 @@ msgstr "" "冲çªè§£å†³å®Œæ¯•åŽï¼Œç”¨ 'git add <paths>' 或 'git rm <paths>'\n" "对修æ£åŽçš„文件åšæ ‡è®°ï¼Œç„¶åŽç”¨ 'git commit' æ交" -#: sequencer.c:162 sequencer.c:774 sequencer.c:857 +#: sequencer.c:245 sequencer.c:859 sequencer.c:942 #, c-format msgid "Could not write to %s" msgstr "ä¸èƒ½å†™å…¥ %s" -#: sequencer.c:165 +#: sequencer.c:248 #, c-format msgid "Error wrapping up %s" msgstr "错误收尾 %s" -#: sequencer.c:180 +#: sequencer.c:263 msgid "Your local changes would be overwritten by cherry-pick." msgstr "您的本地修改将被拣选æ“作覆盖。" -#: sequencer.c:182 +#: sequencer.c:265 msgid "Your local changes would be overwritten by revert." msgstr "您的本地修改将被还原æ“作覆盖。" -#: sequencer.c:185 +#: sequencer.c:268 msgid "Commit your changes or stash them to proceed." msgstr "æ交您的修改或ä¿å˜è¿›åº¦åŽå†ç»§ç»ã€‚" #. TRANSLATORS: %s will be "revert" or "cherry-pick" -#: sequencer.c:236 +#: sequencer.c:319 #, c-format msgid "%s: Unable to write new index file" msgstr "%sï¼šæ— æ³•å†™å…¥æ–°ç´¢å¼•æ–‡ä»¶" -#: sequencer.c:267 +#: sequencer.c:350 msgid "Could not resolve HEAD commit\n" msgstr "ä¸èƒ½è§£æž HEAD æ交\n" -#: sequencer.c:288 +#: sequencer.c:371 msgid "Unable to update cache tree\n" msgstr "ä¸èƒ½æ›´æ–°ç¼“å˜\n" -#: sequencer.c:333 +#: sequencer.c:416 #, c-format msgid "Could not parse commit %s\n" msgstr "ä¸èƒ½è§£æžæ交 %s\n" -#: sequencer.c:338 +#: sequencer.c:421 #, c-format msgid "Could not parse parent commit %s\n" msgstr "ä¸èƒ½è§£æžçˆ¶æ交 %s\n" -#: sequencer.c:404 +#: sequencer.c:487 msgid "Your index file is unmerged." msgstr "您的索引文件未完æˆåˆå¹¶ã€‚" -#: sequencer.c:423 +#: sequencer.c:506 #, c-format msgid "Commit %s is a merge but no -m option was given." msgstr "æ交 %s 是一个åˆå¹¶æ交但未æä¾› -m 选项。" -#: sequencer.c:431 +#: sequencer.c:514 #, c-format msgid "Commit %s does not have parent %d" msgstr "æ交 %s 没有父æ交 %d" -#: sequencer.c:435 +#: sequencer.c:518 #, c-format msgid "Mainline was specified but commit %s is not a merge." msgstr "指定了主线但æ交 %s ä¸æ˜¯ä¸€ä¸ªåˆå¹¶ã€‚" #. TRANSLATORS: The first %s will be "revert" or #. "cherry-pick", the second %s a SHA1 -#: sequencer.c:448 +#: sequencer.c:531 #, c-format msgid "%s: cannot parse parent commit %s" msgstr "%s:ä¸èƒ½è§£æžçˆ¶æ交 %s" -#: sequencer.c:452 +#: sequencer.c:535 #, c-format msgid "Cannot get commit message for %s" msgstr "ä¸èƒ½å¾—到 %s çš„æ交说明" -#: sequencer.c:536 +#: sequencer.c:621 #, c-format msgid "could not revert %s... %s" msgstr "ä¸èƒ½è¿˜åŽŸ %s... %s" -#: sequencer.c:537 +#: sequencer.c:622 #, c-format msgid "could not apply %s... %s" msgstr "ä¸èƒ½åº”用 %s... %s" -#: sequencer.c:569 +#: sequencer.c:654 msgid "empty commit set passed" msgstr "æ供了空的æ交集" -#: sequencer.c:577 +#: sequencer.c:662 #, c-format msgid "git %s: failed to read the index" msgstr "git %sï¼šæ— æ³•è¯»å–索引" -#: sequencer.c:582 +#: sequencer.c:667 #, c-format msgid "git %s: failed to refresh the index" msgstr "git %sï¼šæ— æ³•åˆ·æ–°ç´¢å¼•" -#: sequencer.c:640 +#: sequencer.c:725 #, c-format msgid "Cannot %s during a %s" msgstr "æ— æ³• %s 在一个 %s 过程ä¸" -#: sequencer.c:662 +#: sequencer.c:747 #, c-format msgid "Could not parse line %d." msgstr "ä¸èƒ½è§£æžç¬¬ %d 行。" -#: sequencer.c:667 +#: sequencer.c:752 msgid "No commits parsed." msgstr "没有æ交被解æžã€‚" -#: sequencer.c:680 +#: sequencer.c:765 #, c-format msgid "Could not open %s" msgstr "ä¸èƒ½æ‰“å¼€ %s" -#: sequencer.c:684 +#: sequencer.c:769 #, c-format msgid "Could not read %s." msgstr "ä¸èƒ½è¯»å– %s。" -#: sequencer.c:691 +#: sequencer.c:776 #, c-format msgid "Unusable instruction sheet: %s" msgstr "æ— ç”¨çš„æŒ‡ä»¤è¡¨å•ï¼š%s" -#: sequencer.c:719 +#: sequencer.c:804 #, c-format msgid "Invalid key: %s" msgstr "æ— æ•ˆé”®å:%s" -#: sequencer.c:722 +#: sequencer.c:807 #, c-format msgid "Invalid value for %s: %s" msgstr "%s çš„å€¼æ— æ•ˆï¼š%s" -#: sequencer.c:734 +#: sequencer.c:819 #, c-format msgid "Malformed options sheet: %s" msgstr "éžæ³•çš„选项表å•ï¼š%s" -#: sequencer.c:755 +#: sequencer.c:840 msgid "a cherry-pick or revert is already in progress" msgstr "一个拣选或还原æ“作已在进行" -#: sequencer.c:756 +#: sequencer.c:841 msgid "try \"git cherry-pick (--continue | --quit | --abort)\"" msgstr "å°è¯• \"git cherry-pick (--continue | --quit | --abort)\"" -#: sequencer.c:760 +#: sequencer.c:845 #, c-format msgid "Could not create sequencer directory %s" msgstr "ä¸èƒ½åˆ›å»ºåºåˆ—目录 %s" -#: sequencer.c:776 sequencer.c:861 +#: sequencer.c:861 sequencer.c:946 #, c-format msgid "Error wrapping up %s." msgstr "错误收尾 %s。" -#: sequencer.c:795 sequencer.c:929 +#: sequencer.c:880 sequencer.c:1014 msgid "no cherry-pick or revert in progress" msgstr "拣选或还原æ“作并未进行" -#: sequencer.c:797 +#: sequencer.c:882 msgid "cannot resolve HEAD" msgstr "ä¸èƒ½è§£æž HEAD" -#: sequencer.c:799 +#: sequencer.c:884 msgid "cannot abort from a branch yet to be born" msgstr "ä¸èƒ½ä»Žå°šæœªå»ºç«‹çš„分支终æ¢" -#: sequencer.c:821 builtin/apply.c:4056 +#: sequencer.c:906 builtin/apply.c:4060 #, c-format msgid "cannot open %s: %s" msgstr "ä¸èƒ½æ‰“å¼€ %s:%s" -#: sequencer.c:824 +#: sequencer.c:909 #, c-format msgid "cannot read %s: %s" msgstr "ä¸èƒ½è¯»å– %s:%s" -#: sequencer.c:825 +#: sequencer.c:910 msgid "unexpected end of file" msgstr "æ„外的文件结æŸ" -#: sequencer.c:831 +#: sequencer.c:916 #, c-format msgid "stored pre-cherry-pick HEAD file '%s' is corrupt" msgstr "ä¿å˜æ‹£é€‰æ交å‰çš„ HEAD 文件 '%s' æŸå" -#: sequencer.c:854 +#: sequencer.c:939 #, c-format msgid "Could not format %s." msgstr "ä¸èƒ½æ ¼å¼åŒ– %s。" -#: sequencer.c:1016 +#: sequencer.c:1083 +#, c-format +msgid "%s: can't cherry-pick a %s" +msgstr "%s:ä¸èƒ½æ‹£é€‰ä¸€ä¸ª%s" + +#: sequencer.c:1085 +#, c-format +msgid "%s: bad revision" +msgstr "%s:错误的版本" + +#: sequencer.c:1119 msgid "Can't revert as initial commit" msgstr "ä¸èƒ½ä½œä¸ºåˆå§‹æ交还原" -#: sequencer.c:1017 +#: sequencer.c:1120 msgid "Can't cherry-pick into empty head" msgstr "ä¸èƒ½æ‹£é€‰åˆ°ç©ºåˆ†æ”¯" -#: sha1_name.c:1044 +#: sha1_name.c:1036 msgid "HEAD does not point to a branch" msgstr "HEAD 没有指å‘一个分支" -#: sha1_name.c:1047 +#: sha1_name.c:1039 #, c-format msgid "No such branch: '%s'" msgstr "没有æ¤åˆ†æ”¯ï¼š'%s'" -#: sha1_name.c:1049 +#: sha1_name.c:1041 #, c-format msgid "No upstream configured for branch '%s'" msgstr "尚未给分支 '%s' 设置上游" -#: sha1_name.c:1052 +#: sha1_name.c:1044 #, c-format msgid "Upstream branch '%s' not stored as a remote-tracking branch" msgstr "上游分支 '%s' 没有å˜å‚¨ä¸ºä¸€ä¸ªè¿œç¨‹è·Ÿè¸ªåˆ†æ”¯" @@ -1175,291 +1310,328 @@ msgid "untracked content, " msgstr "未跟踪的内容, " # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:303 +#: wt-status.c:306 #, c-format msgid "new file: %s" msgstr "新文件: %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:306 +#: wt-status.c:309 #, c-format msgid "copied: %s -> %s" msgstr "æ‹·è´ï¼š %s -> %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:309 +#: wt-status.c:312 #, c-format msgid "deleted: %s" msgstr "åˆ é™¤ï¼š %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:312 +#: wt-status.c:315 #, c-format msgid "modified: %s" msgstr "修改: %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:315 +#: wt-status.c:318 #, c-format msgid "renamed: %s -> %s" msgstr "é‡å‘½å: %s -> %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:318 +#: wt-status.c:321 #, c-format msgid "typechange: %s" msgstr "类型å˜æ›´ï¼š %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:321 +#: wt-status.c:324 #, c-format msgid "unknown: %s" msgstr "未知: %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: wt-status.c:324 +#: wt-status.c:327 #, c-format msgid "unmerged: %s" msgstr "未åˆå¹¶ï¼š %s" -#: wt-status.c:327 +#: wt-status.c:330 #, c-format msgid "bug: unhandled diff status %c" msgstr "bug:未处ç†çš„å·®å¼‚çŠ¶æ€ %c" -#: wt-status.c:789 +#: wt-status.c:803 msgid "You have unmerged paths." msgstr "您有尚未åˆå¹¶çš„路径。" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:792 wt-status.c:944 +#: wt-status.c:806 wt-status.c:958 msgid " (fix conflicts and run \"git commit\")" msgstr " (解决冲çªå¹¶è¿è¡Œ \"git commit\")" -#: wt-status.c:795 +#: wt-status.c:809 msgid "All conflicts fixed but you are still merging." msgstr "所有冲çªå·²è§£å†³ä½†æ‚¨ä»å¤„于åˆå¹¶ä¸ã€‚" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:798 +#: wt-status.c:812 msgid " (use \"git commit\" to conclude merge)" msgstr " (使用 \"git commit\" 结æŸåˆå¹¶ï¼‰" -#: wt-status.c:808 +#: wt-status.c:822 msgid "You are in the middle of an am session." msgstr "您æ£å¤„于一个 am 过程ä¸ã€‚" -#: wt-status.c:811 +#: wt-status.c:825 msgid "The current patch is empty." msgstr "当å‰çš„è¡¥ä¸ä¸ºç©ºã€‚" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:815 +#: wt-status.c:829 msgid " (fix conflicts and then run \"git am --resolved\")" msgstr " (解决冲çªï¼Œç„¶åŽè¿è¡Œ \"git am --resolved\")" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:817 +#: wt-status.c:831 msgid " (use \"git am --skip\" to skip this patch)" msgstr " (使用 \"git am --skip\" 跳过æ¤è¡¥ä¸ï¼‰" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:819 +#: wt-status.c:833 msgid " (use \"git am --abort\" to restore the original branch)" msgstr " (使用 \"git am --abort\" æ¢å¤åŽŸæœ‰åˆ†æ”¯ï¼‰" -#: wt-status.c:879 wt-status.c:896 +#: wt-status.c:893 wt-status.c:910 #, c-format msgid "You are currently rebasing branch '%s' on '%s'." msgstr "您æ£åœ¨å°†åˆ†æ”¯ '%s' å˜åŸºåˆ° '%s'。" -#: wt-status.c:884 wt-status.c:901 +#: wt-status.c:898 wt-status.c:915 msgid "You are currently rebasing." msgstr "您æ£åœ¨å˜åŸºã€‚" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:887 +#: wt-status.c:901 msgid " (fix conflicts and then run \"git rebase --continue\")" msgstr " (解决冲çªï¼Œç„¶åŽè¿è¡Œ \"git rebase --continue\")" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:889 +#: wt-status.c:903 msgid " (use \"git rebase --skip\" to skip this patch)" msgstr " (使用 \"git rebase --skip\" 跳过æ¤è¡¥ä¸ï¼‰" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:891 +#: wt-status.c:905 msgid " (use \"git rebase --abort\" to check out the original branch)" msgstr " (使用 \"git rebase --abort\" 以检出原有分支)" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:904 +#: wt-status.c:918 msgid " (all conflicts fixed: run \"git rebase --continue\")" msgstr " (所有冲çªå·²è§£å†³ï¼šè¿è¡Œ \"git rebase --continue\")" -#: wt-status.c:908 +#: wt-status.c:922 #, c-format msgid "" "You are currently splitting a commit while rebasing branch '%s' on '%s'." msgstr "您æ£åœ¨å°†åˆ†æ”¯ '%s' å˜åŸºåˆ° '%s' 过程ä¸æ‹†åˆ†ä¸€ä¸ªæ交。" -#: wt-status.c:913 +#: wt-status.c:927 msgid "You are currently splitting a commit during a rebase." msgstr "您æ£åœ¨å˜åŸºè¿‡ç¨‹ä¸æ‹†åˆ†ä¸€ä¸ªæ交。" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:916 +#: wt-status.c:930 msgid " (Once your working directory is clean, run \"git rebase --continue\")" msgstr " (一旦您工作目录æ交干净åŽï¼Œè¿è¡Œ \"git rebase --continue\")" -#: wt-status.c:920 +#: wt-status.c:934 #, c-format msgid "You are currently editing a commit while rebasing branch '%s' on '%s'." msgstr "您æ£åœ¨å°†åˆ†æ”¯ '%s' å˜åŸºåˆ° '%s' 过程ä¸ç¼–辑一个æ交。" -#: wt-status.c:925 +#: wt-status.c:939 msgid "You are currently editing a commit during a rebase." msgstr "您æ£åœ¨å˜åŸºè¿‡ç¨‹ä¸ç¼–辑一个æ交。" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:928 +#: wt-status.c:942 msgid " (use \"git commit --amend\" to amend the current commit)" msgstr " (使用 \"git commit --amend\" 修补当å‰æ交)" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:930 +#: wt-status.c:944 msgid "" " (use \"git rebase --continue\" once you are satisfied with your changes)" msgstr " (当您对您的修改满æ„åŽæ‰§è¡Œ \"git rebase --continue\")" -#: wt-status.c:940 +#: wt-status.c:954 msgid "You are currently cherry-picking." msgstr "您æ£åœ¨åšæ‹£é€‰æ“作。" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:947 +#: wt-status.c:961 msgid " (all conflicts fixed: run \"git commit\")" msgstr " (解决所有冲çªåŽï¼Œæ‰§è¡Œ \"git commit\")" -#: wt-status.c:958 +#: wt-status.c:970 #, c-format -msgid "You are currently bisecting branch '%s'." -msgstr "您æ£åœ¨åˆ†æ”¯ '%s' ä¸åšäºŒåˆ†æŸ¥æ‰¾ã€‚" +msgid "You are currently reverting commit %s." +msgstr "您æ£åœ¨å转æ交 %s 。" + +# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ +#: wt-status.c:975 +msgid " (fix conflicts and run \"git revert --continue\")" +msgstr " (解决冲çªå¹¶è¿è¡Œ \"git revert --continue\")" + +# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ +#: wt-status.c:978 +msgid " (all conflicts fixed: run \"git revert --continue\")" +msgstr " (所有冲çªå·²è§£å†³ï¼šè¿è¡Œ \"git revert --continue\")" + +# 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ +#: wt-status.c:980 +msgid " (use \"git revert --abort\" to cancel the revert operation)" +msgstr " (使用 \"git revert --abort\" 以å–消å转æ交æ“作)" -#: wt-status.c:962 +#: wt-status.c:991 +#, c-format +msgid "You are currently bisecting, started from branch '%s'." +msgstr "您æ£åœ¨ä»Žåˆ†æ”¯ '%s' 开始åšäºŒåˆ†æŸ¥æ‰¾ã€‚" + +#: wt-status.c:995 msgid "You are currently bisecting." msgstr "您æ£åœ¨åšäºŒåˆ†æŸ¥æ‰¾ã€‚" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: wt-status.c:965 +#: wt-status.c:998 msgid " (use \"git bisect reset\" to get back to the original branch)" msgstr " (使用 \"git bisect reset\" 以回到原有分支)" -#: wt-status.c:1064 +#: wt-status.c:1173 msgid "On branch " msgstr "ä½äºŽåˆ†æ”¯ " -#: wt-status.c:1071 +#: wt-status.c:1184 +msgid "HEAD detached at " +msgstr "头指针分离于 " + +#: wt-status.c:1186 +msgid "HEAD detached from " +msgstr "头指针分离自 " + +#: wt-status.c:1189 msgid "Not currently on any branch." msgstr "当å‰ä¸åœ¨ä»»ä½•åˆ†æ”¯ä¸Šã€‚" -#: wt-status.c:1083 +#: wt-status.c:1206 msgid "Initial commit" msgstr "åˆå§‹æ交" -#: wt-status.c:1097 +#: wt-status.c:1220 msgid "Untracked files" msgstr "未跟踪的文件" -#: wt-status.c:1099 +#: wt-status.c:1222 msgid "Ignored files" msgstr "忽略的文件" -#: wt-status.c:1101 +#: wt-status.c:1226 +#, c-format +msgid "" +"It took %.2f seconds to enumerate untracked files. 'status -uno'\n" +"may speed it up, but you have to be careful not to forget to add\n" +"new files yourself (see 'git help status')." +msgstr "" +"耗费了 %.2f 秒以枚举未跟踪的文件。'status -uno' 也许能æ高速度,\n" +"但您需è¦å°å¿ƒä¸è¦å¿˜äº†æ·»åŠ 新文件(å‚è§ 'git help status')。" + +#: wt-status.c:1232 #, c-format msgid "Untracked files not listed%s" msgstr "未跟踪的文件没有列出%s" # 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: wt-status.c:1103 +#: wt-status.c:1234 msgid " (use -u option to show untracked files)" msgstr "(使用 -u å‚数显示未跟踪的文件)" -#: wt-status.c:1109 +#: wt-status.c:1240 msgid "No changes" msgstr "没有修改" -# 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: wt-status.c:1114 +#: wt-status.c:1245 #, c-format msgid "no changes added to commit (use \"git add\" and/or \"git commit -a\")\n" msgstr "ä¿®æ”¹å°šæœªåŠ å…¥æ交(使用 \"git add\" å’Œ/或 \"git commit -a\")\n" -#: wt-status.c:1117 +#: wt-status.c:1248 #, c-format msgid "no changes added to commit\n" msgstr "ä¿®æ”¹å°šæœªåŠ å…¥æ交\n" -#: wt-status.c:1120 +#: wt-status.c:1251 #, c-format msgid "" "nothing added to commit but untracked files present (use \"git add\" to " "track)\n" msgstr "æ交为空,但是å˜åœ¨å°šæœªè·Ÿè¸ªçš„文件(使用 \"git add\" 建立跟踪)\n" -#: wt-status.c:1123 +#: wt-status.c:1254 #, c-format msgid "nothing added to commit but untracked files present\n" msgstr "æ交为空,但是å˜åœ¨å°šæœªè·Ÿè¸ªçš„文件\n" # 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: wt-status.c:1126 +#: wt-status.c:1257 #, c-format msgid "nothing to commit (create/copy files and use \"git add\" to track)\n" msgstr "æ— æ–‡ä»¶è¦æ交(创建/æ‹·è´æ–‡ä»¶å¹¶ä½¿ç”¨ \"git add\" 建立跟踪)\n" -#: wt-status.c:1129 wt-status.c:1134 +#: wt-status.c:1260 wt-status.c:1265 #, c-format msgid "nothing to commit\n" msgstr "æ— æ–‡ä»¶è¦æ交\n" # 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: wt-status.c:1132 +#: wt-status.c:1263 #, c-format msgid "nothing to commit (use -u to show untracked files)\n" msgstr "æ— æ–‡ä»¶è¦æ交(使用 -u 显示未跟踪的文件)\n" # 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: wt-status.c:1136 +#: wt-status.c:1267 #, c-format msgid "nothing to commit, working directory clean\n" msgstr "æ— æ–‡ä»¶è¦æ交,干净的工作区\n" -#: wt-status.c:1244 +#: wt-status.c:1375 msgid "HEAD (no branch)" msgstr "HEAD(éžåˆ†æ”¯ï¼‰" # 译者:注æ„ä¿æŒå¥å°¾ç©ºæ ¼ -#: wt-status.c:1250 +#: wt-status.c:1381 msgid "Initial commit on " msgstr "åˆå§‹æ交于 " # 译者:注æ„ä¿æŒå¥å°¾ç©ºæ ¼ -#: wt-status.c:1265 +#: wt-status.c:1396 msgid "behind " msgstr "è½åŽ " # 译者:注æ„ä¿æŒå¥å°¾ç©ºæ ¼ -#: wt-status.c:1268 wt-status.c:1271 +#: wt-status.c:1399 wt-status.c:1402 msgid "ahead " msgstr "领先 " # 译者:注æ„ä¿æŒå¥å°¾ç©ºæ ¼ -#: wt-status.c:1273 +#: wt-status.c:1404 msgid ", behind " msgstr ",è½åŽ " -#: compat/precompose_utf8.c:58 builtin/clone.c:341 +#: compat/precompose_utf8.c:58 builtin/clone.c:352 #, c-format msgid "failed to unlink '%s'" msgstr "æ— æ³•åˆ é™¤ '%s'" @@ -1468,193 +1640,225 @@ msgstr "æ— æ³•åˆ é™¤ '%s'" msgid "git add [options] [--] <pathspec>..." msgstr "git add [选项] [--] <路径匹é…>..." -#: builtin/add.c:63 +# 译者:å—符串首行行首è¦æ·»åŠ “warning: â€å—串,故æ¤é¦–è¡Œè¦è¾ƒå…¶ä½™è¡ŒçŸ +#. +#. * To be consistent with "git add -p" and most Git +#. * commands, we should default to being tree-wide, but +#. * this is not the original behavior and can't be +#. * changed until users trained themselves not to type +#. * "git add -u" or "git add -A". For now, we warn and +#. * keep the old behavior. Later, the behavior can be changed +#. * to tree-wide, keeping the warning for a while, and +#. * eventually we can drop the warning. +#. +#: builtin/add.c:58 +#, c-format +msgid "" +"The behavior of 'git add %s (or %s)' with no path argument from a\n" +"subdirectory of the tree will change in Git 2.0 and should not be used " +"anymore.\n" +"To add content for the whole tree, run:\n" +"\n" +" git add %s :/\n" +" (or git add %s :/)\n" +"\n" +"To restrict the command to the current directory, run:\n" +"\n" +" git add %s .\n" +" (or git add %s .)\n" +"\n" +"With the current Git version, the command is restricted to the current " +"directory.\n" +msgstr "" +"在 Git 2.0 版本,ä½äºŽä¸€ä¸ªå目录下ä¸å¸¦ä»»ä½•è·¯å¾„å‚数地执行命令\n" +"'git add %s (或 %s)' 的行为将被改å˜ï¼Œä¸è¦å†ç»§ç»ä½¿ç”¨äº†ã€‚\n" +"如果è¦æ·»åŠ æ•´ä¸ªç›®å½•æ ‘çš„å†…å®¹ï¼Œæ‰§è¡Œï¼š\n" +"\n" +" git add %s :/\n" +" (或 git add %s :/)\n" +"\n" +"如果è¦é™åˆ¶è¯¥å‘½ä»¤åªä½œç”¨äºŽå½“å‰ç›®å½•ï¼Œæ‰§è¡Œï¼š\n" +"\n" +" git add %s .\n" +" (或 git add %s .)\n" +"\n" +"对于当å‰ç‰ˆæœ¬çš„ Git,这æ¡å‘½ä»¤åªä½œç”¨äºŽå½“å‰ç›®å½•ã€‚\n" + +#: builtin/add.c:100 +#, c-format +msgid "" +"You ran 'git add' with neither '-A (--all)' or '--ignore-removal',\n" +"whose behaviour will change in Git 2.0 with respect to paths you removed.\n" +"Paths like '%s' that are\n" +"removed from your working tree are ignored with this version of Git.\n" +"\n" +"* 'git add --ignore-removal <pathspec>', which is the current default,\n" +" ignores paths you removed from your working tree.\n" +"\n" +"* 'git add --all <pathspec>' will let you also record the removals.\n" +"\n" +"Run 'git status' to check the paths you removed from your working tree.\n" +msgstr "" +"您在è¿è¡Œ 'git add' 时没有指定 '-A (--all)' 或 '--ignore-removal',\n" +"针对其ä¸æœ¬åœ°ç§»é™¤è·¯å¾„的行为将在 Git 2.0 版本库å‘生å˜åŒ–。\n" +"åƒæœ¬åœ°å·¥ä½œåŒºç§»é™¤çš„路径 '%s'\n" +"在æ¤ç‰ˆæœ¬çš„ Git ä¸è¢«å¿½ç•¥ã€‚\n" +"\n" +"* 'git add --ignore-removal <pathspec>',是当å‰ç‰ˆæœ¬çš„默认æ“作,\n" +" 忽略您本地工作区ä¸ç§»é™¤çš„文件。\n" +"\n" +"* 'git add --all <pathspec>' 将让您åŒæ—¶å¯¹åˆ 除æ“作进行记录。\n" +"\n" +"è¿è¡Œ 'git status' æ¥æ£€æŸ¥æ‚¨æœ¬åœ°å·¥ä½œåŒºä¸ç§»é™¤çš„路径。\n" + +#: builtin/add.c:144 #, c-format msgid "unexpected diff status %c" msgstr "æ„å¤–çš„å·®å¼‚çŠ¶æ€ %c" -#: builtin/add.c:68 builtin/commit.c:231 +#: builtin/add.c:149 builtin/commit.c:233 msgid "updating files failed" msgstr "更新文件失败" -#: builtin/add.c:78 +#: builtin/add.c:163 #, c-format msgid "remove '%s'\n" msgstr "åˆ é™¤ '%s'\n" -#: builtin/add.c:148 +#: builtin/add.c:253 msgid "Unstaged changes after refreshing the index:" msgstr "刷新索引之åŽå°šæœªè¢«æš‚å˜çš„å˜æ›´ï¼š" -#: builtin/add.c:151 builtin/add.c:460 builtin/rm.c:275 +#: builtin/add.c:256 builtin/add.c:572 builtin/rm.c:275 #, c-format msgid "pathspec '%s' did not match any files" msgstr "路径 '%s' 未匹é…任何文件" -#: builtin/add.c:234 +#: builtin/add.c:339 msgid "Could not read the index" msgstr "ä¸èƒ½è¯»å–索引" -#: builtin/add.c:244 +#: builtin/add.c:349 #, c-format msgid "Could not open '%s' for writing." msgstr "ä¸èƒ½æ‰“å¼€ '%s' 以写入。" -#: builtin/add.c:248 +#: builtin/add.c:353 msgid "Could not write patch" msgstr "ä¸èƒ½ç”Ÿæˆè¡¥ä¸" -#: builtin/add.c:253 +#: builtin/add.c:358 #, c-format msgid "Could not stat '%s'" msgstr "ä¸èƒ½æŸ¥çœ‹æ–‡ä»¶çŠ¶æ€ '%s'" -#: builtin/add.c:255 +#: builtin/add.c:360 msgid "Empty patch. Aborted." msgstr "空补ä¸ã€‚异常终æ¢ã€‚" -#: builtin/add.c:261 +#: builtin/add.c:366 #, c-format msgid "Could not apply '%s'" msgstr "ä¸èƒ½åº”用 '%s'" -#: builtin/add.c:271 +#: builtin/add.c:376 msgid "The following paths are ignored by one of your .gitignore files:\n" msgstr "ä¸‹åˆ—è·¯å¾„æ ¹æ®æ‚¨çš„一个 .gitignore 文件而被忽略:\n" -#: builtin/add.c:277 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 +#: builtin/add.c:393 builtin/clean.c:161 builtin/fetch.c:78 builtin/mv.c:63 #: builtin/prune-packed.c:76 builtin/push.c:425 builtin/remote.c:1253 #: builtin/rm.c:206 msgid "dry run" msgstr "æ¼”ä¹ " -#: builtin/add.c:278 builtin/apply.c:4405 builtin/check-ignore.c:19 -#: builtin/commit.c:1150 builtin/count-objects.c:82 builtin/fsck.c:613 -#: builtin/log.c:1522 builtin/mv.c:62 builtin/read-tree.c:112 +#: builtin/add.c:394 builtin/apply.c:4409 builtin/check-ignore.c:19 +#: builtin/commit.c:1152 builtin/count-objects.c:95 builtin/fsck.c:613 +#: builtin/log.c:1518 builtin/mv.c:62 builtin/read-tree.c:112 msgid "be verbose" msgstr "冗长输出" -#: builtin/add.c:280 +#: builtin/add.c:396 msgid "interactive picking" msgstr "交互å¼æ‹£é€‰" -#: builtin/add.c:281 builtin/checkout.c:1031 builtin/reset.c:258 +#: builtin/add.c:397 builtin/checkout.c:1063 builtin/reset.c:258 msgid "select hunks interactively" msgstr "交互å¼æŒ‘选数æ®å—" -#: builtin/add.c:282 +#: builtin/add.c:398 msgid "edit current diff and apply" msgstr "编辑当å‰å·®å¼‚并应用" -#: builtin/add.c:283 +#: builtin/add.c:399 msgid "allow adding otherwise ignored files" msgstr "å…è®¸æ·»åŠ å¿½ç•¥çš„æ–‡ä»¶" -#: builtin/add.c:284 +#: builtin/add.c:400 msgid "update tracked files" msgstr "更新已跟踪的文件" -#: builtin/add.c:285 +#: builtin/add.c:401 msgid "record only the fact that the path will be added later" msgstr "åªè®°å½•ï¼Œè¯¥è·¯å¾„ç¨åŽå†æ·»åŠ " -#: builtin/add.c:286 +#: builtin/add.c:402 msgid "add changes from all tracked and untracked files" msgstr "æ·»åŠ æ‰€æœ‰æ”¹å˜çš„已跟踪文件和未跟踪文件" -#: builtin/add.c:287 +#. takes no arguments +#: builtin/add.c:405 +msgid "ignore paths removed in the working tree (same as --no-all)" +msgstr "忽略工作区ä¸ç§»é™¤çš„路径(和 --no-all 相åŒï¼‰" + +#: builtin/add.c:407 msgid "don't add, only refresh the index" msgstr "ä¸æ·»åŠ ,åªåˆ·æ–°ç´¢å¼•" -#: builtin/add.c:288 +#: builtin/add.c:408 msgid "just skip files which cannot be added because of errors" msgstr "è·³è¿‡å› å‡ºé”™ä¸èƒ½æ·»åŠ 的文件" -#: builtin/add.c:289 +#: builtin/add.c:409 msgid "check if - even missing - files are ignored in dry run" msgstr "æ£€æŸ¥åœ¨æ¼”ä¹ æ¨¡å¼ä¸‹æ–‡ä»¶ï¼ˆå³ä½¿ä¸å˜åœ¨ï¼‰æ˜¯å¦è¢«å¿½ç•¥" -#: builtin/add.c:311 +#: builtin/add.c:431 #, c-format msgid "Use -f if you really want to add them.\n" msgstr "使用 -f å‚数如果您确实è¦æ·»åŠ 它们。\n" -#: builtin/add.c:312 +#: builtin/add.c:432 msgid "no files added" msgstr "æ²¡æœ‰æ–‡ä»¶è¢«æ·»åŠ " -#: builtin/add.c:318 +#: builtin/add.c:438 msgid "adding files failed" msgstr "æ·»åŠ æ–‡ä»¶å¤±è´¥" -# 译者:å—符串首行行首è¦æ·»åŠ “warning: â€å—串,故æ¤é¦–è¡Œè¦è¾ƒå…¶ä½™è¡ŒçŸ -#. -#. * To be consistent with "git add -p" and most Git -#. * commands, we should default to being tree-wide, but -#. * this is not the original behavior and can't be -#. * changed until users trained themselves not to type -#. * "git add -u" or "git add -A". For now, we warn and -#. * keep the old behavior. Later, this warning can be -#. * turned into a die(...), and eventually we may -#. * reallow the command with a new behavior. -#. -#: builtin/add.c:335 -#, c-format -msgid "" -"The behavior of 'git add %s (or %s)' with no path argument from a\n" -"subdirectory of the tree will change in Git 2.0 and should not be used " -"anymore.\n" -"To add content for the whole tree, run:\n" -"\n" -" git add %s :/\n" -" (or git add %s :/)\n" -"\n" -"To restrict the command to the current directory, run:\n" -"\n" -" git add %s .\n" -" (or git add %s .)\n" -"\n" -"With the current Git version, the command is restricted to the current " -"directory." -msgstr "" -"在 Git 2.0 版本,将ä¸å†å…许在一个å目录下ä¸å¸¦ä»»ä½•è·¯å¾„å‚数地执行\n" -"命令 'git add %s (或 %s)'。所以ä¸è¦å†ç»§ç»ä½¿ç”¨äº†ã€‚\n" -"如果è¦æ·»åŠ æ•´ä¸ªç›®å½•æ ‘çš„å†…å®¹ï¼Œæ‰§è¡Œï¼š\n" -"\n" -" git add %s :/\n" -" (或 git add %s :/)\n" -"\n" -"如果è¦é™åˆ¶è¯¥å‘½ä»¤åªä½œç”¨äºŽå½“å‰ç›®å½•ï¼Œæ‰§è¡Œï¼š\n" -"\n" -" git add %s .\n" -" (或 git add %s .)\n" -"\n" -"对于当å‰ç‰ˆæœ¬çš„ Git,这æ¡å‘½ä»¤åªä½œç”¨äºŽå½“å‰ç›®å½•ã€‚" - -#: builtin/add.c:381 +#: builtin/add.c:477 msgid "-A and -u are mutually incompatible" msgstr "-A å’Œ -u 选项互斥" -#: builtin/add.c:383 +#: builtin/add.c:495 msgid "Option --ignore-missing can only be used together with --dry-run" msgstr "选项 --ignore-missing åªèƒ½å’Œ --dry-run åŒæ—¶ä½¿ç”¨" -#: builtin/add.c:414 +#: builtin/add.c:525 #, c-format msgid "Nothing specified, nothing added.\n" msgstr "æ²¡æœ‰æŒ‡å®šæ–‡ä»¶ï¼Œä¹Ÿæ²¡æœ‰æ–‡ä»¶è¢«æ·»åŠ ã€‚\n" -#: builtin/add.c:415 +#: builtin/add.c:526 #, c-format msgid "Maybe you wanted to say 'git add .'?\n" msgstr "也许您想è¦æ‰§è¡Œ 'git add .'?\n" -#: builtin/add.c:421 builtin/check-ignore.c:67 builtin/clean.c:204 -#: builtin/commit.c:291 builtin/mv.c:82 builtin/rm.c:235 +#: builtin/add.c:532 builtin/check-ignore.c:66 builtin/clean.c:204 +#: builtin/commit.c:293 builtin/mv.c:82 builtin/rm.c:235 msgid "index file corrupt" msgstr "索引文件æŸå" -#: builtin/add.c:481 builtin/apply.c:4501 builtin/mv.c:229 builtin/rm.c:370 +#: builtin/add.c:604 builtin/apply.c:4505 builtin/mv.c:229 builtin/rm.c:370 msgid "Unable to write new index file" msgstr "æ— æ³•å†™å…¥æ–°ç´¢å¼•æ–‡ä»¶" @@ -1782,24 +1986,24 @@ msgstr "æ— æ³•è¯»å–符å·é“¾æŽ¥ %s" msgid "unable to open or read %s" msgstr "ä¸èƒ½æ‰“å¼€æˆ–è¯»å– %s" -#: builtin/apply.c:2684 +#: builtin/apply.c:2688 #, c-format msgid "invalid start of line: '%c'" msgstr "æ— æ•ˆçš„è¡Œé¦–å—符:'%c'" -#: builtin/apply.c:2802 +#: builtin/apply.c:2806 #, c-format msgid "Hunk #%d succeeded at %d (offset %d line)." msgid_plural "Hunk #%d succeeded at %d (offset %d lines)." msgstr[0] "å— #%d æˆåŠŸåº”用于 %d(å移 %d 行)" msgstr[1] "å— #%d æˆåŠŸåº”用于 %d(å移 %d 行)" -#: builtin/apply.c:2814 +#: builtin/apply.c:2818 #, c-format msgid "Context reduced to (%ld/%ld) to apply fragment at %d" msgstr "上下文å‡å°‘到(%ld/%ld)以在第 %d 行应用补ä¸ç‰‡æ®µ" -#: builtin/apply.c:2820 +#: builtin/apply.c:2824 #, c-format msgid "" "while searching for:\n" @@ -1808,318 +2012,318 @@ msgstr "" "当查询:\n" "%.*s" -#: builtin/apply.c:2839 +#: builtin/apply.c:2843 #, c-format msgid "missing binary patch data for '%s'" msgstr "缺失 '%s' 的二进制补ä¸æ•°æ®" -#: builtin/apply.c:2942 +#: builtin/apply.c:2946 #, c-format msgid "binary patch does not apply to '%s'" msgstr "二进制补ä¸æœªåº”用到 '%s'" -#: builtin/apply.c:2948 +#: builtin/apply.c:2952 #, c-format msgid "binary patch to '%s' creates incorrect result (expecting %s, got %s)" msgstr "到 '%s' 的二进制补ä¸äº§ç”Ÿäº†ä¸æ£ç¡®çš„结果(应为 %s,å´ä¸º %s)" -#: builtin/apply.c:2969 +#: builtin/apply.c:2973 #, c-format msgid "patch failed: %s:%ld" msgstr "打补ä¸å¤±è´¥ï¼š%s:%ld" -#: builtin/apply.c:3091 +#: builtin/apply.c:3095 #, c-format msgid "cannot checkout %s" msgstr "ä¸èƒ½æ£€å‡º %s" -#: builtin/apply.c:3136 builtin/apply.c:3145 builtin/apply.c:3189 +#: builtin/apply.c:3140 builtin/apply.c:3149 builtin/apply.c:3193 #, c-format msgid "read of %s failed" msgstr "è¯»å– %s 失败" -#: builtin/apply.c:3169 builtin/apply.c:3391 +#: builtin/apply.c:3173 builtin/apply.c:3395 #, c-format msgid "path %s has been renamed/deleted" msgstr "路径 %s å·²ç»è¢«é‡å‘½å/åˆ é™¤" -#: builtin/apply.c:3250 builtin/apply.c:3405 +#: builtin/apply.c:3254 builtin/apply.c:3409 #, c-format msgid "%s: does not exist in index" msgstr "%s:ä¸å˜åœ¨äºŽç´¢å¼•ä¸" -#: builtin/apply.c:3254 builtin/apply.c:3397 builtin/apply.c:3419 +#: builtin/apply.c:3258 builtin/apply.c:3401 builtin/apply.c:3423 #, c-format msgid "%s: %s" msgstr "%s:%s" -#: builtin/apply.c:3259 builtin/apply.c:3413 +#: builtin/apply.c:3263 builtin/apply.c:3417 #, c-format msgid "%s: does not match index" msgstr "%s:和索引ä¸åŒ¹é…" -#: builtin/apply.c:3361 +#: builtin/apply.c:3365 msgid "removal patch leaves file contents" msgstr "移除补ä¸ä»ç•™ä¸‹äº†æ–‡ä»¶å†…容" -#: builtin/apply.c:3430 +#: builtin/apply.c:3434 #, c-format msgid "%s: wrong type" msgstr "%s:错误类型" -#: builtin/apply.c:3432 +#: builtin/apply.c:3436 #, c-format msgid "%s has type %o, expected %o" msgstr "%s 的类型是 %o,应为 %o" -#: builtin/apply.c:3533 +#: builtin/apply.c:3537 #, c-format msgid "%s: already exists in index" msgstr "%s:已ç»å˜åœ¨äºŽç´¢å¼•ä¸" -#: builtin/apply.c:3536 +#: builtin/apply.c:3540 #, c-format msgid "%s: already exists in working directory" msgstr "%s:已ç»å˜åœ¨äºŽå·¥ä½œåŒºä¸" -#: builtin/apply.c:3556 +#: builtin/apply.c:3560 #, c-format msgid "new mode (%o) of %s does not match old mode (%o)" msgstr "%2$s 的新模å¼ï¼ˆ%1$o)和旧模å¼ï¼ˆ%3$o)ä¸åŒ¹é…" -#: builtin/apply.c:3561 +#: builtin/apply.c:3565 #, c-format msgid "new mode (%o) of %s does not match old mode (%o) of %s" msgstr "%2$s 的新模å¼ï¼ˆ%1$o)和 %4$s 的旧模å¼ï¼ˆ%3$o)ä¸åŒ¹é…" -#: builtin/apply.c:3569 +#: builtin/apply.c:3573 #, c-format msgid "%s: patch does not apply" msgstr "%s:补ä¸æœªåº”用" -#: builtin/apply.c:3582 +#: builtin/apply.c:3586 #, c-format msgid "Checking patch %s..." msgstr "æ£€æŸ¥è¡¥ä¸ %s..." -#: builtin/apply.c:3675 builtin/checkout.c:215 builtin/reset.c:124 +#: builtin/apply.c:3679 builtin/checkout.c:216 builtin/reset.c:124 #, c-format msgid "make_cache_entry failed for path '%s'" msgstr "对路径 '%s' çš„ make_cache_entry æ“作失败" -#: builtin/apply.c:3818 +#: builtin/apply.c:3822 #, c-format msgid "unable to remove %s from index" msgstr "ä¸èƒ½ä»Žç´¢å¼•ä¸ç§»é™¤ %s" -#: builtin/apply.c:3846 +#: builtin/apply.c:3850 #, c-format msgid "corrupt patch for subproject %s" msgstr "å项目 %s æŸåçš„è¡¥ä¸" -#: builtin/apply.c:3850 +#: builtin/apply.c:3854 #, c-format msgid "unable to stat newly created file '%s'" msgstr "ä¸èƒ½æžšä¸¾æ–°å»ºæ–‡ä»¶ '%s' 的状æ€" -#: builtin/apply.c:3855 +#: builtin/apply.c:3859 #, c-format msgid "unable to create backing store for newly created file %s" msgstr "ä¸èƒ½ä¸ºæ–°å»ºæ–‡ä»¶ %s 创建åŽç«¯å˜å‚¨" -#: builtin/apply.c:3858 builtin/apply.c:3966 +#: builtin/apply.c:3862 builtin/apply.c:3970 #, c-format msgid "unable to add cache entry for %s" msgstr "æ— æ³•ä¸º %s æ·»åŠ ç¼“å˜æ¡ç›®" -#: builtin/apply.c:3891 +#: builtin/apply.c:3895 #, c-format msgid "closing file '%s'" msgstr "å…³é—文件 '%s'" -#: builtin/apply.c:3940 +#: builtin/apply.c:3944 #, c-format msgid "unable to write file '%s' mode %o" msgstr "ä¸èƒ½å†™æ–‡ä»¶ '%s' æƒé™ %o" -#: builtin/apply.c:4027 +#: builtin/apply.c:4031 #, c-format msgid "Applied patch %s cleanly." msgstr "æˆåŠŸåº”ç”¨è¡¥ä¸ %s。" -#: builtin/apply.c:4035 +#: builtin/apply.c:4039 msgid "internal error" msgstr "内部错误" #. Say this even without --verbose -#: builtin/apply.c:4038 +#: builtin/apply.c:4042 #, c-format msgid "Applying patch %%s with %d reject..." msgid_plural "Applying patch %%s with %d rejects..." msgstr[0] "应用 %%s 个补ä¸ï¼Œå…¶ä¸ %d 个被拒ç»..." msgstr[1] "应用 %%s 个补ä¸ï¼Œå…¶ä¸ %d 个被拒ç»..." -#: builtin/apply.c:4048 +#: builtin/apply.c:4052 #, c-format msgid "truncating .rej filename to %.*s.rej" msgstr "æˆªçŸ .rej 文件å为 %.*s.rej" -#: builtin/apply.c:4069 +#: builtin/apply.c:4073 #, c-format msgid "Hunk #%d applied cleanly." msgstr "第 #%d 个片段æˆåŠŸåº”用。" -#: builtin/apply.c:4072 +#: builtin/apply.c:4076 #, c-format msgid "Rejected hunk #%d." msgstr "æ‹’ç»ç¬¬ #%d 个片段。" -#: builtin/apply.c:4222 +#: builtin/apply.c:4226 msgid "unrecognized input" msgstr "未能识别的输入" -#: builtin/apply.c:4233 +#: builtin/apply.c:4237 msgid "unable to read index file" msgstr "æ— æ³•è¯»å–索引文件" -#: builtin/apply.c:4352 builtin/apply.c:4355 builtin/clone.c:91 +#: builtin/apply.c:4356 builtin/apply.c:4359 builtin/clone.c:92 #: builtin/fetch.c:63 msgid "path" msgstr "路径" -#: builtin/apply.c:4353 +#: builtin/apply.c:4357 msgid "don't apply changes matching the given path" msgstr "ä¸è¦åº”用与给出路径å‘匹é…çš„å˜æ›´" -#: builtin/apply.c:4356 +#: builtin/apply.c:4360 msgid "apply changes matching the given path" msgstr "应用与给出路径å‘匹é…çš„å˜æ›´" -#: builtin/apply.c:4358 +#: builtin/apply.c:4362 msgid "num" msgstr "æ•°å—" -#: builtin/apply.c:4359 +#: builtin/apply.c:4363 msgid "remove <num> leading slashes from traditional diff paths" msgstr "ä»Žä¼ ç»Ÿçš„ diff 路径ä¸ç§»é™¤æŒ‡å®šæ•°é‡çš„å‰å¯¼æ–œçº¿" -#: builtin/apply.c:4362 +#: builtin/apply.c:4366 msgid "ignore additions made by the patch" msgstr "忽略补ä¸ä¸çš„æ·»åŠ çš„æ–‡ä»¶" -#: builtin/apply.c:4364 +#: builtin/apply.c:4368 msgid "instead of applying the patch, output diffstat for the input" msgstr "ä¸åº”用补ä¸ï¼Œè€Œæ˜¯æ˜¾ç¤ºè¾“入的差异统计(diffstat)" -#: builtin/apply.c:4368 +#: builtin/apply.c:4372 msgid "show number of added and deleted lines in decimal notation" msgstr "以åè¿›åˆ¶æ•°æ˜¾ç¤ºæ·»åŠ å’Œåˆ é™¤çš„è¡Œæ•°" -#: builtin/apply.c:4370 +#: builtin/apply.c:4374 msgid "instead of applying the patch, output a summary for the input" msgstr "ä¸åº”用补ä¸ï¼Œè€Œæ˜¯æ˜¾ç¤ºè¾“入的概è¦" -#: builtin/apply.c:4372 +#: builtin/apply.c:4376 msgid "instead of applying the patch, see if the patch is applicable" msgstr "ä¸åº”用补ä¸ï¼Œè€Œæ˜¯æŸ¥çœ‹è¡¥ä¸æ˜¯å¦å¯åº”用" -#: builtin/apply.c:4374 +#: builtin/apply.c:4378 msgid "make sure the patch is applicable to the current index" msgstr "确认补ä¸å¯ä»¥åº”用到当å‰ç´¢å¼•" -#: builtin/apply.c:4376 +#: builtin/apply.c:4380 msgid "apply a patch without touching the working tree" msgstr "应用补ä¸è€Œä¸ä¿®æ”¹å·¥ä½œåŒº" -#: builtin/apply.c:4378 +#: builtin/apply.c:4382 msgid "also apply the patch (use with --stat/--summary/--check)" msgstr "还应用æ¤è¡¥ä¸ï¼ˆä¸Ž --stat/--summary/--check 选项åŒæ—¶ä½¿ç”¨ï¼‰" -#: builtin/apply.c:4380 +#: builtin/apply.c:4384 msgid "attempt three-way merge if a patch does not apply" msgstr "如果一个补ä¸ä¸èƒ½åº”用则å°è¯•ä¸‰è·¯åˆå¹¶" -#: builtin/apply.c:4382 +#: builtin/apply.c:4386 msgid "build a temporary index based on embedded index information" msgstr "创建一个临时索引基于嵌入的索引信æ¯" -#: builtin/apply.c:4384 builtin/checkout-index.c:197 builtin/ls-files.c:463 +#: builtin/apply.c:4388 builtin/checkout-index.c:197 builtin/ls-files.c:456 msgid "paths are separated with NUL character" msgstr "路径以 NUL å—符分隔" -#: builtin/apply.c:4387 +#: builtin/apply.c:4391 msgid "ensure at least <n> lines of context match" msgstr "ç¡®ä¿è‡³å°‘åŒ¹é… <n> 行上下文" -#: builtin/apply.c:4388 +#: builtin/apply.c:4392 msgid "action" msgstr "动作" -#: builtin/apply.c:4389 +#: builtin/apply.c:4393 msgid "detect new or modified lines that have whitespace errors" msgstr "检查新增和修改的行ä¸é—´çš„空白å—符滥用" -#: builtin/apply.c:4392 builtin/apply.c:4395 +#: builtin/apply.c:4396 builtin/apply.c:4399 msgid "ignore changes in whitespace when finding context" msgstr "查找上下文时忽略空白å—符的å˜æ›´" -#: builtin/apply.c:4398 +#: builtin/apply.c:4402 msgid "apply the patch in reverse" msgstr "åå‘应用补ä¸" -#: builtin/apply.c:4400 +#: builtin/apply.c:4404 msgid "don't expect at least one line of context" msgstr "æ— éœ€è‡³å°‘ä¸€è¡Œä¸Šä¸‹æ–‡" -#: builtin/apply.c:4402 +#: builtin/apply.c:4406 msgid "leave the rejected hunks in corresponding *.rej files" msgstr "将拒ç»çš„è¡¥ä¸ç‰‡æ®µä¿å˜åœ¨å¯¹åº”çš„ *.rej 文件ä¸" -#: builtin/apply.c:4404 +#: builtin/apply.c:4408 msgid "allow overlapping hunks" msgstr "å…许é‡å çš„è¡¥ä¸ç‰‡æ®µ" -#: builtin/apply.c:4407 +#: builtin/apply.c:4411 msgid "tolerate incorrectly detected missing new-line at the end of file" msgstr "å…许ä¸æ£ç¡®çš„文件末尾æ¢è¡Œç¬¦" -#: builtin/apply.c:4410 +#: builtin/apply.c:4414 msgid "do not trust the line counts in the hunk headers" msgstr "ä¸ä¿¡ä»»è¡¥ä¸ç‰‡æ®µçš„头信æ¯ä¸çš„è¡Œå·" -#: builtin/apply.c:4412 +#: builtin/apply.c:4416 msgid "root" msgstr "æ ¹ç›®å½•" -#: builtin/apply.c:4413 +#: builtin/apply.c:4417 msgid "prepend <root> to all filenames" msgstr "为所有文件åå‰æ·»åŠ <æ ¹ç›®å½•>" -#: builtin/apply.c:4435 +#: builtin/apply.c:4439 msgid "--3way outside a repository" msgstr "--3way 在一个版本库之外" -#: builtin/apply.c:4443 +#: builtin/apply.c:4447 msgid "--index outside a repository" msgstr "--index 在一个版本库之外" -#: builtin/apply.c:4446 +#: builtin/apply.c:4450 msgid "--cached outside a repository" msgstr "--cached 在一个版本库之外" -#: builtin/apply.c:4462 +#: builtin/apply.c:4466 #, c-format msgid "can't open patch '%s'" msgstr "ä¸èƒ½æ‰“å¼€è¡¥ä¸ '%s'" -#: builtin/apply.c:4476 +#: builtin/apply.c:4480 #, c-format msgid "squelched %d whitespace error" msgid_plural "squelched %d whitespace errors" msgstr[0] "抑制下ä»æœ‰ %d 个空白å—符误用" msgstr[1] "抑制下ä»æœ‰ %d 个空白å—符误用" -#: builtin/apply.c:4482 builtin/apply.c:4492 +#: builtin/apply.c:4486 builtin/apply.c:4496 #, c-format msgid "%d line adds whitespace errors." msgid_plural "%d lines add whitespace errors." @@ -2143,21 +2347,21 @@ msgstr "git archive:未æ供远程URL" msgid "git archive: expected ACK/NAK, got EOF" msgstr "git archive:应为ACK/NACK,å´å¾—到EOF" -#: builtin/archive.c:63 +#: builtin/archive.c:61 #, c-format msgid "git archive: NACK %s" msgstr "git archive:NACK %s" -#: builtin/archive.c:65 +#: builtin/archive.c:63 #, c-format msgid "remote error: %s" msgstr "远程错误:%s" -#: builtin/archive.c:66 +#: builtin/archive.c:64 msgid "git archive: protocol error" msgstr "git archive:å议错误" -#: builtin/archive.c:71 +#: builtin/archive.c:68 msgid "git archive: expected a flush" msgstr "git archive:应为刷新" @@ -2177,120 +2381,120 @@ msgstr "æ›´æ–° BISECT_HEAD 而éžæ£€å‡ºå½“å‰æ交" msgid "git blame [options] [rev-opts] [rev] [--] file" msgstr "git blame [选项] [版本选项] [版本] [--] 文件" -#: builtin/blame.c:30 builtin/shortlog.c:15 +#: builtin/blame.c:30 msgid "[rev-opts] are documented in git-rev-list(1)" msgstr "[版本选项] 的文档记录在 git-rev-list(1) ä¸" -#: builtin/blame.c:2350 +#: builtin/blame.c:2355 msgid "Show blame entries as we find them, incrementally" msgstr "增é‡å¼åœ°æ˜¾ç¤ºå‘现的 blame æ¡ç›®" -#: builtin/blame.c:2351 +#: builtin/blame.c:2356 msgid "Show blank SHA-1 for boundary commits (Default: off)" msgstr "边界æ交显示空的 SHA-1(默认:关é—)" -#: builtin/blame.c:2352 +#: builtin/blame.c:2357 msgid "Do not treat root commits as boundaries (Default: off)" msgstr "ä¸æŠŠæ ¹æ交作为边界(默认:关é—)" -#: builtin/blame.c:2353 +#: builtin/blame.c:2358 msgid "Show work cost statistics" msgstr "显示命令消耗统计" -#: builtin/blame.c:2354 +#: builtin/blame.c:2359 msgid "Show output score for blame entries" msgstr "æ˜¾ç¤ºåˆ¤æ– blame æ¡ç›®ä½ç§»çš„得分诊æ–ä¿¡æ¯" -#: builtin/blame.c:2355 +#: builtin/blame.c:2360 msgid "Show original filename (Default: auto)" msgstr "显示原始文件å(默认:自动)" -#: builtin/blame.c:2356 +#: builtin/blame.c:2361 msgid "Show original linenumber (Default: off)" msgstr "显示原始的行å·ï¼ˆé»˜è®¤ï¼šå…³é—)" -#: builtin/blame.c:2357 +#: builtin/blame.c:2362 msgid "Show in a format designed for machine consumption" msgstr "显示为一个适åˆæœºå™¨è¯»å–çš„æ ¼å¼" -#: builtin/blame.c:2358 +#: builtin/blame.c:2363 msgid "Show porcelain format with per-line commit information" msgstr "为æ¯ä¸€è¡Œæ˜¾ç¤ºæœºå™¨é€‚用的æ交信æ¯" -#: builtin/blame.c:2359 +#: builtin/blame.c:2364 msgid "Use the same output mode as git-annotate (Default: off)" msgstr "使用和 git-annotate 相åŒçš„输出模å¼ï¼ˆé»˜è®¤ï¼šå…³é—)" -#: builtin/blame.c:2360 +#: builtin/blame.c:2365 msgid "Show raw timestamp (Default: off)" msgstr "显示原始时间戳(默认:关é—)" -#: builtin/blame.c:2361 +#: builtin/blame.c:2366 msgid "Show long commit SHA1 (Default: off)" msgstr "显示长的SHA1æ交å·ï¼ˆé»˜è®¤ï¼šå…³é—)" -#: builtin/blame.c:2362 +#: builtin/blame.c:2367 msgid "Suppress author name and timestamp (Default: off)" msgstr "éšè—作者åå—和时间戳(默认:关é—)" -#: builtin/blame.c:2363 +#: builtin/blame.c:2368 msgid "Show author email instead of name (Default: off)" msgstr "显示作者的邮箱而ä¸æ˜¯åå—(默认:关é—)" -#: builtin/blame.c:2364 +#: builtin/blame.c:2369 msgid "Ignore whitespace differences" msgstr "忽略空白差异" -#: builtin/blame.c:2365 +#: builtin/blame.c:2370 msgid "Spend extra cycles to find better match" msgstr "花费é¢å¤–的循环æ¥æ‰¾åˆ°æ›´å¥½çš„匹é…" -#: builtin/blame.c:2366 +#: builtin/blame.c:2371 msgid "Use revisions from <file> instead of calling git-rev-list" msgstr "使用æ¥è‡ª <file> 的修订集而ä¸æ˜¯è°ƒç”¨ git-rev-list" -#: builtin/blame.c:2367 +#: builtin/blame.c:2372 msgid "Use <file>'s contents as the final image" msgstr "使用 <file> 的内容作为最终的图片" -#: builtin/blame.c:2368 builtin/blame.c:2369 +#: builtin/blame.c:2373 builtin/blame.c:2374 msgid "score" msgstr "得分" -#: builtin/blame.c:2368 +#: builtin/blame.c:2373 msgid "Find line copies within and across files" msgstr "找到文件内åŠè·¨æ–‡ä»¶çš„行拷è´" -#: builtin/blame.c:2369 +#: builtin/blame.c:2374 msgid "Find line movements within and across files" msgstr "找到文件内åŠè·¨æ–‡ä»¶çš„行移动" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "n,m" msgstr "n,m" -#: builtin/blame.c:2370 +#: builtin/blame.c:2375 msgid "Process only line range n,m, counting from 1" msgstr "åªå¤„ç†è¡ŒèŒƒå›´åœ¨ n å’Œ m 之间的,从 1 开始" -#: builtin/branch.c:23 +#: builtin/branch.c:24 msgid "git branch [options] [-r | -a] [--merged | --no-merged]" msgstr "git branch [选项] [-r | -a] [--merged | --no-merged]" -#: builtin/branch.c:24 +#: builtin/branch.c:25 msgid "git branch [options] [-l] [-f] <branchname> [<start-point>]" msgstr "git branch [选项] [-l] [-f] <分支å> [<起始点>]" -#: builtin/branch.c:25 +#: builtin/branch.c:26 msgid "git branch [options] [-r] (-d | -D) <branchname>..." msgstr "git branch [选项] [-r] (-d | -D) <分支å>..." -#: builtin/branch.c:26 +#: builtin/branch.c:27 msgid "git branch [options] (-m | -M) [<oldbranch>] <newbranch>" msgstr "git branch [选项] (-m | -M) [<旧分支>] <新分支>" # 译者:ä¿æŒåŽŸæ¢è¡Œæ ¼å¼ï¼Œåœ¨è¾“出时 %s 的替代内容会让å—符串å˜é•¿ -#: builtin/branch.c:145 +#: builtin/branch.c:150 #, c-format msgid "" "deleting branch '%s' that has been merged to\n" @@ -2300,7 +2504,7 @@ msgstr "" " '%s',但未åˆå¹¶åˆ° HEAD。" # 译者:ä¿æŒåŽŸæ¢è¡Œæ ¼å¼ï¼Œåœ¨è¾“出时 %s 的替代内容会让å—符串å˜é•¿ -#: builtin/branch.c:149 +#: builtin/branch.c:154 #, c-format msgid "" "not deleting branch '%s' that is not yet merged to\n" @@ -2309,12 +2513,12 @@ msgstr "" "å¹¶æœªåˆ é™¤åˆ†æ”¯ '%s', 虽然它已ç»åˆå¹¶åˆ° HEAD,\n" " 然而å´å°šæœªè¢«åˆå¹¶åˆ°åˆ†æ”¯ '%s' 。" -#: builtin/branch.c:163 +#: builtin/branch.c:168 #, c-format msgid "Couldn't look up commit object for '%s'" msgstr "æ— æ³•æŸ¥è¯¢ '%s' 指å‘çš„æ交对象" -#: builtin/branch.c:167 +#: builtin/branch.c:172 #, c-format msgid "" "The branch '%s' is not fully merged.\n" @@ -2323,285 +2527,327 @@ msgstr "" "分支 '%s' 没有完全åˆå¹¶ã€‚\n" "如果您确认è¦åˆ 除它,执行 'git branch -D %s'。" -#: builtin/branch.c:180 +#: builtin/branch.c:185 msgid "Update of config-file failed" msgstr "æ— æ³•æ›´æ–° config 文件" -#: builtin/branch.c:208 +#: builtin/branch.c:213 msgid "cannot use -a with -d" msgstr "ä¸èƒ½å°† -a å’Œ -d åŒæ—¶ä½¿ç”¨" -#: builtin/branch.c:214 +#: builtin/branch.c:219 msgid "Couldn't look up commit object for HEAD" msgstr "æ— æ³•æŸ¥è¯¢ HEAD 指å‘çš„æ交对象" -#: builtin/branch.c:222 +#: builtin/branch.c:227 #, c-format msgid "Cannot delete the branch '%s' which you are currently on." msgstr "æ— æ³•åˆ é™¤æ‚¨å½“å‰æ‰€åœ¨çš„分支 '%s'。" -#: builtin/branch.c:235 +#: builtin/branch.c:240 #, c-format msgid "remote branch '%s' not found." msgstr "远程分支 '%s' 未å‘现。" -#: builtin/branch.c:236 +#: builtin/branch.c:241 #, c-format msgid "branch '%s' not found." msgstr "分支 '%s' 未å‘现。" -#: builtin/branch.c:250 +#: builtin/branch.c:255 #, c-format msgid "Error deleting remote branch '%s'" msgstr "åˆ é™¤è¿œç¨‹åˆ†æ”¯ '%s' 时出错" -#: builtin/branch.c:251 +#: builtin/branch.c:256 #, c-format msgid "Error deleting branch '%s'" msgstr "åˆ é™¤åˆ†æ”¯ '%s' 时出错" -#: builtin/branch.c:258 +#: builtin/branch.c:263 #, c-format msgid "Deleted remote branch %s (was %s).\n" msgstr "å·²åˆ é™¤è¿œç¨‹åˆ†æ”¯ %s(曾为 %s)。\n" -#: builtin/branch.c:259 +#: builtin/branch.c:264 #, c-format msgid "Deleted branch %s (was %s).\n" msgstr "å·²åˆ é™¤åˆ†æ”¯ %s(曾为 %s)。\n" -#: builtin/branch.c:361 +#: builtin/branch.c:366 #, c-format msgid "branch '%s' does not point at a commit" msgstr "分支 '%s' 未指å‘一个æ交" -#: builtin/branch.c:433 +#: builtin/branch.c:453 #, c-format msgid "[%s: behind %d]" msgstr "[%s:è½åŽ %d]" -#: builtin/branch.c:435 +#: builtin/branch.c:455 #, c-format msgid "[behind %d]" msgstr "[è½åŽ %d]" -#: builtin/branch.c:439 +#: builtin/branch.c:459 #, c-format msgid "[%s: ahead %d]" msgstr "[%s:领先 %d]" -#: builtin/branch.c:441 +#: builtin/branch.c:461 #, c-format msgid "[ahead %d]" msgstr "[领先 %d]" -#: builtin/branch.c:444 +#: builtin/branch.c:464 #, c-format msgid "[%s: ahead %d, behind %d]" msgstr "[%s:领先 %d,è½åŽ %d]" -#: builtin/branch.c:447 +#: builtin/branch.c:467 #, c-format msgid "[ahead %d, behind %d]" msgstr "[领先 %d,è½åŽ %d]" -#: builtin/branch.c:469 +#: builtin/branch.c:490 msgid " **** invalid ref ****" msgstr " **** æ— æ•ˆå¼•ç”¨ ****" -#: builtin/branch.c:560 +#: builtin/branch.c:582 +#, c-format +msgid "(no branch, rebasing %s)" +msgstr "(éžåˆ†æ”¯ï¼Œæ£å˜åŸº %s)" + +#: builtin/branch.c:585 +#, c-format +msgid "(no branch, bisect started on %s)" +msgstr "(éžåˆ†æ”¯ï¼ŒäºŒåˆ†æŸ¥æ‰¾å¼€å§‹äºŽ %s)" + +#: builtin/branch.c:588 +#, c-format +msgid "(detached from %s)" +msgstr "(分离自 %s)" + +#: builtin/branch.c:591 msgid "(no branch)" msgstr "(éžåˆ†æ”¯ï¼‰" -#: builtin/branch.c:593 +#: builtin/branch.c:637 #, c-format msgid "object '%s' does not point to a commit" msgstr "对象 '%s' 没有指å‘一个æ交" -#: builtin/branch.c:625 +#: builtin/branch.c:669 msgid "some refs could not be read" msgstr "一些引用ä¸èƒ½è¯»å–" -#: builtin/branch.c:638 +#: builtin/branch.c:682 msgid "cannot rename the current branch while not on any." msgstr "æ— æ³•é‡å‘½å当å‰åˆ†æ”¯å› 为ä¸å¤„于任何分支上。" -#: builtin/branch.c:648 +#: builtin/branch.c:692 #, c-format msgid "Invalid branch name: '%s'" msgstr "æ— æ•ˆçš„åˆ†æ”¯å:'%s'" -#: builtin/branch.c:663 +#: builtin/branch.c:707 msgid "Branch rename failed" msgstr "分支é‡å‘½å失败" -#: builtin/branch.c:667 +#: builtin/branch.c:711 #, c-format msgid "Renamed a misnamed branch '%s' away" msgstr "é‡å‘½å掉一个错误命å的旧分支 '%s'" -#: builtin/branch.c:671 +#: builtin/branch.c:715 #, c-format msgid "Branch renamed to %s, but HEAD is not updated!" msgstr "分支é‡å‘½å为 %s,但 HEAD 没有更新ï¼" -#: builtin/branch.c:678 +#: builtin/branch.c:722 msgid "Branch is renamed, but update of config-file failed" msgstr "分支被é‡å‘½å,但更新 config 文件失败" -#: builtin/branch.c:693 +#: builtin/branch.c:737 #, c-format msgid "malformed object name %s" msgstr "éžæ³•çš„对象å %s" -#: builtin/branch.c:717 +#: builtin/branch.c:761 #, c-format msgid "could not write branch description template: %s" msgstr "ä¸èƒ½å†™åˆ†æ”¯æ述模版:%s" -#: builtin/branch.c:747 +#: builtin/branch.c:791 msgid "Generic options" msgstr "通用选项" -#: builtin/branch.c:749 +#: builtin/branch.c:793 msgid "show hash and subject, give twice for upstream branch" msgstr "显示哈希值和主题,若å‚数出现两次则显示上游分支" -#: builtin/branch.c:750 +#: builtin/branch.c:794 msgid "suppress informational messages" msgstr "ä¸æ˜¾ç¤ºä¿¡æ¯" -#: builtin/branch.c:751 +#: builtin/branch.c:795 msgid "set up tracking mode (see git-pull(1))" msgstr "设置跟踪模å¼ï¼ˆå‚è§ git-pull(1))" -#: builtin/branch.c:753 +#: builtin/branch.c:797 msgid "change upstream info" msgstr "改å˜ä¸Šæ¸¸ä¿¡æ¯" -#: builtin/branch.c:757 +#: builtin/branch.c:801 msgid "use colored output" msgstr "使用彩色输出" -#: builtin/branch.c:758 +#: builtin/branch.c:802 msgid "act on remote-tracking branches" msgstr "作用于远程跟踪分支" -#: builtin/branch.c:761 builtin/branch.c:767 builtin/branch.c:788 -#: builtin/branch.c:794 builtin/commit.c:1366 builtin/commit.c:1367 -#: builtin/commit.c:1368 builtin/commit.c:1369 builtin/tag.c:468 +#: builtin/branch.c:805 builtin/branch.c:811 builtin/branch.c:832 +#: builtin/branch.c:838 builtin/commit.c:1368 builtin/commit.c:1369 +#: builtin/commit.c:1370 builtin/commit.c:1371 builtin/tag.c:468 msgid "commit" msgstr "æ交" -#: builtin/branch.c:762 builtin/branch.c:768 +#: builtin/branch.c:806 builtin/branch.c:812 msgid "print only branches that contain the commit" msgstr "åªæ‰“å°åŒ…å«è¯¥æ交的分支" -#: builtin/branch.c:774 +#: builtin/branch.c:818 msgid "Specific git-branch actions:" msgstr "具体的 git-branch 动作:" -#: builtin/branch.c:775 +#: builtin/branch.c:819 msgid "list both remote-tracking and local branches" msgstr "列出远程跟踪åŠæœ¬åœ°åˆ†æ”¯" -#: builtin/branch.c:777 +#: builtin/branch.c:821 msgid "delete fully merged branch" msgstr "åˆ é™¤å®Œå…¨åˆå¹¶çš„分支" -#: builtin/branch.c:778 +#: builtin/branch.c:822 msgid "delete branch (even if not merged)" msgstr "åˆ é™¤åˆ†æ”¯ï¼ˆå³ä½¿æ²¡æœ‰åˆå¹¶ï¼‰" -#: builtin/branch.c:779 +#: builtin/branch.c:823 msgid "move/rename a branch and its reflog" msgstr "移动/é‡å‘½å一个分支,以åŠå®ƒçš„引用日志" -#: builtin/branch.c:780 +#: builtin/branch.c:824 msgid "move/rename a branch, even if target exists" msgstr "移动/é‡å‘½å一个分支,å³ä½¿ç›®æ ‡å·²å˜åœ¨" -#: builtin/branch.c:781 +#: builtin/branch.c:825 msgid "list branch names" msgstr "列出分支å" -#: builtin/branch.c:782 +#: builtin/branch.c:826 msgid "create the branch's reflog" msgstr "创建分支的引用日志" -#: builtin/branch.c:784 +#: builtin/branch.c:828 msgid "edit the description for the branch" msgstr "æ ‡è®°åˆ†æ”¯çš„æè¿°" -#: builtin/branch.c:785 +#: builtin/branch.c:829 msgid "force creation (when already exists)" msgstr "强制创建(当已ç»å˜åœ¨ï¼‰" -#: builtin/branch.c:788 +#: builtin/branch.c:832 msgid "print only not merged branches" msgstr "åªæ‰“å°æ²¡æœ‰åˆå¹¶çš„分支" -#: builtin/branch.c:794 +#: builtin/branch.c:838 msgid "print only merged branches" msgstr "åªæ‰“å°åˆå¹¶çš„分支" -#: builtin/branch.c:798 +#: builtin/branch.c:842 msgid "list branches in columns" msgstr "以列的方å¼æ˜¾ç¤ºåˆ†æ”¯" -#: builtin/branch.c:811 +#: builtin/branch.c:855 msgid "Failed to resolve HEAD as a valid ref." msgstr "æ— æ³•å°† HEAD 解æžä¸ºæœ‰æ•ˆå¼•ç”¨ã€‚" -#: builtin/branch.c:816 builtin/clone.c:561 +#: builtin/branch.c:860 builtin/clone.c:619 msgid "HEAD not found below refs/heads!" msgstr "HEAD 没有ä½äºŽ /refs/heads 之下ï¼" -#: builtin/branch.c:839 +#: builtin/branch.c:883 msgid "--column and --verbose are incompatible" msgstr "--column å’Œ --verbose ä¸å…¼å®¹" -#: builtin/branch.c:845 +#: builtin/branch.c:889 builtin/branch.c:928 msgid "branch name required" msgstr "å¿…é¡»æ供分支å" -#: builtin/branch.c:860 +#: builtin/branch.c:904 msgid "Cannot give description to detached HEAD" msgstr "ä¸èƒ½å‘分离头指针æä¾›æè¿°" -#: builtin/branch.c:865 +#: builtin/branch.c:909 msgid "cannot edit description of more than one branch" msgstr "ä¸èƒ½ä¸ºä¸€ä¸ªä»¥ä¸Šçš„分支编辑æè¿°" -#: builtin/branch.c:872 +#: builtin/branch.c:916 #, c-format msgid "No commit on branch '%s' yet." msgstr "分支 '%s' å°šæ— æ交。" -#: builtin/branch.c:875 +#: builtin/branch.c:919 #, c-format msgid "No branch named '%s'." msgstr "没有分支 '%s'。" -#: builtin/branch.c:888 +#: builtin/branch.c:934 msgid "too many branches for a rename operation" msgstr "为é‡å‘½åæ“作æ供了太多的分支å" -#: builtin/branch.c:893 +#: builtin/branch.c:939 +msgid "too many branches to set new upstream" +msgstr "为设置新上游æ供了太多的分支å" + +#: builtin/branch.c:943 +#, c-format +msgid "" +"could not set upstream of HEAD to %s when it does not point to any branch." +msgstr "æ— æ³•è®¾ç½® HEAD 的上游为 %sï¼Œå› ä¸º HEAD 没有指å‘任何分支。" + +#: builtin/branch.c:946 builtin/branch.c:968 builtin/branch.c:990 +#, c-format +msgid "no such branch '%s'" +msgstr "没有æ¤åˆ†æ”¯ '%s'" + +#: builtin/branch.c:950 #, c-format msgid "branch '%s' does not exist" msgstr "分支 '%s' ä¸å˜åœ¨" -#: builtin/branch.c:905 +#: builtin/branch.c:962 +msgid "too many branches to unset upstream" +msgstr "为å–消上游设置æ“作æ供了太多的分支å" + +#: builtin/branch.c:966 +msgid "could not unset upstream of HEAD when it does not point to any branch." +msgstr "æ— æ³•å–消 HEAD çš„ä¸Šæ¸¸è®¾ç½®å› ä¸ºå®ƒæ²¡æœ‰æŒ‡å‘一个分支" + +#: builtin/branch.c:972 #, c-format msgid "Branch '%s' has no upstream information" msgstr "分支 '%s' 没有上游信æ¯" -#: builtin/branch.c:920 +#: builtin/branch.c:987 +msgid "it does not make sense to create 'HEAD' manually" +msgstr "手工创建 'HEAD' 没有æ„义" + +#: builtin/branch.c:993 msgid "-a and -r options to 'git branch' do not make sense with a branch name" msgstr "'git branch' çš„ -a å’Œ -r 选项带一个分支åå‚数没有æ„义" -#: builtin/branch.c:923 +#: builtin/branch.c:996 #, c-format msgid "" "The --set-upstream flag is deprecated and will be removed. Consider using --" @@ -2609,7 +2855,7 @@ msgid "" msgstr "" "选项 --set-upstream 已弃用并将被移除。考虑使用 --track 或 --set-upstream-to\n" -#: builtin/branch.c:940 +#: builtin/branch.c:1013 #, c-format msgid "" "\n" @@ -2620,12 +2866,12 @@ msgstr "" "å¦‚æžœä½ æƒ³ç”¨ '%s' 跟踪 '%s', 这么åšï¼š\n" "\n" -#: builtin/branch.c:941 +#: builtin/branch.c:1014 #, c-format msgid " git branch -d %s\n" msgstr " git branch -d %s\n" -#: builtin/branch.c:942 +#: builtin/branch.c:1015 #, c-format msgid " git branch --set-upstream-to %s\n" msgstr " git branch --set-upstream-to %s\n" @@ -2643,43 +2889,43 @@ msgstr "需è¦ä¸€ä¸ªç‰ˆæœ¬åº“æ¥åˆ›å»ºåŒ…。" msgid "Need a repository to unbundle." msgstr "需è¦ä¸€ä¸ªç‰ˆæœ¬åº“æ¥è§£åŒ…。" -#: builtin/cat-file.c:247 +#: builtin/cat-file.c:176 msgid "git cat-file (-t|-s|-e|-p|<type>|--textconv) <object>" msgstr "git cat-file (-t|-s|-e|-p|<类型>|--textconv) <对象>" -#: builtin/cat-file.c:248 +#: builtin/cat-file.c:177 msgid "git cat-file (--batch|--batch-check) < <list_of_objects>" msgstr "git cat-file (--batch|--batch-check) < <对象列表>" -#: builtin/cat-file.c:266 +#: builtin/cat-file.c:195 msgid "<type> can be one of: blob, tree, commit, tag" msgstr "<类型> å¯ä»¥æ˜¯å…¶ä¸ä¹‹ä¸€ï¼šblobã€treeã€commitã€tag" -#: builtin/cat-file.c:267 +#: builtin/cat-file.c:196 msgid "show object type" msgstr "显示对象类型" -#: builtin/cat-file.c:268 +#: builtin/cat-file.c:197 msgid "show object size" msgstr "显示对象大å°" -#: builtin/cat-file.c:270 +#: builtin/cat-file.c:199 msgid "exit with zero when there's no error" msgstr "当没有错误时退出并返回零" -#: builtin/cat-file.c:271 +#: builtin/cat-file.c:200 msgid "pretty-print object's content" msgstr "美观地打å°å¯¹è±¡çš„内容" -#: builtin/cat-file.c:273 +#: builtin/cat-file.c:202 msgid "for blob objects, run textconv on object's content" msgstr "对于数æ®ï¼ˆblob)对象,对其内容执行 textconv" -#: builtin/cat-file.c:275 +#: builtin/cat-file.c:204 msgid "show info and content of objects fed from the standard input" msgstr "æ˜¾ç¤ºä»Žæ ‡å‡†è¾“å…¥æ供的对象的信æ¯å’Œå†…容" -#: builtin/cat-file.c:278 +#: builtin/cat-file.c:207 msgid "show info about objects fed from the standard input" msgstr "æ˜¾ç¤ºä»Žæ ‡å‡†è¾“å…¥æ供的对象的信æ¯" @@ -2707,27 +2953,27 @@ msgstr "ä»Žæ ‡å‡†è¾“å…¥è¯»å‡ºæ–‡ä»¶å" msgid "input paths are terminated by a null character" msgstr "输入路径以nullå—符终æ¢" -#: builtin/check-ignore.c:18 builtin/checkout.c:1012 builtin/gc.c:177 +#: builtin/check-ignore.c:18 builtin/checkout.c:1044 builtin/gc.c:177 msgid "suppress progress reporting" msgstr "ä¸æ˜¾ç¤ºè¿›åº¦æŠ¥å‘Š" -#: builtin/check-ignore.c:151 +#: builtin/check-ignore.c:146 msgid "cannot specify pathnames with --stdin" msgstr "ä¸èƒ½åŒæ—¶æä¾›è·¯å¾„åŠ --stdin å‚æ•°" -#: builtin/check-ignore.c:154 +#: builtin/check-ignore.c:149 msgid "-z only makes sense with --stdin" msgstr "-z 需è¦å’Œ --stdin å‚数共用æ‰æœ‰æ„义" -#: builtin/check-ignore.c:156 +#: builtin/check-ignore.c:151 msgid "no path specified" msgstr "未指定路径" -#: builtin/check-ignore.c:160 +#: builtin/check-ignore.c:155 msgid "--quiet is only valid with a single pathname" msgstr "å‚æ•° --quiet åªåœ¨æ供一个路径å时有效" -#: builtin/check-ignore.c:162 +#: builtin/check-ignore.c:157 msgid "cannot have both --quiet and --verbose" msgstr "ä¸èƒ½åŒæ—¶æä¾› --quiet å’Œ --verbose å‚æ•°" @@ -2783,107 +3029,107 @@ msgstr "git checkout [选项] <分支>" msgid "git checkout [options] [<branch>] -- <file>..." msgstr "git checkout [选项] [<分支>] -- <文件>..." -#: builtin/checkout.c:116 builtin/checkout.c:149 +#: builtin/checkout.c:117 builtin/checkout.c:150 #, c-format msgid "path '%s' does not have our version" msgstr "路径 '%s' 没有我们的版本" -#: builtin/checkout.c:118 builtin/checkout.c:151 +#: builtin/checkout.c:119 builtin/checkout.c:152 #, c-format msgid "path '%s' does not have their version" msgstr "路径 '%s' 没有他们的版本" -#: builtin/checkout.c:134 +#: builtin/checkout.c:135 #, c-format msgid "path '%s' does not have all necessary versions" msgstr "路径 '%s' 没有全部必须的版本" -#: builtin/checkout.c:178 +#: builtin/checkout.c:179 #, c-format msgid "path '%s' does not have necessary versions" msgstr "路径 '%s' 没有必须的版本" -#: builtin/checkout.c:195 +#: builtin/checkout.c:196 #, c-format msgid "path '%s': cannot merge" msgstr "path '%s'ï¼šæ— æ³•åˆå¹¶" -#: builtin/checkout.c:212 +#: builtin/checkout.c:213 #, c-format msgid "Unable to add merge result for '%s'" msgstr "æ— æ³•ä¸º '%s' æ·»åŠ åˆå¹¶ç»“æžœ" -#: builtin/checkout.c:236 builtin/checkout.c:239 builtin/checkout.c:242 -#: builtin/checkout.c:245 +#: builtin/checkout.c:237 builtin/checkout.c:240 builtin/checkout.c:243 +#: builtin/checkout.c:246 #, c-format msgid "'%s' cannot be used with updating paths" msgstr "'%s' ä¸èƒ½åœ¨æ›´æ–°è·¯å¾„时使用" -#: builtin/checkout.c:248 builtin/checkout.c:251 +#: builtin/checkout.c:249 builtin/checkout.c:252 #, c-format msgid "'%s' cannot be used with %s" msgstr "'%s' ä¸èƒ½å’Œ %s åŒæ—¶ä½¿ç”¨" -#: builtin/checkout.c:254 +#: builtin/checkout.c:255 #, c-format msgid "Cannot update paths and switch to branch '%s' at the same time." msgstr "ä¸èƒ½åŒæ—¶æ›´æ–°è·¯å¾„并切æ¢åˆ°åˆ†æ”¯'%s'。" -#: builtin/checkout.c:265 builtin/checkout.c:426 +#: builtin/checkout.c:266 builtin/checkout.c:458 msgid "corrupt index file" msgstr "æŸå的索引文件" -#: builtin/checkout.c:295 builtin/checkout.c:302 +#: builtin/checkout.c:329 builtin/checkout.c:336 #, c-format msgid "path '%s' is unmerged" msgstr "路径 '%s' 未åˆå¹¶" -#: builtin/checkout.c:448 +#: builtin/checkout.c:480 msgid "you need to resolve your current index first" msgstr "您需è¦å…ˆè§£å†³å½“å‰ç´¢å¼•çš„冲çª" -#: builtin/checkout.c:569 +#: builtin/checkout.c:601 #, c-format msgid "Can not do reflog for '%s'\n" msgstr "ä¸èƒ½å¯¹ '%s' 执行 reflog æ“作\n" -#: builtin/checkout.c:602 +#: builtin/checkout.c:634 msgid "HEAD is now at" msgstr "HEAD ç›®å‰ä½äºŽ" -#: builtin/checkout.c:609 +#: builtin/checkout.c:641 #, c-format msgid "Reset branch '%s'\n" msgstr "é‡ç½®åˆ†æ”¯ '%s'\n" -#: builtin/checkout.c:612 +#: builtin/checkout.c:644 #, c-format msgid "Already on '%s'\n" msgstr "å·²ç»ä½äºŽ '%s'\n" -#: builtin/checkout.c:616 +#: builtin/checkout.c:648 #, c-format msgid "Switched to and reset branch '%s'\n" msgstr "切æ¢å¹¶é‡ç½®åˆ†æ”¯ '%s'\n" -#: builtin/checkout.c:618 builtin/checkout.c:955 +#: builtin/checkout.c:650 builtin/checkout.c:987 #, c-format msgid "Switched to a new branch '%s'\n" msgstr "切æ¢åˆ°ä¸€ä¸ªæ–°åˆ†æ”¯ '%s'\n" -#: builtin/checkout.c:620 +#: builtin/checkout.c:652 #, c-format msgid "Switched to branch '%s'\n" msgstr "切æ¢åˆ°åˆ†æ”¯ '%s'\n" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/checkout.c:676 +#: builtin/checkout.c:708 #, c-format msgid " ... and %d more.\n" msgstr " ... åŠå…¶å®ƒ %d 个。\n" #. The singular version -#: builtin/checkout.c:682 +#: builtin/checkout.c:714 #, c-format msgid "" "Warning: you are leaving %d commit behind, not connected to\n" @@ -2904,7 +3150,7 @@ msgstr[1] "" "\n" "%s\n" -#: builtin/checkout.c:700 +#: builtin/checkout.c:732 #, c-format msgid "" "If you want to keep them by creating a new branch, this may be a good time\n" @@ -2919,132 +3165,136 @@ msgstr "" " git branch new_branch_name %s\n" "\n" -#: builtin/checkout.c:730 +#: builtin/checkout.c:762 msgid "internal error in revision walk" msgstr "在版本é历时é‡åˆ°å†…部错误" -#: builtin/checkout.c:734 +#: builtin/checkout.c:766 msgid "Previous HEAD position was" msgstr "之å‰çš„ HEAD ä½ç½®æ˜¯" -#: builtin/checkout.c:761 builtin/checkout.c:950 +#: builtin/checkout.c:793 builtin/checkout.c:982 msgid "You are on a branch yet to be born" msgstr "您ä½äºŽä¸€ä¸ªå°šæœªåˆå§‹åŒ–的分支" #. case (1) -#: builtin/checkout.c:886 +#: builtin/checkout.c:918 #, c-format msgid "invalid reference: %s" msgstr "æ— æ•ˆå¼•ç”¨ï¼š%s" #. case (1): want a tree -#: builtin/checkout.c:925 +#: builtin/checkout.c:957 #, c-format msgid "reference is not a tree: %s" msgstr "引用ä¸æ˜¯ä¸€ä¸ªæ ‘:%s" -#: builtin/checkout.c:964 +#: builtin/checkout.c:996 msgid "paths cannot be used with switching branches" msgstr "路径ä¸èƒ½å’Œåˆ‡æ¢åˆ†æ”¯åŒæ—¶ä½¿ç”¨" -#: builtin/checkout.c:967 builtin/checkout.c:971 +#: builtin/checkout.c:999 builtin/checkout.c:1003 #, c-format msgid "'%s' cannot be used with switching branches" msgstr "'%s' ä¸èƒ½å’Œåˆ‡æ¢åˆ†æ”¯åŒæ—¶ä½¿ç”¨" -#: builtin/checkout.c:975 builtin/checkout.c:978 builtin/checkout.c:983 -#: builtin/checkout.c:986 +#: builtin/checkout.c:1007 builtin/checkout.c:1010 builtin/checkout.c:1015 +#: builtin/checkout.c:1018 #, c-format msgid "'%s' cannot be used with '%s'" msgstr "'%s' ä¸èƒ½å’Œ '%s' åŒæ—¶ä½¿ç”¨" -#: builtin/checkout.c:991 +#: builtin/checkout.c:1023 #, c-format msgid "Cannot switch branch to a non-commit '%s'" msgstr "ä¸èƒ½åˆ‡æ¢åˆ†æ”¯åˆ°ä¸€ä¸ªéžæ交 '%s'" -#: builtin/checkout.c:1013 builtin/checkout.c:1015 builtin/clone.c:89 +#: builtin/checkout.c:1045 builtin/checkout.c:1047 builtin/clone.c:90 #: builtin/remote.c:169 builtin/remote.c:171 msgid "branch" msgstr "分支" -#: builtin/checkout.c:1014 +#: builtin/checkout.c:1046 msgid "create and checkout a new branch" msgstr "创建并检出一个新的分支" -#: builtin/checkout.c:1016 +#: builtin/checkout.c:1048 msgid "create/reset and checkout a branch" msgstr "创建/é‡ç½®å¹¶æ£€å‡ºä¸€ä¸ªåˆ†æ”¯" -#: builtin/checkout.c:1017 +#: builtin/checkout.c:1049 msgid "create reflog for new branch" msgstr "为新的分支创建引用日志" -#: builtin/checkout.c:1018 +#: builtin/checkout.c:1050 msgid "detach the HEAD at named commit" msgstr "æˆä¸ºæŒ‡å‘该æ交的分离头指针" -#: builtin/checkout.c:1019 +#: builtin/checkout.c:1051 msgid "set upstream info for new branch" msgstr "为新的分支设置上游信æ¯" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new branch" msgstr "新分支" -#: builtin/checkout.c:1021 +#: builtin/checkout.c:1053 msgid "new unparented branch" msgstr "新的没有父æ交的分支" -#: builtin/checkout.c:1022 +#: builtin/checkout.c:1054 msgid "checkout our version for unmerged files" msgstr "对尚未åˆå¹¶çš„文件检出我们的版本" -#: builtin/checkout.c:1024 +#: builtin/checkout.c:1056 msgid "checkout their version for unmerged files" msgstr "对尚未åˆå¹¶çš„文件检出他们的版本" -#: builtin/checkout.c:1026 +#: builtin/checkout.c:1058 msgid "force checkout (throw away local modifications)" msgstr "强制检出(丢弃本地修改)" -#: builtin/checkout.c:1027 +#: builtin/checkout.c:1059 msgid "perform a 3-way merge with the new branch" msgstr "和新的分支执行三路åˆå¹¶" -#: builtin/checkout.c:1028 builtin/merge.c:215 +#: builtin/checkout.c:1060 builtin/merge.c:217 msgid "update ignored files (default)" msgstr "更新忽略的文件(默认)" -#: builtin/checkout.c:1029 builtin/log.c:1147 parse-options.h:245 +#: builtin/checkout.c:1061 builtin/log.c:1158 parse-options.h:245 msgid "style" msgstr "é£Žæ ¼" -#: builtin/checkout.c:1030 +#: builtin/checkout.c:1062 msgid "conflict style (merge or diff3)" msgstr "冲çªè¾“å‡ºé£Žæ ¼ï¼ˆmerge 或 diff3)" -#: builtin/checkout.c:1033 +#: builtin/checkout.c:1065 +msgid "do not limit pathspecs to sparse entries only" +msgstr "对路径ä¸åšç¨€ç–检出的é™åˆ¶" + +#: builtin/checkout.c:1067 msgid "second guess 'git checkout no-such-branch'" msgstr "å†è€…猜测'git checkout no-such-branch'" -#: builtin/checkout.c:1057 +#: builtin/checkout.c:1091 msgid "-b, -B and --orphan are mutually exclusive" msgstr "-bã€-B å’Œ --orphan 是互斥的" -#: builtin/checkout.c:1074 +#: builtin/checkout.c:1108 msgid "--track needs a branch name" msgstr "--track 需è¦ä¸€ä¸ªåˆ†æ”¯å" -#: builtin/checkout.c:1081 +#: builtin/checkout.c:1115 msgid "Missing branch name; try -b" msgstr "缺少分支åï¼›å°è¯• -b" -#: builtin/checkout.c:1116 +#: builtin/checkout.c:1150 msgid "invalid path specification" msgstr "æ— æ•ˆçš„è·¯å¾„è§„æ ¼" -#: builtin/checkout.c:1123 +#: builtin/checkout.c:1157 #, c-format msgid "" "Cannot update paths and switch to branch '%s' at the same time.\n" @@ -3053,12 +3303,12 @@ msgstr "" "ä¸èƒ½åŒæ—¶æ›´æ–°è·¯å¾„并切æ¢åˆ°åˆ†æ”¯'%s'。\n" "您是想è¦æ£€å‡º '%s' 但其未能解æžä¸ºæ交么?" -#: builtin/checkout.c:1128 +#: builtin/checkout.c:1162 #, c-format msgid "git checkout: --detach does not take a path argument '%s'" msgstr "git checkout:--detach ä¸èƒ½æŽ¥æ”¶è·¯å¾„å‚æ•° '%s'" -#: builtin/checkout.c:1132 +#: builtin/checkout.c:1166 msgid "" "git checkout: --ours/--theirs, --force and --merge are incompatible when\n" "checking out of the index." @@ -3106,8 +3356,8 @@ msgstr "强制" msgid "remove whole directories" msgstr "åˆ é™¤æ•´ä¸ªç›®å½•" -#: builtin/clean.c:165 builtin/describe.c:413 builtin/grep.c:717 -#: builtin/ls-files.c:494 builtin/name-rev.c:231 builtin/show-ref.c:182 +#: builtin/clean.c:165 builtin/describe.c:412 builtin/grep.c:717 +#: builtin/ls-files.c:487 builtin/name-rev.c:231 builtin/show-ref.c:182 msgid "pattern" msgstr "模å¼" @@ -3140,215 +3390,233 @@ msgid "" msgstr "" "clean.requireForce 默认为 true 且未æä¾› -n 或 -f 选项,拒ç»æ‰§è¡Œæ¸…ç†åŠ¨ä½œ" -#: builtin/clone.c:36 +#: builtin/clone.c:37 msgid "git clone [options] [--] <repo> [<dir>]" msgstr "git clone [选项] [--] <版本库> [<路径>]" -#: builtin/clone.c:64 builtin/fetch.c:82 builtin/merge.c:212 +#: builtin/clone.c:65 builtin/fetch.c:82 builtin/merge.c:214 #: builtin/push.c:436 msgid "force progress reporting" msgstr "强制显示进度报告" -#: builtin/clone.c:66 +#: builtin/clone.c:67 msgid "don't create a checkout" msgstr "ä¸åˆ›å»ºä¸€ä¸ªæ£€å‡º" -#: builtin/clone.c:67 builtin/clone.c:69 builtin/init-db.c:488 +#: builtin/clone.c:68 builtin/clone.c:70 builtin/init-db.c:488 msgid "create a bare repository" msgstr "创建一个裸版本库" -#: builtin/clone.c:72 +#: builtin/clone.c:73 msgid "create a mirror repository (implies bare)" msgstr "创建一个镜åƒç‰ˆæœ¬åº“(也是裸版本库)" -#: builtin/clone.c:74 +#: builtin/clone.c:75 msgid "to clone from a local repository" msgstr "从本地版本库克隆" -#: builtin/clone.c:76 +#: builtin/clone.c:77 msgid "don't use local hardlinks, always copy" msgstr "ä¸ä½¿ç”¨æœ¬åœ°ç¡¬é“¾æŽ¥ï¼Œå§‹ç»ˆå¤åˆ¶" -#: builtin/clone.c:78 +#: builtin/clone.c:79 msgid "setup as shared repository" msgstr "设置为共享版本库" -#: builtin/clone.c:80 builtin/clone.c:82 +#: builtin/clone.c:81 builtin/clone.c:83 msgid "initialize submodules in the clone" msgstr "在克隆时åˆå§‹åŒ–å模组" -#: builtin/clone.c:83 builtin/init-db.c:485 +#: builtin/clone.c:84 builtin/init-db.c:485 msgid "template-directory" msgstr "模æ¿ç›®å½•" -#: builtin/clone.c:84 builtin/init-db.c:486 +#: builtin/clone.c:85 builtin/init-db.c:486 msgid "directory from which templates will be used" msgstr "模æ¿ç›®å½•å°†è¢«ä½¿ç”¨" -#: builtin/clone.c:86 +#: builtin/clone.c:87 msgid "reference repository" msgstr "引用版本库" -#: builtin/clone.c:87 builtin/column.c:26 builtin/merge-file.c:44 +#: builtin/clone.c:88 builtin/column.c:26 builtin/merge-file.c:44 msgid "name" msgstr "å称" -#: builtin/clone.c:88 +#: builtin/clone.c:89 msgid "use <name> instead of 'origin' to track upstream" msgstr "使用<å称>而ä¸æ˜¯ 'origin' 去跟踪上游" -#: builtin/clone.c:90 +#: builtin/clone.c:91 msgid "checkout <branch> instead of the remote's HEAD" msgstr "检出<分支>而ä¸æ˜¯è¿œç¨‹HEAD" -#: builtin/clone.c:92 +#: builtin/clone.c:93 msgid "path to git-upload-pack on the remote" msgstr "远程 git-upload-pack 路径" -#: builtin/clone.c:93 builtin/fetch.c:83 builtin/grep.c:662 +#: builtin/clone.c:94 builtin/fetch.c:83 builtin/grep.c:662 msgid "depth" msgstr "深度" -#: builtin/clone.c:94 +#: builtin/clone.c:95 msgid "create a shallow clone of that depth" msgstr "创建一个指定深度的浅克隆" -#: builtin/clone.c:96 +#: builtin/clone.c:97 msgid "clone only one branch, HEAD or --branch" msgstr "åªå…‹éš†ä¸€ä¸ªåˆ†æ”¯ã€HEAD 或 --branch" -#: builtin/clone.c:97 builtin/init-db.c:494 +#: builtin/clone.c:98 builtin/init-db.c:494 msgid "gitdir" msgstr "git目录" -#: builtin/clone.c:98 builtin/init-db.c:495 +#: builtin/clone.c:99 builtin/init-db.c:495 msgid "separate git dir from working tree" msgstr "git目录和工作区分离" -#: builtin/clone.c:99 +#: builtin/clone.c:100 msgid "key=value" msgstr "key=value" -#: builtin/clone.c:100 +#: builtin/clone.c:101 msgid "set config inside the new repository" msgstr "在新版本库ä¸è®¾ç½®é…置信æ¯" -#: builtin/clone.c:243 +#: builtin/clone.c:254 #, c-format -msgid "reference repository '%s' is not a local directory." -msgstr "引用版本库 '%s' ä¸æ˜¯ä¸€ä¸ªæœ¬åœ°ç›®å½•ã€‚" +msgid "reference repository '%s' is not a local repository." +msgstr "引用版本库 '%s' ä¸æ˜¯ä¸€ä¸ªæœ¬åœ°ç‰ˆæœ¬åº“。" -#: builtin/clone.c:306 +#: builtin/clone.c:317 #, c-format msgid "failed to create directory '%s'" msgstr "æ— æ³•åˆ›å»ºç›®å½• '%s'" -#: builtin/clone.c:308 builtin/diff.c:77 +#: builtin/clone.c:319 builtin/diff.c:77 #, c-format msgid "failed to stat '%s'" msgstr "æ— æ³•æžšä¸¾ '%s' 状æ€" -#: builtin/clone.c:310 +#: builtin/clone.c:321 #, c-format msgid "%s exists and is not a directory" msgstr "%s å˜åœ¨ä¸”ä¸æ˜¯ä¸€ä¸ªç›®å½•" -#: builtin/clone.c:324 +#: builtin/clone.c:335 #, c-format msgid "failed to stat %s\n" msgstr "æ— æ³•æžšä¸¾ %s 状æ€\n" -#: builtin/clone.c:346 +#: builtin/clone.c:357 #, c-format msgid "failed to create link '%s'" msgstr "æ— æ³•åˆ›å»ºé“¾æŽ¥ '%s'" -#: builtin/clone.c:350 +#: builtin/clone.c:361 #, c-format msgid "failed to copy file to '%s'" msgstr "æ— æ³•æ‹·è´æ–‡ä»¶è‡³ '%s'" -#: builtin/clone.c:373 +#: builtin/clone.c:384 #, c-format msgid "done.\n" msgstr "完æˆã€‚\n" -#: builtin/clone.c:443 +#: builtin/clone.c:397 +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 "" +"克隆æˆåŠŸï¼Œä½†æ˜¯æ£€å‡ºå¤±è´¥ã€‚\n" +"您å¯ä»¥é€šè¿‡ 'git status' 检查哪些已被检出,然åŽä½¿ç”¨å‘½ä»¤\n" +"'git checkout -f HEAD' é‡è¯•\n" + +#: builtin/clone.c:476 #, c-format msgid "Could not find remote branch %s to clone." msgstr "ä¸èƒ½å‘现è¦å…‹éš†çš„远程分支 %s。" -#: builtin/clone.c:552 +#: builtin/clone.c:550 +msgid "remote did not send all necessary objects" +msgstr "远程没有å‘é€æ‰€æœ‰å¿…须的对象" + +#: builtin/clone.c:610 msgid "remote HEAD refers to nonexistent ref, unable to checkout.\n" msgstr "远程 HEAD 指å‘一个ä¸å˜åœ¨çš„å¼•ç”¨ï¼Œæ— æ³•æ£€å‡ºã€‚\n" -#: builtin/clone.c:690 +#: builtin/clone.c:641 +msgid "unable to checkout working tree" +msgstr "ä¸èƒ½æ£€å‡ºå·¥ä½œåŒº" + +#: builtin/clone.c:749 msgid "Too many arguments." msgstr "太多å‚数。" -#: builtin/clone.c:694 +#: builtin/clone.c:753 msgid "You must specify a repository to clone." msgstr "您必须指定一个版本库æ¥å…‹éš†ã€‚" -#: builtin/clone.c:705 +#: builtin/clone.c:764 #, c-format msgid "--bare and --origin %s options are incompatible." msgstr "--bare å’Œ --origin %s 选项ä¸å…¼å®¹ã€‚" -#: builtin/clone.c:708 +#: builtin/clone.c:767 msgid "--bare and --separate-git-dir are incompatible." msgstr "--bare å’Œ --separate-git-dir 选项ä¸å…¼å®¹ã€‚" -#: builtin/clone.c:721 +#: builtin/clone.c:780 #, c-format msgid "repository '%s' does not exist" msgstr "版本库 '%s' ä¸å˜åœ¨" -#: builtin/clone.c:726 +#: builtin/clone.c:785 msgid "--depth is ignored in local clones; use file:// instead." msgstr "--depth 在本地克隆被忽略,改为 file:// å议试试。" -#: builtin/clone.c:736 +#: builtin/clone.c:795 #, c-format msgid "destination path '%s' already exists and is not an empty directory." msgstr "ç›®æ ‡è·¯å¾„ '%s' å·²ç»å˜åœ¨ï¼Œå¹¶ä¸”ä¸æ˜¯ä¸€ä¸ªç©ºç›®å½•ã€‚" -#: builtin/clone.c:746 +#: builtin/clone.c:805 #, c-format msgid "working tree '%s' already exists." msgstr "工作区 '%s' å·²ç»å˜åœ¨ã€‚" -#: builtin/clone.c:759 builtin/clone.c:771 +#: builtin/clone.c:818 builtin/clone.c:830 #, c-format msgid "could not create leading directories of '%s'" msgstr "ä¸èƒ½ä¸º '%s' 创建先导目录" -#: builtin/clone.c:762 +#: builtin/clone.c:821 #, c-format msgid "could not create work tree dir '%s'." msgstr "ä¸èƒ½ä¸º '%s' 创建工作区目录。" -#: builtin/clone.c:781 +#: builtin/clone.c:840 #, c-format msgid "Cloning into bare repository '%s'...\n" msgstr "克隆到裸版本库 '%s'...\n" -#: builtin/clone.c:783 +#: builtin/clone.c:842 #, c-format msgid "Cloning into '%s'...\n" msgstr "æ£å…‹éš†åˆ° '%s'...\n" -#: builtin/clone.c:818 +#: builtin/clone.c:877 #, c-format msgid "Don't know how to clone %s" msgstr "ä¸çŸ¥é“如何克隆 %s" -#: builtin/clone.c:867 +#: builtin/clone.c:926 #, c-format msgid "Remote branch %s not found in upstream %s" msgstr "远程分支 %s 在上游 %s 未å‘现" -#: builtin/clone.c:874 +#: builtin/clone.c:933 msgid "You appear to have cloned an empty repository." msgstr "您似乎克隆了一个空版本库。" @@ -3440,93 +3708,93 @@ msgstr "" "\n" "å¦åˆ™ï¼Œè¯·ä½¿ç”¨å‘½ä»¤ 'git reset'\n" -#: builtin/commit.c:258 +#: builtin/commit.c:260 msgid "failed to unpack HEAD tree object" msgstr "æ— æ³•è§£åŒ… HEAD æ ‘å¯¹è±¡" -#: builtin/commit.c:300 +#: builtin/commit.c:302 msgid "unable to create temporary index" msgstr "ä¸èƒ½åˆ›å»ºä¸´æ—¶ç´¢å¼•" -#: builtin/commit.c:306 +#: builtin/commit.c:308 msgid "interactive add failed" msgstr "交互å¼æ·»åŠ 失败" -#: builtin/commit.c:339 builtin/commit.c:360 builtin/commit.c:410 +#: builtin/commit.c:341 builtin/commit.c:362 builtin/commit.c:412 msgid "unable to write new_index file" msgstr "æ— æ³•å†™ new_index 文件" -#: builtin/commit.c:391 +#: builtin/commit.c:393 msgid "cannot do a partial commit during a merge." msgstr "在åˆå¹¶è¿‡ç¨‹ä¸ä¸èƒ½åšéƒ¨åˆ†æ交。" -#: builtin/commit.c:393 +#: builtin/commit.c:395 msgid "cannot do a partial commit during a cherry-pick." msgstr "在拣选过程ä¸ä¸èƒ½åšéƒ¨åˆ†æ交。" -#: builtin/commit.c:403 +#: builtin/commit.c:405 msgid "cannot read the index" msgstr "æ— æ³•è¯»å–索引" -#: builtin/commit.c:423 +#: builtin/commit.c:425 msgid "unable to write temporary index file" msgstr "æ— æ³•å†™ä¸´æ—¶ç´¢å¼•æ–‡ä»¶" -#: builtin/commit.c:511 builtin/commit.c:517 +#: builtin/commit.c:513 builtin/commit.c:519 #, c-format msgid "invalid commit: %s" msgstr "æ— æ•ˆçš„æ交:%s" -#: builtin/commit.c:540 +#: builtin/commit.c:542 msgid "malformed --author parameter" msgstr "éžæ³•çš„ --author å‚æ•°" -#: builtin/commit.c:560 +#: builtin/commit.c:562 #, c-format msgid "Malformed ident string: '%s'" msgstr "éžæ³•çš„身份å—符串:'%s'" -#: builtin/commit.c:598 builtin/commit.c:631 builtin/commit.c:954 +#: builtin/commit.c:600 builtin/commit.c:633 builtin/commit.c:956 #, c-format msgid "could not lookup commit %s" msgstr "ä¸èƒ½æŸ¥è¯¢æ交 %s" -#: builtin/commit.c:610 builtin/shortlog.c:272 +#: builtin/commit.c:612 builtin/shortlog.c:270 #, c-format msgid "(reading log message from standard input)\n" msgstr "(æ£ä»Žæ ‡å‡†è¾“å…¥ä¸è¯»å–日志信æ¯ï¼‰\n" -#: builtin/commit.c:612 +#: builtin/commit.c:614 msgid "could not read log from standard input" msgstr "ä¸èƒ½ä»Žæ ‡å‡†è¾“å…¥ä¸è¯»å–日志信æ¯" -#: builtin/commit.c:616 +#: builtin/commit.c:618 #, c-format msgid "could not read log file '%s'" msgstr "ä¸èƒ½è¯»å–日志文件 '%s'" -#: builtin/commit.c:622 +#: builtin/commit.c:624 msgid "commit has empty message" msgstr "æ交说明为空" -#: builtin/commit.c:638 +#: builtin/commit.c:640 msgid "could not read MERGE_MSG" msgstr "ä¸èƒ½è¯»å– MERGE_MSG" -#: builtin/commit.c:642 +#: builtin/commit.c:644 msgid "could not read SQUASH_MSG" msgstr "ä¸èƒ½è¯»å– SQUASH_MSG" -#: builtin/commit.c:646 +#: builtin/commit.c:648 #, c-format msgid "could not read '%s'" msgstr "ä¸èƒ½è¯»å– '%s'" -#: builtin/commit.c:707 +#: builtin/commit.c:709 msgid "could not write commit template" msgstr "ä¸èƒ½å†™æ交模版" -#: builtin/commit.c:718 +#: builtin/commit.c:720 #, c-format msgid "" "\n" @@ -3540,7 +3808,7 @@ msgstr "" "\t%s\n" "然åŽé‡è¯•ã€‚\n" -#: builtin/commit.c:723 +#: builtin/commit.c:725 #, c-format msgid "" "\n" @@ -3554,7 +3822,7 @@ msgstr "" "\t%s\n" "然åŽé‡è¯•ã€‚\n" -#: builtin/commit.c:735 +#: builtin/commit.c:737 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3563,7 +3831,7 @@ msgstr "" "请为您的å˜æ›´è¾“å…¥æ交说明。以 '%c' 开始的行将被忽略,而一个空的æ交\n" "说明将会终æ¢æ交。\n" -#: builtin/commit.c:740 +#: builtin/commit.c:742 #, c-format msgid "" "Please enter the commit message for your changes. Lines starting\n" @@ -3574,355 +3842,355 @@ msgstr "" "也å¯ä»¥åˆ 除它们。一个空的æ交说明将会终æ¢æ交。\n" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: builtin/commit.c:753 +#: builtin/commit.c:755 #, c-format msgid "%sAuthor: %s" msgstr "%s作者: %s" # 译者:为ä¿è¯åœ¨è¾“出ä¸å¯¹é½ï¼Œæ³¨æ„调整å¥ä¸ç©ºæ ¼ï¼ -#: builtin/commit.c:760 +#: builtin/commit.c:762 #, c-format msgid "%sCommitter: %s" msgstr "%sæ交者: %s" -#: builtin/commit.c:780 +#: builtin/commit.c:782 msgid "Cannot read index" msgstr "æ— æ³•è¯»å–索引" -#: builtin/commit.c:817 +#: builtin/commit.c:819 msgid "Error building trees" msgstr "æ— æ³•åˆ›å»ºæ ‘å¯¹è±¡" -#: builtin/commit.c:832 builtin/tag.c:359 +#: builtin/commit.c:834 builtin/tag.c:359 #, c-format msgid "Please supply the message using either -m or -F option.\n" msgstr "请使用 -m 或 -F 选项æä¾›æ交说明。\n" -#: builtin/commit.c:929 +#: builtin/commit.c:931 #, c-format msgid "No existing author found with '%s'" msgstr "æ²¡æœ‰æ‰¾åˆ°åŒ¹é… '%s' 的作者" -#: builtin/commit.c:944 builtin/commit.c:1138 +#: builtin/commit.c:946 builtin/commit.c:1140 #, c-format msgid "Invalid untracked files mode '%s'" msgstr "æ— æ•ˆçš„æœªè¿½è¸ªæ–‡ä»¶å‚æ•° '%s'" -#: builtin/commit.c:974 +#: builtin/commit.c:976 msgid "Using both --reset-author and --author does not make sense" msgstr "åŒæ—¶ä½¿ç”¨ --reset-author å’Œ --author 没有æ„义" -#: builtin/commit.c:985 +#: builtin/commit.c:987 msgid "You have nothing to amend." msgstr "您没有å¯ä¿®è¡¥çš„æ交。" -#: builtin/commit.c:988 +#: builtin/commit.c:990 msgid "You are in the middle of a merge -- cannot amend." msgstr "您æ£å¤„于一个åˆå¹¶è¿‡ç¨‹ä¸ -- æ— æ³•ä¿®è¡¥æ交。" -#: builtin/commit.c:990 +#: builtin/commit.c:992 msgid "You are in the middle of a cherry-pick -- cannot amend." msgstr "您æ£å¤„äºŽä¸€ä¸ªæ‹£é€‰è¿‡ç¨‹ä¸ -- æ— æ³•ä¿®è¡¥æ交。" -#: builtin/commit.c:993 +#: builtin/commit.c:995 msgid "Options --squash and --fixup cannot be used together" msgstr "选项 --squash å’Œ --fixup ä¸èƒ½åŒæ—¶ä½¿ç”¨" -#: builtin/commit.c:1003 +#: builtin/commit.c:1005 msgid "Only one of -c/-C/-F/--fixup can be used." msgstr "åªèƒ½ç”¨ä¸€ä¸ª -c/-C/-F/--fixup 选项。" -#: builtin/commit.c:1005 +#: builtin/commit.c:1007 msgid "Option -m cannot be combined with -c/-C/-F/--fixup." msgstr "选项 -m ä¸èƒ½å’Œ -c/-C/-F/--fixup åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/commit.c:1013 +#: builtin/commit.c:1015 msgid "--reset-author can be used only with -C, -c or --amend." msgstr "--reset-author åªèƒ½å’Œ -Cã€-c 或 --amend åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/commit.c:1030 +#: builtin/commit.c:1032 msgid "Only one of --include/--only/--all/--interactive/--patch can be used." msgstr "åªèƒ½ç”¨ä¸€ä¸ª --include/--only/--all/--interactive/--patch 选项。" -#: builtin/commit.c:1032 +#: builtin/commit.c:1034 msgid "No paths with --include/--only does not make sense." msgstr "å‚æ•° --include/--only ä¸è·Ÿè·¯å¾„没有æ„义。" -#: builtin/commit.c:1034 +#: builtin/commit.c:1036 msgid "Clever... amending the last one with dirty index." msgstr "èªæ˜Ž... 在索引ä¸å¹²å‡€ä¸‹ä¿®è¡¥æœ€åŽçš„æ交。" -#: builtin/commit.c:1036 +#: builtin/commit.c:1038 msgid "Explicit paths specified without -i nor -o; assuming --only paths..." msgstr "指定了明确的路径而没有使用 -i 或 -o 选项;认为是 --only paths..." -#: builtin/commit.c:1046 builtin/tag.c:575 +#: builtin/commit.c:1048 builtin/tag.c:575 #, c-format msgid "Invalid cleanup mode %s" msgstr "æ— æ•ˆçš„æ¸…ç†æ¨¡å¼ %s" -#: builtin/commit.c:1051 +#: builtin/commit.c:1053 msgid "Paths with -a does not make sense." msgstr "路径和 -a 选项åŒæ—¶ä½¿ç”¨æ²¡æœ‰æ„义。" -#: builtin/commit.c:1057 builtin/commit.c:1192 +#: builtin/commit.c:1059 builtin/commit.c:1194 msgid "--long and -z are incompatible" msgstr "--long å’Œ -z 选项ä¸å…¼å®¹" -#: builtin/commit.c:1152 builtin/commit.c:1388 +#: builtin/commit.c:1154 builtin/commit.c:1390 msgid "show status concisely" msgstr "以简æ´çš„æ ¼å¼æ˜¾ç¤ºçŠ¶æ€" -#: builtin/commit.c:1154 builtin/commit.c:1390 +#: builtin/commit.c:1156 builtin/commit.c:1392 msgid "show branch information" msgstr "显示分支信æ¯" -#: builtin/commit.c:1156 builtin/commit.c:1392 builtin/push.c:426 +#: builtin/commit.c:1158 builtin/commit.c:1394 builtin/push.c:426 msgid "machine-readable output" msgstr "机器å¯è¯»çš„输出" -#: builtin/commit.c:1159 builtin/commit.c:1394 +#: builtin/commit.c:1161 builtin/commit.c:1396 msgid "show status in long format (default)" msgstr "ä»¥é•¿æ ¼å¼æ˜¾ç¤ºçŠ¶æ€ï¼ˆé»˜è®¤ï¼‰" -#: builtin/commit.c:1162 builtin/commit.c:1397 +#: builtin/commit.c:1164 builtin/commit.c:1399 msgid "terminate entries with NUL" msgstr "æ¡ç›®ä»¥NULå—符结尾" -#: builtin/commit.c:1164 builtin/commit.c:1400 builtin/fast-export.c:647 -#: builtin/fast-export.c:650 builtin/tag.c:459 +#: builtin/commit.c:1166 builtin/commit.c:1402 builtin/fast-export.c:659 +#: builtin/fast-export.c:662 builtin/tag.c:459 msgid "mode" msgstr "模å¼" -#: builtin/commit.c:1165 builtin/commit.c:1400 +#: builtin/commit.c:1167 builtin/commit.c:1402 msgid "show untracked files, optional modes: all, normal, no. (Default: all)" msgstr "显示未跟踪的文件,“模å¼â€çš„å¯é€‰å‚数:allã€normalã€no。(默认:all)" -#: builtin/commit.c:1168 +#: builtin/commit.c:1170 msgid "show ignored files" msgstr "显示忽略的文件" -#: builtin/commit.c:1169 parse-options.h:151 +#: builtin/commit.c:1171 parse-options.h:151 msgid "when" msgstr "何时" -#: builtin/commit.c:1170 +#: builtin/commit.c:1172 msgid "" "ignore changes to submodules, optional when: all, dirty, untracked. " "(Default: all)" msgstr "" "忽略å模组的更改,“何时â€çš„å¯é€‰å‚数:allã€dirtyã€untracked。(默认:all)" -#: builtin/commit.c:1172 +#: builtin/commit.c:1174 msgid "list untracked files in columns" msgstr "以列的方å¼æ˜¾ç¤ºæœªè·Ÿè¸ªçš„文件" -#: builtin/commit.c:1246 +#: builtin/commit.c:1248 msgid "couldn't look up newly created commit" msgstr "æ— æ³•æ‰¾åˆ°æ–°åˆ›å»ºçš„æ交" -#: builtin/commit.c:1248 +#: builtin/commit.c:1250 msgid "could not parse newly created commit" msgstr "ä¸èƒ½è§£æžæ–°åˆ›å»ºçš„æ交" -#: builtin/commit.c:1289 +#: builtin/commit.c:1291 msgid "detached HEAD" msgstr "分离头指针" # 译者:ä¸æ–‡å—符串拼接,å¯åˆ 除å‰å¯¼ç©ºæ ¼ -#: builtin/commit.c:1291 +#: builtin/commit.c:1293 msgid " (root-commit)" msgstr "ï¼ˆæ ¹æ交)" -#: builtin/commit.c:1358 +#: builtin/commit.c:1360 msgid "suppress summary after successful commit" msgstr "æ交æˆåŠŸåŽä¸æ˜¾ç¤ºæ¦‚è¿°ä¿¡æ¯" -#: builtin/commit.c:1359 +#: builtin/commit.c:1361 msgid "show diff in commit message template" msgstr "在æ交说明模æ¿é‡Œæ˜¾ç¤ºå·®å¼‚" -#: builtin/commit.c:1361 +#: builtin/commit.c:1363 msgid "Commit message options" msgstr "æ交说明选项" -#: builtin/commit.c:1362 builtin/tag.c:457 +#: builtin/commit.c:1364 builtin/tag.c:457 msgid "read message from file" msgstr "从文件ä¸è¯»å–æ交说明" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "author" msgstr "作者" -#: builtin/commit.c:1363 +#: builtin/commit.c:1365 msgid "override author for commit" msgstr "æ交时覆盖作者" -#: builtin/commit.c:1364 builtin/gc.c:178 +#: builtin/commit.c:1366 builtin/gc.c:178 msgid "date" msgstr "日期" -#: builtin/commit.c:1364 +#: builtin/commit.c:1366 msgid "override date for commit" msgstr "æ交时覆盖日期" -#: builtin/commit.c:1365 builtin/merge.c:206 builtin/notes.c:533 +#: builtin/commit.c:1367 builtin/merge.c:208 builtin/notes.c:533 #: builtin/notes.c:690 builtin/tag.c:455 msgid "message" msgstr "说明" -#: builtin/commit.c:1365 +#: builtin/commit.c:1367 msgid "commit message" msgstr "æ交说明" -#: builtin/commit.c:1366 +#: builtin/commit.c:1368 msgid "reuse and edit message from specified commit" msgstr "é‡ç”¨å¹¶ç¼–辑指定æ交的æ交说明" -#: builtin/commit.c:1367 +#: builtin/commit.c:1369 msgid "reuse message from specified commit" msgstr "é‡ç”¨æŒ‡å®šæ交的æ交说明" -#: builtin/commit.c:1368 +#: builtin/commit.c:1370 msgid "use autosquash formatted message to fixup specified commit" msgstr "使用 autosquash æ ¼å¼çš„æ交说明用以修æ£æŒ‡å®šçš„æ交" -#: builtin/commit.c:1369 +#: builtin/commit.c:1371 msgid "use autosquash formatted message to squash specified commit" msgstr "使用 autosquash æ ¼å¼çš„æ交说明用以压缩至指定的æ交" -#: builtin/commit.c:1370 +#: builtin/commit.c:1372 msgid "the commit is authored by me now (used with -C/-c/--amend)" msgstr "现在将该æ交的作者改为我(和 -C/-c/--amend å‚数共用)" -#: builtin/commit.c:1371 builtin/log.c:1102 builtin/revert.c:109 +#: builtin/commit.c:1373 builtin/log.c:1113 builtin/revert.c:109 msgid "add Signed-off-by:" msgstr "æ·»åŠ Signed-off-by: ç¾å" -#: builtin/commit.c:1372 +#: builtin/commit.c:1374 msgid "use specified template file" msgstr "使用指定的模æ¿æ–‡ä»¶" -#: builtin/commit.c:1373 +#: builtin/commit.c:1375 msgid "force edit of commit" msgstr "强制编辑æ交" # 译者:å¯é€‰å€¼ï¼Œä¸èƒ½ç¿»è¯‘(或是原文ä¸ç¬”误,应为 mode) -#: builtin/commit.c:1374 +#: builtin/commit.c:1376 msgid "default" msgstr "default" -#: builtin/commit.c:1374 builtin/tag.c:460 +#: builtin/commit.c:1376 builtin/tag.c:460 msgid "how to strip spaces and #comments from message" msgstr "è®¾ç½®å¦‚ä½•åˆ é™¤æäº¤è¯´æ˜Žé‡Œçš„ç©ºæ ¼å’Œ#注释" -#: builtin/commit.c:1375 +#: builtin/commit.c:1377 msgid "include status in commit message template" msgstr "在æ交说明模æ¿é‡ŒåŒ…å«çŠ¶æ€ä¿¡æ¯" -#: builtin/commit.c:1376 builtin/merge.c:213 builtin/tag.c:461 +#: builtin/commit.c:1378 builtin/merge.c:215 builtin/tag.c:461 msgid "key id" msgstr "key id" -#: builtin/commit.c:1377 builtin/merge.c:214 +#: builtin/commit.c:1379 builtin/merge.c:216 msgid "GPG sign commit" msgstr "GPG æ交ç¾å" #. end commit message options -#: builtin/commit.c:1380 +#: builtin/commit.c:1382 msgid "Commit contents options" msgstr "æ交内容选项" -#: builtin/commit.c:1381 +#: builtin/commit.c:1383 msgid "commit all changed files" msgstr "æ交所有改动的文件" -#: builtin/commit.c:1382 +#: builtin/commit.c:1384 msgid "add specified files to index for commit" msgstr "æ·»åŠ æŒ‡å®šçš„æ–‡ä»¶åˆ°ç´¢å¼•åŒºç‰å¾…æ交" -#: builtin/commit.c:1383 +#: builtin/commit.c:1385 msgid "interactively add files" msgstr "交互å¼æ·»åŠ 文件" -#: builtin/commit.c:1384 +#: builtin/commit.c:1386 msgid "interactively add changes" msgstr "交互å¼æ·»åŠ å˜æ›´" -#: builtin/commit.c:1385 +#: builtin/commit.c:1387 msgid "commit only specified files" msgstr "åªæ交指定的文件" -#: builtin/commit.c:1386 +#: builtin/commit.c:1388 msgid "bypass pre-commit hook" msgstr "绕过 pre-commit é’©å" -#: builtin/commit.c:1387 +#: builtin/commit.c:1389 msgid "show what would be committed" msgstr "显示将è¦æ交的内容" -#: builtin/commit.c:1398 +#: builtin/commit.c:1400 msgid "amend previous commit" msgstr "修改先å‰çš„æ交" -#: builtin/commit.c:1399 +#: builtin/commit.c:1401 msgid "bypass post-rewrite hook" msgstr "绕过 post-rewrite é’©å" -#: builtin/commit.c:1404 +#: builtin/commit.c:1406 msgid "ok to record an empty change" msgstr "å…许一个空æ交" -#: builtin/commit.c:1407 +#: builtin/commit.c:1409 msgid "ok to record a change with an empty message" msgstr "å…许空的æ交说明" -#: builtin/commit.c:1439 +#: builtin/commit.c:1441 msgid "could not parse HEAD commit" msgstr "ä¸èƒ½è§£æž HEAD æ交" -#: builtin/commit.c:1477 builtin/merge.c:508 +#: builtin/commit.c:1479 builtin/merge.c:510 #, c-format msgid "could not open '%s' for reading" msgstr "ä¸èƒ½ä¸ºè¯»å…¥æ‰“å¼€ '%s'" -#: builtin/commit.c:1484 +#: builtin/commit.c:1486 #, c-format msgid "Corrupt MERGE_HEAD file (%s)" msgstr "æŸåçš„ MERGE_HEAD 文件(%s)" -#: builtin/commit.c:1491 +#: builtin/commit.c:1493 msgid "could not read MERGE_MODE" msgstr "ä¸èƒ½è¯»å– MERGE_MODE" -#: builtin/commit.c:1510 +#: builtin/commit.c:1512 #, c-format msgid "could not read commit message: %s" msgstr "ä¸èƒ½è¯»å–æ交说明:%s" -#: builtin/commit.c:1524 +#: builtin/commit.c:1526 #, c-format msgid "Aborting commit; you did not edit the message.\n" msgstr "终æ¢æ交;您未更改æ¥è‡ªæ¨¡ç‰ˆçš„æ交说明。\n" -#: builtin/commit.c:1529 +#: builtin/commit.c:1531 #, c-format msgid "Aborting commit due to empty commit message.\n" msgstr "终æ¢æäº¤å› ä¸ºæ交说明为空。\n" -#: builtin/commit.c:1544 builtin/merge.c:832 builtin/merge.c:857 +#: builtin/commit.c:1546 builtin/merge.c:847 builtin/merge.c:872 msgid "failed to write commit object" msgstr "æ— æ³•å†™æ交对象" -#: builtin/commit.c:1565 +#: builtin/commit.c:1567 msgid "cannot lock HEAD ref" msgstr "æ— æ³•é”定 HEAD 引用" -#: builtin/commit.c:1569 +#: builtin/commit.c:1571 msgid "cannot update HEAD ref" msgstr "æ— æ³•æ›´æ–° HEAD 引用" -#: builtin/commit.c:1580 +#: builtin/commit.c:1582 msgid "" "Repository has been updated, but unable to write\n" "new_index file. Check that disk is not full or quota is\n" @@ -4047,9 +4315,13 @@ msgstr "终æ¢å€¼æ˜¯NULå—节" msgid "respect include directives on lookup" msgstr "查询时å‚ç…§ include 指令递归查找" -#: builtin/count-objects.c:69 -msgid "git count-objects [-v]" -msgstr "git count-objects [-v]" +#: builtin/count-objects.c:82 +msgid "git count-objects [-v] [-H | --human-readable]" +msgstr "git count-objects [-v] [-H | --human-readable]" + +#: builtin/count-objects.c:97 +msgid "print sizes in human readable format" +msgstr "以用户å¯è¯»çš„æ ¼å¼æ˜¾ç¤ºå¤§å°" #: builtin/describe.c:15 msgid "git describe [options] <committish>*" @@ -4059,47 +4331,47 @@ msgstr "git describe [选项] <æ交å·>*" msgid "git describe [options] --dirty" msgstr "git describe [选项] --dirty" -#: builtin/describe.c:234 +#: builtin/describe.c:233 #, c-format msgid "annotated tag %s not available" msgstr "注释 tag %s æ— æ•ˆ" -#: builtin/describe.c:238 +#: builtin/describe.c:237 #, c-format msgid "annotated tag %s has no embedded name" msgstr "注释 tag %s 没有嵌入å称" -#: builtin/describe.c:240 +#: builtin/describe.c:239 #, c-format msgid "tag '%s' is really '%s' here" msgstr "tag '%s' 的确是在 '%s'" -#: builtin/describe.c:267 +#: builtin/describe.c:266 #, c-format msgid "Not a valid object name %s" msgstr "ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„对象å %s" -#: builtin/describe.c:270 +#: builtin/describe.c:269 #, c-format msgid "%s is not a valid '%s' object" msgstr "%s ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ '%s' 对象" -#: builtin/describe.c:287 +#: builtin/describe.c:286 #, c-format msgid "no tag exactly matches '%s'" msgstr "没有 tag å‡†ç¡®åŒ¹é… '%s'" -#: builtin/describe.c:289 +#: builtin/describe.c:288 #, c-format msgid "searching to describe %s\n" msgstr "æœç´¢æè¿° %s\n" -#: builtin/describe.c:329 +#: builtin/describe.c:328 #, c-format msgid "finished search at %s\n" msgstr "完æˆæœç´¢ %s\n" -#: builtin/describe.c:353 +#: builtin/describe.c:352 #, c-format msgid "" "No annotated tags can describe '%s'.\n" @@ -4108,7 +4380,7 @@ msgstr "" "没有注释 tag 能æè¿° '%s'。\n" "然而,有éžæ³¨é‡Š tag:å°è¯• --tags。" -#: builtin/describe.c:357 +#: builtin/describe.c:356 #, c-format msgid "" "No tags can describe '%s'.\n" @@ -4117,12 +4389,12 @@ msgstr "" "没有注释 tag 能æè¿° '%s'。\n" "å°è¯• --always,或者创建一些 tag。" -#: builtin/describe.c:378 +#: builtin/describe.c:377 #, c-format msgid "traversed %lu commits\n" msgstr "å·²é历 %lu 个æ交\n" -#: builtin/describe.c:381 +#: builtin/describe.c:380 #, c-format msgid "" "more than %i tags found; listed %i most recent\n" @@ -4131,59 +4403,59 @@ msgstr "" "å‘现多于 %i 个 tag,列出最近的 %i 个\n" "在 %s 放弃æœç´¢\n" -#: builtin/describe.c:403 +#: builtin/describe.c:402 msgid "find the tag that comes after the commit" msgstr "寻找æ交之åŽçš„ tag(用于æè¿°æ交)" -#: builtin/describe.c:404 +#: builtin/describe.c:403 msgid "debug search strategy on stderr" msgstr "åœ¨æ ‡å‡†é”™è¯¯ä¸Šè°ƒè¯•æœç´¢ç–ç•¥" +#: builtin/describe.c:404 +msgid "use any ref" +msgstr "使用任æ„引用" + #: builtin/describe.c:405 -msgid "use any ref in .git/refs" -msgstr "使用 .git/refs 里的任æ„引用" +msgid "use any tag, even unannotated" +msgstr "ä½¿ç”¨ä»»æ„ tag,å³ä½¿æœªå¸¦æ³¨è§£" #: builtin/describe.c:406 -msgid "use any tag in .git/refs/tags" -msgstr "使用 .git/refs/tags é‡Œçš„ä»»æ„ tag" - -#: builtin/describe.c:407 msgid "always use long format" msgstr "始终使用长æ交å·æ ¼å¼" -#: builtin/describe.c:410 +#: builtin/describe.c:409 msgid "only output exact matches" msgstr "åªè¾“出精确匹é…" -#: builtin/describe.c:412 +#: builtin/describe.c:411 msgid "consider <n> most recent tags (default: 10)" msgstr "考虑最近 <n> 个 tags(默认:10)" -#: builtin/describe.c:414 +#: builtin/describe.c:413 msgid "only consider tags matching <pattern>" msgstr "åªè€ƒè™‘åŒ¹é… <模å¼> çš„ tags" -#: builtin/describe.c:416 builtin/name-rev.c:238 +#: builtin/describe.c:415 builtin/name-rev.c:238 msgid "show abbreviated commit object as fallback" msgstr "显示简写的æ交å·ä½œä¸ºåŽå¤‡" -#: builtin/describe.c:417 +#: builtin/describe.c:416 msgid "mark" msgstr "æ ‡è®°" -#: builtin/describe.c:418 +#: builtin/describe.c:417 msgid "append <mark> on dirty working tree (default: \"-dirty\")" msgstr "若工作区è„(有å˜æ›´ï¼‰åœ¨ç»“å°¾æ·»åŠ <æ ‡è®°>(默认:\"-dirty\")" -#: builtin/describe.c:436 +#: builtin/describe.c:435 msgid "--long is incompatible with --abbrev=0" msgstr "--long 与 --abbrev=0 ä¸å…¼å®¹" -#: builtin/describe.c:462 +#: builtin/describe.c:461 msgid "No names found, cannot describe anything." msgstr "没有å‘现åç§°ï¼Œæ— æ³•æ述任何东西。" -#: builtin/describe.c:482 +#: builtin/describe.c:481 msgid "--dirty is incompatible with committishes" msgstr "--dirty ä¸èƒ½ä¸Žæ交åŒæ—¶ä½¿ç”¨" @@ -4225,39 +4497,39 @@ msgstr "æä¾›äº†æ— æ³•å¤„ç†çš„对象 '%s'。" msgid "git fast-export [rev-list-opts]" msgstr "git fast-export [rev-list-opts]" -#: builtin/fast-export.c:646 +#: builtin/fast-export.c:658 msgid "show progress after <n> objects" msgstr "在 <n> 个对象之åŽæ˜¾ç¤ºè¿›åº¦" -#: builtin/fast-export.c:648 +#: builtin/fast-export.c:660 msgid "select handling of signed tags" msgstr "选择如何处ç†ç¾å tags" -#: builtin/fast-export.c:651 +#: builtin/fast-export.c:663 msgid "select handling of tags that tag filtered objects" msgstr "选择当 tag 指å‘被过滤时 tags 的处ç†æ–¹å¼" -#: builtin/fast-export.c:654 +#: builtin/fast-export.c:666 msgid "Dump marks to this file" msgstr "æŠŠæ ‡è®°å˜å‚¨åˆ°è¿™ä¸ªæ–‡ä»¶" -#: builtin/fast-export.c:656 +#: builtin/fast-export.c:668 msgid "Import marks from this file" msgstr "ä»Žè¿™ä¸ªæ–‡ä»¶å¯¼å…¥æ ‡è®°" -#: builtin/fast-export.c:658 +#: builtin/fast-export.c:670 msgid "Fake a tagger when tags lack one" msgstr "当 tags ç¼ºå°‘æ ‡è®°è€…å—段时,å‡è£…æ供一个" -#: builtin/fast-export.c:660 +#: builtin/fast-export.c:672 msgid "Output full tree for each commit" msgstr "æ¯æ¬¡æäº¤éƒ½è¾“å‡ºæ•´ä¸ªæ ‘" -#: builtin/fast-export.c:662 +#: builtin/fast-export.c:674 msgid "Use the done feature to terminate the stream" msgstr "使用 done 功能æ¥ç»ˆæ¢æµ" -#: builtin/fast-export.c:663 +#: builtin/fast-export.c:675 msgid "Skip output of blob data" msgstr "跳过数æ®å¯¹è±¡çš„输出" @@ -4334,7 +4606,7 @@ msgstr "深化浅克隆的历å²" msgid "convert to a complete repository" msgstr "转æ¢ä¸ºä¸€ä¸ªå®Œæ•´çš„版本库" -#: builtin/fetch.c:88 builtin/log.c:1119 +#: builtin/fetch.c:88 builtin/log.c:1130 msgid "dir" msgstr "目录" @@ -4515,29 +4787,29 @@ msgid "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" msgstr "" "git fmt-merge-msg [-m <message>] [--log[=<n>]|--no-log] [--file <file>]" -#: builtin/fmt-merge-msg.c:659 builtin/fmt-merge-msg.c:662 builtin/grep.c:701 -#: builtin/merge.c:188 builtin/show-branch.c:656 builtin/show-ref.c:175 +#: builtin/fmt-merge-msg.c:663 builtin/fmt-merge-msg.c:666 builtin/grep.c:701 +#: builtin/merge.c:188 builtin/show-branch.c:655 builtin/show-ref.c:175 #: builtin/tag.c:446 parse-options.h:133 parse-options.h:239 msgid "n" msgstr "n" -#: builtin/fmt-merge-msg.c:660 +#: builtin/fmt-merge-msg.c:664 msgid "populate log with at most <n> entries from shortlog" msgstr "å‘æ交说明ä¸æœ€å¤šå¤åˆ¶æŒ‡å®šæ¡ç›®ï¼ˆåˆå¹¶è€Œæ¥çš„æ交)的简çŸè¯´æ˜Ž" -#: builtin/fmt-merge-msg.c:663 +#: builtin/fmt-merge-msg.c:667 msgid "alias for --log (deprecated)" msgstr "å‚æ•° --log 的别å(已弃用)" -#: builtin/fmt-merge-msg.c:666 +#: builtin/fmt-merge-msg.c:670 msgid "text" msgstr "文本" -#: builtin/fmt-merge-msg.c:667 +#: builtin/fmt-merge-msg.c:671 msgid "use <text> as start of message" msgstr "使用 <文本> 作为æ交说明的开始" -#: builtin/fmt-merge-msg.c:668 +#: builtin/fmt-merge-msg.c:672 msgid "file to read from" msgstr "从文件ä¸è¯»å–" @@ -4872,28 +5144,23 @@ msgstr "显示用法" msgid "no pattern given." msgstr "未æ供模å¼åŒ¹é…。" -#: builtin/grep.c:825 -#, c-format -msgid "bad object %s" -msgstr "å对象 %s" - -#: builtin/grep.c:868 +#: builtin/grep.c:866 msgid "--open-files-in-pager only works on the worktree" msgstr "--open-files-in-pager 仅用于工作区" -#: builtin/grep.c:891 +#: builtin/grep.c:889 msgid "--cached or --untracked cannot be used with --no-index." msgstr "--cached 或 --untracked ä¸èƒ½ä¸Ž --no-index åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/grep.c:896 +#: builtin/grep.c:894 msgid "--no-index or --untracked cannot be used with revs." msgstr "--no-index 或 --untracked ä¸èƒ½å’Œç‰ˆæœ¬åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/grep.c:899 +#: builtin/grep.c:897 msgid "--[no-]exclude-standard cannot be used for tracked contents." msgstr "--[no-]exclude-standard ä¸èƒ½ç”¨äºŽå·²è·Ÿè¸ªå†…容。" -#: builtin/grep.c:907 +#: builtin/grep.c:905 msgid "both --cached and trees are given." msgstr "åŒæ—¶ç»™å‡ºäº† --cached å’Œæ ‘å¯¹è±¡ã€‚" @@ -4933,50 +5200,54 @@ msgstr "åŽŸæ ·å˜å‚¨æ–‡ä»¶ä¸ä½¿ç”¨è¿‡æ»¤å™¨" msgid "process file as it were from this path" msgstr "处ç†æ–‡ä»¶å¹¶å‡è®¾å…¶æ¥è‡ªäºŽæ¤è·¯å¾„" -#: builtin/help.c:42 +#: builtin/help.c:43 msgid "print all available commands" msgstr "打å°æ‰€æœ‰å¯ç”¨çš„命令" -#: builtin/help.c:43 +#: builtin/help.c:44 +msgid "print list of useful guides" +msgstr "显示有用的指å—列表" + +#: builtin/help.c:45 msgid "show man page" msgstr "显示 man 手册" -#: builtin/help.c:44 +#: builtin/help.c:46 msgid "show manual in web browser" msgstr "在 web æµè§ˆå™¨ä¸æ˜¾ç¤ºæ‰‹å†Œ" -#: builtin/help.c:46 +#: builtin/help.c:48 msgid "show info page" msgstr "显示 info 手册" -#: builtin/help.c:52 -msgid "git help [--all] [--man|--web|--info] [command]" -msgstr "git help [--all] [--man|--web|--info] [命令]" +#: builtin/help.c:54 +msgid "git help [--all] [--guides] [--man|--web|--info] [command]" +msgstr "git help [--all] [--guides] [--man|--web|--info] [命令]" -#: builtin/help.c:64 +#: builtin/help.c:66 #, c-format msgid "unrecognized help format '%s'" msgstr "æœªèƒ½è¯†åˆ«çš„å¸®åŠ©æ ¼å¼ '%s'" -#: builtin/help.c:92 +#: builtin/help.c:94 msgid "Failed to start emacsclient." msgstr "æ— æ³•å¯åŠ¨ emacsclient。" -#: builtin/help.c:105 +#: builtin/help.c:107 msgid "Failed to parse emacsclient version." msgstr "æ— æ³•è§£æž emacsclient 版本。" -#: builtin/help.c:113 +#: builtin/help.c:115 #, c-format msgid "emacsclient version '%d' too old (< 22)." msgstr "emacsclient 版本 '%d' 太è€ï¼ˆ< 22)。" -#: builtin/help.c:131 builtin/help.c:159 builtin/help.c:168 builtin/help.c:176 +#: builtin/help.c:133 builtin/help.c:161 builtin/help.c:170 builtin/help.c:178 #, c-format msgid "failed to exec '%s': %s" msgstr "æ— æ³•æ‰§è¡Œ '%s':%s" -#: builtin/help.c:216 +#: builtin/help.c:218 #, c-format msgid "" "'%s': path for unsupported man viewer.\n" @@ -4985,7 +5256,7 @@ msgstr "" "'%s':ä¸æ”¯æŒçš„ man 手册查看器的路径。\n" "请使用 'man.<tool>.cmd'。" -#: builtin/help.c:228 +#: builtin/help.c:230 #, c-format msgid "" "'%s': cmd for supported man viewer.\n" @@ -4994,303 +5265,335 @@ msgstr "" "'%s': 支æŒçš„ man 手册查看器命令。\n" "请使用 'man.<tool>.path'。" -#: builtin/help.c:349 +#: builtin/help.c:351 #, c-format msgid "'%s': unknown man viewer." msgstr "'%s':未知的 man 查看器。" -#: builtin/help.c:366 +#: builtin/help.c:368 msgid "no man viewer handled the request" msgstr "没有 man 查看器处ç†æ¤è¯·æ±‚" -#: builtin/help.c:374 +#: builtin/help.c:376 msgid "no info viewer handled the request" msgstr "没有 info 查看器处ç†æ¤è¯·æ±‚" -#: builtin/help.c:429 builtin/help.c:436 +#: builtin/help.c:422 +msgid "Defining attributes per path" +msgstr "定义路径的属性" + +#: builtin/help.c:423 +msgid "A Git glossary" +msgstr "Git è¯æ±‡è¡¨" + +#: builtin/help.c:424 +msgid "Specifies intentionally untracked files to ignore" +msgstr "忽略指定的未跟踪文件" + +#: builtin/help.c:425 +msgid "Defining submodule properties" +msgstr "定义å模组属性" + +#: builtin/help.c:426 +msgid "Specifying revisions and ranges for Git" +msgstr "指定 Git 的版本和版本范围" + +#: builtin/help.c:427 +msgid "A tutorial introduction to Git (for version 1.5.1 or newer)" +msgstr "一个 Git 教程(针对 1.5.1 或更新版本)" + +#: builtin/help.c:428 +msgid "An overview of recommended workflows with Git" +msgstr "Git 推è的工作æµæ¦‚览" + +#: builtin/help.c:440 +msgid "The common Git guides are:\n" +msgstr "最常用的 Git å‘导有:\n" + +#: builtin/help.c:462 builtin/help.c:478 #, c-format msgid "usage: %s%s" msgstr "用法:%s%s" -#: builtin/help.c:452 +#: builtin/help.c:494 #, c-format msgid "`git %s' is aliased to `%s'" msgstr "`git %s' 是 `%s' 的别å" -#: builtin/index-pack.c:170 +#: builtin/index-pack.c:182 #, c-format msgid "object type mismatch at %s" msgstr "%s 的对象类型ä¸åŒ¹é…" -#: builtin/index-pack.c:190 +#: builtin/index-pack.c:202 msgid "object of unexpected type" msgstr "æ„外的类型的对象" -#: builtin/index-pack.c:227 +#: builtin/index-pack.c:239 #, c-format msgid "cannot fill %d byte" msgid_plural "cannot fill %d bytes" msgstr[0] "æ— æ³•å¡«å…… %d å—节" msgstr[1] "æ— æ³•å¡«å…… %d å—节" -#: builtin/index-pack.c:237 +#: builtin/index-pack.c:249 msgid "early EOF" msgstr "过早的文件结æŸç¬¦ï¼ˆEOF)" -#: builtin/index-pack.c:238 +#: builtin/index-pack.c:250 msgid "read error on input" msgstr "输入上的读错误" -#: builtin/index-pack.c:250 +#: builtin/index-pack.c:262 msgid "used more bytes than were available" msgstr "用掉了超过å¯ç”¨çš„å—节" -#: builtin/index-pack.c:257 +#: builtin/index-pack.c:269 msgid "pack too large for current definition of off_t" msgstr "åŒ…å¤ªå¤§è¶…è¿‡äº†å½“å‰ off_t 的定义" -#: builtin/index-pack.c:273 +#: builtin/index-pack.c:285 #, c-format msgid "unable to create '%s'" msgstr "ä¸èƒ½åˆ›å»º '%s'" -#: builtin/index-pack.c:278 +#: builtin/index-pack.c:290 #, c-format msgid "cannot open packfile '%s'" msgstr "æ— æ³•æ‰“å¼€åŒ…æ–‡ä»¶ '%s'" -#: builtin/index-pack.c:292 +#: builtin/index-pack.c:304 msgid "pack signature mismatch" msgstr "包ç¾åä¸åŒ¹é…" -#: builtin/index-pack.c:294 +#: builtin/index-pack.c:306 #, c-format msgid "pack version %<PRIu32> unsupported" msgstr "ä¸æ”¯æŒåŒ…版本 %<PRIu32>" -#: builtin/index-pack.c:312 +#: builtin/index-pack.c:324 #, c-format msgid "pack has bad object at offset %lu: %s" msgstr "包ä¸æœ‰é”™è¯¯çš„对象ä½äºŽ %lu:%s" -#: builtin/index-pack.c:434 +#: builtin/index-pack.c:446 #, c-format msgid "inflate returned %d" msgstr "解压缩返回 %d" -#: builtin/index-pack.c:483 +#: builtin/index-pack.c:495 msgid "offset value overflow for delta base object" msgstr "å移值覆盖了 delta 基准对象" -#: builtin/index-pack.c:491 +#: builtin/index-pack.c:503 msgid "delta base offset is out of bound" msgstr "delta 基准å移越界" -#: builtin/index-pack.c:499 +#: builtin/index-pack.c:511 #, c-format msgid "unknown object type %d" msgstr "未知对象类型 %d" -#: builtin/index-pack.c:530 +#: builtin/index-pack.c:542 msgid "cannot pread pack file" msgstr "æ— æ³•è¯»å–包文件" -#: builtin/index-pack.c:532 +#: builtin/index-pack.c:544 #, c-format msgid "premature end of pack file, %lu byte missing" msgid_plural "premature end of pack file, %lu bytes missing" msgstr[0] "包文件过早结æŸï¼Œç¼ºå°‘ %lu å—节" msgstr[1] "包文件过早结æŸï¼Œç¼ºå°‘ %lu å—节" -#: builtin/index-pack.c:558 +#: builtin/index-pack.c:570 msgid "serious inflate inconsistency" msgstr "解压缩严é‡çš„ä¸ä¸€è‡´" -#: builtin/index-pack.c:649 builtin/index-pack.c:655 builtin/index-pack.c:678 -#: builtin/index-pack.c:712 builtin/index-pack.c:721 +#: builtin/index-pack.c:661 builtin/index-pack.c:667 builtin/index-pack.c:690 +#: builtin/index-pack.c:724 builtin/index-pack.c:733 #, c-format msgid "SHA1 COLLISION FOUND WITH %s !" msgstr "å‘现 %s 出现 SHA1 冲çªï¼" -#: builtin/index-pack.c:652 builtin/pack-objects.c:170 +#: builtin/index-pack.c:664 builtin/pack-objects.c:170 #: builtin/pack-objects.c:262 #, c-format msgid "unable to read %s" msgstr "ä¸èƒ½è¯» %s" -#: builtin/index-pack.c:718 +#: builtin/index-pack.c:730 #, c-format msgid "cannot read existing object %s" msgstr "ä¸èƒ½è¯»å–现å˜å¯¹è±¡ %s" -#: builtin/index-pack.c:732 +#: builtin/index-pack.c:744 #, c-format msgid "invalid blob object %s" msgstr "æ— æ•ˆçš„æ•°æ®ï¼ˆblob)对象 %s" -#: builtin/index-pack.c:747 +#: builtin/index-pack.c:759 #, c-format msgid "invalid %s" msgstr "æ— æ•ˆçš„ %s" -#: builtin/index-pack.c:749 +#: builtin/index-pack.c:761 msgid "Error in object" msgstr "对象ä¸å‡ºé”™" -#: builtin/index-pack.c:751 +#: builtin/index-pack.c:763 #, c-format msgid "Not all child objects of %s are reachable" msgstr "%s 的所有å对象并éžéƒ½å¯è¾¾" -#: builtin/index-pack.c:821 builtin/index-pack.c:847 +#: builtin/index-pack.c:833 builtin/index-pack.c:863 msgid "failed to apply delta" msgstr "æ— æ³•åº”ç”¨ delta" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Receiving objects" msgstr "接收对象ä¸" -#: builtin/index-pack.c:986 +#: builtin/index-pack.c:1004 msgid "Indexing objects" msgstr "索引对象ä¸" -#: builtin/index-pack.c:1012 +#: builtin/index-pack.c:1030 msgid "pack is corrupted (SHA1 mismatch)" msgstr "包冲çªï¼ˆSHA1 ä¸åŒ¹é…)" -#: builtin/index-pack.c:1017 +#: builtin/index-pack.c:1035 msgid "cannot fstat packfile" msgstr "ä¸èƒ½æžšä¸¾åŒ…文件状æ€" -#: builtin/index-pack.c:1020 +#: builtin/index-pack.c:1038 msgid "pack has junk at the end" msgstr "包的结尾有垃圾数æ®" -#: builtin/index-pack.c:1031 +#: builtin/index-pack.c:1049 msgid "confusion beyond insanity in parse_pack_objects()" msgstr "parse_pack_objects() ä¸é‡åˆ°ä¸å¯ç†å–»çš„问题" -#: builtin/index-pack.c:1054 +#: builtin/index-pack.c:1072 msgid "Resolving deltas" msgstr "å¤„ç† delta ä¸" -#: builtin/index-pack.c:1064 +#: builtin/index-pack.c:1082 #, c-format msgid "unable to create thread: %s" msgstr "ä¸èƒ½åˆ›å»ºçº¿ç¨‹ï¼š%s" -#: builtin/index-pack.c:1106 +#: builtin/index-pack.c:1124 msgid "confusion beyond insanity" msgstr "ä¸å¯ç†å–»" -#: builtin/index-pack.c:1112 +#: builtin/index-pack.c:1132 #, c-format msgid "completed with %d local objects" msgstr "å®Œæˆ %d 个本地对象" -#: builtin/index-pack.c:1121 +#: builtin/index-pack.c:1142 #, c-format msgid "Unexpected tail checksum for %s (disk corruption?)" msgstr "对 %s çš„å°¾éƒ¨æ ¡éªŒå‡ºçŽ°æ„外(ç£ç›˜æŸå?)" -#: builtin/index-pack.c:1125 +#: builtin/index-pack.c:1146 #, c-format msgid "pack has %d unresolved delta" msgid_plural "pack has %d unresolved deltas" msgstr[0] "包有 %d 个未解决的 delta" msgstr[1] "包有 %d 个未解决的 delta" -#: builtin/index-pack.c:1150 +#: builtin/index-pack.c:1171 #, c-format msgid "unable to deflate appended object (%d)" msgstr "ä¸èƒ½åŽ‹ç¼©é™„åŠ å¯¹è±¡ï¼ˆ%d)" -#: builtin/index-pack.c:1229 +#: builtin/index-pack.c:1250 #, c-format msgid "local object %s is corrupt" msgstr "本地对象 %s å·²æŸå" -#: builtin/index-pack.c:1253 +#: builtin/index-pack.c:1274 msgid "error while closing pack file" msgstr "å…³é—包文件时出错" -#: builtin/index-pack.c:1266 +#: builtin/index-pack.c:1287 #, c-format msgid "cannot write keep file '%s'" msgstr "æ— æ³•å†™ä¿ç•™æ–‡ä»¶ '%s'" -#: builtin/index-pack.c:1274 +#: builtin/index-pack.c:1295 #, c-format msgid "cannot close written keep file '%s'" msgstr "æ— æ³•å…³é—ä¿ç•™æ–‡ä»¶ '%s'" -#: builtin/index-pack.c:1287 +#: builtin/index-pack.c:1308 msgid "cannot store pack file" msgstr "æ— æ³•å˜å‚¨åŒ…文件" -#: builtin/index-pack.c:1298 +#: builtin/index-pack.c:1319 msgid "cannot store index file" msgstr "æ— æ³•å˜å‚¨ç´¢å¼•æ–‡ä»¶" -#: builtin/index-pack.c:1331 +#: builtin/index-pack.c:1352 #, c-format msgid "bad pack.indexversion=%<PRIu32>" msgstr "åçš„ pack.indexversion=%<PRIu32>" -#: builtin/index-pack.c:1337 +#: builtin/index-pack.c:1358 #, c-format msgid "invalid number of threads specified (%d)" msgstr "æŒ‡å®šçš„çº¿ç¨‹æ•°æ— æ•ˆï¼ˆ%d)" -#: builtin/index-pack.c:1341 builtin/index-pack.c:1514 +#: builtin/index-pack.c:1362 builtin/index-pack.c:1535 #, c-format msgid "no threads support, ignoring %s" msgstr "没有线程支æŒï¼Œå¿½ç•¥ %s" -#: builtin/index-pack.c:1399 +#: builtin/index-pack.c:1420 #, c-format msgid "Cannot open existing pack file '%s'" msgstr "æ— æ³•æ‰“å¼€çŽ°å˜åŒ…文件 '%s'" -#: builtin/index-pack.c:1401 +#: builtin/index-pack.c:1422 #, c-format msgid "Cannot open existing pack idx file for '%s'" msgstr "æ— æ³•ä¸º %s 打开包索引文件" -#: builtin/index-pack.c:1448 +#: builtin/index-pack.c:1469 #, c-format msgid "non delta: %d object" msgid_plural "non delta: %d objects" msgstr[0] "éž delta:%d 个对象" msgstr[1] "éž delta:%d 个对象" -#: builtin/index-pack.c:1455 +#: builtin/index-pack.c:1476 #, c-format msgid "chain length = %d: %lu object" msgid_plural "chain length = %d: %lu objects" msgstr[0] "链长 = %d: %lu 对象" msgstr[1] "链长 = %d: %lu 对象" -#: builtin/index-pack.c:1482 +#: builtin/index-pack.c:1503 msgid "Cannot come back to cwd" msgstr "æ— æ³•è¿”å›žå½“å‰å·¥ä½œç›®å½•" -#: builtin/index-pack.c:1526 builtin/index-pack.c:1529 -#: builtin/index-pack.c:1541 builtin/index-pack.c:1545 +#: builtin/index-pack.c:1547 builtin/index-pack.c:1550 +#: builtin/index-pack.c:1562 builtin/index-pack.c:1566 #, c-format msgid "bad %s" msgstr "错误选项 %s" -#: builtin/index-pack.c:1559 +#: builtin/index-pack.c:1580 msgid "--fix-thin cannot be used without --stdin" msgstr "--fix-thin ä¸èƒ½å’Œ --stdin åŒæ—¶ä½¿ç”¨" -#: builtin/index-pack.c:1563 builtin/index-pack.c:1573 +#: builtin/index-pack.c:1584 builtin/index-pack.c:1594 #, c-format msgid "packfile name '%s' does not end with '.pack'" msgstr "包å '%s' 没有以 '.pack' 结尾" -#: builtin/index-pack.c:1582 +#: builtin/index-pack.c:1603 msgid "--verify with no packfile name given" msgstr "--verify 没有æ供包åå‚æ•°" @@ -5459,345 +5762,340 @@ msgstr "ä¸èƒ½è®¿é—®å½“å‰å·¥ä½œç›®å½•" msgid "Cannot access work tree '%s'" msgstr "ä¸èƒ½è®¿é—®å·¥ä½œåŒº '%s'" -#: builtin/log.c:39 -msgid "git log [<options>] [<since>..<until>] [[--] <path>...]\n" -msgstr "git log [<选项>] [<从>..<到>] [[--] <路径>...]\n" - #: builtin/log.c:40 +msgid "git log [<options>] [<revision range>] [[--] <path>...]\n" +msgstr "git log [<选项>] [<版本范围>] [[--] <路径>...]\n" + +#: builtin/log.c:41 msgid " or: git show [options] <object>..." msgstr " 或者:git show [选项] <对象>..." -#: builtin/log.c:102 +#: builtin/log.c:103 msgid "suppress diff output" msgstr "ä¸æ˜¾ç¤ºå·®å¼‚输出" -#: builtin/log.c:103 +#: builtin/log.c:104 msgid "show source" msgstr "显示æº" -#: builtin/log.c:104 +#: builtin/log.c:105 msgid "Use mail map file" msgstr "ä½¿ç”¨é‚®ä»¶æ˜ å°„æ–‡ä»¶" -#: builtin/log.c:105 +#: builtin/log.c:106 msgid "decorate options" msgstr "修饰选项" -#: builtin/log.c:198 +#: builtin/log.c:199 #, c-format msgid "Final output: %d %s\n" msgstr "最终输出:%d %s\n" -#: builtin/log.c:419 builtin/log.c:511 +#: builtin/log.c:422 builtin/log.c:514 #, c-format msgid "Could not read object %s" msgstr "ä¸èƒ½è¯»å–对象 %s" -#: builtin/log.c:535 +#: builtin/log.c:538 #, c-format msgid "Unknown type: %d" msgstr "未知类型:%d" -#: builtin/log.c:627 +#: builtin/log.c:638 msgid "format.headers without value" msgstr "format.headers 没有值" -#: builtin/log.c:701 +#: builtin/log.c:720 msgid "name of output directory is too long" msgstr "输出目录å太长" -#: builtin/log.c:717 +#: builtin/log.c:736 #, c-format msgid "Cannot open patch file %s" msgstr "æ— æ³•æ‰“å¼€è¡¥ä¸æ–‡ä»¶ %s" -#: builtin/log.c:731 +#: builtin/log.c:750 msgid "Need exactly one range." msgstr "åªéœ€è¦ä¸€ä¸ªèŒƒå›´ã€‚" -#: builtin/log.c:739 +#: builtin/log.c:758 msgid "Not a range." msgstr "ä¸æ˜¯ä¸€ä¸ªèŒƒå›´ã€‚" -#: builtin/log.c:812 +#: builtin/log.c:860 msgid "Cover letter needs email format" msgstr "ä¿¡å°éœ€è¦é‚®ä»¶åœ°å€æ ¼å¼" -#: builtin/log.c:885 +#: builtin/log.c:936 #, c-format msgid "insane in-reply-to: %s" msgstr "ä¸æ£å¸¸çš„ in-reply-to:%s" -#: builtin/log.c:913 +#: builtin/log.c:964 msgid "git format-patch [options] [<since> | <revision range>]" msgstr "git format-patch [选项] [<从> | <修订集范围>]" -#: builtin/log.c:958 +#: builtin/log.c:1009 msgid "Two output directories?" msgstr "两个输出目录?" -#: builtin/log.c:1097 +#: builtin/log.c:1108 msgid "use [PATCH n/m] even with a single patch" msgstr "使用 [PATCH n/m],å³ä½¿åªæœ‰ä¸€ä¸ªè¡¥ä¸" -#: builtin/log.c:1100 +#: builtin/log.c:1111 msgid "use [PATCH] even with multiple patches" msgstr "使用 [PATCH],å³ä½¿æœ‰å¤šä¸ªè¡¥ä¸" -#: builtin/log.c:1104 +#: builtin/log.c:1115 msgid "print patches to standard out" msgstr "打å°è¡¥ä¸åˆ°æ ‡å‡†è¾“出" -#: builtin/log.c:1106 +#: builtin/log.c:1117 msgid "generate a cover letter" msgstr "生æˆä¸€å°é™„ä¿¡" -#: builtin/log.c:1108 +#: builtin/log.c:1119 msgid "use simple number sequence for output file names" msgstr "使用简å•çš„æ•°å—åºåˆ—作为输出文件å" -#: builtin/log.c:1109 +#: builtin/log.c:1120 msgid "sfx" msgstr "åŽç¼€" -#: builtin/log.c:1110 +#: builtin/log.c:1121 msgid "use <sfx> instead of '.patch'" msgstr "使用 <åŽç¼€> 代替 '.patch'" -#: builtin/log.c:1112 +#: builtin/log.c:1123 msgid "start numbering patches at <n> instead of 1" msgstr "è¡¥ä¸ä»¥ <n> 开始编å·ï¼Œè€Œä¸æ˜¯1" -#: builtin/log.c:1114 +#: builtin/log.c:1125 msgid "mark the series as Nth re-roll" msgstr "æ ‡è®°è¡¥ä¸ç³»åˆ—æ˜¯ç¬¬å‡ æ¬¡é‡åˆ¶" -#: builtin/log.c:1116 +#: builtin/log.c:1127 msgid "Use [<prefix>] instead of [PATCH]" msgstr "使用 [<å‰ç¼€>] 代替 [PATCH]" -#: builtin/log.c:1119 +#: builtin/log.c:1130 msgid "store resulting files in <dir>" msgstr "把结果文件å˜å‚¨åœ¨ <dir>" -#: builtin/log.c:1122 +#: builtin/log.c:1133 msgid "don't strip/add [PATCH]" msgstr "ä¸åˆ 除/æ·»åŠ [PATCH]" -#: builtin/log.c:1125 +#: builtin/log.c:1136 msgid "don't output binary diffs" msgstr "ä¸è¾“出二进制差异" -#: builtin/log.c:1127 +#: builtin/log.c:1138 msgid "don't include a patch matching a commit upstream" msgstr "ä¸åŒ…å«å·²åœ¨ä¸Šæ¸¸æ交ä¸çš„è¡¥ä¸" -#: builtin/log.c:1129 +#: builtin/log.c:1140 msgid "show patch format instead of default (patch + stat)" msgstr "显示纯补ä¸æ ¼å¼è€Œéžé»˜è®¤çš„(补ä¸+状æ€ï¼‰" -#: builtin/log.c:1131 +#: builtin/log.c:1142 msgid "Messaging" msgstr "邮件å‘é€" -#: builtin/log.c:1132 +#: builtin/log.c:1143 msgid "header" msgstr "header" -#: builtin/log.c:1133 +#: builtin/log.c:1144 msgid "add email header" msgstr "æ·»åŠ é‚®ä»¶å¤´" -#: builtin/log.c:1134 builtin/log.c:1136 +#: builtin/log.c:1145 builtin/log.c:1147 msgid "email" msgstr "邮件地å€" -#: builtin/log.c:1134 +#: builtin/log.c:1145 msgid "add To: header" msgstr "æ·»åŠ æ”¶ä»¶äºº" -#: builtin/log.c:1136 +#: builtin/log.c:1147 msgid "add Cc: header" msgstr "æ·»åŠ æŠ„é€" -#: builtin/log.c:1138 +#: builtin/log.c:1149 msgid "message-id" msgstr "message-id" -#: builtin/log.c:1139 +#: builtin/log.c:1150 msgid "make first mail a reply to <message-id>" msgstr "使第一å°é‚®ä»¶ä½œä¸ºå¯¹ <message-id> 的回å¤" -#: builtin/log.c:1140 builtin/log.c:1143 +#: builtin/log.c:1151 builtin/log.c:1154 msgid "boundary" msgstr "边界" -#: builtin/log.c:1141 +#: builtin/log.c:1152 msgid "attach the patch" msgstr "附件方å¼æ·»åŠ è¡¥ä¸" -#: builtin/log.c:1144 +#: builtin/log.c:1155 msgid "inline the patch" msgstr "内è”显示补ä¸" -#: builtin/log.c:1148 +#: builtin/log.c:1159 msgid "enable message threading, styles: shallow, deep" msgstr "å¯ç”¨é‚®ä»¶çº¿ç´¢ï¼Œé£Žæ ¼ï¼šæµ…,深" -#: builtin/log.c:1150 +#: builtin/log.c:1161 msgid "signature" msgstr "ç¾å" -#: builtin/log.c:1151 +#: builtin/log.c:1162 msgid "add a signature" msgstr "æ·»åŠ ä¸€ä¸ªç¾å" -#: builtin/log.c:1153 +#: builtin/log.c:1164 msgid "don't print the patch filenames" msgstr "ä¸è¦æ‰“å°è¡¥ä¸æ–‡ä»¶å" -#: builtin/log.c:1202 -#, c-format -msgid "bogus committer info %s" -msgstr "虚å‡çš„æäº¤è€…ä¿¡æ¯ %s" - -#: builtin/log.c:1247 +#: builtin/log.c:1248 msgid "-n and -k are mutually exclusive." msgstr "-n å’Œ -k 互斥。" -#: builtin/log.c:1249 +#: builtin/log.c:1250 msgid "--subject-prefix and -k are mutually exclusive." msgstr "--subject-prefix å’Œ -k 互斥。" -#: builtin/log.c:1257 +#: builtin/log.c:1258 msgid "--name-only does not make sense" msgstr "--name-only æ— æ„义" -#: builtin/log.c:1259 +#: builtin/log.c:1260 msgid "--name-status does not make sense" msgstr "--name-status æ— æ„义" -#: builtin/log.c:1261 +#: builtin/log.c:1262 msgid "--check does not make sense" msgstr "--check æ— æ„义" -#: builtin/log.c:1284 +#: builtin/log.c:1285 msgid "standard output, or directory, which one?" msgstr "æ ‡å‡†è¾“å‡ºæˆ–ç›®å½•ï¼Œå“ªä¸€ä¸ªï¼Ÿ" -#: builtin/log.c:1286 +#: builtin/log.c:1287 #, c-format msgid "Could not create directory '%s'" msgstr "ä¸èƒ½åˆ›å»ºç›®å½• '%s'" -#: builtin/log.c:1439 +#: builtin/log.c:1435 msgid "Failed to create output files" msgstr "æ— æ³•åˆ›å»ºè¾“å‡ºæ–‡ä»¶" -#: builtin/log.c:1488 +#: builtin/log.c:1484 msgid "git cherry [-v] [<upstream> [<head> [<limit>]]]" msgstr "git cherry [-v] [<上游> [<头> [<é™åˆ¶>]]]" -#: builtin/log.c:1543 +#: builtin/log.c:1539 #, c-format msgid "" "Could not find a tracked remote branch, please specify <upstream> manually.\n" msgstr "ä¸èƒ½æ‰¾åˆ°è·Ÿè¸ªçš„远程分支,请手工指定 <upstream>。\n" -#: builtin/log.c:1556 builtin/log.c:1558 builtin/log.c:1570 +#: builtin/log.c:1552 builtin/log.c:1554 builtin/log.c:1566 #, c-format msgid "Unknown commit %s" msgstr "未知æ交 %s" -#: builtin/ls-files.c:409 +#: builtin/ls-files.c:402 msgid "git ls-files [options] [<file>...]" msgstr "git ls-files [选项] [<文件>...]" -#: builtin/ls-files.c:466 +#: builtin/ls-files.c:459 msgid "identify the file status with tags" msgstr "ç”¨æ ‡ç¾æ ‡è¯†æ–‡ä»¶çš„状æ€" -#: builtin/ls-files.c:468 +#: builtin/ls-files.c:461 msgid "use lowercase letters for 'assume unchanged' files" msgstr "使用å°å†™å—æ¯è¡¨ç¤º 'å‡è®¾æœªæ”¹å˜çš„' 文件" -#: builtin/ls-files.c:470 +#: builtin/ls-files.c:463 msgid "show cached files in the output (default)" msgstr "显示缓å˜çš„文件(默认)" -#: builtin/ls-files.c:472 +#: builtin/ls-files.c:465 msgid "show deleted files in the output" msgstr "æ˜¾ç¤ºå·²åˆ é™¤çš„æ–‡ä»¶" -#: builtin/ls-files.c:474 +#: builtin/ls-files.c:467 msgid "show modified files in the output" msgstr "显示已修改的文件" -#: builtin/ls-files.c:476 +#: builtin/ls-files.c:469 msgid "show other files in the output" msgstr "显示其它文件" -#: builtin/ls-files.c:478 +#: builtin/ls-files.c:471 msgid "show ignored files in the output" msgstr "显示忽略的文件" -#: builtin/ls-files.c:481 +#: builtin/ls-files.c:474 msgid "show staged contents' object name in the output" msgstr "显示暂å˜åŒºå†…容的对象å称" -#: builtin/ls-files.c:483 +#: builtin/ls-files.c:476 msgid "show files on the filesystem that need to be removed" msgstr "显示文件系统需è¦åˆ 除的文件" -#: builtin/ls-files.c:485 +#: builtin/ls-files.c:478 msgid "show 'other' directories' name only" msgstr "åªæ˜¾ç¤ºâ€œå…¶ä»–â€ç›®å½•çš„å称" -#: builtin/ls-files.c:488 +#: builtin/ls-files.c:481 msgid "don't show empty directories" msgstr "ä¸æ˜¾ç¤ºç©ºç›®å½•" -#: builtin/ls-files.c:491 +#: builtin/ls-files.c:484 msgid "show unmerged files in the output" msgstr "显示未åˆå¹¶çš„文件" -#: builtin/ls-files.c:493 +#: builtin/ls-files.c:486 msgid "show resolve-undo information" msgstr "显示 resolve-undo ä¿¡æ¯" -#: builtin/ls-files.c:495 +#: builtin/ls-files.c:488 msgid "skip files matching pattern" msgstr "匹é…排除文件的模å¼" -#: builtin/ls-files.c:498 +#: builtin/ls-files.c:491 msgid "exclude patterns are read from <file>" msgstr "从 <文件> ä¸è¯»å–排除模å¼" -#: builtin/ls-files.c:501 +#: builtin/ls-files.c:494 msgid "read additional per-directory exclude patterns in <file>" msgstr "从 <文件> 读å–é¢å¤–çš„æ¯ä¸ªç›®å½•çš„排除模å¼" -#: builtin/ls-files.c:503 +#: builtin/ls-files.c:496 msgid "add the standard git exclusions" msgstr "æ·»åŠ æ ‡å‡†çš„ git 排除" -#: builtin/ls-files.c:506 +#: builtin/ls-files.c:499 msgid "make the output relative to the project top directory" msgstr "显示相对于顶级目录的文件å" -#: builtin/ls-files.c:509 +#: builtin/ls-files.c:502 msgid "if any <file> is not in the index, treat this as an error" msgstr "如果任何 <文件> 都ä¸åœ¨ç´¢å¼•åŒºï¼Œè§†ä¸ºé”™è¯¯" -#: builtin/ls-files.c:510 +#: builtin/ls-files.c:503 msgid "tree-ish" msgstr "æ ‘æˆ–æ交" -#: builtin/ls-files.c:511 +#: builtin/ls-files.c:504 msgid "pretend that paths removed since <tree-ish> are still present" msgstr "å‡è£…自从 <æ ‘æˆ–æ交> 之åŽåˆ 除的路径ä»ç„¶å˜åœ¨" -#: builtin/ls-files.c:513 +#: builtin/ls-files.c:506 msgid "show debugging data" msgstr "显示调试数æ®" @@ -5904,109 +6202,113 @@ msgstr "å…许快进(默认)" msgid "abort if fast-forward is not possible" msgstr "如果ä¸èƒ½å¿«è¿›å°±æ”¾å¼ƒåˆå¹¶" -#: builtin/merge.c:202 builtin/notes.c:866 builtin/revert.c:112 +#: builtin/merge.c:203 +msgid "Verify that the named commit has a valid GPG signature" +msgstr "验è¯æŒ‡å®šçš„æ交是å¦åŒ…å«ä¸€ä¸ªæœ‰æ•ˆçš„ GPG ç¾å" + +#: builtin/merge.c:204 builtin/notes.c:866 builtin/revert.c:112 msgid "strategy" msgstr "ç–ç•¥" -#: builtin/merge.c:203 +#: builtin/merge.c:205 msgid "merge strategy to use" msgstr "è¦ä½¿ç”¨çš„åˆå¹¶ç–ç•¥" -#: builtin/merge.c:204 +#: builtin/merge.c:206 msgid "option=value" msgstr "option=value" -#: builtin/merge.c:205 +#: builtin/merge.c:207 msgid "option for selected merge strategy" msgstr "所选的åˆå¹¶ç–略的选项" -#: builtin/merge.c:207 +#: builtin/merge.c:209 msgid "merge commit message (for a non-fast-forward merge)" msgstr "åˆå¹¶çš„æ交说明(针对éžå¿«è¿›å¼åˆå¹¶ï¼‰" -#: builtin/merge.c:211 +#: builtin/merge.c:213 msgid "abort the current in-progress merge" msgstr "放弃当å‰æ£åœ¨è¿›è¡Œçš„åˆå¹¶" -#: builtin/merge.c:240 +#: builtin/merge.c:242 msgid "could not run stash." msgstr "ä¸èƒ½è¿›è¡Œè¿›åº¦ä¿å˜ã€‚" -#: builtin/merge.c:245 +#: builtin/merge.c:247 msgid "stash failed" msgstr "进度ä¿å˜å¤±è´¥" -#: builtin/merge.c:250 +#: builtin/merge.c:252 #, c-format msgid "not a valid object: %s" msgstr "ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆå¯¹è±¡ï¼š%s" -#: builtin/merge.c:269 builtin/merge.c:286 +#: builtin/merge.c:271 builtin/merge.c:288 msgid "read-tree failed" msgstr "读å–æ ‘å¤±è´¥" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: builtin/merge.c:316 +#: builtin/merge.c:318 msgid " (nothing to squash)" msgstr " ï¼ˆæ— å¯åŽ‹ç¼©ï¼‰" -#: builtin/merge.c:329 +#: builtin/merge.c:331 #, c-format msgid "Squash commit -- not updating HEAD\n" msgstr "压缩æ交 -- 未更新 HEAD\n" -#: builtin/merge.c:361 +#: builtin/merge.c:363 msgid "Writing SQUASH_MSG" msgstr "写入 SQUASH_MSG" -#: builtin/merge.c:363 +#: builtin/merge.c:365 msgid "Finishing SQUASH_MSG" msgstr "å®Œæˆ SQUASH_MSG" -#: builtin/merge.c:386 +#: builtin/merge.c:388 #, c-format msgid "No merge message -- not updating HEAD\n" msgstr "æ— åˆå¹¶ä¿¡æ¯ -- 未更新 HEAD\n" -#: builtin/merge.c:436 +#: builtin/merge.c:438 #, c-format msgid "'%s' does not point to a commit" msgstr "'%s' 没有指å‘一个æ交" -#: builtin/merge.c:535 +#: builtin/merge.c:550 #, c-format msgid "Bad branch.%s.mergeoptions string: %s" msgstr "åçš„ branch.%s.mergeoptions å—符串:%s" -#: builtin/merge.c:628 +#: builtin/merge.c:643 msgid "git write-tree failed to write a tree" msgstr "git write-tree æ— æ³•å†™å…¥ä¸€æ ‘å¯¹è±¡" -#: builtin/merge.c:656 +#: builtin/merge.c:671 msgid "Not handling anything other than two heads merge." msgstr "ä¸èƒ½å¤„ç†ä¸¤ä¸ªå¤´åˆå¹¶ä¹‹å¤–的任何æ“作。" -#: builtin/merge.c:670 +#: builtin/merge.c:685 #, c-format msgid "Unknown option for merge-recursive: -X%s" msgstr "merge-recursive 的未知选项:-X%s" -#: builtin/merge.c:684 +#: builtin/merge.c:699 #, c-format msgid "unable to write %s" msgstr "ä¸èƒ½å†™ %s" -#: builtin/merge.c:773 +#: builtin/merge.c:788 #, c-format msgid "Could not read from '%s'" msgstr "ä¸èƒ½ä»Ž '%s' 读å–" -#: builtin/merge.c:782 +#: builtin/merge.c:797 #, c-format msgid "Not committing merge; use 'git commit' to complete the merge.\n" msgstr "未æ交åˆå¹¶ï¼Œä½¿ç”¨ 'git commit' 完æˆæ¤æ¬¡åˆå¹¶ã€‚\n" -#: builtin/merge.c:788 +#: builtin/merge.c:803 #, c-format msgid "" "Please enter a commit message to explain why this merge is necessary,\n" @@ -6020,52 +6322,52 @@ msgstr "" "\n" "以 '%c' 开头的行将被忽略,而且空æ交说明将会终æ¢æ交。\n" -#: builtin/merge.c:812 +#: builtin/merge.c:827 msgid "Empty commit message." msgstr "空æ交信æ¯ã€‚" -#: builtin/merge.c:824 +#: builtin/merge.c:839 #, c-format msgid "Wonderful.\n" msgstr "太棒了。\n" -#: builtin/merge.c:889 +#: builtin/merge.c:904 #, c-format msgid "Automatic merge failed; fix conflicts and then commit the result.\n" msgstr "自动åˆå¹¶å¤±è´¥ï¼Œä¿®æ£å†²çªç„¶åŽæ交修æ£çš„结果。\n" -#: builtin/merge.c:905 +#: builtin/merge.c:920 #, c-format msgid "'%s' is not a commit" msgstr "'%s' ä¸æ˜¯ä¸€ä¸ªæ交" -#: builtin/merge.c:946 +#: builtin/merge.c:961 msgid "No current branch." msgstr "没有当å‰åˆ†æ”¯ã€‚" -#: builtin/merge.c:948 +#: builtin/merge.c:963 msgid "No remote for the current branch." msgstr "当å‰åˆ†æ”¯æ²¡æœ‰å¯¹åº”的远程版本库。" -#: builtin/merge.c:950 +#: builtin/merge.c:965 msgid "No default upstream defined for the current branch." msgstr "当å‰åˆ†æ”¯æ²¡æœ‰å®šä¹‰é»˜è®¤çš„上游分支。" -#: builtin/merge.c:955 +#: builtin/merge.c:970 #, c-format msgid "No remote tracking branch for %s from %s" msgstr "%s 没有æ¥è‡ª %s 的远程跟踪分支" -#: builtin/merge.c:1042 builtin/merge.c:1199 +#: builtin/merge.c:1057 builtin/merge.c:1214 #, c-format msgid "%s - not something we can merge" msgstr "%s - ä¸èƒ½è¢«åˆå¹¶" -#: builtin/merge.c:1110 +#: builtin/merge.c:1125 msgid "There is no merge to abort (MERGE_HEAD missing)." msgstr "没有è¦ç»ˆæ¢çš„åˆå¹¶ï¼ˆMERGE_HEAD 丢失)。" -#: builtin/merge.c:1126 git-pull.sh:31 +#: builtin/merge.c:1141 git-pull.sh:31 msgid "" "You have not concluded your merge (MERGE_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6073,11 +6375,11 @@ msgstr "" "您尚未结æŸæ‚¨çš„åˆå¹¶ï¼ˆå˜åœ¨ MERGE_HEAD)。\n" "请在åˆå¹¶å‰å…ˆæ交您的修改。" -#: builtin/merge.c:1129 git-pull.sh:34 +#: builtin/merge.c:1144 git-pull.sh:34 msgid "You have not concluded your merge (MERGE_HEAD exists)." msgstr "您尚未结æŸæ‚¨çš„åˆå¹¶ï¼ˆå˜åœ¨ MERGE_HEAD)。" -#: builtin/merge.c:1133 +#: builtin/merge.c:1148 msgid "" "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists).\n" "Please, commit your changes before you can merge." @@ -6085,79 +6387,100 @@ msgstr "" "您尚未结æŸæ‚¨çš„拣选(å˜åœ¨ CHERRY_PICK_HEAD)。\n" "请在åˆå¹¶å‰å…ˆæ交您的修改。" -#: builtin/merge.c:1136 +#: builtin/merge.c:1151 msgid "You have not concluded your cherry-pick (CHERRY_PICK_HEAD exists)." msgstr "您尚未结æŸæ‚¨çš„拣选(å˜åœ¨ CHERRY_PICK_HEAD)。" -#: builtin/merge.c:1145 +#: builtin/merge.c:1160 msgid "You cannot combine --squash with --no-ff." msgstr "您ä¸èƒ½å°† --squash 与 --no-ff åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/merge.c:1150 +#: builtin/merge.c:1165 msgid "You cannot combine --no-ff with --ff-only." msgstr "您ä¸èƒ½å°† --no-ff 与 --ff-only åŒæ—¶ä½¿ç”¨ã€‚" -#: builtin/merge.c:1157 +#: builtin/merge.c:1172 msgid "No commit specified and merge.defaultToUpstream not set." msgstr "未指定æ交并且 merge.defaultToUpstream 未设置。" -#: builtin/merge.c:1189 +#: builtin/merge.c:1204 msgid "Can merge only exactly one commit into empty head" msgstr "åªèƒ½å°†ä¸€ä¸ªæ交åˆå¹¶åˆ°ç©ºåˆ†æ”¯ä¸Š" -#: builtin/merge.c:1192 +#: builtin/merge.c:1207 msgid "Squash commit into empty head not supported yet" msgstr "å°šä¸æ”¯æŒåˆ°ç©ºåˆ†æ”¯çš„压缩æ交" -#: builtin/merge.c:1194 +#: builtin/merge.c:1209 msgid "Non-fast-forward commit does not make sense into an empty head" msgstr "到空分支的éžå¿«è¿›å¼æ交没有æ„义" -#: builtin/merge.c:1310 +#: builtin/merge.c:1265 +#, c-format +msgid "Commit %s has an untrusted GPG signature, allegedly by %s." +msgstr "æ交 %s 有一个éžå¯ä¿¡çš„声称æ¥è‡ª %s çš„ GPG ç¾å。" + +#: builtin/merge.c:1268 +#, c-format +msgid "Commit %s has a bad GPG signature allegedly by %s." +msgstr "æ交 %s 有一个错误的声称æ¥è‡ª %s çš„ GPG ç¾å。" + +#. 'N' +#: builtin/merge.c:1271 +#, c-format +msgid "Commit %s does not have a GPG signature." +msgstr "æ交 %s 没有一个 GPG ç¾å。" + +#: builtin/merge.c:1274 +#, c-format +msgid "Commit %s has a good GPG signature by %s\n" +msgstr "æ交 %s 有一个æ¥è‡ª %s 的好的 GPG ç¾å。\n" + +#: builtin/merge.c:1358 #, c-format msgid "Updating %s..%s\n" msgstr "æ›´æ–° %s..%s\n" -#: builtin/merge.c:1349 +#: builtin/merge.c:1397 #, c-format msgid "Trying really trivial in-index merge...\n" msgstr "å°è¯•éžå¸¸å°çš„索引内åˆå¹¶...\n" -#: builtin/merge.c:1356 +#: builtin/merge.c:1404 #, c-format msgid "Nope.\n" msgstr "æ— ã€‚\n" -#: builtin/merge.c:1388 +#: builtin/merge.c:1436 msgid "Not possible to fast-forward, aborting." msgstr "æ— æ³•å¿«è¿›ï¼Œç»ˆæ¢ã€‚" -#: builtin/merge.c:1411 builtin/merge.c:1490 +#: builtin/merge.c:1459 builtin/merge.c:1538 #, c-format msgid "Rewinding the tree to pristine...\n" msgstr "å°†æ ‘å›žæ»šè‡³åŽŸå§‹çŠ¶æ€...\n" -#: builtin/merge.c:1415 +#: builtin/merge.c:1463 #, c-format msgid "Trying merge strategy %s...\n" msgstr "å°è¯•åˆå¹¶ç–ç•¥ %s...\n" -#: builtin/merge.c:1481 +#: builtin/merge.c:1529 #, c-format msgid "No merge strategy handled the merge.\n" msgstr "没有åˆå¹¶ç–略处ç†æ¤åˆå¹¶ã€‚\n" -#: builtin/merge.c:1483 +#: builtin/merge.c:1531 #, c-format msgid "Merge with strategy %s failed.\n" msgstr "使用ç–ç•¥ %s åˆå¹¶å¤±è´¥ã€‚\n" -#: builtin/merge.c:1492 +#: builtin/merge.c:1540 #, c-format msgid "Using the %s to prepare resolving by hand.\n" msgstr "使用 %s 以准备手工解决。\n" -#: builtin/merge.c:1504 +#: builtin/merge.c:1552 #, c-format msgid "Automatic merge went well; stopped before committing as requested\n" msgstr "自动åˆå¹¶è¿›å±•é¡ºåˆ©ï¼ŒæŒ‰è¦æ±‚在æ交å‰åœæ¢\n" @@ -7172,11 +7495,15 @@ msgstr "æ¸…é™¤æœ¬åœ°åˆ é™¤çš„å¼•ç”¨" msgid "bypass pre-push hook" msgstr "绕过 pre-push é’©å" -#: builtin/push.c:448 +#: builtin/push.c:440 +msgid "push missing but relevant tags" +msgstr "推é€ç¼ºå¤±çš„有关的 tags" + +#: builtin/push.c:450 msgid "--delete is incompatible with --all, --mirror and --tags" msgstr "--delete 与 --allã€--mirror åŠ --tags ä¸å…¼å®¹" -#: builtin/push.c:450 +#: builtin/push.c:452 msgid "--delete doesn't make sense without any refs" msgstr "--delete 未接任何引用没有æ„义" @@ -7930,16 +8257,16 @@ msgstr "" "åˆæ¬¡ä½¿ç”¨æ—¶æ‰§è¡Œ \"git rev-parse --parseopt -h\" æ¥èŽ·å¾—更多信æ¯ã€‚" #: builtin/revert.c:22 -msgid "git revert [options] <commit-ish>" -msgstr "git revert [选项] <æ交å·>" +msgid "git revert [options] <commit-ish>..." +msgstr "git revert [选项] <æ交å·>..." #: builtin/revert.c:23 msgid "git revert <subcommand>" msgstr "git revert <å命令>" #: builtin/revert.c:28 -msgid "git cherry-pick [options] <commit-ish>" -msgstr "git cherry-pick [选项] <æ交å·>" +msgid "git cherry-pick [options] <commit-ish>..." +msgstr "git cherry-pick [选项] <æ交å·>..." #: builtin/revert.c:29 msgid "git cherry-pick <subcommand>" @@ -8089,31 +8416,31 @@ msgid "git rm: unable to remove %s" msgstr "git rm:ä¸èƒ½åˆ 除 %s" #: builtin/shortlog.c:13 -msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" -msgstr "git shortlog [-n] [-s] [-e] [-w] [版本选项] [--] [<æ交å·>... ]" +msgid "git shortlog [<options>] [<revision range>] [[--] [<path>...]]" +msgstr "git shortlog [<选项>] [<版本范围>] [[--] [<路径>...]]" -#: builtin/shortlog.c:133 +#: builtin/shortlog.c:131 #, c-format msgid "Missing author: %s" msgstr "缺少作者:%s" -#: builtin/shortlog.c:229 +#: builtin/shortlog.c:227 msgid "sort output according to the number of commits per author" msgstr "æ ¹æ®æ¯ä¸ªä½œè€…çš„æ交数é‡æŽ’åº" -#: builtin/shortlog.c:231 +#: builtin/shortlog.c:229 msgid "Suppress commit descriptions, only provides commit count" msgstr "éšè—æ交说明,åªæä¾›æ交数é‡" -#: builtin/shortlog.c:233 +#: builtin/shortlog.c:231 msgid "Show the email address of each author" msgstr "显示æ¯ä¸ªä½œè€…的电å邮件地å€" -#: builtin/shortlog.c:234 +#: builtin/shortlog.c:232 msgid "w[,i1[,i2]]" msgstr "w[,i1[,i2]]" -#: builtin/shortlog.c:235 +#: builtin/shortlog.c:233 msgid "Linewrap output" msgstr "折行输出" @@ -8133,67 +8460,67 @@ msgstr "" msgid "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" msgstr "git show-branch (-g|--reflog)[=<n>[,<base>]] [--list] [<ref>]" -#: builtin/show-branch.c:651 +#: builtin/show-branch.c:650 msgid "show remote-tracking and local branches" msgstr "显示远程跟踪的和本地的分支" -#: builtin/show-branch.c:653 +#: builtin/show-branch.c:652 msgid "show remote-tracking branches" msgstr "显示远程跟踪的分支" -#: builtin/show-branch.c:655 +#: builtin/show-branch.c:654 msgid "color '*!+-' corresponding to the branch" msgstr "ç€è‰² '*!+-' 到相应的分支" -#: builtin/show-branch.c:657 +#: builtin/show-branch.c:656 msgid "show <n> more commits after the common ancestor" msgstr "显示共åŒç¥–å…ˆåŽçš„ <n> 个æ交" -#: builtin/show-branch.c:659 +#: builtin/show-branch.c:658 msgid "synonym to more=-1" msgstr "å’Œ more=-1 åŒä¹‰" -#: builtin/show-branch.c:660 +#: builtin/show-branch.c:659 msgid "suppress naming strings" msgstr "ä¸æ˜¾ç¤ºå—符串命å" -#: builtin/show-branch.c:662 +#: builtin/show-branch.c:661 msgid "include the current branch" msgstr "包括当å‰åˆ†æ”¯" -#: builtin/show-branch.c:664 +#: builtin/show-branch.c:663 msgid "name commits with their object names" msgstr "以对象åå—命åæ交" -#: builtin/show-branch.c:666 +#: builtin/show-branch.c:665 msgid "show possible merge bases" msgstr "显示å¯èƒ½åˆå¹¶çš„基线" -#: builtin/show-branch.c:668 +#: builtin/show-branch.c:667 msgid "show refs unreachable from any other ref" msgstr "显示没有任何引用的的引用" -#: builtin/show-branch.c:670 +#: builtin/show-branch.c:669 msgid "show commits in topological order" msgstr "以拓扑顺åºæ˜¾ç¤ºæ交" -#: builtin/show-branch.c:672 +#: builtin/show-branch.c:671 msgid "show only commits not on the first branch" msgstr "åªæ˜¾ç¤ºä¸åœ¨ç¬¬ä¸€ä¸ªåˆ†æ”¯ä¸Šçš„æ交" -#: builtin/show-branch.c:674 +#: builtin/show-branch.c:673 msgid "show merges reachable from only one tip" msgstr "显示仅一个分支å¯è®¿é—®çš„åˆå¹¶æ交" -#: builtin/show-branch.c:676 +#: builtin/show-branch.c:675 msgid "show commits where no parent comes before its children" msgstr "显示æ交时以时间为åºä¸”父æ交ä¸èƒ½é¢†å…ˆåæ交" -#: builtin/show-branch.c:678 +#: builtin/show-branch.c:677 msgid "<n>[,<base>]" msgstr "<n>[,<base>]" -#: builtin/show-branch.c:679 +#: builtin/show-branch.c:678 msgid "show <n> most recent ref-log entries starting at base" msgstr "显示从 base 开始的 <n> æ¡æœ€è¿‘的引用日志记录" @@ -8650,8 +8977,13 @@ msgid "only useful for debugging" msgstr "åªå¯¹è°ƒè¯•æœ‰ç”¨" #: git.c:16 -msgid "See 'git help <command>' for more information on a specific command." -msgstr "å‚è§ 'git help <command>' 以获得该特定命令的详细信æ¯ã€‚" +msgid "" +"'git help -a' and 'git help -g' lists available subcommands and some\n" +"concept guides. See 'git help <command>' or 'git help <concept>'\n" +"to read about a specific subcommand or concept." +msgstr "" +"命令 'git help -a' å’Œ 'git help -g' 显示å¯ç”¨çš„å命令和一些指å—。å‚è§\n" +"'git help <命令>' 或 'git help <指å—>' æ¥æŸ¥çœ‹ç»™å®šçš„å命令帮助或指å—。" #: parse-options.h:156 msgid "no-op (backward compatibility)" @@ -9010,16 +9342,16 @@ msgstr "" "然åŽéœ€è¦æ供我至少一个好版本和一个å版本。\n" "(您å¯ä»¥ç”¨ \"git bisect bad\" å’Œ \"git bisect good\" 命令æ¥æ ‡è¯†ã€‚)" -#: git-bisect.sh:347 git-bisect.sh:474 +#: git-bisect.sh:363 git-bisect.sh:490 msgid "We are not bisecting." msgstr "我们没有在二分查找。" -#: git-bisect.sh:354 +#: git-bisect.sh:370 #, sh-format msgid "'$invalid' is not a valid commit" msgstr "'$invalid' ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„æ交" -#: git-bisect.sh:363 +#: git-bisect.sh:379 #, sh-format msgid "" "Could not check out original HEAD '$branch'.\n" @@ -9028,25 +9360,25 @@ msgstr "" "ä¸èƒ½æ£€å‡ºåŽŸå§‹ HEAD '$branch'。\n" "å°è¯• 'git bisect reset <æ交>'。" -#: git-bisect.sh:390 +#: git-bisect.sh:406 msgid "No logfile given" msgstr "未æ供日志文件" -#: git-bisect.sh:391 +#: git-bisect.sh:407 #, sh-format msgid "cannot read $file for replaying" msgstr "ä¸èƒ½è¯»å– $file æ¥é‡æ”¾" -#: git-bisect.sh:408 +#: git-bisect.sh:424 msgid "?? what are you talking about?" msgstr "?? 您在说什么?" -#: git-bisect.sh:420 +#: git-bisect.sh:436 #, sh-format msgid "running $command" msgstr "è¿è¡Œ $command" -#: git-bisect.sh:427 +#: git-bisect.sh:443 #, sh-format msgid "" "bisect run failed:\n" @@ -9055,11 +9387,11 @@ msgstr "" "二分查找è¿è¡Œå¤±è´¥ï¼š\n" "命令 '$command' 的退出ç $res å°äºŽ 0 或大于ç‰äºŽ 128" -#: git-bisect.sh:453 +#: git-bisect.sh:469 msgid "bisect run cannot continue any more" msgstr "二分查找ä¸èƒ½ç»§ç»è¿è¡Œ" -#: git-bisect.sh:459 +#: git-bisect.sh:475 #, sh-format msgid "" "bisect run failed:\n" @@ -9068,7 +9400,7 @@ msgstr "" "二分查找è¿è¡Œå¤±è´¥ï¼š\n" "'bisect_state $state' 退出ç 为 $res" -#: git-bisect.sh:466 +#: git-bisect.sh:482 msgid "bisect run success" msgstr "二分查找è¿è¡ŒæˆåŠŸ" @@ -9086,7 +9418,7 @@ msgstr "" msgid "Pull is not possible because you have unmerged files." msgstr "Pull ä¸å¯ç”¨ï¼Œå› 为您尚有未åˆå¹¶çš„文件。" -#: git-pull.sh:197 +#: git-pull.sh:203 msgid "updating an unborn branch with changes added to the index" msgstr "更新尚未诞生的分支,å˜æ›´æ·»åŠ 至索引" @@ -9094,7 +9426,7 @@ msgstr "更新尚未诞生的分支,å˜æ›´æ·»åŠ 至索引" #. The working tree and the index file is still based on the #. $orig_head commit, but we are merging into $curr_head. #. First update the working tree to match $curr_head. -#: git-pull.sh:229 +#: git-pull.sh:235 #, sh-format msgid "" "Warning: fetch updated the current branch head.\n" @@ -9104,11 +9436,11 @@ msgstr "" "è¦å‘Šï¼šfetch 更新了当å‰çš„分支。您的工作区\n" "è¦å‘Šï¼šä»ŽåŽŸæ交 $orig_head 快进。" -#: git-pull.sh:254 +#: git-pull.sh:260 msgid "Cannot merge multiple branches into empty head" msgstr "æ— æ³•å°†å¤šä¸ªåˆ†æ”¯åˆå¹¶åˆ°ç©ºåˆ†æ”¯" -#: git-pull.sh:258 +#: git-pull.sh:264 msgid "Cannot rebase onto multiple branches" msgstr "æ— æ³•å˜åŸºåˆ°å¤šä¸ªåˆ†æ”¯" @@ -9362,37 +9694,37 @@ msgstr "未指定分支å" msgid "(To restore them type \"git stash apply\")" msgstr "(为æ¢å¤æ•°æ®è¾“å…¥ \"git stash apply\")" -#: git-submodule.sh:90 +#: git-submodule.sh:91 #, sh-format msgid "cannot strip one component off url '$remoteurl'" msgstr "æ— æ³•ä»Ž url '$remoteurl' 剥离一个组件" -#: git-submodule.sh:195 +#: git-submodule.sh:196 #, sh-format msgid "No submodule mapping found in .gitmodules for path '$sm_path'" msgstr "未在 .gitmodules ä¸å‘现路径 '$sm_path' çš„åæ¨¡ç»„æ˜ å°„" -#: git-submodule.sh:238 +#: git-submodule.sh:239 #, sh-format msgid "Clone of '$url' into submodule path '$sm_path' failed" msgstr "æ— æ³•å…‹éš† '$url' 到å模组路径 '$sm_path'" -#: git-submodule.sh:250 +#: git-submodule.sh:251 #, sh-format msgid "Gitdir '$a' is part of the submodule path '$b' or vice versa" msgstr "Gitdir '$a' 在å模组路径 '$b' 之下或相å" -#: git-submodule.sh:343 +#: git-submodule.sh:349 #, sh-format msgid "repo URL: '$repo' must be absolute or begin with ./|../" msgstr "版本库URL:'$repo' 必须是ç»å¯¹è·¯å¾„或以 ./|../ 起始" -#: git-submodule.sh:360 +#: git-submodule.sh:366 #, sh-format msgid "'$sm_path' already exists in the index" msgstr "'$sm_path' å·²ç»å˜åœ¨äºŽç´¢å¼•ä¸" -#: git-submodule.sh:364 +#: git-submodule.sh:370 #, sh-format msgid "" "The following path is ignored by one of your .gitignore files:\n" @@ -9403,189 +9735,278 @@ msgstr "" "$sm_path\n" "å¦‚æžœæ‚¨ç¡®å®žæƒ³æ·»åŠ å®ƒï¼Œä½¿ç”¨ -f å‚数。" -#: git-submodule.sh:382 +#: git-submodule.sh:388 #, sh-format msgid "Adding existing repo at '$sm_path' to the index" msgstr "æ·»åŠ ä½äºŽ '$sm_path' 的现å˜ç‰ˆæœ¬åº“到索引" -#: git-submodule.sh:384 +#: git-submodule.sh:390 #, sh-format msgid "'$sm_path' already exists and is not a valid git repo" msgstr "'$sm_path' å·²å˜åœ¨ä¸”ä¸æ˜¯ä¸€ä¸ªæœ‰æ•ˆçš„ git 版本库" -#: git-submodule.sh:392 +#: git-submodule.sh:398 #, sh-format msgid "A git directory for '$sm_name' is found locally with remote(s):" msgstr "本地å‘现 '$sm_name' 的一个 git 目录,与其对应的远程版本库:" -#: git-submodule.sh:394 +#: git-submodule.sh:400 #, sh-format msgid "" "If you want to reuse this local git directory instead of cloning again from" msgstr "如果您想é‡ç”¨æ¤æœ¬åœ° git 目录而ä¸æ˜¯é‡æ–°å…‹éš†è‡ª" -#: git-submodule.sh:396 +#: git-submodule.sh:402 #, sh-format msgid "" "use the '--force' option. If the local git directory is not the correct repo" msgstr "使用 '--force' å‚数。如果本地 git 目录ä¸æ˜¯æ£ç¡®çš„版本库" -#: git-submodule.sh:397 +#: git-submodule.sh:403 #, sh-format msgid "" "or you are unsure what this means choose another name with the '--name' " "option." msgstr "或者您ä¸ç¡®å®šå…¶ä¸å«ä¹‰ä½¿ç”¨ '--name' å‚数选择å¦å¤–一个å称。" -#: git-submodule.sh:399 +#: git-submodule.sh:405 #, sh-format msgid "Reactivating local git directory for submodule '$sm_name'." msgstr "激活本地 git 目录到å模组 '$sm_name'。" -#: git-submodule.sh:411 +#: git-submodule.sh:417 #, sh-format msgid "Unable to checkout submodule '$sm_path'" msgstr "ä¸èƒ½æ£€å‡ºå模组 '$sm_path'" -#: git-submodule.sh:416 +#: git-submodule.sh:422 #, sh-format msgid "Failed to add submodule '$sm_path'" msgstr "æ— æ³•æ·»åŠ å模组 '$sm_path'" -#: git-submodule.sh:425 +#: git-submodule.sh:431 #, sh-format msgid "Failed to register submodule '$sm_path'" msgstr "æ— æ³•æ³¨å†Œå模组 '$sm_path'" -#: git-submodule.sh:468 +#: git-submodule.sh:474 #, sh-format msgid "Entering '$prefix$sm_path'" msgstr "æ£åœ¨è¿›å…¥ '$prefix$sm_path'" -#: git-submodule.sh:482 +#: git-submodule.sh:488 #, sh-format msgid "Stopping at '$sm_path'; script returned non-zero status." msgstr "åœæ¢äºŽ '$sm_path',脚本返回éžé›¶å€¼ã€‚" -#: git-submodule.sh:526 +#: git-submodule.sh:532 #, sh-format msgid "No url found for submodule path '$sm_path' in .gitmodules" msgstr "在 .gitmodules ä¸æœªæ‰¾åˆ°å模组路径 '$sm_path' çš„ url" -#: git-submodule.sh:535 +#: git-submodule.sh:541 #, sh-format msgid "Failed to register url for submodule path '$sm_path'" msgstr "æ— æ³•ä¸ºå模组路径 '$sm_path' 注册 url" -#: git-submodule.sh:537 +#: git-submodule.sh:543 #, sh-format msgid "Submodule '$name' ($url) registered for path '$sm_path'" msgstr "å模组 '$name' ($url) 已为路径 '$sm_path' 注册" -#: git-submodule.sh:545 +#: git-submodule.sh:551 #, sh-format msgid "Failed to register update mode for submodule path '$sm_path'" msgstr "æ— æ³•ä¸ºå模组路径 '$sm_path' 注册更新模å¼" -#: git-submodule.sh:649 +#: git-submodule.sh:588 +#, sh-format +msgid "Use '.' if you really want to deinitialize all submodules" +msgstr "使用 '.' 如果您真的想è¦å¯¹æ‰€æœ‰å模组å–消åˆå§‹åŒ–" + +#: git-submodule.sh:603 +#, sh-format +msgid "Submodule work tree '$sm_path' contains a .git directory" +msgstr "å模组工作区 '$sm_path' 包å«ä¸€ä¸ª .git 目录" + +#: git-submodule.sh:604 +#, sh-format +msgid "" +"(use 'rm -rf' if you really want to remove it including all of its history)" +msgstr "(使用 'rm -rf' å‘½ä»¤å¦‚æžœæ‚¨çœŸçš„æƒ³åˆ é™¤å®ƒåŠå…¶å…¨éƒ¨åŽ†å²ï¼‰" + +#: git-submodule.sh:610 +#, sh-format +msgid "" +"Submodule work tree '$sm_path' contains local modifications; use '-f' to " +"discard them" +msgstr "å模组工作区 '$sm_path' 包å«æœ¬åœ°ä¿®æ”¹ï¼›ä½¿ç”¨ '-f' 丢弃它们" + +#: git-submodule.sh:613 +#, sh-format +msgid "Cleared directory '$sm_path'" +msgstr "已清除目录 '$sm_path'" + +#: git-submodule.sh:614 +#, sh-format +msgid "Could not remove submodule work tree '$sm_path'" +msgstr "æ— æ³•ç§»é™¤å模组工作区 '$sm_path'" + +#: git-submodule.sh:617 +#, sh-format +msgid "Could not create empty submodule directory '$sm_path'" +msgstr "ä¸èƒ½åˆ›å»ºç©ºçš„å模组目录 '$sm_path'" + +#: git-submodule.sh:626 +#, sh-format +msgid "Submodule '$name' ($url) unregistered for path '$sm_path'" +msgstr "å模组 '$name' ($url) 未对路径 '$sm_path' 注册" + +#: git-submodule.sh:731 #, sh-format msgid "" -"Submodule path '$sm_path' not initialized\n" +"Submodule path '$prefix$sm_path' not initialized\n" "Maybe you want to use 'update --init'?" msgstr "" -"å模组路径 '$sm_path' 没有åˆå§‹åŒ–\n" +"å模组路径 '$prefix$sm_path' 没有åˆå§‹åŒ–\n" "也许您想用 'update --init'?" -#: git-submodule.sh:662 +#: git-submodule.sh:744 #, sh-format -msgid "Unable to find current revision in submodule path '$sm_path'" -msgstr "æ— æ³•åœ¨å模组路径 '$sm_path' ä¸æ‰¾åˆ°å½“å‰ç‰ˆæœ¬" +msgid "Unable to find current revision in submodule path '$prefix$sm_path'" +msgstr "æ— æ³•åœ¨å模组路径 '$prefix$sm_path' ä¸æ‰¾åˆ°å½“å‰ç‰ˆæœ¬" -#: git-submodule.sh:671 git-submodule.sh:695 +#: git-submodule.sh:753 #, sh-format msgid "Unable to fetch in submodule path '$sm_path'" msgstr "æ— æ³•åœ¨å模组路径 '$sm_path' ä¸èŽ·å–" -#: git-submodule.sh:709 +#: git-submodule.sh:777 #, sh-format -msgid "Unable to rebase '$sha1' in submodule path '$sm_path'" -msgstr "æ— æ³•åœ¨å模组路径 '$sm_path' ä¸å˜åŸº '$sha1'" +msgid "Unable to fetch in submodule path '$prefix$sm_path'" +msgstr "æ— æ³•åœ¨å模组路径 '$prefix$sm_path' ä¸èŽ·å–" -#: git-submodule.sh:710 +#: git-submodule.sh:791 #, sh-format -msgid "Submodule path '$sm_path': rebased into '$sha1'" -msgstr "å模组路径 '$sm_path':å˜åŸºè‡³ '$sha1'" +msgid "Unable to rebase '$sha1' in submodule path '$prefix$sm_path'" +msgstr "æ— æ³•åœ¨å模组路径 '$prefix$sm_path' ä¸å˜åŸº '$sha1'" -#: git-submodule.sh:715 +#: git-submodule.sh:792 #, sh-format -msgid "Unable to merge '$sha1' in submodule path '$sm_path'" -msgstr "æ— æ³•åˆå¹¶ '$sha1' 到å模组路径 '$sm_path' ä¸" +msgid "Submodule path '$prefix$sm_path': rebased into '$sha1'" +msgstr "å模组路径 '$prefix$sm_path':å˜åŸºè‡³ '$sha1'" -#: git-submodule.sh:716 +#: git-submodule.sh:797 #, sh-format -msgid "Submodule path '$sm_path': merged in '$sha1'" -msgstr "å模组路径 '$sm_path':已åˆå¹¶å…¥ '$sha1'" +msgid "Unable to merge '$sha1' in submodule path '$prefix$sm_path'" +msgstr "æ— æ³•åˆå¹¶ '$sha1' 到å模组路径 '$prefix$sm_path' ä¸" -#: git-submodule.sh:721 +#: git-submodule.sh:798 #, sh-format -msgid "Unable to checkout '$sha1' in submodule path '$sm_path'" -msgstr "æ— æ³•åœ¨å模组路径 '$sm_path' ä¸æ£€å‡º '$sha1'" +msgid "Submodule path '$prefix$sm_path': merged in '$sha1'" +msgstr "å模组路径 '$prefix$sm_path':已åˆå¹¶å…¥ '$sha1'" -#: git-submodule.sh:722 +#: git-submodule.sh:803 #, sh-format -msgid "Submodule path '$sm_path': checked out '$sha1'" -msgstr "å模组路径 '$sm_path':检出 '$sha1'" +msgid "Unable to checkout '$sha1' in submodule path '$prefix$sm_path'" +msgstr "æ— æ³•åœ¨å模组路径 '$prefix$sm_path' ä¸æ£€å‡º '$sha1'" -#: git-submodule.sh:744 git-submodule.sh:1066 +#: git-submodule.sh:804 #, sh-format -msgid "Failed to recurse into submodule path '$sm_path'" -msgstr "æ— æ³•é€’å½’è¿›å模组路径 '$sm_path'" +msgid "Submodule path '$prefix$sm_path': checked out '$sha1'" +msgstr "å模组路径 '$prefix$sm_path':检出 '$sha1'" -#: git-submodule.sh:852 +#: git-submodule.sh:831 +#, sh-format +msgid "Failed to recurse into submodule path '$prefix$sm_path'" +msgstr "æ— æ³•é€’å½’è¿›å模组路径 '$prefix$sm_path'" + +#: git-submodule.sh:939 msgid "The --cached option cannot be used with the --files option" msgstr "选项 --cached ä¸èƒ½å’Œé€‰é¡¹ --files åŒæ—¶ä½¿ç”¨" #. unexpected type -#: git-submodule.sh:892 +#: git-submodule.sh:979 #, sh-format msgid "unexpected mode $mod_dst" msgstr "æ„å¤–çš„æ¨¡å¼ $mod_dst" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: git-submodule.sh:910 +#: git-submodule.sh:997 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_src" msgstr " è¦å‘Šï¼š$name 未包å«æ交 $sha1_src" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: git-submodule.sh:913 +#: git-submodule.sh:1000 #, sh-format msgid " Warn: $name doesn't contain commit $sha1_dst" msgstr " è¦å‘Šï¼š$name 未包å«æ交 $sha1_dst" # 译者:注æ„ä¿æŒå‰å¯¼ç©ºæ ¼ -#: git-submodule.sh:916 +#: git-submodule.sh:1003 #, sh-format msgid " Warn: $name doesn't contain commits $sha1_src and $sha1_dst" msgstr " è¦å‘Šï¼š$name 未包å«æ交 $sha1_src å’Œ $sha1_dst" -#: git-submodule.sh:941 +#: git-submodule.sh:1028 msgid "blob" msgstr "æ•°æ®å¯¹è±¡" -#: git-submodule.sh:979 +#: git-submodule.sh:1066 msgid "Submodules changed but not updated:" msgstr "å模组已修改但尚未更新:" -#: git-submodule.sh:981 +#: git-submodule.sh:1068 msgid "Submodule changes to be committed:" msgstr "è¦æ交的å模组å˜æ›´ï¼š" -#: git-submodule.sh:1129 +#: git-submodule.sh:1153 +#, sh-format +msgid "Failed to recurse into submodule path '$sm_path'" +msgstr "æ— æ³•é€’å½’è¿›å模组路径 '$sm_path'" + +#: git-submodule.sh:1216 #, sh-format msgid "Synchronizing submodule url for '$prefix$sm_path'" msgstr "为 '$prefix$sm_path' åŒæ¥å模组 url" +#~ msgid "git shortlog [-n] [-s] [-e] [-w] [rev-opts] [--] [<commit-id>... ]" +#~ msgstr "git shortlog [-n] [-s] [-e] [-w] [版本选项] [--] [<æ交å·>... ]" + +#~ msgid "See 'git help <command>' for more information on a specific command." +#~ msgstr "å‚è§ 'git help <command>' 以获得该特定命令的详细信æ¯ã€‚" + +#~ msgid "BUG: impossible combination of %d and %p" +#~ msgstr "BUG: æ— æ³•ç»„åˆ %d å’Œ %p" + +# 译者:以下三æ¡å®žé™…ä¸ºä¸€ä¸ªæ®µè½ +#~ msgid "It took %.2f seconds to enumerate untracked files. 'status -uno'" +#~ msgstr "耗费了 %.2f 秒以枚举未跟踪的文件。'status -uno'" + +# 译者:为对é½ï¼Œä¸‹é¢ä¸¤å¥å†…容有调整 +#~ msgid "may speed it up, but you have to be careful not to forget to add" +#~ msgstr "也许能æ高速度,但您需è¦å°å¿ƒä¸è¦å¿˜äº†æ·»åŠ 新文件" + +#~ msgid "new files yourself (see 'git help status')." +#~ msgstr "(å‚è§ 'git help status')。" + +#, fuzzy +#~ msgid "aaaSynchronizing submodule url for '$prefix$sm_path'" +#~ msgstr "为 '$prefix$sm_path' åŒæ¥å模组 url" + +#~ msgid "use any ref in .git/refs" +#~ msgstr "使用 .git/refs 里的任æ„引用" + +#~ msgid "use any tag in .git/refs/tags" +#~ msgstr "使用 .git/refs/tags é‡Œçš„ä»»æ„ tag" + +#~ msgid "bad object %s" +#~ msgstr "å对象 %s" + +#~ msgid "bogus committer info %s" +#~ msgstr "虚å‡çš„æäº¤è€…ä¿¡æ¯ %s" + #~ msgid "can't fdopen 'show' output fd" #~ msgstr "ä¸èƒ½æ‰“å¼€ 'show' 输出文件å¥æŸ„" @@ -410,10 +410,7 @@ void pp_user_info(const struct pretty_print_context *pp, const char *what, struct strbuf *sb, const char *line, const char *encoding) { - struct strbuf name; - struct strbuf mail; struct ident_split ident; - int linelen; char *line_end; const char *mailbuf, *namebuf; size_t namelen, maillen; @@ -422,18 +419,10 @@ void pp_user_info(const struct pretty_print_context *pp, if (pp->fmt == CMIT_FMT_ONELINE) return; - line_end = strchr(line, '\n'); - if (!line_end) { - line_end = strchr(line, '\0'); - if (!line_end) - return; - } - - linelen = ++line_end - line; - if (split_ident_line(&ident, line, linelen)) + line_end = strchrnul(line, '\n'); + if (split_ident_line(&ident, line, line_end - line)) return; - mailbuf = ident.mail_begin; maillen = ident.mail_end - ident.mail_begin; namebuf = ident.name_begin; @@ -442,43 +431,33 @@ void pp_user_info(const struct pretty_print_context *pp, if (pp->mailmap) map_user(pp->mailmap, &mailbuf, &maillen, &namebuf, &namelen); - strbuf_init(&mail, 0); - strbuf_init(&name, 0); - - strbuf_add(&mail, mailbuf, maillen); - strbuf_add(&name, namebuf, namelen); - - namelen = name.len + mail.len + 3; /* ' ' + '<' + '>' */ - if (pp->fmt == CMIT_FMT_EMAIL) { strbuf_addstr(sb, "From: "); - if (needs_rfc2047_encoding(name.buf, name.len, RFC2047_ADDRESS)) { - add_rfc2047(sb, name.buf, name.len, + if (needs_rfc2047_encoding(namebuf, namelen, RFC2047_ADDRESS)) { + add_rfc2047(sb, namebuf, namelen, encoding, RFC2047_ADDRESS); max_length = 76; /* per rfc2047 */ - } else if (needs_rfc822_quoting(name.buf, name.len)) { + } else if (needs_rfc822_quoting(namebuf, namelen)) { struct strbuf quoted = STRBUF_INIT; - add_rfc822_quoted("ed, name.buf, name.len); + add_rfc822_quoted("ed, namebuf, namelen); strbuf_add_wrapped_bytes(sb, quoted.buf, quoted.len, -6, 1, max_length); strbuf_release("ed); } else { - strbuf_add_wrapped_bytes(sb, name.buf, name.len, + strbuf_add_wrapped_bytes(sb, namebuf, namelen, -6, 1, max_length); } - if (namelen - name.len + last_line_length(sb) > max_length) - strbuf_addch(sb, '\n'); - strbuf_addf(sb, " <%s>\n", mail.buf); + if (max_length < + last_line_length(sb) + strlen(" <") + maillen + strlen(">")) + strbuf_addch(sb, '\n'); + strbuf_addf(sb, " <%.*s>\n", (int)maillen, mailbuf); } else { - strbuf_addf(sb, "%s: %.*s%s <%s>\n", what, - (pp->fmt == CMIT_FMT_FULLER) ? 4 : 0, - " ", name.buf, mail.buf); + strbuf_addf(sb, "%s: %.*s%.*s <%.*s>\n", what, + (pp->fmt == CMIT_FMT_FULLER) ? 4 : 0, " ", + (int)namelen, namebuf, (int)maillen, mailbuf); } - strbuf_release(&mail); - strbuf_release(&name); - switch (pp->fmt) { case CMIT_FMT_MEDIUM: strbuf_addf(sb, "Date: %s\n", @@ -606,6 +585,7 @@ static char *replace_encoding_header(char *buf, const char *encoding) } char *logmsg_reencode(const struct commit *commit, + char **commit_encoding, const char *output_encoding) { static const char *utf8 = "UTF-8"; @@ -627,9 +607,15 @@ char *logmsg_reencode(const struct commit *commit, sha1_to_hex(commit->object.sha1), typename(type)); } - if (!output_encoding || !*output_encoding) + if (!output_encoding || !*output_encoding) { + if (commit_encoding) + *commit_encoding = + get_header(commit, msg, "encoding"); return msg; + } encoding = get_header(commit, msg, "encoding"); + if (commit_encoding) + *commit_encoding = encoding; use_encoding = encoding ? encoding : utf8; if (same_encoding(use_encoding, output_encoding)) { /* @@ -670,7 +656,8 @@ char *logmsg_reencode(const struct commit *commit, if (out) out = replace_encoding_header(out, output_encoding); - free(encoding); + if (!commit_encoding) + free(encoding); /* * If the re-encoding failed, out might be NULL here; in that * case we just return the commit message verbatim. @@ -764,26 +751,38 @@ struct chunk { size_t len; }; +enum flush_type { + no_flush, + flush_right, + flush_left, + flush_left_and_steal, + flush_both +}; + +enum trunc_type { + trunc_none, + trunc_left, + trunc_middle, + trunc_right +}; + struct format_commit_context { const struct commit *commit; const struct pretty_print_context *pretty_ctx; unsigned commit_header_parsed:1; unsigned commit_message_parsed:1; - unsigned commit_signature_parsed:1; - struct { - char *gpg_output; - char *gpg_status; - char good_bad; - char *signer; - char *key; - } signature; + struct signature_check signature_check; + enum flush_type flush_type; + enum trunc_type truncate; char *message; + char *commit_encoding; size_t width, indent1, indent2; + int auto_color; + int padding; /* These offsets are relative to the start of the commit message. */ struct chunk author; struct chunk committer; - struct chunk encoding; size_t message_off; size_t subject_off; size_t body_off; @@ -830,9 +829,6 @@ static void parse_commit_header(struct format_commit_context *context) } else if (!prefixcmp(msg + i, "committer ")) { context->committer.off = i + 10; context->committer.len = eol - i - 10; - } else if (!prefixcmp(msg + i, "encoding ")) { - context->encoding.off = i + 9; - context->encoding.len = eol - i - 9; } i = eol; } @@ -913,23 +909,6 @@ static void parse_commit_message(struct format_commit_context *c) c->commit_message_parsed = 1; } -static void format_decoration(struct strbuf *sb, const struct commit *commit) -{ - struct name_decoration *d; - const char *prefix = " ("; - - load_ref_decorations(DECORATE_SHORT_REFS); - d = lookup_decoration(&name_decoration, &commit->object); - while (d) { - strbuf_addstr(sb, prefix); - prefix = ", "; - strbuf_addstr(sb, d->name); - d = d->next; - } - if (prefix[0] == ',') - strbuf_addch(sb, ')'); -} - static void strbuf_wrap(struct strbuf *sb, size_t pos, size_t width, size_t indent1, size_t indent2) { @@ -959,64 +938,6 @@ static void rewrap_message_tail(struct strbuf *sb, c->indent2 = new_indent2; } -static struct { - char result; - const char *check; -} signature_check[] = { - { 'G', "\n[GNUPG:] GOODSIG " }, - { 'B', "\n[GNUPG:] BADSIG " }, -}; - -static void parse_signature_lines(struct format_commit_context *ctx) -{ - const char *buf = ctx->signature.gpg_status; - int i; - - for (i = 0; i < ARRAY_SIZE(signature_check); i++) { - const char *found = strstr(buf, signature_check[i].check); - const char *next; - if (!found) - continue; - ctx->signature.good_bad = signature_check[i].result; - found += strlen(signature_check[i].check); - ctx->signature.key = xmemdupz(found, 16); - found += 17; - next = strchrnul(found, '\n'); - ctx->signature.signer = xmemdupz(found, next - found); - break; - } -} - -static void parse_commit_signature(struct format_commit_context *ctx) -{ - struct strbuf payload = STRBUF_INIT; - struct strbuf signature = STRBUF_INIT; - struct strbuf gpg_output = STRBUF_INIT; - struct strbuf gpg_status = STRBUF_INIT; - int status; - - ctx->commit_signature_parsed = 1; - - if (parse_signed_commit(ctx->commit->object.sha1, - &payload, &signature) <= 0) - goto out; - status = verify_signed_buffer(payload.buf, payload.len, - signature.buf, signature.len, - &gpg_output, &gpg_status); - if (status && !gpg_output.len) - goto out; - ctx->signature.gpg_output = strbuf_detach(&gpg_output, NULL); - ctx->signature.gpg_status = strbuf_detach(&gpg_status, NULL); - parse_signature_lines(ctx); - - out: - strbuf_release(&gpg_status); - strbuf_release(&gpg_output); - strbuf_release(&payload); - strbuf_release(&signature); -} - - static int format_reflog_person(struct strbuf *sb, char part, struct reflog_walk_info *log, @@ -1034,7 +955,112 @@ static int format_reflog_person(struct strbuf *sb, return format_person_part(sb, part, ident, strlen(ident), dmode); } -static size_t format_commit_one(struct strbuf *sb, const char *placeholder, +static size_t parse_color(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, + struct format_commit_context *c) +{ + if (placeholder[1] == '(') { + const char *begin = placeholder + 2; + const char *end = strchr(begin, ')'); + char color[COLOR_MAXLEN]; + + if (!end) + return 0; + if (!prefixcmp(begin, "auto,")) { + if (!want_color(c->pretty_ctx->color)) + return end - placeholder + 1; + begin += 5; + } + color_parse_mem(begin, + end - begin, + "--pretty format", color); + strbuf_addstr(sb, color); + return end - placeholder + 1; + } + if (!prefixcmp(placeholder + 1, "red")) { + strbuf_addstr(sb, GIT_COLOR_RED); + return 4; + } else if (!prefixcmp(placeholder + 1, "green")) { + strbuf_addstr(sb, GIT_COLOR_GREEN); + return 6; + } else if (!prefixcmp(placeholder + 1, "blue")) { + strbuf_addstr(sb, GIT_COLOR_BLUE); + return 5; + } else if (!prefixcmp(placeholder + 1, "reset")) { + strbuf_addstr(sb, GIT_COLOR_RESET); + return 6; + } else + return 0; +} + +static size_t parse_padding_placeholder(struct strbuf *sb, + const char *placeholder, + struct format_commit_context *c) +{ + const char *ch = placeholder; + enum flush_type flush_type; + int to_column = 0; + + switch (*ch++) { + case '<': + flush_type = flush_right; + break; + case '>': + if (*ch == '<') { + flush_type = flush_both; + ch++; + } else if (*ch == '>') { + flush_type = flush_left_and_steal; + ch++; + } else + flush_type = flush_left; + break; + default: + return 0; + } + + /* the next value means "wide enough to that column" */ + if (*ch == '|') { + to_column = 1; + ch++; + } + + if (*ch == '(') { + const char *start = ch + 1; + const char *end = start + strcspn(start, ",)"); + char *next; + int width; + if (!end || end == start) + return 0; + width = strtoul(start, &next, 10); + if (next == start || width == 0) + return 0; + c->padding = to_column ? -width : width; + c->flush_type = flush_type; + + if (*end == ',') { + start = end + 1; + end = strchr(start, ')'); + if (!end || end == start) + return 0; + if (!prefixcmp(start, "trunc)")) + c->truncate = trunc_right; + else if (!prefixcmp(start, "ltrunc)")) + c->truncate = trunc_left; + else if (!prefixcmp(start, "mtrunc)")) + c->truncate = trunc_middle; + else + return 0; + } else + c->truncate = trunc_none; + + return end - placeholder + 1; + } + return 0; +} + +static size_t format_commit_one(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, void *context) { struct format_commit_context *c = context; @@ -1046,38 +1072,20 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, /* these are independent of the commit */ switch (placeholder[0]) { case 'C': - if (placeholder[1] == '(') { - const char *begin = placeholder + 2; - const char *end = strchr(begin, ')'); - char color[COLOR_MAXLEN]; - - if (!end) - return 0; - if (!prefixcmp(begin, "auto,")) { - if (!want_color(c->pretty_ctx->color)) - return end - placeholder + 1; - begin += 5; - } - color_parse_mem(begin, - end - begin, - "--pretty format", color); - strbuf_addstr(sb, color); - return end - placeholder + 1; + if (!prefixcmp(placeholder + 1, "(auto)")) { + c->auto_color = 1; + return 7; /* consumed 7 bytes, "C(auto)" */ + } else { + int ret = parse_color(sb, placeholder, c); + if (ret) + c->auto_color = 0; + /* + * Otherwise, we decided to treat %C<unknown> + * as a literal string, and the previous + * %C(auto) is still valid. + */ + return ret; } - if (!prefixcmp(placeholder + 1, "red")) { - strbuf_addstr(sb, GIT_COLOR_RED); - return 4; - } else if (!prefixcmp(placeholder + 1, "green")) { - strbuf_addstr(sb, GIT_COLOR_GREEN); - return 6; - } else if (!prefixcmp(placeholder + 1, "blue")) { - strbuf_addstr(sb, GIT_COLOR_BLUE); - return 5; - } else if (!prefixcmp(placeholder + 1, "reset")) { - strbuf_addstr(sb, GIT_COLOR_RESET); - return 6; - } else - return 0; case 'n': /* newline */ strbuf_addch(sb, '\n'); return 1; @@ -1115,6 +1123,10 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, return end - placeholder + 1; } else return 0; + + case '<': + case '>': + return parse_padding_placeholder(sb, placeholder, c); } /* these depend on the commit */ @@ -1123,13 +1135,19 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, switch (placeholder[0]) { case 'H': /* commit hash */ + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT)); strbuf_addstr(sb, sha1_to_hex(commit->object.sha1)); + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); return 1; case 'h': /* abbreviated commit hash */ - if (add_again(sb, &c->abbrev_commit_hash)) + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_COMMIT)); + if (add_again(sb, &c->abbrev_commit_hash)) { + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); return 1; + } strbuf_addstr(sb, find_unique_abbrev(commit->object.sha1, c->pretty_ctx->abbrev)); + strbuf_addstr(sb, diff_get_color(c->auto_color, DIFF_RESET)); c->abbrev_commit_hash.len = sb->len - c->abbrev_commit_hash.off; return 1; case 'T': /* tree hash */ @@ -1166,7 +1184,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, strbuf_addstr(sb, get_revision_mark(NULL, commit)); return 1; case 'd': - format_decoration(sb, commit); + load_ref_decorations(DECORATE_SHORT_REFS); + format_decorations(sb, commit, c->auto_color); return 1; case 'g': /* reflog info */ switch(placeholder[1]) { @@ -1202,27 +1221,29 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, } if (placeholder[0] == 'G') { - if (!c->commit_signature_parsed) - parse_commit_signature(c); + if (!c->signature_check.result) + check_commit_signature(c->commit, &(c->signature_check)); switch (placeholder[1]) { case 'G': - if (c->signature.gpg_output) - strbuf_addstr(sb, c->signature.gpg_output); + if (c->signature_check.gpg_output) + strbuf_addstr(sb, c->signature_check.gpg_output); break; case '?': - switch (c->signature.good_bad) { + switch (c->signature_check.result) { case 'G': case 'B': - strbuf_addch(sb, c->signature.good_bad); + case 'U': + case 'N': + strbuf_addch(sb, c->signature_check.result); } break; case 'S': - if (c->signature.signer) - strbuf_addstr(sb, c->signature.signer); + if (c->signature_check.signer) + strbuf_addstr(sb, c->signature_check.signer); break; case 'K': - if (c->signature.key) - strbuf_addstr(sb, c->signature.key); + if (c->signature_check.key) + strbuf_addstr(sb, c->signature_check.key); break; } return 2; @@ -1243,7 +1264,8 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, msg + c->committer.off, c->committer.len, c->pretty_ctx->date_mode); case 'e': /* encoding */ - strbuf_add(sb, msg + c->encoding.off, c->encoding.len); + if (c->commit_encoding) + strbuf_addstr(sb, c->commit_encoding); return 1; case 'B': /* raw body */ /* message_off is always left at the initial newline */ @@ -1269,7 +1291,111 @@ static size_t format_commit_one(struct strbuf *sb, const char *placeholder, return 0; /* unknown placeholder */ } -static size_t format_commit_item(struct strbuf *sb, const char *placeholder, +static size_t format_and_pad_commit(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, + struct format_commit_context *c) +{ + struct strbuf local_sb = STRBUF_INIT; + int total_consumed = 0, len, padding = c->padding; + if (padding < 0) { + const char *start = strrchr(sb->buf, '\n'); + int occupied; + if (!start) + start = sb->buf; + occupied = utf8_strnwidth(start, -1, 1); + padding = (-padding) - occupied; + } + while (1) { + int modifier = *placeholder == 'C'; + int consumed = format_commit_one(&local_sb, placeholder, c); + total_consumed += consumed; + + if (!modifier) + break; + + placeholder += consumed; + if (*placeholder != '%') + break; + placeholder++; + total_consumed++; + } + len = utf8_strnwidth(local_sb.buf, -1, 1); + + if (c->flush_type == flush_left_and_steal) { + const char *ch = sb->buf + sb->len - 1; + while (len > padding && ch > sb->buf) { + const char *p; + if (*ch == ' ') { + ch--; + padding++; + continue; + } + /* check for trailing ansi sequences */ + if (*ch != 'm') + break; + p = ch - 1; + while (ch - p < 10 && *p != '\033') + p--; + if (*p != '\033' || + ch + 1 - p != display_mode_esc_sequence_len(p)) + break; + /* + * got a good ansi sequence, put it back to + * local_sb as we're cutting sb + */ + strbuf_insert(&local_sb, 0, p, ch + 1 - p); + ch = p - 1; + } + strbuf_setlen(sb, ch + 1 - sb->buf); + c->flush_type = flush_left; + } + + if (len > padding) { + switch (c->truncate) { + case trunc_left: + strbuf_utf8_replace(&local_sb, + 0, len - (padding - 2), + ".."); + break; + case trunc_middle: + strbuf_utf8_replace(&local_sb, + padding / 2 - 1, + len - (padding - 2), + ".."); + break; + case trunc_right: + strbuf_utf8_replace(&local_sb, + padding - 2, len - (padding - 2), + ".."); + break; + case trunc_none: + break; + } + strbuf_addstr(sb, local_sb.buf); + } else { + int sb_len = sb->len, offset = 0; + if (c->flush_type == flush_left) + offset = padding - len; + else if (c->flush_type == flush_both) + offset = (padding - len) / 2; + /* + * we calculate padding in columns, now + * convert it back to chars + */ + padding = padding - len + local_sb.len; + strbuf_grow(sb, padding); + strbuf_setlen(sb, sb_len + padding); + memset(sb->buf + sb_len, ' ', sb->len - sb_len); + memcpy(sb->buf + sb_len + offset, local_sb.buf, + local_sb.len); + } + strbuf_release(&local_sb); + c->flush_type = no_flush; + return total_consumed; +} + +static size_t format_commit_item(struct strbuf *sb, /* in UTF-8 */ + const char *placeholder, void *context) { int consumed; @@ -1298,7 +1424,10 @@ static size_t format_commit_item(struct strbuf *sb, const char *placeholder, placeholder++; orig_len = sb->len; - consumed = format_commit_one(sb, placeholder, context); + if (((struct format_commit_context *)context)->flush_type != no_flush) + consumed = format_and_pad_commit(sb, placeholder, context); + else + consumed = format_commit_one(sb, placeholder, context); if (magic == NO_MAGIC) return consumed; @@ -1349,19 +1478,40 @@ void format_commit_message(const struct commit *commit, { struct format_commit_context context; const char *output_enc = pretty_ctx->output_encoding; + const char *utf8 = "UTF-8"; memset(&context, 0, sizeof(context)); context.commit = commit; context.pretty_ctx = pretty_ctx; context.wrap_start = sb->len; - context.message = logmsg_reencode(commit, output_enc); + context.message = logmsg_reencode(commit, + &context.commit_encoding, + output_enc); strbuf_expand(sb, format, format_commit_item, &context); rewrap_message_tail(sb, &context, 0, 0, 0); + if (output_enc) { + if (same_encoding(utf8, output_enc)) + output_enc = NULL; + } else { + if (context.commit_encoding && + !same_encoding(context.commit_encoding, utf8)) + output_enc = context.commit_encoding; + } + + if (output_enc) { + int outsz; + char *out = reencode_string_len(sb->buf, sb->len, + output_enc, utf8, &outsz); + if (out) + strbuf_attach(sb, out, outsz, outsz + 1); + } + + free(context.commit_encoding); logmsg_free(context.message, commit); - free(context.signature.gpg_output); - free(context.signature.signer); + free(context.signature_check.gpg_output); + free(context.signature_check.signer); } static void pp_header(const struct pretty_print_context *pp, @@ -1517,7 +1667,7 @@ void pretty_print_commit(const struct pretty_print_context *pp, } encoding = get_log_output_encoding(); - msg = reencoded = logmsg_reencode(commit, encoding); + msg = reencoded = logmsg_reencode(commit, NULL, encoding); if (pp->fmt == CMIT_FMT_ONELINE || pp->fmt == CMIT_FMT_EMAIL) indent = 0; diff --git a/progress.c b/progress.c index 3971f49f4d..10652b174d 100644 --- a/progress.c +++ b/progress.c @@ -10,6 +10,7 @@ #include "git-compat-util.h" #include "progress.h" +#include "strbuf.h" #define TP_IDX_MAX 8 @@ -112,34 +113,14 @@ static int display(struct progress *progress, unsigned n, const char *done) return 0; } -static void throughput_string(struct throughput *tp, off_t total, +static void throughput_string(struct strbuf *buf, off_t total, unsigned int rate) { - int l = sizeof(tp->display); - if (total > 1 << 30) { - l -= snprintf(tp->display, l, ", %u.%2.2u GiB", - (int)(total >> 30), - (int)(total & ((1 << 30) - 1)) / 10737419); - } else if (total > 1 << 20) { - int x = total + 5243; /* for rounding */ - l -= snprintf(tp->display, l, ", %u.%2.2u MiB", - x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20); - } else if (total > 1 << 10) { - int x = total + 5; /* for rounding */ - l -= snprintf(tp->display, l, ", %u.%2.2u KiB", - x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); - } else { - l -= snprintf(tp->display, l, ", %u bytes", (int)total); - } - - if (rate > 1 << 10) { - int x = rate + 5; /* for rounding */ - snprintf(tp->display + sizeof(tp->display) - l, l, - " | %u.%2.2u MiB/s", - x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); - } else if (rate) - snprintf(tp->display + sizeof(tp->display) - l, l, - " | %u KiB/s", rate); + strbuf_addstr(buf, ", "); + strbuf_humanise_bytes(buf, total); + strbuf_addstr(buf, " | "); + strbuf_humanise_bytes(buf, rate * 1024); + strbuf_addstr(buf, "/s"); } void display_throughput(struct progress *progress, off_t total) @@ -183,6 +164,7 @@ void display_throughput(struct progress *progress, off_t total) misecs += (int)(tv.tv_usec - tp->prev_tv.tv_usec) / 977; if (misecs > 512) { + struct strbuf buf = STRBUF_INIT; unsigned int count, rate; count = total - tp->prev_total; @@ -197,7 +179,9 @@ void display_throughput(struct progress *progress, off_t total) tp->last_misecs[tp->idx] = misecs; tp->idx = (tp->idx + 1) % TP_IDX_MAX; - throughput_string(tp, total, rate); + throughput_string(&buf, total, rate); + strncpy(tp->display, buf.buf, sizeof(tp->display)); + strbuf_release(&buf); if (progress->last_value != -1 && progress_update) display(progress, progress->last_value, NULL); } @@ -253,9 +237,12 @@ void stop_progress_msg(struct progress **p_progress, const char *msg) bufp = (len < sizeof(buf)) ? buf : xmalloc(len + 1); if (tp) { + struct strbuf strbuf = STRBUF_INIT; unsigned int rate = !tp->avg_misecs ? 0 : tp->avg_bytes / tp->avg_misecs; - throughput_string(tp, tp->curr_total, rate); + throughput_string(&strbuf, tp->curr_total, rate); + strncpy(tp->display, strbuf.buf, sizeof(tp->display)); + strbuf_release(&strbuf); } progress_update = 1; sprintf(bufp, ", %s.\n", msg); diff --git a/read-cache.c b/read-cache.c index 5a9704f4e5..04ed561bfe 100644 --- a/read-cache.c +++ b/read-cache.c @@ -1899,3 +1899,37 @@ int index_name_is_other(const struct index_state *istate, const char *name, } return 1; } + +void *read_blob_data_from_index(struct index_state *istate, const char *path, unsigned long *size) +{ + int pos, len; + unsigned long sz; + enum object_type type; + void *data; + + len = strlen(path); + pos = index_name_pos(istate, path, len); + if (pos < 0) { + /* + * We might be in the middle of a merge, in which + * case we would read stage #2 (ours). + */ + int i; + for (i = -pos - 1; + (pos < 0 && i < istate->cache_nr && + !strcmp(istate->cache[i]->name, path)); + i++) + if (ce_stage(istate->cache[i]) == 2) + pos = i; + } + if (pos < 0) + return NULL; + data = read_sha1_file(istate->cache[pos]->sha1, &type, &sz); + if (!data || type != OBJ_BLOB) { + free(data); + return NULL; + } + if (size) + *size = sz; + return data; +} @@ -109,7 +109,20 @@ struct ref_entry; * (ref_entry->flag & REF_DIR) is zero. */ struct ref_value { + /* + * The name of the object to which this reference resolves + * (which may be a tag object). If REF_ISBROKEN, this is + * null. If REF_ISSYMREF, then this is the name of the object + * referred to by the last reference in the symlink chain. + */ unsigned char sha1[20]; + + /* + * If REF_KNOWS_PEELED, then this field holds the peeled value + * of this reference, or null if the reference is known not to + * be peelable. See the documentation for peel_ref() for an + * exact definition of "peelable". + */ unsigned char peeled[20]; }; @@ -158,7 +171,17 @@ struct ref_dir { struct ref_entry **entries; }; -/* ISSYMREF=0x01, ISPACKED=0x02, and ISBROKEN=0x04 are public interfaces */ +/* + * Bit values for ref_entry::flag. REF_ISSYMREF=0x01, + * REF_ISPACKED=0x02, and REF_ISBROKEN=0x04 are public values; see + * refs.h. + */ + +/* + * The field ref_entry->u.value.peeled of this value entry contains + * the correct peeled value for the reference, which might be + * null_sha1 if the reference is not a tag or if it is broken. + */ #define REF_KNOWS_PEELED 0x08 /* ref_entry represents a directory of references */ @@ -343,18 +366,17 @@ static int ref_entry_cmp_sslice(const void *key_, const void *ent_) } /* - * Return the entry with the given refname from the ref_dir - * (non-recursively), sorting dir if necessary. Return NULL if no - * such entry is found. dir must already be complete. + * Return the index of the entry with the given refname from the + * ref_dir (non-recursively), sorting dir if necessary. Return -1 if + * no such entry is found. dir must already be complete. */ -static struct ref_entry *search_ref_dir(struct ref_dir *dir, - const char *refname, size_t len) +static int search_ref_dir(struct ref_dir *dir, const char *refname, size_t len) { struct ref_entry **r; struct string_slice key; if (refname == NULL || !dir->nr) - return NULL; + return -1; sort_ref_dir(dir); key.len = len; @@ -363,9 +385,9 @@ static struct ref_entry *search_ref_dir(struct ref_dir *dir, ref_entry_cmp_sslice); if (r == NULL) - return NULL; + return -1; - return *r; + return r - dir->entries; } /* @@ -379,8 +401,9 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir, const char *subdirname, size_t len, int mkdir) { - struct ref_entry *entry = search_ref_dir(dir, subdirname, len); - if (!entry) { + int entry_index = search_ref_dir(dir, subdirname, len); + struct ref_entry *entry; + if (entry_index == -1) { if (!mkdir) return NULL; /* @@ -391,6 +414,8 @@ static struct ref_dir *search_for_subdir(struct ref_dir *dir, */ entry = create_dir_entry(dir->ref_cache, subdirname, len, 0); add_entry_to_dir(dir, entry); + } else { + entry = dir->entries[entry_index]; } return get_ref_dir(entry); } @@ -429,12 +454,67 @@ static struct ref_dir *find_containing_dir(struct ref_dir *dir, */ static struct ref_entry *find_ref(struct ref_dir *dir, const char *refname) { + int entry_index; struct ref_entry *entry; dir = find_containing_dir(dir, refname, 0); if (!dir) return NULL; - entry = search_ref_dir(dir, refname, strlen(refname)); - return (entry && !(entry->flag & REF_DIR)) ? entry : NULL; + entry_index = search_ref_dir(dir, refname, strlen(refname)); + if (entry_index == -1) + return NULL; + entry = dir->entries[entry_index]; + return (entry->flag & REF_DIR) ? NULL : entry; +} + +/* + * Remove the entry with the given name from dir, recursing into + * subdirectories as necessary. If refname is the name of a directory + * (i.e., ends with '/'), then remove the directory and its contents. + * If the removal was successful, return the number of entries + * remaining in the directory entry that contained the deleted entry. + * If the name was not found, return -1. Please note that this + * function only deletes the entry from the cache; it does not delete + * it from the filesystem or ensure that other cache entries (which + * might be symbolic references to the removed entry) are updated. + * Nor does it remove any containing dir entries that might be made + * empty by the removal. dir must represent the top-level directory + * and must already be complete. + */ +static int remove_entry(struct ref_dir *dir, const char *refname) +{ + int refname_len = strlen(refname); + int entry_index; + struct ref_entry *entry; + int is_dir = refname[refname_len - 1] == '/'; + if (is_dir) { + /* + * refname represents a reference directory. Remove + * the trailing slash; otherwise we will get the + * directory *representing* refname rather than the + * one *containing* it. + */ + char *dirname = xmemdupz(refname, refname_len - 1); + dir = find_containing_dir(dir, dirname, 0); + free(dirname); + } else { + dir = find_containing_dir(dir, refname, 0); + } + if (!dir) + return -1; + entry_index = search_ref_dir(dir, refname, refname_len); + if (entry_index == -1) + return -1; + entry = dir->entries[entry_index]; + + memmove(&dir->entries[entry_index], + &dir->entries[entry_index + 1], + (dir->nr - entry_index - 1) * sizeof(*dir->entries) + ); + dir->nr--; + if (dir->sorted > entry_index) + dir->sorted--; + free_ref_entry(entry); + return dir->nr; } /* @@ -503,27 +583,64 @@ static void sort_ref_dir(struct ref_dir *dir) dir->sorted = dir->nr = i; } -#define DO_FOR_EACH_INCLUDE_BROKEN 01 +/* 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 + * object does not exist. + */ +static int ref_resolves_to_object(struct ref_entry *entry) +{ + if (entry->flag & REF_ISBROKEN) + return 0; + if (!has_sha1_file(entry->u.value.sha1)) { + error("%s does not point to a valid object!", entry->name); + return 0; + } + return 1; +} + +/* + * current_ref is a performance hack: when iterating over references + * using the for_each_ref*() functions, current_ref is set to the + * current reference's entry before calling the callback function. If + * the callback function calls peel_ref(), then peel_ref() first + * checks whether the reference to be peeled is the current reference + * (it usually is) and if so, returns that reference's peeled version + * if it is available. This avoids a refname lookup in a common case. + */ static struct ref_entry *current_ref; -static int do_one_ref(const char *base, each_ref_fn fn, int trim, - int flags, void *cb_data, struct ref_entry *entry) +typedef int each_ref_entry_fn(struct ref_entry *entry, void *cb_data); + +struct ref_entry_cb { + const char *base; + int trim; + int flags; + each_ref_fn *fn; + void *cb_data; +}; + +/* + * Handle one reference in a do_for_each_ref*()-style iteration, + * calling an each_ref_fn for each entry. + */ +static int do_one_ref(struct ref_entry *entry, void *cb_data) { + struct ref_entry_cb *data = cb_data; int retval; - if (prefixcmp(entry->name, base)) + if (prefixcmp(entry->name, data->base)) + return 0; + + if (!(data->flags & DO_FOR_EACH_INCLUDE_BROKEN) && + !ref_resolves_to_object(entry)) return 0; - if (!(flags & DO_FOR_EACH_INCLUDE_BROKEN)) { - if (entry->flag & REF_ISBROKEN) - return 0; /* ignore broken refs e.g. dangling symref */ - if (!has_sha1_file(entry->u.value.sha1)) { - error("%s does not point to a valid object!", entry->name); - return 0; - } - } current_ref = entry; - retval = fn(entry->name + trim, entry->u.value.sha1, entry->flag, cb_data); + retval = data->fn(entry->name + data->trim, entry->u.value.sha1, + entry->flag, data->cb_data); current_ref = NULL; return retval; } @@ -532,11 +649,11 @@ static int do_one_ref(const char *base, each_ref_fn fn, int trim, * Call fn for each reference in dir that has index in the range * offset <= index < dir->nr. Recurse into subdirectories that are in * that index range, sorting them before iterating. This function - * does not sort dir itself; it should be sorted beforehand. + * does not sort dir itself; it should be sorted beforehand. fn is + * called for all references, including broken ones. */ -static int do_for_each_ref_in_dir(struct ref_dir *dir, int offset, - const char *base, - each_ref_fn fn, int trim, int flags, void *cb_data) +static int do_for_each_entry_in_dir(struct ref_dir *dir, int offset, + each_ref_entry_fn fn, void *cb_data) { int i; assert(dir->sorted == dir->nr); @@ -546,10 +663,9 @@ static int do_for_each_ref_in_dir(struct ref_dir *dir, int offset, if (entry->flag & REF_DIR) { struct ref_dir *subdir = get_ref_dir(entry); sort_ref_dir(subdir); - retval = do_for_each_ref_in_dir(subdir, 0, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dir(subdir, 0, fn, cb_data); } else { - retval = do_one_ref(base, fn, trim, flags, cb_data, entry); + retval = fn(entry, cb_data); } if (retval) return retval; @@ -562,12 +678,12 @@ static int do_for_each_ref_in_dir(struct ref_dir *dir, int offset, * by refname. Recurse into subdirectories. If a value entry appears * in both dir1 and dir2, then only process the version that is in * dir2. The input dirs must already be sorted, but subdirs will be - * sorted as needed. + * sorted as needed. fn is called for all references, including + * broken ones. */ -static int do_for_each_ref_in_dirs(struct ref_dir *dir1, - struct ref_dir *dir2, - const char *base, each_ref_fn fn, int trim, - int flags, void *cb_data) +static int do_for_each_entry_in_dirs(struct ref_dir *dir1, + struct ref_dir *dir2, + each_ref_entry_fn fn, void *cb_data) { int retval; int i1 = 0, i2 = 0; @@ -578,12 +694,10 @@ static int do_for_each_ref_in_dirs(struct ref_dir *dir1, struct ref_entry *e1, *e2; int cmp; if (i1 == dir1->nr) { - return do_for_each_ref_in_dir(dir2, i2, - base, fn, trim, flags, cb_data); + return do_for_each_entry_in_dir(dir2, i2, fn, cb_data); } if (i2 == dir2->nr) { - return do_for_each_ref_in_dir(dir1, i1, - base, fn, trim, flags, cb_data); + return do_for_each_entry_in_dir(dir1, i1, fn, cb_data); } e1 = dir1->entries[i1]; e2 = dir2->entries[i2]; @@ -595,14 +709,13 @@ static int do_for_each_ref_in_dirs(struct ref_dir *dir1, struct ref_dir *subdir2 = get_ref_dir(e2); sort_ref_dir(subdir1); sort_ref_dir(subdir2); - retval = do_for_each_ref_in_dirs( - subdir1, subdir2, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dirs( + subdir1, subdir2, fn, cb_data); i1++; i2++; } else if (!(e1->flag & REF_DIR) && !(e2->flag & REF_DIR)) { /* Both are references; ignore the one from dir1. */ - retval = do_one_ref(base, fn, trim, flags, cb_data, e2); + retval = fn(e2, cb_data); i1++; i2++; } else { @@ -621,23 +734,15 @@ static int do_for_each_ref_in_dirs(struct ref_dir *dir1, if (e->flag & REF_DIR) { struct ref_dir *subdir = get_ref_dir(e); sort_ref_dir(subdir); - retval = do_for_each_ref_in_dir( - subdir, 0, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dir( + subdir, 0, fn, cb_data); } else { - retval = do_one_ref(base, fn, trim, flags, cb_data, e); + retval = fn(e, cb_data); } } if (retval) return retval; } - if (i1 < dir1->nr) - return do_for_each_ref_in_dir(dir1, i1, - base, fn, trim, flags, cb_data); - if (i2 < dir2->nr) - return do_for_each_ref_in_dir(dir2, i2, - base, fn, trim, flags, cb_data); - return 0; } /* @@ -661,14 +766,13 @@ struct name_conflict_cb { const char *conflicting_refname; }; -static int name_conflict_fn(const char *existingrefname, const unsigned char *sha1, - int flags, void *cb_data) +static int name_conflict_fn(struct ref_entry *entry, void *cb_data) { struct name_conflict_cb *data = (struct name_conflict_cb *)cb_data; - if (data->oldrefname && !strcmp(data->oldrefname, existingrefname)) + if (data->oldrefname && !strcmp(data->oldrefname, entry->name)) return 0; - if (names_conflict(data->refname, existingrefname)) { - data->conflicting_refname = existingrefname; + if (names_conflict(data->refname, entry->name)) { + data->conflicting_refname = entry->name; return 1; } return 0; @@ -676,7 +780,7 @@ static int name_conflict_fn(const char *existingrefname, const unsigned char *sh /* * Return true iff a reference named refname could be created without - * conflicting with the name of an existing reference in array. If + * conflicting with the name of an existing reference in dir. If * oldrefname is non-NULL, ignore potential conflicts with oldrefname * (e.g., because oldrefname is scheduled for deletion in the same * operation). @@ -690,9 +794,7 @@ static int is_refname_available(const char *refname, const char *oldrefname, data.conflicting_refname = NULL; sort_ref_dir(dir); - if (do_for_each_ref_in_dir(dir, 0, "", name_conflict_fn, - 0, DO_FOR_EACH_INCLUDE_BROKEN, - &data)) { + if (do_for_each_entry_in_dir(dir, 0, name_conflict_fn, &data)) { error("'%s' exists; cannot create '%s'", data.conflicting_refname, refname); return 0; @@ -708,9 +810,13 @@ static struct ref_cache { struct ref_cache *next; struct ref_entry *loose; struct ref_entry *packed; - /* The submodule name, or "" for the main repo. */ - char name[FLEX_ARRAY]; -} *ref_cache; + /* + * The submodule name, or "" for the main repo. We allocate + * length 1 rather than FLEX_ARRAY so that the main ref_cache + * is initialized correctly. + */ + char name[1]; +} ref_cache, *submodule_ref_caches; static void clear_packed_ref_cache(struct ref_cache *refs) { @@ -748,18 +854,18 @@ static struct ref_cache *create_ref_cache(const char *submodule) */ static struct ref_cache *get_ref_cache(const char *submodule) { - struct ref_cache *refs = ref_cache; - if (!submodule) - submodule = ""; - while (refs) { + struct ref_cache *refs; + + if (!submodule || !*submodule) + return &ref_cache; + + for (refs = submodule_ref_caches; refs; refs = refs->next) if (!strcmp(submodule, refs->name)) return refs; - refs = refs->next; - } refs = create_ref_cache(submodule); - refs->next = ref_cache; - ref_cache = refs; + refs->next = submodule_ref_caches; + submodule_ref_caches = refs; return refs; } @@ -770,6 +876,16 @@ void invalidate_ref_cache(const char *submodule) clear_loose_ref_cache(refs); } +/* The length of a peeled reference line in packed-refs, including EOL: */ +#define PEELED_LINE_LENGTH 42 + +/* + * The packed-refs header line that we write out. Perhaps other + * traits will be added later. The trailing space is required. + */ +static const char PACKED_REFS_HEADER[] = + "# pack-refs with: peeled fully-peeled \n"; + /* * Parse one line from a packed-refs file. Write the SHA1 to sha1. * Return a pointer to the refname within the line (null-terminated), @@ -862,8 +978,8 @@ static void read_packed_refs(FILE *f, struct ref_dir *dir) } if (last && refline[0] == '^' && - strlen(refline) == 42 && - refline[41] == '\n' && + strlen(refline) == PEELED_LINE_LENGTH && + refline[PEELED_LINE_LENGTH - 1] == '\n' && !get_sha1_hex(refline + 1, sha1)) { hashcpy(last->u.value.peeled, sha1); /* @@ -898,8 +1014,8 @@ static struct ref_dir *get_packed_refs(struct ref_cache *refs) void add_packed_ref(const char *refname, const unsigned char *sha1) { - add_ref(get_packed_refs(get_ref_cache(NULL)), - create_ref_entry(refname, sha1, REF_ISPACKED, 1)); + add_ref(get_packed_refs(&ref_cache), + create_ref_entry(refname, sha1, REF_ISPACKED, 1)); } /* @@ -1069,18 +1185,12 @@ int resolve_gitlink_ref(const char *path, const char *refname, unsigned char *sh } /* - * Try to read ref from the packed references. On success, set sha1 - * and return 0; otherwise, return -1. + * Return the ref_entry for the given refname from the packed + * references. If it does not exist, return NULL. */ -static int get_packed_ref(const char *refname, unsigned char *sha1) +static struct ref_entry *get_packed_ref(const char *refname) { - struct ref_dir *packed = get_packed_refs(get_ref_cache(NULL)); - struct ref_entry *entry = find_ref(packed, refname); - if (entry) { - hashcpy(sha1, entry->u.value.sha1); - return 0; - } - return -1; + return find_ref(get_packed_refs(&ref_cache), refname); } const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int reading, int *flag) @@ -1108,13 +1218,17 @@ const char *resolve_ref_unsafe(const char *refname, unsigned char *sha1, int rea git_snpath(path, sizeof(path), "%s", refname); if (lstat(path, &st) < 0) { + struct ref_entry *entry; + if (errno != ENOENT) return NULL; /* * The loose reference file does not exist; * check for a packed reference. */ - if (!get_packed_ref(refname, sha1)) { + entry = get_packed_ref(refname); + if (entry) { + hashcpy(sha1, entry->u.value.sha1); if (flag) *flag |= REF_ISPACKED; return refname; @@ -1231,54 +1345,130 @@ static int filter_refs(const char *refname, const unsigned char *sha1, int flags return filter->fn(refname, sha1, flags, filter->cb_data); } +enum peel_status { + /* object was peeled successfully: */ + PEEL_PEELED = 0, + + /* + * object cannot be peeled because the named object (or an + * object referred to by a tag in the peel chain), does not + * exist. + */ + PEEL_INVALID = -1, + + /* object cannot be peeled because it is not a tag: */ + PEEL_NON_TAG = -2, + + /* ref_entry contains no peeled value because it is a symref: */ + PEEL_IS_SYMREF = -3, + + /* + * ref_entry cannot be peeled because it is broken (i.e., the + * symbolic reference cannot even be resolved to an object + * name): + */ + PEEL_BROKEN = -4 +}; + +/* + * Peel the named object; i.e., if the object is a tag, resolve the + * tag recursively until a non-tag is found. If successful, store the + * result to sha1 and return PEEL_PEELED. If the object is not a tag + * or is not valid, return PEEL_NON_TAG or PEEL_INVALID, respectively, + * and leave sha1 unchanged. + */ +static enum peel_status peel_object(const unsigned char *name, unsigned char *sha1) +{ + struct object *o = lookup_unknown_object(name); + + if (o->type == OBJ_NONE) { + int type = sha1_object_info(name, NULL); + if (type < 0) + return PEEL_INVALID; + o->type = type; + } + + if (o->type != OBJ_TAG) + return PEEL_NON_TAG; + + o = deref_tag_noverify(o); + if (!o) + return PEEL_INVALID; + + hashcpy(sha1, o->sha1); + return PEEL_PEELED; +} + +/* + * Peel the entry (if possible) and return its new peel_status. If + * repeel is true, re-peel the entry even if there is an old peeled + * value that is already stored in it. + * + * It is OK to call this function with a packed reference entry that + * might be stale and might even refer to an object that has since + * been garbage-collected. In such a case, if the entry has + * REF_KNOWS_PEELED then leave the status unchanged and return + * PEEL_PEELED or PEEL_NON_TAG; otherwise, return PEEL_INVALID. + */ +static enum peel_status peel_entry(struct ref_entry *entry, int repeel) +{ + enum peel_status status; + + if (entry->flag & REF_KNOWS_PEELED) { + if (repeel) { + entry->flag &= ~REF_KNOWS_PEELED; + hashclr(entry->u.value.peeled); + } else { + return is_null_sha1(entry->u.value.peeled) ? + PEEL_NON_TAG : PEEL_PEELED; + } + } + if (entry->flag & REF_ISBROKEN) + return PEEL_BROKEN; + if (entry->flag & REF_ISSYMREF) + return PEEL_IS_SYMREF; + + status = peel_object(entry->u.value.sha1, entry->u.value.peeled); + if (status == PEEL_PEELED || status == PEEL_NON_TAG) + entry->flag |= REF_KNOWS_PEELED; + return status; +} + int peel_ref(const char *refname, unsigned char *sha1) { int flag; unsigned char base[20]; - struct object *o; if (current_ref && (current_ref->name == refname - || !strcmp(current_ref->name, refname))) { - if (current_ref->flag & REF_KNOWS_PEELED) { - if (is_null_sha1(current_ref->u.value.peeled)) - return -1; - hashcpy(sha1, current_ref->u.value.peeled); - return 0; - } - hashcpy(base, current_ref->u.value.sha1); - goto fallback; + || !strcmp(current_ref->name, refname))) { + if (peel_entry(current_ref, 0)) + return -1; + hashcpy(sha1, current_ref->u.value.peeled); + return 0; } if (read_ref_full(refname, base, 1, &flag)) return -1; - if ((flag & REF_ISPACKED)) { - struct ref_dir *dir = get_packed_refs(get_ref_cache(NULL)); - struct ref_entry *r = find_ref(dir, refname); - - if (r != NULL && r->flag & REF_KNOWS_PEELED) { + /* + * If the reference is packed, read its ref_entry from the + * cache in the hope that we already know its peeled value. + * We only try this optimization on packed references because + * (a) forcing the filling of the loose reference cache could + * be expensive and (b) loose references anyway usually do not + * have REF_KNOWS_PEELED. + */ + if (flag & REF_ISPACKED) { + struct ref_entry *r = get_packed_ref(refname); + if (r) { + if (peel_entry(r, 0)) + return -1; hashcpy(sha1, r->u.value.peeled); return 0; } } -fallback: - o = lookup_unknown_object(base); - if (o->type == OBJ_NONE) { - int type = sha1_object_info(base, NULL); - if (type < 0) - return -1; - o->type = type; - } - - if (o->type == OBJ_TAG) { - o = deref_tag_noverify(o); - if (o) { - hashcpy(sha1, o->sha1); - return 0; - } - } - return -1; + return peel_object(base, sha1); } struct warn_if_dangling_data { @@ -1316,10 +1506,16 @@ void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refname) for_each_rawref(warn_if_dangling_symref, &data); } -static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn fn, - int trim, int flags, void *cb_data) +/* + * Call fn for each reference in the specified ref_cache, omitting + * references not in the containing_dir of base. fn is called for all + * references, including broken ones. If fn ever returns a non-zero + * value, stop the iteration and return that value; otherwise, return + * 0. + */ +static int do_for_each_entry(struct ref_cache *refs, const char *base, + each_ref_entry_fn fn, void *cb_data) { - struct ref_cache *refs = get_ref_cache(submodule); struct ref_dir *packed_dir = get_packed_refs(refs); struct ref_dir *loose_dir = get_loose_refs(refs); int retval = 0; @@ -1332,24 +1528,43 @@ static int do_for_each_ref(const char *submodule, const char *base, each_ref_fn if (packed_dir && loose_dir) { sort_ref_dir(packed_dir); sort_ref_dir(loose_dir); - retval = do_for_each_ref_in_dirs( - packed_dir, loose_dir, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dirs( + packed_dir, loose_dir, fn, cb_data); } else if (packed_dir) { sort_ref_dir(packed_dir); - retval = do_for_each_ref_in_dir( - packed_dir, 0, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dir( + packed_dir, 0, fn, cb_data); } else if (loose_dir) { sort_ref_dir(loose_dir); - retval = do_for_each_ref_in_dir( - loose_dir, 0, - base, fn, trim, flags, cb_data); + retval = do_for_each_entry_in_dir( + loose_dir, 0, fn, cb_data); } return retval; } +/* + * Call fn for each reference in the specified ref_cache for which the + * refname begins with base. If trim is non-zero, then trim that many + * characters off the beginning of each refname before passing the + * refname to fn. flags can be DO_FOR_EACH_INCLUDE_BROKEN to include + * broken references in the iteration. If fn ever returns a non-zero + * 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) +{ + struct ref_entry_cb data; + data.base = base; + data.trim = trim; + data.flags = flags; + data.fn = fn; + data.cb_data = cb_data; + + 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) { unsigned char sha1[20]; @@ -1380,23 +1595,23 @@ int head_ref_submodule(const char *submodule, each_ref_fn fn, void *cb_data) int for_each_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref(NULL, "", fn, 0, 0, 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(submodule, "", fn, 0, 0, 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(NULL, prefix, fn, strlen(prefix), 0, cb_data); + return do_for_each_ref(&ref_cache, prefix, fn, strlen(prefix), 0, 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); + return do_for_each_ref(get_ref_cache(submodule), prefix, fn, strlen(prefix), 0, cb_data); } int for_each_tag_ref(each_ref_fn fn, void *cb_data) @@ -1431,7 +1646,7 @@ int for_each_remote_ref_submodule(const char *submodule, each_ref_fn fn, void *c int for_each_replace_ref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref(NULL, "refs/replace/", fn, 13, 0, cb_data); + return do_for_each_ref(&ref_cache, "refs/replace/", fn, 13, 0, cb_data); } int head_ref_namespaced(each_ref_fn fn, void *cb_data) @@ -1454,7 +1669,7 @@ 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); + ret = do_for_each_ref(&ref_cache, buf.buf, fn, 0, 0, cb_data); strbuf_release(&buf); return ret; } @@ -1496,7 +1711,7 @@ int for_each_glob_ref(each_ref_fn fn, const char *pattern, void *cb_data) int for_each_rawref(each_ref_fn fn, void *cb_data) { - return do_for_each_ref(NULL, "", fn, 0, + return do_for_each_ref(&ref_cache, "", fn, 0, DO_FOR_EACH_INCLUDE_BROKEN, cb_data); } @@ -1702,7 +1917,7 @@ static struct ref_lock *lock_ref_sha1_basic(const char *refname, * name is a proper prefix of our refname. */ if (missing && - !is_refname_available(refname, NULL, get_packed_refs(get_ref_cache(NULL)))) { + !is_refname_available(refname, NULL, get_packed_refs(&ref_cache))) { last_errno = ENOTDIR; goto error_return; } @@ -1754,47 +1969,224 @@ struct ref_lock *lock_any_ref_for_update(const char *refname, return lock_ref_sha1_basic(refname, old_sha1, flags, NULL); } -struct repack_without_ref_sb { - const char *refname; - int fd; -}; - -static int repack_without_ref_fn(const char *refname, const unsigned char *sha1, - int flags, void *cb_data) +/* + * Write an entry to the packed-refs file for the specified refname. + * If peeled is non-NULL, write it as the entry's peeled value. + */ +static void write_packed_entry(int fd, char *refname, unsigned char *sha1, + unsigned char *peeled) { - struct repack_without_ref_sb *data = cb_data; char line[PATH_MAX + 100]; int len; - if (!strcmp(data->refname, refname)) - return 0; len = snprintf(line, sizeof(line), "%s %s\n", sha1_to_hex(sha1), refname); /* this should not happen but just being defensive */ if (len > sizeof(line)) die("too long a refname '%s'", refname); - write_or_die(data->fd, line, len); + write_or_die(fd, line, len); + + if (peeled) { + if (snprintf(line, sizeof(line), "^%s\n", + sha1_to_hex(peeled)) != PEELED_LINE_LENGTH) + die("internal error"); + write_or_die(fd, line, PEELED_LINE_LENGTH); + } +} + +struct ref_to_prune { + struct ref_to_prune *next; + unsigned char sha1[20]; + char name[FLEX_ARRAY]; +}; + +struct pack_refs_cb_data { + unsigned int flags; + struct ref_to_prune *ref_to_prune; + int fd; +}; + +static int pack_one_ref(struct ref_entry *entry, void *cb_data) +{ + struct pack_refs_cb_data *cb = cb_data; + enum peel_status peel_status; + int is_tag_ref = !prefixcmp(entry->name, "refs/tags/"); + + /* ALWAYS pack refs that were already packed or are tags */ + if (!(cb->flags & PACK_REFS_ALL) && !is_tag_ref && + !(entry->flag & REF_ISPACKED)) + return 0; + + /* Do not pack symbolic or broken refs: */ + if ((entry->flag & REF_ISSYMREF) || !ref_resolves_to_object(entry)) + return 0; + + peel_status = peel_entry(entry, 1); + if (peel_status != PEEL_PEELED && peel_status != PEEL_NON_TAG) + die("internal error peeling reference %s (%s)", + entry->name, sha1_to_hex(entry->u.value.sha1)); + write_packed_entry(cb->fd, entry->name, entry->u.value.sha1, + peel_status == PEEL_PEELED ? + entry->u.value.peeled : NULL); + + /* If the ref was already packed, there is no need to prune it. */ + if ((cb->flags & PACK_REFS_PRUNE) && !(entry->flag & REF_ISPACKED)) { + int namelen = strlen(entry->name) + 1; + struct ref_to_prune *n = xcalloc(1, sizeof(*n) + namelen); + hashcpy(n->sha1, entry->u.value.sha1); + strcpy(n->name, entry->name); + n->next = cb->ref_to_prune; + cb->ref_to_prune = n; + } return 0; } +/* + * Remove empty parents, but spare refs/ and immediate subdirs. + * Note: munges *name. + */ +static void try_remove_empty_parents(char *name) +{ + char *p, *q; + int i; + p = name; + for (i = 0; i < 2; i++) { /* refs/{heads,tags,...}/ */ + while (*p && *p != '/') + p++; + /* tolerate duplicate slashes; see check_refname_format() */ + while (*p == '/') + p++; + } + for (q = p; *q; q++) + ; + while (1) { + while (q > p && *q != '/') + q--; + while (q > p && *(q-1) == '/') + q--; + if (q == p) + break; + *q = '\0'; + if (rmdir(git_path("%s", name))) + break; + } +} + +/* make sure nobody touched the ref, and unlink */ +static void prune_ref(struct ref_to_prune *r) +{ + struct ref_lock *lock = lock_ref_sha1(r->name + 5, r->sha1); + + if (lock) { + unlink_or_warn(git_path("%s", r->name)); + unlock_ref(lock); + try_remove_empty_parents(r->name); + } +} + +static void prune_refs(struct ref_to_prune *r) +{ + while (r) { + prune_ref(r); + r = r->next; + } +} + static struct lock_file packlock; -static int repack_without_ref(const char *refname) +int pack_refs(unsigned int flags) +{ + struct pack_refs_cb_data cbdata; + + memset(&cbdata, 0, sizeof(cbdata)); + cbdata.flags = flags; + + cbdata.fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), + LOCK_DIE_ON_ERROR); + + write_or_die(cbdata.fd, PACKED_REFS_HEADER, strlen(PACKED_REFS_HEADER)); + + do_for_each_entry(&ref_cache, "", pack_one_ref, &cbdata); + if (commit_lock_file(&packlock) < 0) + die_errno("unable to overwrite old ref-pack file"); + prune_refs(cbdata.ref_to_prune); + return 0; +} + +static int repack_ref_fn(struct ref_entry *entry, void *cb_data) { - struct repack_without_ref_sb data; - struct ref_cache *refs = get_ref_cache(NULL); - struct ref_dir *packed = get_packed_refs(refs); - if (find_ref(packed, refname) == NULL) + int *fd = cb_data; + enum peel_status peel_status; + + if (entry->flag & REF_ISBROKEN) { + /* This shouldn't happen to packed refs. */ + error("%s is broken!", entry->name); return 0; - data.refname = refname; - data.fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0); - if (data.fd < 0) { + } + if (!has_sha1_file(entry->u.value.sha1)) { + unsigned char sha1[20]; + int flags; + + if (read_ref_full(entry->name, sha1, 0, &flags)) + /* We should at least have found the packed ref. */ + die("Internal error"); + if ((flags & REF_ISSYMREF) || !(flags & REF_ISPACKED)) + /* + * This packed reference is overridden by a + * loose reference, so it is OK that its value + * is no longer valid; for example, it might + * refer to an object that has been garbage + * collected. For this purpose we don't even + * care whether the loose reference itself is + * invalid, broken, symbolic, etc. Silently + * omit the packed reference from the output. + */ + return 0; + /* + * There is no overriding loose reference, so the fact + * that this reference doesn't refer to a valid object + * indicates some kind of repository corruption. + * Report the problem, then omit the reference from + * the output. + */ + error("%s does not point to a valid object!", entry->name); + return 0; + } + + peel_status = peel_entry(entry, 0); + write_packed_entry(*fd, entry->name, entry->u.value.sha1, + peel_status == PEEL_PEELED ? + entry->u.value.peeled : NULL); + + return 0; +} + +static int repack_without_ref(const char *refname) +{ + int fd; + struct ref_dir *packed; + + if (!get_packed_ref(refname)) + return 0; /* refname does not exist in packed refs */ + + fd = hold_lock_file_for_update(&packlock, git_path("packed-refs"), 0); + if (fd < 0) { unable_to_lock_error(git_path("packed-refs"), errno); return error("cannot delete '%s' from packed refs", refname); } - clear_packed_ref_cache(refs); - packed = get_packed_refs(refs); - do_for_each_ref_in_dir(packed, 0, "", repack_without_ref_fn, 0, 0, &data); + clear_packed_ref_cache(&ref_cache); + packed = get_packed_refs(&ref_cache); + /* Remove refname from the cache. */ + if (remove_entry(packed, refname) == -1) { + /* + * The packed entry disappeared while we were + * acquiring the lock. + */ + rollback_lock_file(&packlock); + return 0; + } + write_or_die(fd, PACKED_REFS_HEADER, strlen(PACKED_REFS_HEADER)); + do_for_each_entry_in_dir(packed, 0, repack_ref_fn, &fd); return commit_lock_file(&packlock); } @@ -1823,7 +2215,7 @@ int delete_ref(const char *refname, const unsigned char *sha1, int delopt) ret |= repack_without_ref(lock->ref_name); unlink_or_warn(git_path("logs/%s", lock->ref_name)); - invalidate_ref_cache(NULL); + clear_loose_ref_cache(&ref_cache); unlock_ref(lock); return ret; } @@ -1845,7 +2237,6 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms struct stat loginfo; int log = !lstat(git_path("logs/%s", oldrefname), &loginfo); const char *symref = NULL; - struct ref_cache *refs = get_ref_cache(NULL); if (log && S_ISLNK(loginfo.st_mode)) return error("reflog for %s is a symlink", oldrefname); @@ -1857,10 +2248,10 @@ int rename_ref(const char *oldrefname, const char *newrefname, const char *logms if (!symref) return error("refname %s not found", oldrefname); - if (!is_refname_available(newrefname, oldrefname, get_packed_refs(refs))) + if (!is_refname_available(newrefname, oldrefname, get_packed_refs(&ref_cache))) return 1; - if (!is_refname_available(newrefname, oldrefname, get_loose_refs(refs))) + if (!is_refname_available(newrefname, oldrefname, get_loose_refs(&ref_cache))) return 1; if (log && rename(git_path("logs/%s", oldrefname), git_path(TMP_RENAMED_LOG))) @@ -2116,7 +2507,7 @@ int write_ref_sha1(struct ref_lock *lock, unlock_ref(lock); return -1; } - clear_loose_ref_cache(get_ref_cache(NULL)); + clear_loose_ref_cache(&ref_cache); if (log_ref_write(lock->ref_name, lock->old_sha1, sha1, logmsg) < 0 || (strcmp(lock->ref_name, lock->orig_ref_name) && log_ref_write(lock->orig_ref_name, lock->old_sha1, sha1, logmsg) < 0)) { @@ -2332,59 +2723,117 @@ int read_ref_at(const char *refname, unsigned long at_time, int cnt, return 1; } -int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long ofs, void *cb_data) +static int show_one_reflog_ent(struct strbuf *sb, each_reflog_ent_fn fn, void *cb_data) +{ + unsigned char osha1[20], nsha1[20]; + char *email_end, *message; + unsigned long timestamp; + int tz; + + /* old SP new SP name <email> SP time TAB msg LF */ + if (sb->len < 83 || sb->buf[sb->len - 1] != '\n' || + get_sha1_hex(sb->buf, osha1) || sb->buf[40] != ' ' || + get_sha1_hex(sb->buf + 41, nsha1) || sb->buf[81] != ' ' || + !(email_end = strchr(sb->buf + 82, '>')) || + email_end[1] != ' ' || + !(timestamp = strtoul(email_end + 2, &message, 10)) || + !message || message[0] != ' ' || + (message[1] != '+' && message[1] != '-') || + !isdigit(message[2]) || !isdigit(message[3]) || + !isdigit(message[4]) || !isdigit(message[5])) + return 0; /* corrupt? */ + email_end[1] = '\0'; + tz = strtol(message + 1, NULL, 10); + if (message[6] != '\t') + message += 6; + else + message += 7; + return fn(osha1, nsha1, sb->buf + 82, timestamp, tz, message, cb_data); +} + +static char *find_beginning_of_line(char *bob, char *scan) +{ + while (bob < scan && *(--scan) != '\n') + ; /* keep scanning backwards */ + /* + * Return either beginning of the buffer, or LF at the end of + * the previous line. + */ + return scan; +} + +int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data) { - const char *logfile; - FILE *logfp; struct strbuf sb = STRBUF_INIT; - int ret = 0; + FILE *logfp; + long pos; + int ret = 0, at_tail = 1; - logfile = git_path("logs/%s", refname); - logfp = fopen(logfile, "r"); + logfp = fopen(git_path("logs/%s", refname), "r"); if (!logfp) return -1; - if (ofs) { - struct stat statbuf; - if (fstat(fileno(logfp), &statbuf) || - statbuf.st_size < ofs || - fseek(logfp, -ofs, SEEK_END) || - strbuf_getwholeline(&sb, logfp, '\n')) { - fclose(logfp); - strbuf_release(&sb); - return -1; + /* Jump to the end */ + if (fseek(logfp, 0, SEEK_END) < 0) + return error("cannot seek back reflog for %s: %s", + refname, strerror(errno)); + pos = ftell(logfp); + while (!ret && 0 < pos) { + int cnt; + size_t nread; + char buf[BUFSIZ]; + char *endp, *scanp; + + /* Fill next block from the end */ + cnt = (sizeof(buf) < pos) ? sizeof(buf) : pos; + if (fseek(logfp, pos - cnt, SEEK_SET)) + return error("cannot seek back reflog for %s: %s", + refname, strerror(errno)); + nread = fread(buf, cnt, 1, logfp); + if (nread != 1) + return error("cannot read %d bytes from reflog for %s: %s", + cnt, refname, strerror(errno)); + pos -= cnt; + + scanp = endp = buf + cnt; + if (at_tail && scanp[-1] == '\n') + /* Looking at the final LF at the end of the file */ + scanp--; + at_tail = 0; + + while (buf < scanp) { + /* + * terminating LF of the previous line, or the beginning + * of the buffer. + */ + char *bp; + + bp = find_beginning_of_line(buf, scanp); + + if (*bp != '\n') { + strbuf_splice(&sb, 0, 0, buf, endp - buf); + if (pos) + break; /* need to fill another block */ + scanp = buf - 1; /* leave loop */ + } else { + /* + * (bp + 1) thru endp is the beginning of the + * current line we have in sb + */ + strbuf_splice(&sb, 0, 0, bp + 1, endp - (bp + 1)); + scanp = bp; + endp = bp + 1; + } + ret = show_one_reflog_ent(&sb, fn, cb_data); + strbuf_reset(&sb); + if (ret) + break; } - } - while (!strbuf_getwholeline(&sb, logfp, '\n')) { - unsigned char osha1[20], nsha1[20]; - char *email_end, *message; - unsigned long timestamp; - int tz; - - /* old SP new SP name <email> SP time TAB msg LF */ - if (sb.len < 83 || sb.buf[sb.len - 1] != '\n' || - get_sha1_hex(sb.buf, osha1) || sb.buf[40] != ' ' || - get_sha1_hex(sb.buf + 41, nsha1) || sb.buf[81] != ' ' || - !(email_end = strchr(sb.buf + 82, '>')) || - email_end[1] != ' ' || - !(timestamp = strtoul(email_end + 2, &message, 10)) || - !message || message[0] != ' ' || - (message[1] != '+' && message[1] != '-') || - !isdigit(message[2]) || !isdigit(message[3]) || - !isdigit(message[4]) || !isdigit(message[5])) - continue; /* corrupt? */ - email_end[1] = '\0'; - tz = strtol(message + 1, NULL, 10); - if (message[6] != '\t') - message += 6; - else - message += 7; - ret = fn(osha1, nsha1, sb.buf + 82, timestamp, tz, message, - cb_data); - if (ret) - break; } + if (!ret && sb.len) + ret = show_one_reflog_ent(&sb, fn, cb_data); + fclose(logfp); strbuf_release(&sb); return ret; @@ -2392,9 +2841,20 @@ int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data) { - return for_each_recent_reflog_ent(refname, fn, 0, cb_data); -} + FILE *logfp; + struct strbuf sb = STRBUF_INIT; + int ret = 0; + logfp = fopen(git_path("logs/%s", refname), "r"); + if (!logfp) + return -1; + + while (!ret && !strbuf_getwholeline(&sb, logfp, '\n')) + ret = show_one_reflog_ent(&sb, fn, cb_data); + fclose(logfp); + strbuf_release(&sb); + return ret; +} /* * Call fn for each reflog in the namespace indicated by name. name * must be empty or end with '/'. Name will be used as a scratch @@ -10,8 +10,21 @@ struct ref_lock { int force_write; }; +/* + * Bit values set in the flags argument passed to each_ref_fn(): + */ + +/* Reference is a symbolic reference. */ #define REF_ISSYMREF 0x01 + +/* Reference is a packed reference. */ #define REF_ISPACKED 0x02 + +/* + * Reference cannot be resolved to an object name: dangling symbolic + * reference (directly or indirectly), corrupt reference file, or + * symbolic reference refers to ill-formatted reference name. + */ #define REF_ISBROKEN 0x04 /* @@ -59,8 +72,30 @@ extern void warn_dangling_symref(FILE *fp, const char *msg_fmt, const char *refn */ extern void add_packed_ref(const char *refname, const unsigned char *sha1); +/* + * Flags for controlling behaviour of pack_refs() + * PACK_REFS_PRUNE: Prune loose refs after packing + * PACK_REFS_ALL: Pack _all_ refs, not just tags and already packed refs + */ +#define PACK_REFS_PRUNE 0x0001 +#define PACK_REFS_ALL 0x0002 + +/* + * Write a packed-refs file for the current repository. + * flags: Combination of the above PACK_REFS_* flags. + */ +int pack_refs(unsigned int flags); + extern int ref_exists(const char *); +/* + * If refname is a non-symbolic reference that refers to a tag object, + * and the tag can be (recursively) dereferenced to a non-tag object, + * store the SHA1 of the referred-to object to sha1 and return 0. If + * any of these conditions are not met, return a non-zero value. + * Symbolic references are considered unpeelable, even if they + * ultimately resolve to a peelable tag. + */ extern int peel_ref(const char *refname, unsigned char *sha1); /** Locks a "refs/" ref returning the lock on success and NULL on failure. **/ @@ -103,7 +138,7 @@ extern int read_ref_at(const char *refname, unsigned long at_time, int cnt, /* iterate over reflog entries */ typedef int each_reflog_ent_fn(unsigned char *osha1, unsigned char *nsha1, const char *, unsigned long, int, const char *, void *); int for_each_reflog_ent(const char *refname, each_reflog_ent_fn fn, void *cb_data); -int for_each_recent_reflog_ent(const char *refname, each_reflog_ent_fn fn, long, void *cb_data); +int for_each_reflog_ent_reverse(const char *refname, each_reflog_ent_fn fn, void *cb_data); /* * Calls the specified function for each reflog file until it returns nonzero, diff --git a/remote-curl.c b/remote-curl.c index 933c69ac26..60eda63081 100644 --- a/remote-curl.c +++ b/remote-curl.c @@ -76,21 +76,109 @@ struct discovery { char *buf_alloc; char *buf; size_t len; + struct ref *refs; unsigned proto_git : 1; }; static struct discovery *last_discovery; +static struct ref *parse_git_refs(struct discovery *heads, int for_push) +{ + struct ref *list = NULL; + get_remote_heads(-1, heads->buf, heads->len, &list, + for_push ? REF_NORMAL : 0, NULL); + return list; +} + +static struct ref *parse_info_refs(struct discovery *heads) +{ + char *data, *start, *mid; + char *ref_name; + int i = 0; + + struct ref *refs = NULL; + struct ref *ref = NULL; + struct ref *last_ref = NULL; + + data = heads->buf; + start = NULL; + mid = data; + while (i < heads->len) { + if (!start) { + start = &data[i]; + } + if (data[i] == '\t') + mid = &data[i]; + if (data[i] == '\n') { + if (mid - start != 40) + die("%sinfo/refs not valid: is this a git repository?", url); + data[i] = 0; + ref_name = mid + 1; + ref = xmalloc(sizeof(struct ref) + + strlen(ref_name) + 1); + memset(ref, 0, sizeof(struct ref)); + strcpy(ref->name, ref_name); + get_sha1_hex(start, ref->old_sha1); + if (!refs) + refs = ref; + if (last_ref) + last_ref->next = ref; + last_ref = ref; + start = NULL; + } + i++; + } + + ref = alloc_ref("HEAD"); + if (!http_fetch_ref(url, ref) && + !resolve_remote_symref(ref, refs)) { + ref->next = refs; + refs = ref; + } else { + free(ref); + } + + return refs; +} + static void free_discovery(struct discovery *d) { if (d) { if (d == last_discovery) last_discovery = NULL; free(d->buf_alloc); + free_refs(d->refs); free(d); } } -static struct discovery* discover_refs(const char *service) +static int show_http_message(struct strbuf *type, struct strbuf *msg) +{ + const char *p, *eol; + + /* + * We only show text/plain parts, as other types are likely + * to be ugly to look at on the user's terminal. + * + * TODO should handle "; charset=XXX", and re-encode into + * logoutputencoding + */ + if (strcasecmp(type->buf, "text/plain")) + return -1; + + strbuf_trim(msg); + if (!msg->len) + return -1; + + p = msg->buf; + do { + eol = strchrnul(p, '\n'); + fprintf(stderr, "remote: %.*s\n", (int)(eol - p), p); + p = eol + 1; + } while(*eol); + return 0; +} + +static struct discovery* discover_refs(const char *service, int for_push) { struct strbuf exp = STRBUF_INIT; struct strbuf type = STRBUF_INIT; @@ -115,18 +203,20 @@ static struct discovery* discover_refs(const char *service) } refs_url = strbuf_detach(&buffer, NULL); - http_ret = http_get_strbuf(refs_url, &type, &buffer, HTTP_NO_CACHE); + http_ret = http_get_strbuf(refs_url, &type, &buffer, + HTTP_NO_CACHE | HTTP_KEEP_ERROR); switch (http_ret) { case HTTP_OK: break; case HTTP_MISSING_TARGET: - die("%s not found: did you run git update-server-info on the" - " server?", refs_url); + show_http_message(&type, &buffer); + die("repository '%s' not found", url); case HTTP_NOAUTH: - die("Authentication failed"); + show_http_message(&type, &buffer); + die("Authentication failed for '%s'", url); default: - http_error(refs_url, http_ret); - die("HTTP request failed"); + show_http_message(&type, &buffer); + die("unable to access '%s': %s", url, curl_errorstr); } last= xcalloc(1, sizeof(*last_discovery)); @@ -138,32 +228,35 @@ static struct discovery* discover_refs(const char *service) if (maybe_smart && (5 <= last->len && last->buf[4] == '#') && !strbuf_cmp(&exp, &type)) { + char *line; + /* * smart HTTP response; validate that the service * pkt-line matches our request. */ - if (packet_get_line(&buffer, &last->buf, &last->len) <= 0) - die("%s has invalid packet header", refs_url); - if (buffer.len && buffer.buf[buffer.len - 1] == '\n') - strbuf_setlen(&buffer, buffer.len - 1); + line = packet_read_line_buf(&last->buf, &last->len, NULL); strbuf_reset(&exp); strbuf_addf(&exp, "# service=%s", service); - if (strbuf_cmp(&exp, &buffer)) - die("invalid server response; got '%s'", buffer.buf); + if (strcmp(line, exp.buf)) + die("invalid server response; got '%s'", line); strbuf_release(&exp); /* The header can include additional metadata lines, up * until a packet flush marker. Ignore these now, but * in the future we might start to scan them. */ - strbuf_reset(&buffer); - while (packet_get_line(&buffer, &last->buf, &last->len) > 0) - strbuf_reset(&buffer); + while (packet_read_line_buf(&last->buf, &last->len, NULL)) + ; last->proto_git = 1; } + if (last->proto_git) + last->refs = parse_git_refs(last, for_push); + else + last->refs = parse_info_refs(last); + free(refs_url); strbuf_release(&exp); strbuf_release(&type); @@ -172,99 +265,16 @@ static struct discovery* discover_refs(const char *service) return last; } -static int write_discovery(int in, int out, void *data) -{ - struct discovery *heads = data; - int err = 0; - if (write_in_full(out, heads->buf, heads->len) != heads->len) - err = 1; - close(out); - return err; -} - -static struct ref *parse_git_refs(struct discovery *heads, int for_push) -{ - struct ref *list = NULL; - struct async async; - - memset(&async, 0, sizeof(async)); - async.proc = write_discovery; - async.data = heads; - async.out = -1; - - if (start_async(&async)) - die("cannot start thread to parse advertised refs"); - get_remote_heads(async.out, &list, - for_push ? REF_NORMAL : 0, NULL); - close(async.out); - if (finish_async(&async)) - die("ref parsing thread failed"); - return list; -} - -static struct ref *parse_info_refs(struct discovery *heads) -{ - char *data, *start, *mid; - char *ref_name; - int i = 0; - - struct ref *refs = NULL; - struct ref *ref = NULL; - struct ref *last_ref = NULL; - - data = heads->buf; - start = NULL; - mid = data; - while (i < heads->len) { - if (!start) { - start = &data[i]; - } - if (data[i] == '\t') - mid = &data[i]; - if (data[i] == '\n') { - if (mid - start != 40) - die("%sinfo/refs not valid: is this a git repository?", url); - data[i] = 0; - ref_name = mid + 1; - ref = xmalloc(sizeof(struct ref) + - strlen(ref_name) + 1); - memset(ref, 0, sizeof(struct ref)); - strcpy(ref->name, ref_name); - get_sha1_hex(start, ref->old_sha1); - if (!refs) - refs = ref; - if (last_ref) - last_ref->next = ref; - last_ref = ref; - start = NULL; - } - i++; - } - - ref = alloc_ref("HEAD"); - if (!http_fetch_ref(url, ref) && - !resolve_remote_symref(ref, refs)) { - ref->next = refs; - refs = ref; - } else { - free(ref); - } - - return refs; -} - static struct ref *get_refs(int for_push) { struct discovery *heads; if (for_push) - heads = discover_refs("git-receive-pack"); + heads = discover_refs("git-receive-pack", for_push); else - heads = discover_refs("git-upload-pack"); + heads = discover_refs("git-upload-pack", for_push); - if (heads->proto_git) - return parse_git_refs(heads, for_push); - return parse_info_refs(heads); + return heads->refs; } static void output_refs(struct ref *refs) @@ -278,7 +288,6 @@ static void output_refs(struct ref *refs) } printf("\n"); fflush(stdout); - free_refs(refs); } struct rpc_state { @@ -308,7 +317,7 @@ static size_t rpc_out(void *ptr, size_t eltsize, if (!avail) { rpc->initial_buffer = 0; - avail = packet_read_line(rpc->out, rpc->buf, rpc->alloc); + avail = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0); if (!avail) return 0; rpc->pos = 0; @@ -425,7 +434,7 @@ static int post_rpc(struct rpc_state *rpc) break; } - n = packet_read_line(rpc->out, buf, left); + n = packet_read(rpc->out, NULL, NULL, buf, left, 0); if (!n) break; rpc->len += n; @@ -579,7 +588,7 @@ static int rpc_service(struct rpc_state *rpc, struct discovery *heads) rpc->hdr_accept = strbuf_detach(&buf, NULL); while (!err) { - int n = packet_read_line(rpc->out, rpc->buf, rpc->alloc); + int n = packet_read(rpc->out, NULL, NULL, rpc->buf, rpc->alloc, 0); if (!n) break; rpc->pos = 0; @@ -685,7 +694,7 @@ static int fetch_git(struct discovery *heads, err = rpc_service(&rpc, heads); if (rpc.result.len) - safe_write(1, rpc.result.buf, rpc.result.len); + write_or_die(1, rpc.result.buf, rpc.result.len); strbuf_release(&rpc.result); strbuf_release(&preamble); free(depth_arg); @@ -694,7 +703,7 @@ static int fetch_git(struct discovery *heads, static int fetch(int nr_heads, struct ref **to_fetch) { - struct discovery *d = discover_refs("git-upload-pack"); + struct discovery *d = discover_refs("git-upload-pack", 0); if (d->proto_git) return fetch_git(d, nr_heads, to_fetch); else @@ -805,7 +814,7 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) err = rpc_service(&rpc, heads); if (rpc.result.len) - safe_write(1, rpc.result.buf, rpc.result.len); + write_or_die(1, rpc.result.buf, rpc.result.len); strbuf_release(&rpc.result); free(argv); return err; @@ -813,7 +822,7 @@ static int push_git(struct discovery *heads, int nr_spec, char **specs) static int push(int nr_spec, char **specs) { - struct discovery *heads = discover_refs("git-receive-pack"); + struct discovery *heads = discover_refs("git-receive-pack", 1); int ret; if (heads->proto_git) diff --git a/remote-testsvn.c b/remote-testsvn.c index 5ddf11cc61..d7cd5d272f 100644 --- a/remote-testsvn.c +++ b/remote-testsvn.c @@ -286,7 +286,7 @@ static int do_command(struct strbuf *line) return 0; } -int main(int argc, const char **argv) +int main(int argc, char **argv) { struct strbuf buf = STRBUF_INIT, url_sb = STRBUF_INIT, private_ref_sb = STRBUF_INIT, marksfilename_sb = STRBUF_INIT, @@ -15,6 +15,7 @@ static struct refspec s_tag_refspec = { 0, 1, 0, + 0, "refs/tags/*", "refs/tags/*" }; @@ -48,6 +49,7 @@ static int branches_nr; static struct branch *current_branch; static const char *default_remote_name; +static const char *pushremote_name; static int explicit_default_remote_name; static struct rewrites rewrites; @@ -356,13 +358,16 @@ static int handle_config(const char *key, const char *value, void *cb) return 0; branch = make_branch(name, subkey - name); if (!strcmp(subkey, ".remote")) { - if (!value) - return config_error_nonbool(key); - branch->remote_name = xstrdup(value); + if (git_config_string(&branch->remote_name, key, value)) + return -1; if (branch == current_branch) { default_remote_name = branch->remote_name; explicit_default_remote_name = 1; } + } else if (!strcmp(subkey, ".pushremote")) { + if (branch == current_branch) + if (git_config_string(&pushremote_name, key, value)) + return -1; } else if (!strcmp(subkey, ".merge")) { if (!value) return config_error_nonbool(key); @@ -388,9 +393,16 @@ static int handle_config(const char *key, const char *value, void *cb) add_instead_of(rewrite, xstrdup(value)); } } + if (prefixcmp(key, "remote.")) return 0; name = key + 7; + + /* Handle remote.* variables */ + if (!strcmp(name, "pushdefault")) + return git_config_string(&pushremote_name, key, value); + + /* Handle remote.<name>.* variables */ if (*name == '/') { warning("Config remote shorthand cannot begin with '/': %s", name); @@ -538,7 +550,7 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp /* * Before going on, special case ":" (or "+:") as a refspec - * for matching refs. + * for pushing matching refs. */ if (!fetch && rhs == lhs && rhs[1] == '\0') { rs[i].matching = 1; @@ -565,26 +577,25 @@ static struct refspec *parse_refspec_internal(int nr_refspec, const char **refsp flags = REFNAME_ALLOW_ONELEVEL | (is_glob ? REFNAME_REFSPEC_PATTERN : 0); if (fetch) { - /* - * LHS - * - empty is allowed; it means HEAD. - * - otherwise it must be a valid looking ref. - */ + unsigned char unused[40]; + + /* LHS */ if (!*rs[i].src) - ; /* empty is ok */ - else if (check_refname_format(rs[i].src, flags)) + ; /* empty is ok; it means "HEAD" */ + else if (llen == 40 && !get_sha1_hex(rs[i].src, unused)) + rs[i].exact_sha1 = 1; /* ok */ + else if (!check_refname_format(rs[i].src, flags)) + ; /* valid looking ref is ok */ + else goto invalid; - /* - * RHS - * - missing is ok, and is same as empty. - * - empty is ok; it means not to store. - * - otherwise it must be a valid looking ref. - */ + /* RHS */ if (!rs[i].dst) - ; /* ok */ + ; /* missing is ok; it is the same as empty */ else if (!*rs[i].dst) - ; /* ok */ - else if (check_refname_format(rs[i].dst, flags)) + ; /* empty is ok; it means "do not store" */ + else if (!check_refname_format(rs[i].dst, flags)) + ; /* valid looking ref is ok */ + else goto invalid; } else { /* @@ -671,17 +682,21 @@ static int valid_remote_nick(const char *name) return !strchr(name, '/'); /* no slash */ } -struct remote *remote_get(const char *name) +static struct remote *remote_get_1(const char *name, const char *pushremote_name) { struct remote *ret; int name_given = 0; - read_config(); if (name) name_given = 1; else { - name = default_remote_name; - name_given = explicit_default_remote_name; + if (pushremote_name) { + name = pushremote_name; + name_given = 1; + } else { + name = default_remote_name; + name_given = explicit_default_remote_name; + } } ret = make_remote(name, 0); @@ -700,6 +715,18 @@ struct remote *remote_get(const char *name) return ret; } +struct remote *remote_get(const char *name) +{ + read_config(); + return remote_get_1(name, NULL); +} + +struct remote *pushremote_get(const char *name) +{ + read_config(); + return remote_get_1(name, pushremote_name); +} + int remote_is_configured(const char *name) { int i; @@ -1195,6 +1222,101 @@ static struct ref **tail_ref(struct ref **head) return tail; } +struct tips { + struct commit **tip; + int nr, alloc; +}; + +static void add_to_tips(struct tips *tips, const unsigned char *sha1) +{ + struct commit *commit; + + if (is_null_sha1(sha1)) + return; + commit = lookup_commit_reference_gently(sha1, 1); + if (!commit || (commit->object.flags & TMP_MARK)) + return; + commit->object.flags |= TMP_MARK; + ALLOC_GROW(tips->tip, tips->nr + 1, tips->alloc); + tips->tip[tips->nr++] = commit; +} + +static void add_missing_tags(struct ref *src, struct ref **dst, struct ref ***dst_tail) +{ + struct string_list dst_tag = STRING_LIST_INIT_NODUP; + struct string_list src_tag = STRING_LIST_INIT_NODUP; + struct string_list_item *item; + struct ref *ref; + struct tips sent_tips; + + /* + * Collect everything we know they would have at the end of + * this push, and collect all tags they have. + */ + memset(&sent_tips, 0, sizeof(sent_tips)); + for (ref = *dst; ref; ref = ref->next) { + if (ref->peer_ref && + !is_null_sha1(ref->peer_ref->new_sha1)) + add_to_tips(&sent_tips, ref->peer_ref->new_sha1); + else + add_to_tips(&sent_tips, ref->old_sha1); + if (!prefixcmp(ref->name, "refs/tags/")) + string_list_append(&dst_tag, ref->name); + } + clear_commit_marks_many(sent_tips.nr, sent_tips.tip, TMP_MARK); + + sort_string_list(&dst_tag); + + /* Collect tags they do not have. */ + for (ref = src; ref; ref = ref->next) { + if (prefixcmp(ref->name, "refs/tags/")) + continue; /* not a tag */ + if (string_list_has_string(&dst_tag, ref->name)) + continue; /* they already have it */ + if (sha1_object_info(ref->new_sha1, NULL) != OBJ_TAG) + continue; /* be conservative */ + item = string_list_append(&src_tag, ref->name); + item->util = ref; + } + string_list_clear(&dst_tag, 0); + + /* + * At this point, src_tag lists tags that are missing from + * dst, and sent_tips lists the tips we are pushing or those + * that we know they already have. An element in the src_tag + * that is an ancestor of any of the sent_tips needs to be + * sent to the other side. + */ + if (sent_tips.nr) { + for_each_string_list_item(item, &src_tag) { + struct ref *ref = item->util; + struct ref *dst_ref; + struct commit *commit; + + if (is_null_sha1(ref->new_sha1)) + continue; + commit = lookup_commit_reference_gently(ref->new_sha1, 1); + if (!commit) + /* not pushing a commit, which is not an error */ + continue; + + /* + * Is this tag, which they do not have, reachable from + * any of the commits we are sending? + */ + if (!in_merge_bases_many(commit, sent_tips.nr, sent_tips.tip)) + continue; + + /* Add it in */ + dst_ref = make_linked_ref(ref->name, dst_tail); + hashcpy(dst_ref->new_sha1, ref->new_sha1); + dst_ref->peer_ref = copy_ref(ref); + } + } + string_list_clear(&src_tag, 0); + free(sent_tips.tip); +} + /* * Given the set of refs the local repository has, the set of refs the * remote repository has, and the refspec used for push, determine @@ -1227,9 +1349,6 @@ int match_push_refs(struct ref *src, struct ref **dst, const struct refspec *pat = NULL; char *dst_name; - if (ref->peer_ref) - continue; - dst_name = get_ref_match(rs, nr_refspec, ref, send_mirror, FROM_SRC, &pat); if (!dst_name) continue; @@ -1257,6 +1376,10 @@ int match_push_refs(struct ref *src, struct ref **dst, free_name: free(dst_name); } + + if (flags & MATCH_REFS_FOLLOW_TAGS) + add_missing_tags(src, dst, &dst_tail); + if (send_prune) { /* check for missing refs on the remote */ for (ref = *dst; ref; ref = ref->next) { @@ -1466,7 +1589,12 @@ int get_fetch_map(const struct ref *remote_refs, } else { const char *name = refspec->src[0] ? refspec->src : "HEAD"; - ref_map = get_remote_ref(remote_refs, name); + if (refspec->exact_sha1) { + ref_map = alloc_ref(name); + get_sha1_hex(name, ref_map->old_sha1); + } else { + ref_map = get_remote_ref(remote_refs, name); + } if (!missing_ok && !ref_map) die("Couldn't find remote ref %s", name); if (ref_map) { @@ -51,6 +51,7 @@ struct remote { }; struct remote *remote_get(const char *name); +struct remote *pushremote_get(const char *name); int remote_is_configured(const char *name); typedef int each_remote_fn(struct remote *remote, void *priv); @@ -62,6 +63,7 @@ struct refspec { unsigned force : 1; unsigned pattern : 1; unsigned matching : 1; + unsigned exact_sha1 : 1; char *src; char *dst; @@ -148,7 +150,8 @@ enum match_refs_flags { MATCH_REFS_NONE = 0, MATCH_REFS_ALL = (1 << 0), MATCH_REFS_MIRROR = (1 << 1), - MATCH_REFS_PRUNE = (1 << 2) + MATCH_REFS_PRUNE = (1 << 2), + MATCH_REFS_FOLLOW_TAGS = (1 << 3) }; /* Reporting of tracking info */ diff --git a/resolve-undo.c b/resolve-undo.c index 72b46125b7..639eb9c59f 100644 --- a/resolve-undo.c +++ b/resolve-undo.c @@ -118,7 +118,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos) struct cache_entry *ce; struct string_list_item *item; struct resolve_undo_info *ru; - int i, err = 0; + int i, err = 0, matched; if (!istate->resolve_undo) return pos; @@ -137,6 +137,7 @@ int unmerge_index_entry_at(struct index_state *istate, int pos) ru = item->util; if (!ru) return pos; + matched = ce->ce_flags & CE_MATCHED; remove_index_entry_at(istate, pos); for (i = 0; i < 3; i++) { struct cache_entry *nce; @@ -144,6 +145,8 @@ int unmerge_index_entry_at(struct index_state *istate, int pos) continue; nce = make_cache_entry(ru->mode[i], ru->sha1[i], ce->name, i + 1, 0); + if (matched) + nce->ce_flags |= CE_MATCHED; if (add_index_entry(istate, nce, ADD_CACHE_OK_TO_ADD)) { err = 1; error("cannot unmerge '%s'", ce->name); @@ -156,6 +159,20 @@ int unmerge_index_entry_at(struct index_state *istate, int pos) return unmerge_index_entry_at(istate, pos); } +void unmerge_marked_index(struct index_state *istate) +{ + int i; + + if (!istate->resolve_undo) + return; + + for (i = 0; i < istate->cache_nr; i++) { + struct cache_entry *ce = istate->cache[i]; + if (ce->ce_flags & CE_MATCHED) + i = unmerge_index_entry_at(istate, i); + } +} + void unmerge_index(struct index_state *istate, const char **pathspec) { int i; diff --git a/resolve-undo.h b/resolve-undo.h index 845876911d..7a30206aad 100644 --- a/resolve-undo.h +++ b/resolve-undo.h @@ -12,5 +12,6 @@ extern struct string_list *resolve_undo_read(const char *, unsigned long); extern void resolve_undo_clear_index(struct index_state *); extern int unmerge_index_entry_at(struct index_state *, int); extern void unmerge_index(struct index_state *, const char **); +extern void unmerge_marked_index(struct index_state *); #endif diff --git a/revision.c b/revision.c index cf620c6b36..a67b615bfc 100644 --- a/revision.c +++ b/revision.c @@ -1276,7 +1276,8 @@ static void read_revisions_from_stdin(struct rev_info *revs, } die("options not supported in --stdin mode"); } - if (handle_revision_arg(sb.buf, revs, 0, REVARG_CANNOT_BE_FILENAME)) + if (handle_revision_arg(xstrdup(sb.buf), revs, 0, + REVARG_CANNOT_BE_FILENAME)) die("bad revision '%s'", sb.buf); } if (seen_dashdash) @@ -2022,10 +2023,11 @@ static struct commit_list **simplify_one(struct rev_info *revs, struct commit *c if (revs->first_parent_only) break; } - if (!revs->first_parent_only) - cnt = remove_duplicate_parents(commit); - else + + if (revs->first_parent_only) cnt = 1; + else + cnt = remove_duplicate_parents(commit); /* * It is possible that we are a merge and one side branch @@ -2290,7 +2292,7 @@ static int commit_match(struct commit *commit, struct rev_info *opt) * in it. */ encoding = get_log_output_encoding(); - message = logmsg_reencode(commit, encoding); + message = logmsg_reencode(commit, NULL, encoding); /* Copy the commit to temporary if we are using "fake" headers */ if (buf.len) diff --git a/revision.h b/revision.h index 5da09ee3ef..01bd2b7c07 100644 --- a/revision.h +++ b/revision.h @@ -138,7 +138,7 @@ struct rev_info { int reroll_count; char *message_id; struct string_list *ref_message_ids; - const char *add_signoff; + int add_signoff; const char *extra_headers; const char *log_reencode; const char *subject_prefix; diff --git a/send-pack.c b/send-pack.c index 97ab336097..7d172ef37f 100644 --- a/send-pack.c +++ b/send-pack.c @@ -106,15 +106,11 @@ static int pack_objects(int fd, struct ref *refs, struct extra_have_objects *ext static int receive_status(int in, struct ref *refs) { struct ref *hint; - char line[1000]; int ret = 0; - int len = packet_read_line(in, line, sizeof(line)); - if (len < 10 || memcmp(line, "unpack ", 7)) + char *line = packet_read_line(in, NULL); + if (prefixcmp(line, "unpack ")) return error("did not receive remote status"); - if (memcmp(line, "unpack ok\n", 10)) { - char *p = line + strlen(line) - 1; - if (*p == '\n') - *p = '\0'; + if (strcmp(line, "unpack ok")) { error("unpack failed: %s", line + 7); ret = -1; } @@ -122,17 +118,15 @@ static int receive_status(int in, struct ref *refs) while (1) { char *refname; char *msg; - len = packet_read_line(in, line, sizeof(line)); - if (!len) + line = packet_read_line(in, NULL); + if (!line) break; - if (len < 3 || - (memcmp(line, "ok ", 3) && memcmp(line, "ng ", 3))) { - fprintf(stderr, "protocol error: %s\n", line); + if (prefixcmp(line, "ok ") && prefixcmp(line, "ng ")) { + error("invalid ref status from remote: %s", line); ret = -1; break; } - line[strlen(line)-1] = '\0'; refname = line + 3; msg = strchr(refname, ' '); if (msg) @@ -281,7 +275,7 @@ int send_pack(struct send_pack_args *args, send_sideband(out, -1, req_buf.buf, req_buf.len, LARGE_PACKET_MAX); } } else { - safe_write(out, req_buf.buf, req_buf.len); + write_or_die(out, req_buf.buf, req_buf.len); packet_flush(out); } strbuf_release(&req_buf); diff --git a/sequencer.c b/sequencer.c index bad5077911..ab6f8a722d 100644 --- a/sequencer.c +++ b/sequencer.c @@ -18,6 +18,89 @@ #define GIT_REFLOG_ACTION "GIT_REFLOG_ACTION" const char sign_off_header[] = "Signed-off-by: "; +static const char cherry_picked_prefix[] = "(cherry picked from commit "; + +static int is_rfc2822_line(const char *buf, int len) +{ + int i; + + for (i = 0; i < len; i++) { + int ch = buf[i]; + if (ch == ':') + return 1; + if (!isalnum(ch) && ch != '-') + break; + } + + return 0; +} + +static int is_cherry_picked_from_line(const char *buf, int len) +{ + /* + * We only care that it looks roughly like (cherry picked from ...) + */ + return len > strlen(cherry_picked_prefix) + 1 && + !prefixcmp(buf, cherry_picked_prefix) && buf[len - 1] == ')'; +} + +/* + * Returns 0 for non-conforming footer + * Returns 1 for conforming footer + * Returns 2 when sob exists within conforming footer + * Returns 3 when sob exists within conforming footer as last entry + */ +static int has_conforming_footer(struct strbuf *sb, struct strbuf *sob, + int ignore_footer) +{ + char prev; + int i, k; + int len = sb->len - ignore_footer; + const char *buf = sb->buf; + int found_sob = 0; + + /* footer must end with newline */ + if (!len || buf[len - 1] != '\n') + return 0; + + prev = '\0'; + for (i = len - 1; i > 0; i--) { + char ch = buf[i]; + if (prev == '\n' && ch == '\n') /* paragraph break */ + break; + prev = ch; + } + + /* require at least one blank line */ + if (prev != '\n' || buf[i] != '\n') + return 0; + + /* advance to start of last paragraph */ + while (i < len - 1 && buf[i] == '\n') + i++; + + for (; i < len; i = k) { + int found_rfc2822; + + for (k = i; k < len && buf[k] != '\n'; k++) + ; /* do nothing */ + k++; + + found_rfc2822 = is_rfc2822_line(buf + i, k - i - 1); + if (found_rfc2822 && sob && + !strncmp(buf + i, sob->buf, sob->len)) + found_sob = k; + + if (!(found_rfc2822 || + is_cherry_picked_from_line(buf + i, k - i - 1))) + return 0; + } + if (found_sob == i) + return 3; + if (found_sob) + return 2; + return 1; +} static void remove_sequencer_state(void) { @@ -237,7 +320,7 @@ static int do_recursive_merge(struct commit *base, struct commit *next, rollback_lock_file(&index_lock); if (opts->signoff) - append_signoff(msgbuf, 0); + append_signoff(msgbuf, 0, 0); if (!clean) { int i; @@ -496,7 +579,9 @@ static int do_pick_commit(struct commit *commit, struct replay_opts *opts) } if (opts->record_origin) { - strbuf_addstr(&msgbuf, "(cherry picked from commit "); + if (!has_conforming_footer(&msgbuf, NULL, 0)) + strbuf_addch(&msgbuf, '\n'); + strbuf_addstr(&msgbuf, cherry_picked_prefix); strbuf_addstr(&msgbuf, sha1_to_hex(commit->object.sha1)); strbuf_addstr(&msgbuf, ")\n"); } @@ -962,6 +1047,7 @@ int sequencer_pick_revisions(struct replay_opts *opts) { struct commit_list *todo_list = NULL; unsigned char sha1[20]; + int i; if (opts->subcommand == REPLAY_NONE) assert(opts->revs); @@ -982,6 +1068,23 @@ int sequencer_pick_revisions(struct replay_opts *opts) if (opts->subcommand == REPLAY_CONTINUE) return sequencer_continue(opts); + for (i = 0; i < opts->revs->pending.nr; i++) { + unsigned char sha1[20]; + const char *name = opts->revs->pending.objects[i].name; + + /* This happens when using --stdin. */ + if (!strlen(name)) + continue; + + if (!get_sha1(name, sha1)) { + if (!lookup_commit_reference_gently(sha1, 1)) { + enum object_type type = sha1_object_info(sha1, NULL); + die(_("%s: can't cherry-pick a %s"), name, typename(type)); + } + } else + die(_("%s: bad revision"), name); + } + /* * If we were called as "git cherry-pick <commit>", just * cherry-pick/revert it, set CHERRY_PICK_HEAD / @@ -1021,62 +1124,67 @@ int sequencer_pick_revisions(struct replay_opts *opts) return pick_commits(todo_list, opts); } -static int ends_rfc2822_footer(struct strbuf *sb, int ignore_footer) -{ - int ch; - int hit = 0; - int i, j, k; - int len = sb->len - ignore_footer; - int first = 1; - const char *buf = sb->buf; - - for (i = len - 1; i > 0; i--) { - if (hit && buf[i] == '\n') - break; - hit = (buf[i] == '\n'); - } - - while (i < len - 1 && buf[i] == '\n') - i++; - - for (; i < len; i = k) { - for (k = i; k < len && buf[k] != '\n'; k++) - ; /* do nothing */ - k++; - - if ((buf[k] == ' ' || buf[k] == '\t') && !first) - continue; - - first = 0; - - for (j = 0; i + j < len; j++) { - ch = buf[i + j]; - if (ch == ':') - break; - if (isalnum(ch) || - (ch == '-')) - continue; - return 0; - } - } - return 1; -} - -void append_signoff(struct strbuf *msgbuf, int ignore_footer) +void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag) { + unsigned no_dup_sob = flag & APPEND_SIGNOFF_DEDUP; struct strbuf sob = STRBUF_INIT; - int i; + int has_footer; strbuf_addstr(&sob, sign_off_header); strbuf_addstr(&sob, fmt_name(getenv("GIT_COMMITTER_NAME"), getenv("GIT_COMMITTER_EMAIL"))); strbuf_addch(&sob, '\n'); - for (i = msgbuf->len - 1 - ignore_footer; i > 0 && msgbuf->buf[i - 1] != '\n'; i--) - ; /* do nothing */ - if (prefixcmp(msgbuf->buf + i, sob.buf)) { - if (!i || !ends_rfc2822_footer(msgbuf, ignore_footer)) - strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, "\n", 1); - strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, sob.buf, sob.len); + + /* + * If the whole message buffer is equal to the sob, pretend that we + * found a conforming footer with a matching sob + */ + if (msgbuf->len - ignore_footer == sob.len && + !strncmp(msgbuf->buf, sob.buf, sob.len)) + has_footer = 3; + else + has_footer = has_conforming_footer(msgbuf, &sob, ignore_footer); + + if (!has_footer) { + const char *append_newlines = NULL; + size_t len = msgbuf->len - ignore_footer; + + if (!len) { + /* + * The buffer is completely empty. Leave foom for + * the title and body to be filled in by the user. + */ + append_newlines = "\n\n"; + } else if (msgbuf->buf[len - 1] != '\n') { + /* + * Incomplete line. Complete the line and add a + * blank one so that there is an empty line between + * the message body and the sob. + */ + append_newlines = "\n\n"; + } else if (len == 1) { + /* + * Buffer contains a single newline. Add another + * so that we leave room for the title and body. + */ + append_newlines = "\n"; + } else if (msgbuf->buf[len - 2] != '\n') { + /* + * Buffer ends with a single newline. Add another + * so that there is an empty line between the message + * body and the sob. + */ + append_newlines = "\n"; + } /* else, the buffer already ends with two newlines. */ + + if (append_newlines) + strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, + append_newlines, strlen(append_newlines)); } + + if (has_footer != 3 && (!no_dup_sob || has_footer != 2)) + strbuf_splice(msgbuf, msgbuf->len - ignore_footer, 0, + sob.buf, sob.len); + strbuf_release(&sob); } diff --git a/sequencer.h b/sequencer.h index 9d57d57524..1fc22dcabe 100644 --- a/sequencer.h +++ b/sequencer.h @@ -6,6 +6,8 @@ #define SEQ_TODO_FILE "sequencer/todo" #define SEQ_OPTS_FILE "sequencer/opts" +#define APPEND_SIGNOFF_DEDUP (1u << 0) + enum replay_action { REPLAY_REVERT, REPLAY_PICK @@ -48,6 +50,6 @@ int sequencer_pick_revisions(struct replay_opts *opts); extern const char sign_off_header[]; -void append_signoff(struct strbuf *msgbuf, int ignore_footer); +void append_signoff(struct strbuf *msgbuf, int ignore_footer, unsigned flag); #endif diff --git a/sha1_file.c b/sha1_file.c index 40b23297b2..67e815b2db 100644 --- a/sha1_file.c +++ b/sha1_file.c @@ -21,6 +21,7 @@ #include "sha1-lookup.h" #include "bulk-checkin.h" #include "streaming.h" +#include "dir.h" #ifndef O_NOATIME #if defined(__linux__) && (defined(__i386__) || defined(__PPC__)) @@ -123,8 +124,13 @@ int safe_create_leading_directories(char *path) } } else if (mkdir(path, 0777)) { - *pos = '/'; - return -1; + if (errno == EEXIST && + !stat(path, &st) && S_ISDIR(st.st_mode)) { + ; /* somebody created it since we checked */ + } else { + *pos = '/'; + return -1; + } } else if (adjust_shared_perm(path)) { *pos = '/'; @@ -1000,6 +1006,63 @@ void install_packed_git(struct packed_git *pack) packed_git = pack; } +void (*report_garbage)(const char *desc, const char *path); + +static void report_helper(const struct string_list *list, + int seen_bits, int first, int last) +{ + const char *msg; + switch (seen_bits) { + case 0: + msg = "no corresponding .idx nor .pack"; + break; + case 1: + msg = "no corresponding .idx"; + break; + case 2: + msg = "no corresponding .pack"; + break; + default: + return; + } + for (; first < last; first++) + report_garbage(msg, list->items[first].string); +} + +static void report_pack_garbage(struct string_list *list) +{ + int i, baselen = -1, first = 0, seen_bits = 0; + + if (!report_garbage) + return; + + sort_string_list(list); + + for (i = 0; i < list->nr; i++) { + const char *path = list->items[i].string; + if (baselen != -1 && + strncmp(path, list->items[first].string, baselen)) { + report_helper(list, seen_bits, first, i); + baselen = -1; + seen_bits = 0; + } + if (baselen == -1) { + const char *dot = strrchr(path, '.'); + if (!dot) { + report_garbage("garbage found", path); + continue; + } + baselen = dot - path + 1; + first = i; + } + if (!strcmp(path + baselen, "pack")) + seen_bits |= 1; + else if (!strcmp(path + baselen, "idx")) + seen_bits |= 2; + } + report_helper(list, seen_bits, first, list->nr); +} + static void prepare_packed_git_one(char *objdir, int local) { /* Ensure that this buffer is large enough so that we can @@ -1009,6 +1072,7 @@ static void prepare_packed_git_one(char *objdir, int local) int len; DIR *dir; struct dirent *de; + struct string_list garbage = STRING_LIST_INIT_DUP; sprintf(path, "%s/pack", objdir); len = strlen(path); @@ -1024,29 +1088,49 @@ static void prepare_packed_git_one(char *objdir, int local) int namelen = strlen(de->d_name); struct packed_git *p; - if (!has_extension(de->d_name, ".idx")) + if (len + namelen + 1 > sizeof(path)) { + if (report_garbage) { + struct strbuf sb = STRBUF_INIT; + strbuf_addf(&sb, "%.*s/%s", len - 1, path, de->d_name); + report_garbage("path too long", sb.buf); + strbuf_release(&sb); + } continue; + } - if (len + namelen + 1 > sizeof(path)) + if (is_dot_or_dotdot(de->d_name)) continue; - /* Don't reopen a pack we already have. */ strcpy(path + len, de->d_name); - for (p = packed_git; p; p = p->next) { - if (!memcmp(path, p->pack_name, len + namelen - 4)) - break; + + if (has_extension(de->d_name, ".idx")) { + /* Don't reopen a pack we already have. */ + for (p = packed_git; p; p = p->next) { + if (!memcmp(path, p->pack_name, len + namelen - 4)) + break; + } + if (p == NULL && + /* + * See if it really is a valid .idx file with + * corresponding .pack file that we can map. + */ + (p = add_packed_git(path, len + namelen, local)) != NULL) + install_packed_git(p); } - if (p) - continue; - /* See if it really is a valid .idx file with corresponding - * .pack file that we can map. - */ - p = add_packed_git(path, len + namelen, local); - if (!p) + + if (!report_garbage) continue; - install_packed_git(p); + + if (has_extension(de->d_name, ".idx") || + has_extension(de->d_name, ".pack") || + has_extension(de->d_name, ".keep")) + string_list_append(&garbage, path); + else + report_garbage("garbage found", path); } closedir(dir); + report_pack_garbage(&garbage); + string_list_clear(&garbage, 0); } static int sort_pack(const void *a_, const void *b_) @@ -1187,6 +1271,10 @@ int check_sha1_signature(const unsigned char *sha1, void *map, char buf[1024 * 16]; ssize_t readlen = read_istream(st, buf, sizeof(buf)); + if (readlen < 0) { + close_istream(st); + return -1; + } if (!readlen) break; git_SHA1_Update(&c, buf, readlen); @@ -1560,50 +1648,6 @@ static off_t get_delta_base(struct packed_git *p, return base_offset; } -/* forward declaration for a mutually recursive function */ -static int packed_object_info(struct packed_git *p, off_t offset, - unsigned long *sizep, int *rtype); - -static int packed_delta_info(struct packed_git *p, - struct pack_window **w_curs, - off_t curpos, - enum object_type type, - off_t obj_offset, - unsigned long *sizep) -{ - off_t base_offset; - - base_offset = get_delta_base(p, w_curs, &curpos, type, obj_offset); - if (!base_offset) - return OBJ_BAD; - type = packed_object_info(p, base_offset, NULL, NULL); - if (type <= OBJ_NONE) { - struct revindex_entry *revidx; - const unsigned char *base_sha1; - revidx = find_pack_revindex(p, base_offset); - if (!revidx) - return OBJ_BAD; - base_sha1 = nth_packed_object_sha1(p, revidx->nr); - mark_bad_packed_object(p, base_sha1); - type = sha1_object_info(base_sha1, NULL); - if (type <= OBJ_NONE) - return OBJ_BAD; - } - - /* We choose to only get the type of the base object and - * ignore potentially corrupt pack file that expects the delta - * based on a base with a wrong size. This saves tons of - * inflate() calls. - */ - if (sizep) { - *sizep = get_size_from_delta(p, w_curs, curpos); - if (*sizep == 0) - type = OBJ_BAD; - } - - return type; -} - int unpack_object_header(struct packed_git *p, struct pack_window **w_curs, off_t *curpos, @@ -1630,6 +1674,25 @@ int unpack_object_header(struct packed_git *p, return type; } +static int retry_bad_packed_offset(struct packed_git *p, off_t obj_offset) +{ + int type; + struct revindex_entry *revidx; + const unsigned char *sha1; + revidx = find_pack_revindex(p, obj_offset); + if (!revidx) + return OBJ_BAD; + sha1 = nth_packed_object_sha1(p, revidx->nr); + mark_bad_packed_object(p, sha1); + type = sha1_object_info(sha1, NULL); + if (type <= OBJ_NONE) + return OBJ_BAD; + return type; +} + + +#define POI_STACK_PREALLOC 64 + static int packed_object_info(struct packed_git *p, off_t obj_offset, unsigned long *sizep, int *rtype) { @@ -1637,31 +1700,89 @@ static int packed_object_info(struct packed_git *p, off_t obj_offset, unsigned long size; off_t curpos = obj_offset; enum object_type type; + off_t small_poi_stack[POI_STACK_PREALLOC]; + off_t *poi_stack = small_poi_stack; + int poi_stack_nr = 0, poi_stack_alloc = POI_STACK_PREALLOC; type = unpack_object_header(p, &w_curs, &curpos, &size); + if (rtype) *rtype = type; /* representation type */ + if (sizep) { + if (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { + off_t tmp_pos = curpos; + off_t base_offset = get_delta_base(p, &w_curs, &tmp_pos, + type, obj_offset); + if (!base_offset) { + type = OBJ_BAD; + goto out; + } + *sizep = get_size_from_delta(p, &w_curs, tmp_pos); + if (*sizep == 0) { + type = OBJ_BAD; + goto out; + } + } else { + *sizep = size; + } + } + + while (type == OBJ_OFS_DELTA || type == OBJ_REF_DELTA) { + off_t base_offset; + /* Push the object we're going to leave behind */ + if (poi_stack_nr >= poi_stack_alloc && poi_stack == small_poi_stack) { + poi_stack_alloc = alloc_nr(poi_stack_nr); + poi_stack = xmalloc(sizeof(off_t)*poi_stack_alloc); + memcpy(poi_stack, small_poi_stack, sizeof(off_t)*poi_stack_nr); + } else { + ALLOC_GROW(poi_stack, poi_stack_nr+1, poi_stack_alloc); + } + poi_stack[poi_stack_nr++] = obj_offset; + /* If parsing the base offset fails, just unwind */ + base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); + if (!base_offset) + goto unwind; + curpos = obj_offset = base_offset; + type = unpack_object_header(p, &w_curs, &curpos, &size); + if (type <= OBJ_NONE) { + /* If getting the base itself fails, we first + * retry the base, otherwise unwind */ + type = retry_bad_packed_offset(p, base_offset); + if (type > OBJ_NONE) + goto out; + goto unwind; + } + } + switch (type) { - case OBJ_OFS_DELTA: - case OBJ_REF_DELTA: - type = packed_delta_info(p, &w_curs, curpos, - type, obj_offset, sizep); - break; + case OBJ_BAD: case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - if (sizep) - *sizep = size; break; default: error("unknown object type %i at offset %"PRIuMAX" in %s", type, (uintmax_t)obj_offset, p->pack_name); type = OBJ_BAD; } + +out: + if (poi_stack != small_poi_stack) + free(poi_stack); unuse_pack(&w_curs); return type; + +unwind: + while (poi_stack_nr) { + obj_offset = poi_stack[--poi_stack_nr]; + type = retry_bad_packed_offset(p, obj_offset); + if (type > OBJ_NONE) + goto out; + } + type = OBJ_BAD; + goto out; } static void *unpack_compressed_entry(struct packed_git *p, @@ -1723,32 +1844,51 @@ static unsigned long pack_entry_hash(struct packed_git *p, off_t base_offset) return hash % MAX_DELTA_CACHE; } -static int in_delta_base_cache(struct packed_git *p, off_t base_offset) +static struct delta_base_cache_entry * +get_delta_base_cache_entry(struct packed_git *p, off_t base_offset) { unsigned long hash = pack_entry_hash(p, base_offset); - struct delta_base_cache_entry *ent = delta_base_cache + hash; + return delta_base_cache + hash; +} + +static int eq_delta_base_cache_entry(struct delta_base_cache_entry *ent, + struct packed_git *p, off_t base_offset) +{ return (ent->data && ent->p == p && ent->base_offset == base_offset); } +static int in_delta_base_cache(struct packed_git *p, off_t base_offset) +{ + struct delta_base_cache_entry *ent; + ent = get_delta_base_cache_entry(p, base_offset); + return eq_delta_base_cache_entry(ent, p, base_offset); +} + +static void clear_delta_base_cache_entry(struct delta_base_cache_entry *ent) +{ + ent->data = NULL; + ent->lru.next->prev = ent->lru.prev; + ent->lru.prev->next = ent->lru.next; + delta_base_cached -= ent->size; +} + static void *cache_or_unpack_entry(struct packed_git *p, off_t base_offset, unsigned long *base_size, enum object_type *type, int keep_cache) { + struct delta_base_cache_entry *ent; void *ret; - unsigned long hash = pack_entry_hash(p, base_offset); - struct delta_base_cache_entry *ent = delta_base_cache + hash; - ret = ent->data; - if (!ret || ent->p != p || ent->base_offset != base_offset) + ent = get_delta_base_cache_entry(p, base_offset); + + if (!eq_delta_base_cache_entry(ent, p, base_offset)) return unpack_entry(p, base_offset, type, base_size); - if (!keep_cache) { - ent->data = NULL; - ent->lru.next->prev = ent->lru.prev; - ent->lru.prev->next = ent->lru.next; - delta_base_cached -= ent->size; - } else { + ret = ent->data; + + if (!keep_cache) + clear_delta_base_cache_entry(ent); + else ret = xmemdupz(ent->data, ent->size); - } *type = ent->type; *base_size = ent->size; return ret; @@ -1812,68 +1952,6 @@ static void add_delta_base_cache(struct packed_git *p, off_t base_offset, static void *read_object(const unsigned char *sha1, enum object_type *type, unsigned long *size); -static void *unpack_delta_entry(struct packed_git *p, - struct pack_window **w_curs, - off_t curpos, - unsigned long delta_size, - off_t obj_offset, - enum object_type *type, - unsigned long *sizep) -{ - void *delta_data, *result, *base; - unsigned long base_size; - off_t base_offset; - - base_offset = get_delta_base(p, w_curs, &curpos, *type, obj_offset); - if (!base_offset) { - error("failed to validate delta base reference " - "at offset %"PRIuMAX" from %s", - (uintmax_t)curpos, p->pack_name); - return NULL; - } - unuse_pack(w_curs); - base = cache_or_unpack_entry(p, base_offset, &base_size, type, 0); - if (!base) { - /* - * We're probably in deep shit, but let's try to fetch - * the required base anyway from another pack or loose. - * This is costly but should happen only in the presence - * of a corrupted pack, and is better than failing outright. - */ - struct revindex_entry *revidx; - const unsigned char *base_sha1; - revidx = find_pack_revindex(p, base_offset); - if (!revidx) - return NULL; - base_sha1 = nth_packed_object_sha1(p, revidx->nr); - error("failed to read delta base object %s" - " at offset %"PRIuMAX" from %s", - sha1_to_hex(base_sha1), (uintmax_t)base_offset, - p->pack_name); - mark_bad_packed_object(p, base_sha1); - base = read_object(base_sha1, type, &base_size); - if (!base) - return NULL; - } - - delta_data = unpack_compressed_entry(p, w_curs, curpos, delta_size); - if (!delta_data) { - error("failed to unpack compressed delta " - "at offset %"PRIuMAX" from %s", - (uintmax_t)curpos, p->pack_name); - free(base); - return NULL; - } - result = patch_delta(base, base_size, - delta_data, delta_size, - sizep); - if (!result) - die("failed to apply delta"); - free(delta_data); - add_delta_base_cache(p, base_offset, base, base_size, *type); - return result; -} - static void write_pack_access_log(struct packed_git *p, off_t obj_offset) { static FILE *log_file; @@ -1894,48 +1972,178 @@ static void write_pack_access_log(struct packed_git *p, off_t obj_offset) int do_check_packed_object_crc; +#define UNPACK_ENTRY_STACK_PREALLOC 64 +struct unpack_entry_stack_ent { + off_t obj_offset; + off_t curpos; + unsigned long size; +}; + void *unpack_entry(struct packed_git *p, off_t obj_offset, - enum object_type *type, unsigned long *sizep) + enum object_type *final_type, unsigned long *final_size) { struct pack_window *w_curs = NULL; off_t curpos = obj_offset; - void *data; + void *data = NULL; + unsigned long size; + enum object_type type; + struct unpack_entry_stack_ent small_delta_stack[UNPACK_ENTRY_STACK_PREALLOC]; + struct unpack_entry_stack_ent *delta_stack = small_delta_stack; + int delta_stack_nr = 0, delta_stack_alloc = UNPACK_ENTRY_STACK_PREALLOC; + int base_from_cache = 0; if (log_pack_access) write_pack_access_log(p, obj_offset); - if (do_check_packed_object_crc && p->index_version > 1) { - struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); - unsigned long len = revidx[1].offset - obj_offset; - if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { - const unsigned char *sha1 = - nth_packed_object_sha1(p, revidx->nr); - error("bad packed object CRC for %s", - sha1_to_hex(sha1)); - mark_bad_packed_object(p, sha1); - unuse_pack(&w_curs); - return NULL; + /* PHASE 1: drill down to the innermost base object */ + for (;;) { + off_t base_offset; + int i; + struct delta_base_cache_entry *ent; + + if (do_check_packed_object_crc && p->index_version > 1) { + struct revindex_entry *revidx = find_pack_revindex(p, obj_offset); + unsigned long len = revidx[1].offset - obj_offset; + if (check_pack_crc(p, &w_curs, obj_offset, len, revidx->nr)) { + const unsigned char *sha1 = + nth_packed_object_sha1(p, revidx->nr); + error("bad packed object CRC for %s", + sha1_to_hex(sha1)); + mark_bad_packed_object(p, sha1); + unuse_pack(&w_curs); + return NULL; + } } + + ent = get_delta_base_cache_entry(p, curpos); + if (eq_delta_base_cache_entry(ent, p, curpos)) { + type = ent->type; + data = ent->data; + size = ent->size; + clear_delta_base_cache_entry(ent); + base_from_cache = 1; + break; + } + + type = unpack_object_header(p, &w_curs, &curpos, &size); + if (type != OBJ_OFS_DELTA && type != OBJ_REF_DELTA) + break; + + base_offset = get_delta_base(p, &w_curs, &curpos, type, obj_offset); + if (!base_offset) { + error("failed to validate delta base reference " + "at offset %"PRIuMAX" from %s", + (uintmax_t)curpos, p->pack_name); + /* bail to phase 2, in hopes of recovery */ + data = NULL; + break; + } + + /* push object, proceed to base */ + if (delta_stack_nr >= delta_stack_alloc + && delta_stack == small_delta_stack) { + delta_stack_alloc = alloc_nr(delta_stack_nr); + delta_stack = xmalloc(sizeof(*delta_stack)*delta_stack_alloc); + memcpy(delta_stack, small_delta_stack, + sizeof(*delta_stack)*delta_stack_nr); + } else { + ALLOC_GROW(delta_stack, delta_stack_nr+1, delta_stack_alloc); + } + i = delta_stack_nr++; + delta_stack[i].obj_offset = obj_offset; + delta_stack[i].curpos = curpos; + delta_stack[i].size = size; + + curpos = obj_offset = base_offset; } - *type = unpack_object_header(p, &w_curs, &curpos, sizep); - switch (*type) { + /* PHASE 2: handle the base */ + switch (type) { case OBJ_OFS_DELTA: case OBJ_REF_DELTA: - data = unpack_delta_entry(p, &w_curs, curpos, *sizep, - obj_offset, type, sizep); + if (data) + die("BUG in unpack_entry: left loop at a valid delta"); break; case OBJ_COMMIT: case OBJ_TREE: case OBJ_BLOB: case OBJ_TAG: - data = unpack_compressed_entry(p, &w_curs, curpos, *sizep); + if (!base_from_cache) + data = unpack_compressed_entry(p, &w_curs, curpos, size); break; default: data = NULL; error("unknown object type %i at offset %"PRIuMAX" in %s", - *type, (uintmax_t)obj_offset, p->pack_name); + type, (uintmax_t)obj_offset, p->pack_name); } + + /* PHASE 3: apply deltas in order */ + + /* invariants: + * 'data' holds the base data, or NULL if there was corruption + */ + while (delta_stack_nr) { + void *delta_data; + void *base = data; + unsigned long delta_size, base_size = size; + int i; + + data = NULL; + + if (base) + add_delta_base_cache(p, obj_offset, base, base_size, type); + + if (!base) { + /* + * We're probably in deep shit, but let's try to fetch + * the required base anyway from another pack or loose. + * This is costly but should happen only in the presence + * of a corrupted pack, and is better than failing outright. + */ + struct revindex_entry *revidx; + const unsigned char *base_sha1; + revidx = find_pack_revindex(p, obj_offset); + if (revidx) { + base_sha1 = nth_packed_object_sha1(p, revidx->nr); + error("failed to read delta base object %s" + " at offset %"PRIuMAX" from %s", + sha1_to_hex(base_sha1), (uintmax_t)obj_offset, + p->pack_name); + mark_bad_packed_object(p, base_sha1); + base = read_object(base_sha1, &type, &base_size); + } + } + + i = --delta_stack_nr; + obj_offset = delta_stack[i].obj_offset; + curpos = delta_stack[i].curpos; + delta_size = delta_stack[i].size; + + if (!base) + continue; + + delta_data = unpack_compressed_entry(p, &w_curs, curpos, delta_size); + + if (!delta_data) { + error("failed to unpack compressed delta " + "at offset %"PRIuMAX" from %s", + (uintmax_t)curpos, p->pack_name); + data = NULL; + continue; + } + + data = patch_delta(base, base_size, + delta_data, delta_size, + &size); + if (!data) + die("failed to apply delta"); + + free (delta_data); + } + + *final_type = type; + *final_size = size; + unuse_pack(&w_curs); return data; } diff --git a/sha1_name.c b/sha1_name.c index c50630a3ea..3820f28ae7 100644 --- a/sha1_name.c +++ b/sha1_name.c @@ -594,7 +594,7 @@ struct object *peel_to_type(const char *name, int namelen, while (1) { if (!o || (!o->parsed && !parse_object(o->sha1))) return NULL; - if (o->type == expected_type) + if (expected_type == OBJ_ANY || o->type == expected_type) return o; if (o->type == OBJ_TAG) o = ((struct tag*) o)->tagged; @@ -645,6 +645,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) expected_type = OBJ_TREE; else if (!strncmp(blob_type, sp, 4) && sp[4] == '}') expected_type = OBJ_BLOB; + else if (!prefixcmp(sp, "object}")) + expected_type = OBJ_ANY; else if (sp[0] == '}') expected_type = OBJ_NONE; else if (sp[0] == '/') @@ -654,6 +656,8 @@ static int peel_onion(const char *name, int len, unsigned char *sha1) if (expected_type == OBJ_COMMIT) lookup_flags = GET_SHA1_COMMITTISH; + else if (expected_type == OBJ_TREE) + lookup_flags = GET_SHA1_TREEISH; if (get_sha1_1(name, sp - name - 2, outer, lookup_flags)) return -1; @@ -856,8 +860,8 @@ static int get_sha1_oneline(const char *prefix, unsigned char *sha1, } struct grab_nth_branch_switch_cbdata { - long cnt, alloc; - struct strbuf *buf; + int remaining; + struct strbuf buf; }; static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, @@ -867,7 +871,6 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, struct grab_nth_branch_switch_cbdata *cb = cb_data; const char *match = NULL, *target = NULL; size_t len; - int nth; if (!prefixcmp(message, "checkout: moving from ")) { match = message + strlen("checkout: moving from "); @@ -876,11 +879,12 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, if (!match || !target) return 0; - - len = target - match; - nth = cb->cnt++ % cb->alloc; - strbuf_reset(&cb->buf[nth]); - strbuf_add(&cb->buf[nth], match, len); + if (--(cb->remaining) == 0) { + len = target - match; + strbuf_reset(&cb->buf); + strbuf_add(&cb->buf, match, len); + return 1; /* we are done */ + } return 0; } @@ -891,7 +895,7 @@ static int grab_nth_branch_switch(unsigned char *osha1, unsigned char *nsha1, static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) { long nth; - int i, retval; + int retval; struct grab_nth_branch_switch_cbdata cb; const char *brace; char *num_end; @@ -901,34 +905,22 @@ static int interpret_nth_prior_checkout(const char *name, struct strbuf *buf) brace = strchr(name, '}'); if (!brace) return -1; - nth = strtol(name+3, &num_end, 10); + nth = strtol(name + 3, &num_end, 10); if (num_end != brace) return -1; if (nth <= 0) return -1; - cb.alloc = nth; - cb.buf = xmalloc(nth * sizeof(struct strbuf)); - for (i = 0; i < nth; i++) - strbuf_init(&cb.buf[i], 20); - cb.cnt = 0; + cb.remaining = nth; + strbuf_init(&cb.buf, 20); + retval = 0; - for_each_recent_reflog_ent("HEAD", grab_nth_branch_switch, 40960, &cb); - if (cb.cnt < nth) { - cb.cnt = 0; - for_each_reflog_ent("HEAD", grab_nth_branch_switch, &cb); + if (0 < for_each_reflog_ent_reverse("HEAD", grab_nth_branch_switch, &cb)) { + strbuf_reset(buf); + strbuf_add(buf, cb.buf.buf, cb.buf.len); + retval = brace - name + 1; } - if (cb.cnt < nth) - goto release_return; - i = cb.cnt % nth; - strbuf_reset(buf); - strbuf_add(buf, cb.buf[i].buf, cb.buf[i].len); - retval = brace-name+1; - -release_return: - for (i = 0; i < nth; i++) - strbuf_release(&cb.buf[i]); - free(cb.buf); + strbuf_release(&cb.buf); return retval; } @@ -6,6 +6,7 @@ #define COMMAND_DIR "git-shell-commands" #define HELP_COMMAND COMMAND_DIR "/help" +#define NOLOGIN_COMMAND COMMAND_DIR "/no-interactive-login" static int do_generic_cmd(const char *me, char *arg) { @@ -65,6 +66,18 @@ static void run_shell(void) { int done = 0; static const char *help_argv[] = { HELP_COMMAND, NULL }; + + if (!access(NOLOGIN_COMMAND, F_OK)) { + /* Interactive login disabled. */ + const char *argv[] = { NOLOGIN_COMMAND, NULL }; + int status; + + status = run_command_v_opt(argv, 0); + if (status < 0) + exit(127); + exit(status); + } + /* Print help if enabled */ run_command_v_opt(help_argv, RUN_SILENT_EXEC_FAILURE); diff --git a/sideband.c b/sideband.c index d5ffa1c891..d1125f5c52 100644 --- a/sideband.c +++ b/sideband.c @@ -1,3 +1,4 @@ +#include "cache.h" #include "pkt-line.h" #include "sideband.h" @@ -37,7 +38,7 @@ int recv_sideband(const char *me, int in_stream, int out) while (1) { int band, len; - len = packet_read_line(in_stream, buf + pf, LARGE_PACKET_MAX); + len = packet_read(in_stream, NULL, NULL, buf + pf, LARGE_PACKET_MAX, 0); if (len == 0) break; if (len < 1) { @@ -108,7 +109,7 @@ int recv_sideband(const char *me, int in_stream, int out) } while (len); continue; case 1: - safe_write(out, buf + pf+1, len); + write_or_die(out, buf + pf+1, len); continue; default: fprintf(stderr, "%s: protocol error: bad band #%d\n", @@ -138,12 +139,12 @@ ssize_t send_sideband(int fd, int band, const char *data, ssize_t sz, int packet if (0 <= band) { sprintf(hdr, "%04x", n + 5); hdr[4] = band; - safe_write(fd, hdr, 5); + write_or_die(fd, hdr, 5); } else { sprintf(hdr, "%04x", n + 4); - safe_write(fd, hdr, 4); + write_or_die(fd, hdr, 4); } - safe_write(fd, p, n); + write_or_die(fd, p, n); p += n; sz -= n; } diff --git a/sideband.h b/sideband.h index d72db35d1e..e46bed0b01 100644 --- a/sideband.h +++ b/sideband.h @@ -4,9 +4,6 @@ #define SIDEBAND_PROTOCOL_ERROR -2 #define SIDEBAND_REMOTE_ERROR -1 -#define DEFAULT_PACKET_MAX 1000 -#define LARGE_PACKET_MAX 65520 - int recv_sideband(const char *me, int in_stream, int out); ssize_t send_sideband(int fd, int band, const char *data, ssize_t sz, int packet_max); @@ -528,6 +528,25 @@ void strbuf_addstr_urlencode(struct strbuf *sb, const char *s, strbuf_add_urlencode(sb, s, strlen(s), reserved); } +void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes) +{ + if (bytes > 1 << 30) { + strbuf_addf(buf, "%u.%2.2u GiB", + (int)(bytes >> 30), + (int)(bytes & ((1 << 30) - 1)) / 10737419); + } else if (bytes > 1 << 20) { + int x = bytes + 5243; /* for rounding */ + strbuf_addf(buf, "%u.%2.2u MiB", + x >> 20, ((x & ((1 << 20) - 1)) * 100) >> 20); + } else if (bytes > 1 << 10) { + int x = bytes + 5; /* for rounding */ + strbuf_addf(buf, "%u.%2.2u KiB", + x >> 10, ((x & ((1 << 10) - 1)) * 100) >> 10); + } else { + strbuf_addf(buf, "%u bytes", (int)bytes); + } +} + int printf_ln(const char *fmt, ...) { int ret; @@ -170,6 +170,7 @@ extern int strbuf_check_branch_ref(struct strbuf *sb, const char *name); extern void strbuf_addstr_urlencode(struct strbuf *, const char *, int reserved); +extern void strbuf_humanise_bytes(struct strbuf *buf, off_t bytes); __attribute__((format (printf,1,2))) extern int printf_ln(const char *fmt, ...); diff --git a/streaming.c b/streaming.c index 4d978e54e4..cabcd9d157 100644 --- a/streaming.c +++ b/streaming.c @@ -237,7 +237,7 @@ static read_method_decl(filtered) if (!fs->input_finished) { fs->i_end = read_istream(fs->upstream, fs->ibuf, FILTER_BUFFER); if (fs->i_end < 0) - break; + return -1; if (fs->i_end) continue; } @@ -309,7 +309,7 @@ static read_method_decl(loose) st->z_state = z_done; break; } - if (status != Z_OK && status != Z_BUF_ERROR) { + if (status != Z_OK && (status != Z_BUF_ERROR || total_read < sz)) { git_inflate_end(&st->z); st->z_state = z_error; return -1; @@ -514,6 +514,8 @@ int stream_blob_to_fd(int fd, unsigned const char *sha1, struct stream_filter *f ssize_t wrote, holeto; ssize_t readlen = read_istream(st, buf, sizeof(buf)); + if (readlen < 0) + goto close_and_exit; if (!readlen) break; if (can_seek && sizeof(buf) == readlen) { diff --git a/submodule.c b/submodule.c index 975bc87e48..e728025f60 100644 --- a/submodule.c +++ b/submodule.c @@ -216,6 +216,7 @@ static int prepare_submodule_summary(struct rev_info *rev, const char *path, } static void print_submodule_summary(struct rev_info *rev, FILE *f, + const char *line_prefix, const char *del, const char *add, const char *reset) { static const char format[] = " %m %s"; @@ -226,6 +227,7 @@ static void print_submodule_summary(struct rev_info *rev, FILE *f, struct pretty_print_context ctx = {0}; ctx.date_mode = rev->date_mode; strbuf_setlen(&sb, 0); + strbuf_addstr(&sb, line_prefix); if (commit->object.flags & SYMMETRIC_LEFT) { if (del) strbuf_addstr(&sb, del); @@ -256,6 +258,7 @@ int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg) } void show_submodule_summary(FILE *f, const char *path, + const char *line_prefix, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset) @@ -280,16 +283,18 @@ void show_submodule_summary(FILE *f, const char *path, message = "(revision walker failed)"; if (dirty_submodule & DIRTY_SUBMODULE_UNTRACKED) - fprintf(f, "Submodule %s contains untracked content\n", path); + fprintf(f, "%sSubmodule %s contains untracked content\n", + line_prefix, path); if (dirty_submodule & DIRTY_SUBMODULE_MODIFIED) - fprintf(f, "Submodule %s contains modified content\n", path); + fprintf(f, "%sSubmodule %s contains modified content\n", + line_prefix, path); if (!hashcmp(one, two)) { strbuf_release(&sb); return; } - strbuf_addf(&sb, "%sSubmodule %s %s..", meta, path, + strbuf_addf(&sb, "%s%sSubmodule %s %s..", line_prefix, meta, path, find_unique_abbrev(one, DEFAULT_ABBREV)); if (!fast_backward && !fast_forward) strbuf_addch(&sb, '.'); @@ -301,7 +306,7 @@ void show_submodule_summary(FILE *f, const char *path, fwrite(sb.buf, sb.len, 1, f); if (!message) /* only NULL if we succeeded in setting up the walk */ - print_submodule_summary(&rev, f, del, add, reset); + print_submodule_summary(&rev, f, line_prefix, del, add, reset); if (left) clear_commit_marks(left, ~0); if (right) diff --git a/submodule.h b/submodule.h index 3dc1b3fe89..c7ffc7c399 100644 --- a/submodule.h +++ b/submodule.h @@ -19,6 +19,7 @@ int parse_submodule_config_option(const char *var, const char *value); void handle_ignore_submodules_arg(struct diff_options *diffopt, const char *); int parse_fetch_recurse_submodules_arg(const char *opt, const char *arg); void show_submodule_summary(FILE *f, const char *path, + const char *line_prefix, unsigned char one[20], unsigned char two[20], unsigned dirty_submodule, const char *meta, const char *del, const char *add, const char *reset); diff --git a/t/Makefile b/t/Makefile index 44ca7d32dc..2373a04f7a 100644 --- a/t/Makefile +++ b/t/Makefile @@ -15,9 +15,16 @@ PROVE ?= prove DEFAULT_TEST_TARGET ?= test TEST_LINT ?= test-lint-duplicates test-lint-executable +ifdef TEST_OUTPUT_DIRECTORY +TEST_RESULTS_DIRECTORY = $(TEST_OUTPUT_DIRECTORY)/test-results +else +TEST_RESULTS_DIRECTORY = test-results +endif + # Shell quote; SHELL_PATH_SQ = $(subst ','\'',$(SHELL_PATH)) PERL_PATH_SQ = $(subst ','\'',$(PERL_PATH)) +TEST_RESULTS_DIRECTORY_SQ = $(subst ','\'',$(TEST_RESULTS_DIRECTORY)) T = $(sort $(wildcard t[0-9][0-9][0-9][0-9]-*.sh)) TSVN = $(sort $(wildcard t91[0-9][0-9]-*.sh)) @@ -36,10 +43,10 @@ $(T): @echo "*** $@ ***"; GIT_CONFIG=.git/config '$(SHELL_PATH_SQ)' $@ $(GIT_TEST_OPTS) pre-clean: - $(RM) -r test-results + $(RM) -r '$(TEST_RESULTS_DIRECTORY_SQ)' clean-except-prove-cache: - $(RM) -r 'trash directory'.* test-results + $(RM) -r 'trash directory'.* '$(TEST_RESULTS_DIRECTORY_SQ)' $(RM) -r valgrind/bin clean: clean-except-prove-cache @@ -65,7 +72,7 @@ aggregate-results-and-cleanup: $(T) $(MAKE) clean aggregate-results: - for f in test-results/t*-*.counts; do \ + for f in '$(TEST_RESULTS_DIRECTORY_SQ)'/t*-*.counts; do \ echo "$$f"; \ done | '$(SHELL_PATH_SQ)' ./aggregate-results.sh @@ -95,17 +95,26 @@ appropriately before running "make". This causes additional long-running tests to be run (where available), for more exhaustive testing. ---valgrind:: - Execute all Git binaries with valgrind and exit with status - 126 on errors (just like regular tests, this will only stop - the test script when running under -i). Valgrind errors - go to stderr, so you might want to pass the -v option, too. +--valgrind=<tool>:: + Execute all Git binaries under valgrind tool <tool> and exit + with status 126 on errors (just like regular tests, this will + only stop the test script when running under -i). Since it makes no sense to run the tests with --valgrind and not see any output, this option implies --verbose. For convenience, it also implies --tee. - Note that valgrind is run with the option --leak-check=no, + <tool> defaults to 'memcheck', just like valgrind itself. + Other particularly useful choices include 'helgrind' and + 'drd', but you may use any tool recognized by your valgrind + installation. + + As a special case, <tool> can be 'memcheck-fast', which uses + memcheck but disables --track-origins. Use this if you are + running tests in bulk, to see if there are _any_ memory + issues. + + Note that memcheck is run with the option --leak-check=no, as the git process is short-lived and some errors are not interesting. In order to run a single command under the same conditions manually, you should set GIT_VALGRIND to point to diff --git a/t/lib-gpg/pubring.gpg b/t/lib-gpg/pubring.gpg Binary files differindex 83855fa4e1..1a3c2d487c 100644 --- a/t/lib-gpg/pubring.gpg +++ b/t/lib-gpg/pubring.gpg diff --git a/t/lib-gpg/random_seed b/t/lib-gpg/random_seed Binary files differindex 8fed1339ed..95d249f15f 100644 --- a/t/lib-gpg/random_seed +++ b/t/lib-gpg/random_seed diff --git a/t/lib-gpg/secring.gpg b/t/lib-gpg/secring.gpg Binary files differindex d831cd9eb3..82dca8f80b 100644 --- a/t/lib-gpg/secring.gpg +++ b/t/lib-gpg/secring.gpg diff --git a/t/lib-gpg/trustdb.gpg b/t/lib-gpg/trustdb.gpg Binary files differindex abace962b8..4879ae9a84 100644 --- a/t/lib-gpg/trustdb.gpg +++ b/t/lib-gpg/trustdb.gpg diff --git a/t/lib-httpd/apache.conf b/t/lib-httpd/apache.conf index 542241b229..b5bce459b6 100644 --- a/t/lib-httpd/apache.conf +++ b/t/lib-httpd/apache.conf @@ -64,6 +64,11 @@ Alias /auth/dumb/ www/auth/dumb/ SetEnv GIT_COMMITTER_NAME "Custom User" SetEnv GIT_COMMITTER_EMAIL custom@example.com </LocationMatch> +<LocationMatch /smart_namespace/> + SetEnv GIT_EXEC_PATH ${GIT_EXEC_PATH} + SetEnv GIT_HTTP_EXPORT_ALL + SetEnv GIT_NAMESPACE ns +</LocationMatch> ScriptAliasMatch /smart_*[^/]*/(.*) ${GIT_EXEC_PATH}/git-http-backend/$1 ScriptAlias /broken_smart/ broken-smart-http.sh/ <Directory ${GIT_EXEC_PATH}> diff --git a/t/t0008-ignores.sh b/t/t0008-ignores.sh index 9c1bde1fd6..a56db804cb 100755 --- a/t/t0008-ignores.sh +++ b/t/t0008-ignores.sh @@ -66,16 +66,23 @@ test_check_ignore () { init_vars && rm -f "$HOME/stdout" "$HOME/stderr" "$HOME/cmd" && - echo git $global_args check-ignore $quiet_opt $verbose_opt $args \ + echo git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \ >"$HOME/cmd" && + echo "$expect_code" >"$HOME/expected-exit-code" && test_expect_code "$expect_code" \ - git $global_args check-ignore $quiet_opt $verbose_opt $args \ + git $global_args check-ignore $quiet_opt $verbose_opt $non_matching_opt $args \ >"$HOME/stdout" 2>"$HOME/stderr" && test_cmp "$HOME/expected-stdout" "$HOME/stdout" && stderr_empty_on_success "$expect_code" } -# Runs the same code with 3 different levels of output verbosity, +# Runs the same code with 4 different levels of output verbosity: +# +# 1. with -q / --quiet +# 2. with default verbosity +# 3. with -v / --verbose +# 4. with -v / --verbose, *and* -n / --non-matching +# # expecting success each time. Takes advantage of the fact that # check-ignore --verbose output is the same as normal output except # for the extra first column. @@ -83,7 +90,9 @@ test_check_ignore () { # Arguments: # - (optional) prereqs for this test, e.g. 'SYMLINKS' # - test name -# - output to expect from -v / --verbose mode +# - output to expect from the fourth verbosity mode (the output +# from the other verbosity modes is automatically inferred +# from this value) # - code to run (should invoke test_check_ignore) test_expect_success_multi () { prereq= @@ -92,8 +101,9 @@ test_expect_success_multi () { prereq=$1 shift fi - testname="$1" expect_verbose="$2" code="$3" + testname="$1" expect_all="$2" code="$3" + expect_verbose=$( echo "$expect_all" | grep -v '^:: ' ) expect=$( echo "$expect_verbose" | sed -e 's/.* //' ) test_expect_success $prereq "$testname" ' @@ -101,23 +111,40 @@ test_expect_success_multi () { eval "$code" ' - for quiet_opt in '-q' '--quiet' - do - test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" " + # --quiet is only valid when a single pattern is passed + if test $( echo "$expect_all" | wc -l ) = 1 + then + for quiet_opt in '-q' '--quiet' + do + test_expect_success $prereq "$testname${quiet_opt:+ with $quiet_opt}" " expect '' && $code " - done - quiet_opt= + done + quiet_opt= + fi for verbose_opt in '-v' '--verbose' do - test_expect_success $prereq "$testname${verbose_opt:+ with $verbose_opt}" " - expect '$expect_verbose' && - $code - " + for non_matching_opt in '' ' -n' ' --non-matching' + do + if test -n "$non_matching_opt" + then + my_expect="$expect_all" + else + my_expect="$expect_verbose" + fi + + test_code=" + expect '$my_expect' && + $code + " + opts="$verbose_opt$non_matching_opt" + test_expect_success $prereq "$testname${opts:+ with $opts}" "$test_code" + done done verbose_opt= + non_matching_opt= } test_expect_success 'setup' ' @@ -178,7 +205,7 @@ test_expect_success 'setup' ' # # test invalid inputs -test_expect_success_multi '. corner-case' '' ' +test_expect_success_multi '. corner-case' ':: .' ' test_check_ignore . 1 ' @@ -189,11 +216,7 @@ test_expect_success_multi 'empty command line' '' ' test_expect_success_multi '--stdin with empty STDIN' '' ' test_check_ignore "--stdin" 1 </dev/null && - if test -n "$quiet_opt"; then - test_stderr "" - else - test_stderr "no pathspec given." - fi + test_stderr "" ' test_expect_success '-q with multiple args' ' @@ -276,27 +299,39 @@ do where="in subdir $subdir" fi - test_expect_success_multi "non-existent file $where not ignored" '' " - test_check_ignore '${subdir}non-existent' 1 - " + test_expect_success_multi "non-existent file $where not ignored" \ + ":: ${subdir}non-existent" \ + "test_check_ignore '${subdir}non-existent' 1" test_expect_success_multi "non-existent file $where ignored" \ - ".gitignore:1:one ${subdir}one" " - test_check_ignore '${subdir}one' - " + ".gitignore:1:one ${subdir}one" \ + "test_check_ignore '${subdir}one'" - test_expect_success_multi "existing untracked file $where not ignored" '' " - test_check_ignore '${subdir}not-ignored' 1 - " + test_expect_success_multi "existing untracked file $where not ignored" \ + ":: ${subdir}not-ignored" \ + "test_check_ignore '${subdir}not-ignored' 1" - test_expect_success_multi "existing tracked file $where not ignored" '' " - test_check_ignore '${subdir}ignored-but-in-index' 1 - " + test_expect_success_multi "existing tracked file $where not ignored" \ + ":: ${subdir}ignored-but-in-index" \ + "test_check_ignore '${subdir}ignored-but-in-index' 1" test_expect_success_multi "existing untracked file $where ignored" \ - ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" " - test_check_ignore '${subdir}ignored-and-untracked' - " + ".gitignore:2:ignored-* ${subdir}ignored-and-untracked" \ + "test_check_ignore '${subdir}ignored-and-untracked'" + + test_expect_success_multi "mix of file types $where" \ +":: ${subdir}non-existent +.gitignore:1:one ${subdir}one +:: ${subdir}not-ignored +:: ${subdir}ignored-but-in-index +.gitignore:2:ignored-* ${subdir}ignored-and-untracked" \ + "test_check_ignore ' + ${subdir}non-existent + ${subdir}one + ${subdir}not-ignored + ${subdir}ignored-but-in-index + ${subdir}ignored-and-untracked' + " done # Having established the above, from now on we mostly test against @@ -391,7 +426,7 @@ test_expect_success 'cd to ignored sub-directory with -v' ' # # test handling of symlinks -test_expect_success_multi SYMLINKS 'symlink' '' ' +test_expect_success_multi SYMLINKS 'symlink' ':: a/symlink' ' test_check_ignore "a/symlink" 1 ' @@ -574,37 +609,34 @@ cat <<-\EOF >stdin globaltwo b/globaltwo ../b/globaltwo + c/not-ignored EOF -cat <<-\EOF >expected-default - ../one - one - b/on - b/one - b/one one - b/one two - "b/one\"three" - b/two - b/twooo - ../globaltwo - globaltwo - b/globaltwo - ../b/globaltwo -EOF -cat <<-EOF >expected-verbose +# N.B. we deliberately end STDIN with a non-matching pattern in order +# to test that the exit code indicates that one or more of the +# provided paths is ignored - in other words, that it represents an +# aggregation of all the results, not just the final result. + +cat <<-EOF >expected-all .gitignore:1:one ../one + :: ../not-ignored .gitignore:1:one one + :: not-ignored a/b/.gitignore:8:!on* b/on a/b/.gitignore:8:!on* b/one a/b/.gitignore:8:!on* b/one one a/b/.gitignore:8:!on* b/one two a/b/.gitignore:8:!on* "b/one\"three" a/b/.gitignore:9:!two b/two + :: b/not-ignored a/.gitignore:1:two* b/twooo $global_excludes:2:!globaltwo ../globaltwo $global_excludes:2:!globaltwo globaltwo $global_excludes:2:!globaltwo b/globaltwo $global_excludes:2:!globaltwo ../b/globaltwo + :: c/not-ignored EOF +grep -v '^:: ' expected-all >expected-verbose +sed -e 's/.* //' expected-verbose >expected-default sed -e 's/^"//' -e 's/\\//' -e 's/"$//' stdin | \ tr "\n" "\0" >stdin0 @@ -629,6 +661,14 @@ test_expect_success '--stdin from subdirectory with -v' ' ) ' +test_expect_success '--stdin from subdirectory with -v -n' ' + expect_from_stdin <expected-all && + ( + cd a && + test_check_ignore "--stdin -v -n" <../stdin + ) +' + for opts in '--stdin -z' '-z --stdin' do test_expect_success "$opts from subdirectory" ' @@ -648,5 +688,23 @@ do ' done +test_expect_success PIPE 'streaming support for --stdin' ' + mkfifo in out && + (git check-ignore -n -v --stdin <in >out &) && + + # We cannot just "echo >in" because check-ignore would get EOF + # after echo exited; instead we open the descriptor in our + # shell, and then echo to the fd. We make sure to close it at + # the end, so that the subprocess does get EOF and dies + # properly. + exec 9>in && + test_when_finished "exec 9>&-" && + echo >&9 one && + read response <out && + echo "$response" | grep "^\.gitignore:1:one one" && + echo >&9 two && + read response <out && + echo "$response" | grep "^:: two" +' test_done diff --git a/t/t1011-read-tree-sparse-checkout.sh b/t/t1011-read-tree-sparse-checkout.sh index 5c0053a20b..0c74beedd2 100755 --- a/t/t1011-read-tree-sparse-checkout.sh +++ b/t/t1011-read-tree-sparse-checkout.sh @@ -250,4 +250,28 @@ EOF test_cmp expected actual ' +test_expect_success 'checkout without --ignore-skip-worktree-bits' ' + echo "*" >.git/info/sparse-checkout && + git checkout -f top && + test_path_is_file init.t && + echo sub >.git/info/sparse-checkout && + git checkout && + echo modified >> sub/added && + git checkout . && + test_path_is_missing init.t && + git diff --exit-code HEAD +' + +test_expect_success 'checkout with --ignore-skip-worktree-bits' ' + echo "*" >.git/info/sparse-checkout && + git checkout -f top && + test_path_is_file init.t && + echo sub >.git/info/sparse-checkout && + git checkout && + echo modified >> sub/added && + git checkout --ignore-skip-worktree-bits . && + test_path_is_file init.t && + git diff --exit-code HEAD +' + test_done diff --git a/t/t1060-object-corruption.sh b/t/t1060-object-corruption.sh new file mode 100755 index 0000000000..3f8705139d --- /dev/null +++ b/t/t1060-object-corruption.sh @@ -0,0 +1,104 @@ +#!/bin/sh + +test_description='see how we handle various forms of corruption' +. ./test-lib.sh + +# convert "1234abcd" to ".git/objects/12/34abcd" +obj_to_file() { + echo "$(git rev-parse --git-dir)/objects/$(git rev-parse "$1" | sed 's,..,&/,')" +} + +# Convert byte at offset "$2" of object "$1" into '\0' +corrupt_byte() { + obj_file=$(obj_to_file "$1") && + chmod +w "$obj_file" && + printf '\0' | dd of="$obj_file" bs=1 seek="$2" conv=notrunc +} + +test_expect_success 'setup corrupt repo' ' + git init bit-error && + ( + cd bit-error && + test_commit content && + corrupt_byte HEAD:content.t 10 + ) +' + +test_expect_success 'setup repo with missing object' ' + git init missing && + ( + cd missing && + test_commit content && + rm -f "$(obj_to_file HEAD:content.t)" + ) +' + +test_expect_success 'setup repo with misnamed object' ' + git init misnamed && + ( + cd misnamed && + test_commit content && + good=$(obj_to_file HEAD:content.t) && + blob=$(echo corrupt | git hash-object -w --stdin) && + bad=$(obj_to_file $blob) && + rm -f "$good" && + mv "$bad" "$good" + ) +' + +test_expect_success 'streaming a corrupt blob fails' ' + ( + cd bit-error && + test_must_fail git cat-file blob HEAD:content.t + ) +' + +test_expect_success 'read-tree -u detects bit-errors in blobs' ' + ( + cd bit-error && + rm -f content.t && + test_must_fail git read-tree --reset -u HEAD + ) +' + +test_expect_success 'read-tree -u detects missing objects' ' + ( + cd missing && + rm -f content.t && + test_must_fail git read-tree --reset -u HEAD + ) +' + +# We use --bare to make sure that the transport detects it, not the checkout +# phase. +test_expect_success 'clone --no-local --bare detects corruption' ' + test_must_fail git clone --no-local --bare bit-error corrupt-transport +' + +test_expect_success 'clone --no-local --bare detects missing object' ' + test_must_fail git clone --no-local --bare missing missing-transport +' + +test_expect_success 'clone --no-local --bare detects misnamed object' ' + test_must_fail git clone --no-local --bare misnamed misnamed-transport +' + +# We do not expect --local to detect corruption at the transport layer, +# so we are really checking the checkout() code path. +test_expect_success 'clone --local detects corruption' ' + test_must_fail git clone --local bit-error corrupt-checkout +' + +test_expect_success 'error detected during checkout leaves repo intact' ' + test_path_is_dir corrupt-checkout/.git +' + +test_expect_success 'clone --local detects missing objects' ' + test_must_fail git clone --local missing missing-checkout +' + +test_expect_failure 'clone --local detects misnamed objects' ' + test_must_fail git clone --local misnamed misnamed-checkout +' + +test_done diff --git a/t/t1300-repo-config.sh b/t/t1300-repo-config.sh index 3c96fda548..c4a7d84f46 100755 --- a/t/t1300-repo-config.sh +++ b/t/t1300-repo-config.sh @@ -1087,4 +1087,39 @@ test_expect_success 'barf on incomplete string' ' grep " line 3 " error ' +# good section hygiene +test_expect_failure 'unsetting the last key in a section removes header' ' + cat >.git/config <<-\EOF && + # some generic comment on the configuration file itself + # a comment specific to this "section" section. + [section] + # some intervening lines + # that should also be dropped + + key = value + # please be careful when you update the above variable + EOF + + cat >expect <<-\EOF && + # some generic comment on the configuration file itself + EOF + + git config --unset section.key && + test_cmp expect .git/config +' + +test_expect_failure 'adding a key into an empty section reuses header' ' + cat >.git/config <<-\EOF && + [section] + EOF + + q_to_tab >expect <<-\EOF && + [section] + Qkey = value + EOF + + git config section.key value + test_cmp expect .git/config +' + test_done diff --git a/t/t2022-checkout-paths.sh b/t/t2022-checkout-paths.sh index 56090d2eba..8e3545d868 100755 --- a/t/t2022-checkout-paths.sh +++ b/t/t2022-checkout-paths.sh @@ -39,4 +39,26 @@ test_expect_success 'checking out paths out of a tree does not clobber unrelated test_cmp expect.next2 dir/next2 ' +test_expect_success 'do not touch unmerged entries matching $path but not in $tree' ' + git checkout next && + git reset --hard && + + cat dir/common >expect.common && + EMPTY_SHA1=$(git hash-object -w --stdin </dev/null) && + git rm dir/next0 && + cat >expect.next0 <<-EOF && + 100644 $EMPTY_SHA1 1 dir/next0 + 100644 $EMPTY_SHA1 2 dir/next0 + EOF + git update-index --index-info <expect.next0 && + + git checkout master dir && + + test_cmp expect.common dir/common && + test_path_is_file dir/master && + git diff --exit-code master dir/master && + git ls-files -s dir/next0 >actual.next0 && + test_cmp expect.next0 actual.next0 +' + test_done diff --git a/t/t2024-checkout-dwim.sh b/t/t2024-checkout-dwim.sh new file mode 100755 index 0000000000..dee55e428f --- /dev/null +++ b/t/t2024-checkout-dwim.sh @@ -0,0 +1,167 @@ +#!/bin/sh + +test_description='checkout <branch> + +Ensures that checkout on an unborn branch does what the user expects' + +. ./test-lib.sh + +# Is the current branch "refs/heads/$1"? +test_branch () { + printf "%s\n" "refs/heads/$1" >expect.HEAD && + git symbolic-ref HEAD >actual.HEAD && + test_cmp expect.HEAD actual.HEAD +} + +# Is branch "refs/heads/$1" set to pull from "$2/$3"? +test_branch_upstream () { + printf "%s\n" "$2" "refs/heads/$3" >expect.upstream && + { + git config "branch.$1.remote" && + git config "branch.$1.merge" + } >actual.upstream && + test_cmp expect.upstream actual.upstream +} + +test_expect_success 'setup' ' + test_commit my_master && + git init repo_a && + ( + cd repo_a && + test_commit a_master && + git checkout -b foo && + test_commit a_foo && + git checkout -b bar && + test_commit a_bar + ) && + git init repo_b && + ( + cd repo_b && + test_commit b_master && + git checkout -b foo && + test_commit b_foo && + git checkout -b baz && + test_commit b_baz + ) && + git remote add repo_a repo_a && + git remote add repo_b repo_b && + git config remote.repo_b.fetch \ + "+refs/heads/*:refs/remotes/other_b/*" && + git fetch --all +' + +test_expect_success 'checkout of non-existing branch fails' ' + git checkout -B master && + test_might_fail git branch -D xyzzy && + + test_must_fail git checkout xyzzy && + test_must_fail git rev-parse --verify refs/heads/xyzzy && + test_branch master +' + +test_expect_success 'checkout of branch from multiple remotes fails #1' ' + git checkout -B master && + test_might_fail git branch -D foo && + + test_must_fail git checkout foo && + test_must_fail git rev-parse --verify refs/heads/foo && + test_branch master +' + +test_expect_success 'checkout of branch from a single remote succeeds #1' ' + git checkout -B master && + test_might_fail git branch -D bar && + + git checkout bar && + test_branch bar && + test_cmp_rev remotes/repo_a/bar HEAD && + test_branch_upstream bar repo_a bar +' + +test_expect_success 'checkout of branch from a single remote succeeds #2' ' + git checkout -B master && + test_might_fail git branch -D baz && + + git checkout baz && + test_branch baz && + test_cmp_rev remotes/other_b/baz HEAD && + test_branch_upstream baz repo_b baz +' + +test_expect_success '--no-guess suppresses branch auto-vivification' ' + git checkout -B master && + test_might_fail git branch -D bar && + + test_must_fail git checkout --no-guess bar && + test_must_fail git rev-parse --verify refs/heads/bar && + test_branch master +' + +test_expect_success 'setup more remotes with unconventional refspecs' ' + git checkout -B master && + git init repo_c && + ( + cd repo_c && + test_commit c_master && + git checkout -b bar && + test_commit c_bar + git checkout -b spam && + test_commit c_spam + ) && + git init repo_d && + ( + cd repo_d && + test_commit d_master && + git checkout -b baz && + test_commit f_baz + git checkout -b eggs && + test_commit c_eggs + ) && + git remote add repo_c repo_c && + git config remote.repo_c.fetch \ + "+refs/heads/*:refs/remotes/extra_dir/repo_c/extra_dir/*" && + git remote add repo_d repo_d && + git config remote.repo_d.fetch \ + "+refs/heads/*:refs/repo_d/*" && + git fetch --all +' + +test_expect_success 'checkout of branch from multiple remotes fails #2' ' + git checkout -B master && + test_might_fail git branch -D bar && + + test_must_fail git checkout bar && + test_must_fail git rev-parse --verify refs/heads/bar && + test_branch master +' + +test_expect_success 'checkout of branch from multiple remotes fails #3' ' + git checkout -B master && + test_might_fail git branch -D baz && + + test_must_fail git checkout baz && + test_must_fail git rev-parse --verify refs/heads/baz && + test_branch master +' + +test_expect_success 'checkout of branch from a single remote succeeds #3' ' + git checkout -B master && + test_might_fail git branch -D spam && + + git checkout spam && + test_branch spam && + test_cmp_rev refs/remotes/extra_dir/repo_c/extra_dir/spam HEAD && + test_branch_upstream spam repo_c spam +' + +test_expect_success 'checkout of branch from a single remote succeeds #4' ' + git checkout -B master && + test_might_fail git branch -D eggs && + + git checkout eggs && + test_branch eggs && + test_cmp_rev refs/repo_d/eggs HEAD && + test_branch_upstream eggs repo_d eggs +' + +test_done diff --git a/t/t2200-add-update.sh b/t/t2200-add-update.sh index 4cdebda6a5..b2bd41918e 100755 --- a/t/t2200-add-update.sh +++ b/t/t2200-add-update.sh @@ -80,6 +80,22 @@ test_expect_success 'change gets noticed' ' ' +# Note that this is scheduled to change in Git 2.0, when +# "git add -u" will become full-tree by default. +test_expect_success 'non-limited update in subdir leaves root alone' ' + ( + cd dir1 && + echo even more >>sub2 && + git add -u + ) && + cat >expect <<-\EOF && + check + top + EOF + git diff-files --name-only >actual && + test_cmp expect actual +' + test_expect_success SYMLINKS 'replace a file with a symlink' ' rm foo && @@ -150,9 +166,9 @@ test_expect_success 'add -u resolves unmerged paths' ' echo 2 >path3 && echo 2 >path5 && - # Explicit resolving by adding removed paths should fail - test_must_fail git add path4 && - test_must_fail git add path6 && + # Fail to explicitly resolve removed paths with "git add" + test_must_fail git add --no-all path4 && + test_must_fail git add --no-all path6 && # "add -u" should notice removals no matter what stages # the index entries are in. diff --git a/t/t3001-ls-files-others-exclude.sh b/t/t3001-ls-files-others-exclude.sh index efb7ebc91f..4e3735f0cb 100755 --- a/t/t3001-ls-files-others-exclude.sh +++ b/t/t3001-ls-files-others-exclude.sh @@ -103,7 +103,7 @@ test_expect_success \ test_cmp expect output' test_expect_success 'restore gitignore' ' - git checkout $allignores && + git checkout --ignore-skip-worktree-bits $allignores && rm .git/index ' @@ -214,6 +214,55 @@ test_expect_success 'subdirectory ignore (l1)' ' test_cmp expect actual ' +test_expect_success 'show/hide empty ignored directory (setup)' ' + rm top/l1/l2/l1 && + rm top/l1/.gitignore +' + +test_expect_success 'show empty ignored directory with --directory' ' + ( + cd top && + git ls-files -o -i --exclude l1 --directory + ) >actual && + echo l1/ >expect && + test_cmp expect actual +' + +test_expect_success 'hide empty ignored directory with --no-empty-directory' ' + ( + cd top && + git ls-files -o -i --exclude l1 --directory --no-empty-directory + ) >actual && + >expect && + test_cmp expect actual +' + +test_expect_success 'show/hide empty ignored sub-directory (setup)' ' + > top/l1/tracked && + ( + cd top && + git add -f l1/tracked + ) +' + +test_expect_success 'show empty ignored sub-directory with --directory' ' + ( + cd top && + git ls-files -o -i --exclude l1 --directory + ) >actual && + echo l1/l2/ >expect && + test_cmp expect actual +' + +test_expect_success 'hide empty ignored sub-directory with --no-empty-directory' ' + ( + cd top && + git ls-files -o -i --exclude l1 --directory --no-empty-directory + ) >actual && + >expect && + test_cmp expect actual +' + test_expect_success 'pattern matches prefix completely' ' : >expect && git ls-files -i -o --exclude "/three/a.3[abc]" >actual && diff --git a/t/t3200-branch.sh b/t/t3200-branch.sh index b08c9f2295..44ec6a45f4 100755 --- a/t/t3200-branch.sh +++ b/t/t3200-branch.sh @@ -75,7 +75,7 @@ test_expect_success 'git branch l should work after branch l/m has been deleted' test_expect_success 'git branch -m dumps usage' ' test_expect_code 128 git branch -m 2>err && - test_i18ngrep "too many branches for a rename operation" err + test_i18ngrep "branch name required" err ' test_expect_success 'git branch -m m m/m should work' ' @@ -317,13 +317,13 @@ test_expect_success 'test tracking setup (non-wildcard, matching)' ' test $(git config branch.my4.merge) = refs/heads/master ' -test_expect_success 'test tracking setup (non-wildcard, not matching)' ' +test_expect_success 'tracking setup fails on non-matching refspec' ' git config remote.local.url . && git config remote.local.fetch refs/heads/s:refs/remotes/local/s && (git show-ref -q refs/remotes/local/master || git fetch local) && - git branch --track my5 local/master && - ! test "$(git config branch.my5.remote)" = local && - ! test "$(git config branch.my5.merge)" = refs/heads/master + test_must_fail git branch --track my5 local/master && + test_must_fail git config branch.my5.remote && + test_must_fail git config branch.my5.merge ' test_expect_success 'test tracking setup via config' ' @@ -409,6 +409,18 @@ test_expect_success '--set-upstream-to fails on detached HEAD' ' git checkout - ' +test_expect_success '--set-upstream-to fails on a missing dst branch' ' + test_must_fail git branch --set-upstream-to master does-not-exist +' + +test_expect_success '--set-upstream-to fails on a missing src branch' ' + test_must_fail git branch --set-upstream-to does-not-exist master +' + +test_expect_success '--set-upstream-to fails on a non-ref' ' + test_must_fail git branch --set-upstream-to HEAD^{} +' + test_expect_success 'use --set-upstream-to modify HEAD' ' test_config branch.master.remote foo && test_config branch.master.merge foo && diff --git a/t/t3203-branch-output.sh b/t/t3203-branch-output.sh index 76fe7e0060..ba4f98e800 100755 --- a/t/t3203-branch-output.sh +++ b/t/t3203-branch-output.sh @@ -94,13 +94,13 @@ test_expect_success 'git branch -v pattern does not show branch summaries' ' test_must_fail git branch -v branch* ' -cat >expect <<'EOF' -* (no branch) +test_expect_success 'git branch shows detached HEAD properly' ' + cat >expect <<EOF && +* (detached from $(git rev-parse --short HEAD^0)) branch-one branch-two master EOF -test_expect_success 'git branch shows detached HEAD properly' ' git checkout HEAD^0 && git branch >actual && test_i18ncmp expect actual diff --git a/t/t3210-pack-refs.sh b/t/t3210-pack-refs.sh index cd04361df8..1a2080e3dc 100755 --- a/t/t3210-pack-refs.sh +++ b/t/t3210-pack-refs.sh @@ -118,4 +118,37 @@ test_expect_success 'pack, prune and repack' ' test_cmp all-of-them again ' +test_expect_success 'explicit pack-refs with dangling packed reference' ' + git commit --allow-empty -m "soon to be garbage-collected" && + git pack-refs --all && + git reset --hard HEAD^ && + git reflog expire --expire=all --all && + git prune --expire=all && + git pack-refs --all 2>result && + test_cmp /dev/null result +' + +test_expect_success 'delete ref with dangling packed version' ' + git checkout -b lamb && + git commit --allow-empty -m "future garbage" && + git pack-refs --all && + git reset --hard HEAD^ && + git checkout master && + git reflog expire --expire=all --all && + git prune --expire=all && + git branch -d lamb 2>result && + test_cmp /dev/null result +' + +test_expect_success 'delete ref while another dangling packed ref' ' + git branch lamb && + git commit --allow-empty -m "future garbage" && + git pack-refs --all && + git reset --hard HEAD^ && + git reflog expire --expire=all --all && + git prune --expire=all && + git branch -d lamb 2>result && + test_cmp /dev/null result +' + test_done diff --git a/t/t3211-peel-ref.sh b/t/t3211-peel-ref.sh index d4d7792eae..3b7caca421 100755 --- a/t/t3211-peel-ref.sh +++ b/t/t3211-peel-ref.sh @@ -61,4 +61,13 @@ test_expect_success 'refs are peeled outside of refs/tags (old packed)' ' test_cmp expect actual ' +test_expect_success 'peeled refs survive deletion of packed ref' ' + git pack-refs --all && + cp .git/packed-refs fully-peeled && + git branch yadda && + git pack-refs --all && + git branch -d yadda && + test_cmp fully-peeled .git/packed-refs +' + test_done diff --git a/t/t3400-rebase.sh b/t/t3400-rebase.sh index 1de0ebda25..b58fa1a232 100755 --- a/t/t3400-rebase.sh +++ b/t/t3400-rebase.sh @@ -101,7 +101,14 @@ test_expect_success 'HEAD was detached during rebase' ' test $(git rev-parse HEAD@{1}) != $(git rev-parse my-topic-branch@{1}) ' +test_expect_success 'rebase from ambiguous branch name' ' + git checkout -b topic side && + git rebase master +' + test_expect_success 'rebase after merge master' ' + git checkout --detach refs/tags/topic && + git branch -D topic && git reset --hard topic && git merge master && git rebase master && @@ -138,8 +145,7 @@ test_expect_success 'rebase a single mode change' ' ' test_expect_success 'rebase is not broken by diff.renames' ' - git config diff.renames copies && - test_when_finished "git config --unset diff.renames" && + test_config diff.renames copies && git checkout filemove && GIT_TRACE=1 git rebase force-3way ' diff --git a/t/t3404-rebase-interactive.sh b/t/t3404-rebase-interactive.sh index 15dcbd42d3..a58406d12f 100755 --- a/t/t3404-rebase-interactive.sh +++ b/t/t3404-rebase-interactive.sh @@ -937,8 +937,7 @@ test_expect_success 'rebase --edit-todo can be used to modify todo' ' test_expect_success 'rebase -i respects core.commentchar' ' git reset --hard && git checkout E^0 && - git config core.commentchar "\\" && - test_when_finished "git config --unset core.commentchar" && + test_config core.commentchar "\\" && write_script remove-all-but-first.sh <<-\EOF && sed -e "2,\$s/^/\\\\/" "$1" >"$1.tmp" && mv "$1.tmp" "$1" diff --git a/t/t3508-cherry-pick-many-commits.sh b/t/t3508-cherry-pick-many-commits.sh index 4e7136b837..19c99d7ef1 100755 --- a/t/t3508-cherry-pick-many-commits.sh +++ b/t/t3508-cherry-pick-many-commits.sh @@ -55,6 +55,12 @@ one two" ' +test_expect_success 'cherry-pick three one two: fails' ' + git checkout -f master && + git reset --hard first && + test_must_fail git cherry-pick three one two: +' + test_expect_success 'output to keep user entertained during multi-pick' ' cat <<-\EOF >expected && [master OBJID] second diff --git a/t/t3511-cherry-pick-x.sh b/t/t3511-cherry-pick-x.sh new file mode 100755 index 0000000000..f97727975b --- /dev/null +++ b/t/t3511-cherry-pick-x.sh @@ -0,0 +1,219 @@ +#!/bin/sh + +test_description='Test cherry-pick -x and -s' + +. ./test-lib.sh + +pristine_detach () { + git cherry-pick --quit && + git checkout -f "$1^0" && + git read-tree -u --reset HEAD && + git clean -d -f -f -q -x +} + +mesg_one_line='base: commit message' + +mesg_no_footer="$mesg_one_line + +OneWordBodyThatsNotA-S-o-B" + +mesg_with_footer="$mesg_no_footer + +Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> +Signed-off-by: A.U. Thor <author@example.com> +Signed-off-by: B.U. Thor <buthor@example.com>" + +mesg_broken_footer="$mesg_no_footer + +The signed-off-by string should begin with the words Signed-off-by followed +by a colon and space, and then the signers name and email address. e.g. +Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" + +mesg_with_footer_sob="$mesg_with_footer +Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL>" + +mesg_with_cherry_footer="$mesg_with_footer_sob +(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709) +Tested-by: C.U. Thor <cuthor@example.com>" + + +test_expect_success setup ' + git config advice.detachedhead false && + echo unrelated >unrelated && + git add unrelated && + test_commit initial foo a && + test_commit "$mesg_one_line" foo b mesg-one-line && + git reset --hard initial && + test_commit "$mesg_no_footer" foo b mesg-no-footer && + git reset --hard initial && + test_commit "$mesg_broken_footer" foo b mesg-broken-footer && + git reset --hard initial && + test_commit "$mesg_with_footer" foo b mesg-with-footer && + git reset --hard initial && + test_commit "$mesg_with_footer_sob" foo b mesg-with-footer-sob && + git reset --hard initial && + test_commit "$mesg_with_cherry_footer" foo b mesg-with-cherry-footer && + pristine_detach initial && + test_commit conflicting unrelated +' + +test_expect_success 'cherry-pick -x inserts blank line after one line subject' ' + pristine_detach initial && + sha1=`git rev-parse mesg-one-line^0` && + git cherry-pick -x mesg-one-line && + cat <<-EOF >expect && + $mesg_one_line + + (cherry picked from commit $sha1) + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s inserts blank line after one line subject' ' + pristine_detach initial && + git cherry-pick -s mesg-one-line && + cat <<-EOF >expect && + $mesg_one_line + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s inserts blank line after non-conforming footer' ' + pristine_detach initial && + git cherry-pick -s mesg-broken-footer && + cat <<-EOF >expect && + $mesg_broken_footer + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x inserts blank line when conforming footer not found' ' + pristine_detach initial && + sha1=`git rev-parse mesg-no-footer^0` && + git cherry-pick -x mesg-no-footer && + cat <<-EOF >expect && + $mesg_no_footer + + (cherry picked from commit $sha1) + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s inserts blank line when conforming footer not found' ' + pristine_detach initial && + git cherry-pick -s mesg-no-footer && + cat <<-EOF >expect && + $mesg_no_footer + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x -s inserts blank line when conforming footer not found' ' + pristine_detach initial && + sha1=`git rev-parse mesg-no-footer^0` && + git cherry-pick -x -s mesg-no-footer && + cat <<-EOF >expect && + $mesg_no_footer + + (cherry picked from commit $sha1) + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s adds sob when last sob doesnt match committer' ' + pristine_detach initial && + git cherry-pick -s mesg-with-footer && + cat <<-EOF >expect && + $mesg_with_footer + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x -s adds sob when last sob doesnt match committer' ' + pristine_detach initial && + sha1=`git rev-parse mesg-with-footer^0` && + git cherry-pick -x -s mesg-with-footer && + cat <<-EOF >expect && + $mesg_with_footer + (cherry picked from commit $sha1) + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s refrains from adding duplicate trailing sob' ' + pristine_detach initial && + git cherry-pick -s mesg-with-footer-sob && + cat <<-EOF >expect && + $mesg_with_footer_sob + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x -s adds sob even when trailing sob exists for committer' ' + pristine_detach initial && + sha1=`git rev-parse mesg-with-footer-sob^0` && + git cherry-pick -x -s mesg-with-footer-sob && + cat <<-EOF >expect && + $mesg_with_footer_sob + (cherry picked from commit $sha1) + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x treats "(cherry picked from..." line as part of footer' ' + pristine_detach initial && + sha1=`git rev-parse mesg-with-cherry-footer^0` && + git cherry-pick -x mesg-with-cherry-footer && + cat <<-EOF >expect && + $mesg_with_cherry_footer + (cherry picked from commit $sha1) + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -s treats "(cherry picked from..." line as part of footer' ' + pristine_detach initial && + git cherry-pick -s mesg-with-cherry-footer && + cat <<-EOF >expect && + $mesg_with_cherry_footer + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_expect_success 'cherry-pick -x -s treats "(cherry picked from..." line as part of footer' ' + pristine_detach initial && + sha1=`git rev-parse mesg-with-cherry-footer^0` && + git cherry-pick -x -s mesg-with-cherry-footer && + cat <<-EOF >expect && + $mesg_with_cherry_footer + (cherry picked from commit $sha1) + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + EOF + git log -1 --pretty=format:%B >actual && + test_cmp expect actual +' + +test_done diff --git a/t/t3600-rm.sh b/t/t3600-rm.sh index 37bf5f13b0..0c44e9f5d0 100755 --- a/t/t3600-rm.sh +++ b/t/t3600-rm.sh @@ -622,4 +622,69 @@ test_expect_success 'rm of a populated nested submodule with a nested .git direc rm -rf submod ' +test_expect_success 'rm of d/f when d has become a non-directory' ' + rm -rf d && + mkdir d && + >d/f && + git add d && + rm -rf d && + >d && + git rm d/f && + test_must_fail git rev-parse --verify :d/f && + test_path_is_file d +' + +test_expect_success SYMLINKS 'rm of d/f when d has become a dangling symlink' ' + rm -rf d && + mkdir d && + >d/f && + git add d && + rm -rf d && + ln -s nonexistent d && + git rm d/f && + test_must_fail git rev-parse --verify :d/f && + test -h d && + test_path_is_missing d +' + +test_expect_success 'rm of file when it has become a directory' ' + rm -rf d && + >d && + git add d && + rm -f d && + mkdir d && + >d/f && + test_must_fail git rm d && + git rev-parse --verify :d && + test_path_is_file d/f +' + +test_expect_success SYMLINKS 'rm across a symlinked leading path (no index)' ' + rm -rf d e && + mkdir e && + echo content >e/f && + ln -s e d && + git add -A e d && + git commit -m "symlink d to e, e/f exists" && + test_must_fail git rm d/f && + git rev-parse --verify :d && + git rev-parse --verify :e/f && + test -h d && + test_path_is_file e/f +' + +test_expect_failure SYMLINKS 'rm across a symlinked leading path (w/ index)' ' + rm -rf d e && + mkdir d && + echo content >d/f && + git add -A e d && + git commit -m "d/f exists" && + mv d e && + ln -s e d && + test_must_fail git rm d/f && + git rev-parse --verify :d/f && + test -h d && + test_path_is_file e/f +' + test_done diff --git a/t/t4014-format-patch.sh b/t/t4014-format-patch.sh index 183fbe5bb3..58d418098d 100755 --- a/t/t4014-format-patch.sh +++ b/t/t4014-format-patch.sh @@ -972,6 +972,268 @@ test_expect_success 'empty subject prefix does not have extra space' ' test_cmp expect actual ' +append_signoff() +{ + C=$(git commit-tree HEAD^^{tree} -p HEAD) && + git format-patch --stdout --signoff $C^..$C >append_signoff.patch && + sed -n -e "1,/^---$/p" append_signoff.patch | + egrep -n "^Subject|Sign|^$" +} + +test_expect_success 'signoff: commit with no body' ' + append_signoff </dev/null >actual && + cat <<\EOF | sed "s/EOL$//" >expected && +4:Subject: [PATCH] EOL +8: +9:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: commit with only subject' ' + echo subject | append_signoff >actual && + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: commit with only subject that does not end with NL' ' + printf subject | append_signoff >actual && + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: no existing signoffs' ' + append_signoff <<\EOF >actual && +subject + +body +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: no existing signoffs and no trailing NL' ' + printf "subject\n\nbody" | append_signoff >actual && + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: some random signoff' ' + append_signoff <<\EOF >actual && +subject + +body + +Signed-off-by: my@house +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: my@house +12:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: misc conforming footer elements' ' + append_signoff <<\EOF >actual && +subject + +body + +Signed-off-by: my@house +(cherry picked from commit da39a3ee5e6b4b0d3255bfef95601890afd80709) +Tested-by: Some One <someone@example.com> +Bug: 1234 +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: my@house +15:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: some random signoff-alike' ' + append_signoff <<\EOF >actual && +subject + +body +Fooled-by-me: my@house +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +11: +12:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: not really a signoff' ' + append_signoff <<\EOF >actual && +subject + +I want to mention about Signed-off-by: here. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:I want to mention about Signed-off-by: here. +10: +11:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: not really a signoff (2)' ' + append_signoff <<\EOF >actual && +subject + +My unfortunate +Signed-off-by: example happens to be wrapped here. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10:Signed-off-by: example happens to be wrapped here. +11: +12:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: valid S-o-b paragraph in the middle' ' + append_signoff <<\EOF >actual && +subject + +Signed-off-by: my@house +Signed-off-by: your@house + +A lot of houses. +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:Signed-off-by: my@house +10:Signed-off-by: your@house +11: +13: +14:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: the same signoff at the end' ' + append_signoff <<\EOF >actual && +subject + +body + +Signed-off-by: C O Mitter <committer@example.com> +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: the same signoff at the end, no trailing NL' ' + printf "subject\n\nSigned-off-by: C O Mitter <committer@example.com>" | + append_signoff >actual && + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +9:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: the same signoff NOT at the end' ' + append_signoff <<\EOF >actual && +subject + +body + +Signed-off-by: C O Mitter <committer@example.com> +Signed-off-by: my@house +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +11:Signed-off-by: C O Mitter <committer@example.com> +12:Signed-off-by: my@house +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: detect garbage in non-conforming footer' ' + append_signoff <<\EOF >actual && +subject + +body + +Tested-by: my@house +Some Trash +Signed-off-by: C O Mitter <committer@example.com> +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +13:Signed-off-by: C O Mitter <committer@example.com> +14: +15:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + +test_expect_success 'signoff: footer begins with non-signoff without @ sign' ' + append_signoff <<\EOF >actual && +subject + +body + +Reviewed-id: Noone +Tested-by: my@house +Change-id: Ideadbeef +Signed-off-by: C O Mitter <committer@example.com> +Bug: 1234 +EOF + cat >expected <<\EOF && +4:Subject: [PATCH] subject +8: +10: +14:Signed-off-by: C O Mitter <committer@example.com> +EOF + test_cmp expected actual +' + test_expect_success 'format patch ignores color.ui' ' test_unconfig color.ui && git format-patch --stdout -1 >expect && @@ -1022,4 +1284,37 @@ test_expect_success 'cover letter using branch description (6)' ' grep hello actual >/dev/null ' +test_expect_success 'cover letter with nothing' ' + git format-patch --stdout --cover-letter >actual && + test_line_count = 0 actual +' + +test_expect_success 'cover letter auto' ' + mkdir -p tmp && + test_when_finished "rm -rf tmp; + git config --unset format.coverletter" && + + git config format.coverletter auto && + git format-patch -o tmp -1 >list && + test_line_count = 1 list && + git format-patch -o tmp -2 >list && + test_line_count = 3 list +' + +test_expect_success 'cover letter auto user override' ' + mkdir -p tmp && + test_when_finished "rm -rf tmp; + git config --unset format.coverletter" && + + git config format.coverletter auto && + git format-patch -o tmp --cover-letter -1 >list && + test_line_count = 2 list && + git format-patch -o tmp --cover-letter -2 >list && + test_line_count = 3 list && + git format-patch -o tmp --no-cover-letter -1 >list && + test_line_count = 1 list && + git format-patch -o tmp --no-cover-letter -2 >list && + test_line_count = 2 list +' + test_done diff --git a/t/t4034-diff-words.sh b/t/t4034-diff-words.sh index 40ab333a8a..f2f55fc51c 100755 --- a/t/t4034-diff-words.sh +++ b/t/t4034-diff-words.sh @@ -230,7 +230,7 @@ test_expect_success '.gitattributes override config' ' ' test_expect_success 'setup: remove diff driver regex' ' - test_might_fail git config --unset diff.testdriver.wordRegex + test_unconfig diff.testdriver.wordRegex ' test_expect_success 'use configured regex' ' @@ -335,8 +335,7 @@ test_expect_success 'word-diff with diff.sbe' ' c EOF - test_when_finished "git config --unset diff.suppress-blank-empty" && - git config diff.suppress-blank-empty true && + test_config diff.suppress-blank-empty true && word_diff --word-diff=plain ' @@ -368,7 +367,7 @@ test_expect_success 'setup history with two files' ' test_expect_success 'wordRegex for the first file does not apply to the second' ' echo "*.tex diff=tex" >.gitattributes && - git config diff.tex.wordRegex "[a-z]+|." && + test_config diff.tex.wordRegex "[a-z]+|." && cat >expect <<-\EOF && diff --git a/a.tex b/a.tex --- a/a.tex diff --git a/t/t4038-diff-combined.sh b/t/t4038-diff-combined.sh index b7e16a7840..1261dbbdf5 100755 --- a/t/t4038-diff-combined.sh +++ b/t/t4038-diff-combined.sh @@ -224,4 +224,133 @@ test_expect_success 'check combined output (ignore all spaces)' ' compare_diff_patch expected actual ' +test_expect_success 'combine diff coalesce simple' ' + >test && + git add test && + git commit -m initial && + test_seq 4 >test && + git commit -a -m empty1 && + git branch side1 && + git checkout HEAD^ && + test_seq 5 >test && + git commit -a -m empty2 && + test_must_fail git merge side1 && + >test && + git commit -a -m merge && + git show >actual.tmp && + sed -e "1,/^@@@/d" < actual.tmp >actual && + tr -d Q <<-\EOF >expected && + --1 + --2 + --3 + --4 + - 5 + EOF + compare_diff_patch expected actual +' + +test_expect_success 'combine diff coalesce tricky' ' + >test && + git add test && + git commit -m initial --allow-empty && + cat <<-\EOF >test && + 3 + 1 + 2 + 3 + 4 + EOF + git commit -a -m empty1 && + git branch -f side1 && + git checkout HEAD^ && + cat <<-\EOF >test && + 1 + 3 + 5 + 4 + EOF + git commit -a -m empty2 && + git branch -f side2 && + test_must_fail git merge side1 && + >test && + git commit -a -m merge && + git show >actual.tmp && + sed -e "1,/^@@@/d" < actual.tmp >actual && + tr -d Q <<-\EOF >expected && + -3 + --1 + -2 + --3 + - 5 + --4 + EOF + compare_diff_patch expected actual && + git checkout -f side1 && + test_must_fail git merge side2 && + >test && + git commit -a -m merge && + git show >actual.tmp && + sed -e "1,/^@@@/d" < actual.tmp >actual && + tr -d Q <<-\EOF >expected && + - 3 + --1 + - 2 + --3 + -5 + --4 + EOF + compare_diff_patch expected actual +' + +test_expect_failure 'combine diff coalesce three parents' ' + >test && + git add test && + git commit -m initial --allow-empty && + cat <<-\EOF >test && + 3 + 1 + 2 + 3 + 4 + EOF + git commit -a -m empty1 && + git checkout -B side1 && + git checkout HEAD^ && + cat <<-\EOF >test && + 1 + 3 + 7 + 5 + 4 + EOF + git commit -a -m empty2 && + git branch -f side2 && + git checkout HEAD^ && + cat <<-\EOF >test && + 3 + 1 + 6 + 5 + 4 + EOF + git commit -a -m empty3 && + >test && + git add test && + TREE=$(git write-tree) && + COMMIT=$(git commit-tree -p HEAD -p side1 -p side2 -m merge $TREE) && + git show $COMMIT >actual.tmp && + sed -e "1,/^@@@/d" < actual.tmp >actual && + tr -d Q <<-\EOF >expected && + -- 3 + ---1 + - 6 + - 2 + --3 + -7 + - -5 + ---4 + EOF + compare_diff_patch expected actual +' + test_done diff --git a/t/t4202-log.sh b/t/t4202-log.sh index fa686b887d..9243a97993 100755 --- a/t/t4202-log.sh +++ b/t/t4202-log.sh @@ -419,8 +419,6 @@ test_expect_success 'log --graph with merge' ' ' test_expect_success 'log.decorate configuration' ' - test_might_fail git config --unset-all log.decorate && - git log --oneline >expect.none && git log --oneline --decorate >expect.short && git log --oneline --decorate=full >expect.full && @@ -429,8 +427,7 @@ test_expect_success 'log.decorate configuration' ' git log --oneline >actual && test_cmp expect.short actual && - git config --unset-all log.decorate && - git config log.decorate true && + test_config log.decorate true && git log --oneline >actual && test_cmp expect.short actual && git log --oneline --decorate=full >actual && @@ -438,8 +435,7 @@ test_expect_success 'log.decorate configuration' ' git log --oneline --decorate=no >actual && test_cmp expect.none actual && - git config --unset-all log.decorate && - git config log.decorate no && + test_config log.decorate no && git log --oneline >actual && test_cmp expect.none actual && git log --oneline --decorate >actual && @@ -447,8 +443,7 @@ test_expect_success 'log.decorate configuration' ' git log --oneline --decorate=full >actual && test_cmp expect.full actual && - git config --unset-all log.decorate && - git config log.decorate 1 && + test_config log.decorate 1 && git log --oneline >actual && test_cmp expect.short actual && git log --oneline --decorate=full >actual && @@ -456,8 +451,7 @@ test_expect_success 'log.decorate configuration' ' git log --oneline --decorate=no >actual && test_cmp expect.none actual && - git config --unset-all log.decorate && - git config log.decorate short && + test_config log.decorate short && git log --oneline >actual && test_cmp expect.short actual && git log --oneline --no-decorate >actual && @@ -465,8 +459,7 @@ test_expect_success 'log.decorate configuration' ' git log --oneline --decorate=full >actual && test_cmp expect.full actual && - git config --unset-all log.decorate && - git config log.decorate full && + test_config log.decorate full && git log --oneline >actual && test_cmp expect.full actual && git log --oneline --no-decorate >actual && @@ -474,16 +467,15 @@ test_expect_success 'log.decorate configuration' ' git log --oneline --decorate >actual && test_cmp expect.short actual - git config --unset-all log.decorate && + test_unconfig log.decorate && git log --pretty=raw >expect.raw && - git config log.decorate full && + test_config log.decorate full && git log --pretty=raw >actual && test_cmp expect.raw actual ' test_expect_success 'reflog is expected format' ' - test_might_fail git config --remove-section log && git log -g --abbrev-commit --pretty=oneline >expect && git reflog >actual && test_cmp expect actual @@ -496,10 +488,6 @@ test_expect_success 'whatchanged is expected format' ' ' test_expect_success 'log.abbrevCommit configuration' ' - test_when_finished "git config --unset log.abbrevCommit" && - - test_might_fail git config --unset log.abbrevCommit && - git log --abbrev-commit >expect.log.abbrev && git log --no-abbrev-commit >expect.log.full && git log --pretty=raw >expect.log.raw && @@ -508,7 +496,7 @@ test_expect_success 'log.abbrevCommit configuration' ' git whatchanged --abbrev-commit >expect.whatchanged.abbrev && git whatchanged --no-abbrev-commit >expect.whatchanged.full && - git config log.abbrevCommit true && + test_config log.abbrevCommit true && git log >actual && test_cmp expect.log.abbrev actual && diff --git a/t/t4205-log-pretty-formats.sh b/t/t4205-log-pretty-formats.sh index 98a43d457a..26fbfde4a3 100755 --- a/t/t4205-log-pretty-formats.sh +++ b/t/t4205-log-pretty-formats.sh @@ -99,4 +99,179 @@ test_expect_failure 'NUL termination with --stat' ' test_i18ncmp expected actual ' +test_expect_success 'setup more commits' ' + test_commit "message one" one one message-one && + test_commit "message two" two two message-two +' + +test_expect_success 'left alignment formatting' ' + git log --pretty="format:%<(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +message two Z +message one Z +add bar Z +initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'left alignment formatting at the nth column' ' + git log --pretty="format:%h %<|(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +fa33ab1 message two Z +7cd6c63 message one Z +1711bf9 add bar Z +af20c06 initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'left alignment formatting with no padding' ' + git log --pretty="format:%<(1)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + cat <<\EOF >expected && +message two +message one +add bar +initial +EOF + test_cmp expected actual +' + +test_expect_success 'left alignment formatting with trunc' ' + git log --pretty="format:%<(10,trunc)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +message .. +message .. +add bar Z +initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'left alignment formatting with ltrunc' ' + git log --pretty="format:%<(10,ltrunc)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +..sage two +..sage one +add bar Z +initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'left alignment formatting with mtrunc' ' + git log --pretty="format:%<(10,mtrunc)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +mess.. two +mess.. one +add bar Z +initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'right alignment formatting' ' + git log --pretty="format:%>(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +Z message two +Z message one +Z add bar +Z initial +EOF + test_cmp expected actual +' + +test_expect_success 'right alignment formatting at the nth column' ' + git log --pretty="format:%h %>|(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +fa33ab1 message two +7cd6c63 message one +1711bf9 add bar +af20c06 initial +EOF + test_cmp expected actual +' + +test_expect_success 'right alignment formatting with no padding' ' + git log --pretty="format:%>(1)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + cat <<\EOF >expected && +message two +message one +add bar +initial +EOF + test_cmp expected actual +' + +test_expect_success 'center alignment formatting' ' + git log --pretty="format:%><(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +Z message two Z +Z message one Z +Z add bar Z +Z initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'center alignment formatting at the nth column' ' + git log --pretty="format:%h %><|(40)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + qz_to_tab_space <<\EOF >expected && +fa33ab1 message two Z +7cd6c63 message one Z +1711bf9 add bar Z +af20c06 initial Z +EOF + test_cmp expected actual +' + +test_expect_success 'center alignment formatting with no padding' ' + git log --pretty="format:%><(1)%s" >actual && + # complete the incomplete line at the end + echo >>actual && + cat <<\EOF >expected && +message two +message one +add bar +initial +EOF + test_cmp expected actual +' + +test_expect_success 'left/right alignment formatting with stealing' ' + git commit --amend -m short --author "long long long <long@me.com>" && + git log --pretty="format:%<(10,trunc)%s%>>(10,ltrunc)% an" >actual && + # complete the incomplete line at the end + echo >>actual && + cat <<\EOF >expected && +short long long long +message .. A U Thor +add bar A U Thor +initial A U Thor +EOF + test_cmp expected actual +' + test_done diff --git a/t/t4207-log-decoration-colors.sh b/t/t4207-log-decoration-colors.sh index bbde31b019..925f577a3c 100755 --- a/t/t4207-log-decoration-colors.sh +++ b/t/t4207-log-decoration-colors.sh @@ -44,15 +44,15 @@ test_expect_success setup ' ' cat >expected <<EOF -${c_commit}COMMIT_ID (${c_HEAD}HEAD${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_HEAD}HEAD${c_reset}${c_commit},\ ${c_tag}tag: v1.0${c_reset}${c_commit},\ ${c_tag}tag: B${c_reset}${c_commit},\ ${c_branch}master${c_reset}${c_commit})${c_reset} B -${c_commit}COMMIT_ID (${c_tag}tag: A1${c_reset}${c_commit},\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A1${c_reset}${c_commit},\ ${c_remoteBranch}other/master${c_reset}${c_commit})${c_reset} A1 -${c_commit}COMMIT_ID (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\ +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_stash}refs/stash${c_reset}${c_commit})${c_reset}\ On master: Changes to A.t -${c_commit}COMMIT_ID (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A +${c_commit}COMMIT_ID${c_reset}${c_commit} (${c_tag}tag: A${c_reset}${c_commit})${c_reset} A EOF # We want log to show all, but the second parent to refs/stash is irrelevant diff --git a/t/t4300-merge-tree.sh b/t/t4300-merge-tree.sh index d0b2a457b8..9015e47654 100755 --- a/t/t4300-merge-tree.sh +++ b/t/t4300-merge-tree.sh @@ -26,8 +26,6 @@ EXPECTED test_expect_success 'file add !A, B' ' cat >expected <<\EXPECTED && -added in local - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE EXPECTED git reset --hard initial && @@ -38,9 +36,6 @@ EXPECTED test_expect_success 'file add A, B (same)' ' cat >expected <<\EXPECTED && -added in both - our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE EXPECTED git reset --hard initial && @@ -181,9 +176,6 @@ AAA" && test_expect_success 'file remove A, !B' ' cat >expected <<\EXPECTED && -removed in local - base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE - their 100644 43d5a8ed6ef6c00ff775008633f95787d088285d ONE EXPECTED git reset --hard initial && @@ -213,6 +205,19 @@ EXPECTED test_cmp expected actual ' +test_expect_success 'file remove A, B (same)' ' + cat >expected <<\EXPECTED && +EXPECTED + + git reset --hard initial && + test_commit "rm-a-b-base" "ONE" "AAA" && + git rm ONE && + git commit -m "rm-a-b" && + git tag "rm-a-b" && + git merge-tree rm-a-b-base rm-a-b rm-a-b >actual && + test_cmp expected actual +' + test_expect_success 'file change A, remove B' ' cat >expected <<\EXPECTED && removed in remote @@ -254,6 +259,57 @@ EXPECTED test_cmp expected actual ' +test_expect_success 'tree add A, B (same)' ' + cat >expect <<-\EOF && + EOF + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "file" add-tree-A && + git merge-tree initial add-tree-A add-tree-A >actual && + test_cmp expect actual +' + +test_expect_success 'tree add A, B (different)' ' + cat >expect <<-\EOF && + added in both + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file + their 100644 ba629238ca89489f2b350e196ca445e09d8bb834 sub/file + @@ -1 +1,5 @@ + +<<<<<<< .our + AAA + +======= + +BBB + +>>>>>>> .their + EOF + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "AAA" add-tree-a-b-A && + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "BBB" add-tree-a-b-B && + git merge-tree initial add-tree-a-b-A add-tree-a-b-B >actual && + test_cmp expect actual +' + +test_expect_success 'tree unchanged A, removed B' ' + cat >expect <<-\EOF && + removed in remote + base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file + our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d sub/file + @@ -1 +0,0 @@ + -AAA + EOF + git reset --hard initial && + mkdir sub && + test_commit "add sub/file" "sub/file" "AAA" tree-remove-b-initial && + git rm sub/file && + test_tick && + git commit -m "remove sub/file" && + git tag tree-remove-b-B && + git merge-tree tree-remove-b-initial tree-remove-b-initial tree-remove-b-B >actual && + test_cmp expect actual +' + test_expect_success 'turn file to tree' ' git reset --hard initial && rm initial-file && @@ -283,8 +339,6 @@ test_expect_success 'turn tree to file' ' test_commit "make-file" "dir" "CCC" && git merge-tree add-tree add-another-tree make-file >actual && cat >expect <<-\EOF && - added in local - our 100644 ba629238ca89489f2b350e196ca445e09d8bb834 dir/another removed in remote base 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path our 100644 43d5a8ed6ef6c00ff775008633f95787d088285d dir/path diff --git a/t/t5004-archive-corner-cases.sh b/t/t5004-archive-corner-cases.sh index bfdb56a069..8d1bbd356a 100755 --- a/t/t5004-archive-corner-cases.sh +++ b/t/t5004-archive-corner-cases.sh @@ -23,15 +23,14 @@ check_dir() { echo "$dir/$i" done } | sort >expect && - find "$dir" -print | sort >actual && + find "$dir" ! -name pax_global_header -print | sort >actual && test_cmp expect actual } test_expect_success 'tar archive of empty tree is empty' ' git archive --format=tar HEAD: >empty.tar && - make_dir extract && - "$TAR" xf empty.tar -C extract && - check_dir extract + perl -e "print \"\\0\" x 10240" >10knuls.tar && + test_cmp 10knuls.tar empty.tar ' test_expect_success 'tar archive of empty tree with prefix' ' diff --git a/t/t5304-prune.sh b/t/t5304-prune.sh index d645328609..e4bb3a1457 100755 --- a/t/t5304-prune.sh +++ b/t/t5304-prune.sh @@ -195,4 +195,30 @@ test_expect_success 'gc: prune old objects after local clone' ' ) ' +test_expect_success 'garbage report in count-objects -v' ' + : >.git/objects/pack/foo && + : >.git/objects/pack/foo.bar && + : >.git/objects/pack/foo.keep && + : >.git/objects/pack/foo.pack && + : >.git/objects/pack/fake.bar && + : >.git/objects/pack/fake.keep && + : >.git/objects/pack/fake.pack && + : >.git/objects/pack/fake.idx && + : >.git/objects/pack/fake2.keep && + : >.git/objects/pack/fake3.idx && + git count-objects -v 2>stderr && + grep "index file .git/objects/pack/fake.idx is too small" stderr && + grep "^warning:" stderr | sort >actual && + cat >expected <<\EOF && +warning: garbage found: .git/objects/pack/fake.bar +warning: garbage found: .git/objects/pack/foo +warning: garbage found: .git/objects/pack/foo.bar +warning: no corresponding .idx nor .pack: .git/objects/pack/fake2.keep +warning: no corresponding .idx: .git/objects/pack/foo.keep +warning: no corresponding .idx: .git/objects/pack/foo.pack +warning: no corresponding .pack: .git/objects/pack/fake3.idx +EOF + test_cmp expected actual +' + test_done diff --git a/t/t5404-tracking-branches.sh b/t/t5404-tracking-branches.sh index c24003565d..2b8c0bac7d 100755 --- a/t/t5404-tracking-branches.sh +++ b/t/t5404-tracking-branches.sh @@ -36,7 +36,7 @@ test_expect_success 'prepare pushable branches' ' ' test_expect_success 'mixed-success push returns error' ' - test_must_fail git push + test_must_fail git push origin : ' test_expect_success 'check tracking branches updated correctly after push' ' diff --git a/t/t5500-fetch-pack.sh b/t/t5500-fetch-pack.sh index d574085696..6133d9ed13 100755 --- a/t/t5500-fetch-pack.sh +++ b/t/t5500-fetch-pack.sh @@ -373,6 +373,20 @@ test_expect_success 'clone shallow with packed refs' ' test_cmp count8.expected count8.actual ' +test_expect_success 'fetch in shallow repo unreachable shallow objects' ' + ( + git clone --bare --branch B --single-branch "file://$(pwd)/." no-reflog && + git clone --depth 1 "file://$(pwd)/no-reflog" shallow9 && + cd no-reflog && + git tag -d TAGB1 TAGB2 && + git update-ref refs/heads/B B~~ && + git gc --prune=now && + cd ../shallow9 && + git fetch origin && + git fsck --no-dangling + ) +' + test_expect_success 'setup tests for the --stdin parameter' ' for head in C D E F do diff --git a/t/t5503-tagfollow.sh b/t/t5503-tagfollow.sh index 60de2d6ede..f30c03885c 100755 --- a/t/t5503-tagfollow.sh +++ b/t/t5503-tagfollow.sh @@ -4,10 +4,6 @@ test_description='test automatic tag following' . ./test-lib.sh -if ! test_have_prereq NOT_MINGW; then - say "GIT_DEBUG_SEND_PACK not supported - skipping tests" -fi - # End state of the repository: # # T - tag1 S - tag2 @@ -17,7 +13,7 @@ fi # \ C - origin/cat \ # origin/master master -test_expect_success NOT_MINGW setup ' +test_expect_success setup ' test_tick && echo ichi >file && git add file && @@ -39,28 +35,35 @@ test_expect_success NOT_MINGW setup ' ' U=UPLOAD_LOG +UPATH="$(pwd)/$U" -test_expect_success NOT_MINGW 'setup expect' ' +test_expect_success 'setup expect' ' cat - <<EOF >expect -#S want $A -#E EOF ' -test_expect_success NOT_MINGW 'fetch A (new commit : 1 connection)' ' +get_needs () { + test -s "$1" && + perl -alne ' + next unless $F[1] eq "upload-pack<"; + last if $F[2] eq "0000"; + print $F[2], " ", $F[3]; + ' "$1" +} + +test_expect_success 'fetch A (new commit : 1 connection)' ' rm -f $U && ( cd cloned && - GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + GIT_TRACE_PACKET=$UPATH git fetch && test $A = $(git rev-parse --verify origin/master) ) && - test -s $U && - cut -d" " -f1,2 $U >actual && + get_needs $U >actual && test_cmp expect actual ' -test_expect_success NOT_MINGW "create tag T on A, create C on branch cat" ' +test_expect_success "create tag T on A, create C on branch cat" ' git tag -a -m tag1 tag1 $A && T=$(git rev-parse --verify tag1) && @@ -72,30 +75,27 @@ test_expect_success NOT_MINGW "create tag T on A, create C on branch cat" ' git checkout master ' -test_expect_success NOT_MINGW 'setup expect' ' +test_expect_success 'setup expect' ' cat - <<EOF >expect -#S want $C want $T -#E EOF ' -test_expect_success NOT_MINGW 'fetch C, T (new branch, tag : 1 connection)' ' +test_expect_success 'fetch C, T (new branch, tag : 1 connection)' ' rm -f $U && ( cd cloned && - GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + GIT_TRACE_PACKET=$UPATH git fetch && test $C = $(git rev-parse --verify origin/cat) && test $T = $(git rev-parse --verify tag1) && test $A = $(git rev-parse --verify tag1^0) ) && - test -s $U && - cut -d" " -f1,2 $U >actual && + get_needs $U >actual && test_cmp expect actual ' -test_expect_success NOT_MINGW "create commits O, B, tag S on B" ' +test_expect_success "create commits O, B, tag S on B" ' test_tick && echo O >file && git add file && @@ -111,39 +111,34 @@ test_expect_success NOT_MINGW "create commits O, B, tag S on B" ' S=$(git rev-parse --verify tag2) ' -test_expect_success NOT_MINGW 'setup expect' ' +test_expect_success 'setup expect' ' cat - <<EOF >expect -#S want $B want $S -#E EOF ' -test_expect_success NOT_MINGW 'fetch B, S (commit and tag : 1 connection)' ' +test_expect_success 'fetch B, S (commit and tag : 1 connection)' ' rm -f $U && ( cd cloned && - GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + GIT_TRACE_PACKET=$UPATH git fetch && test $B = $(git rev-parse --verify origin/master) && test $B = $(git rev-parse --verify tag2^0) && test $S = $(git rev-parse --verify tag2) ) && - test -s $U && - cut -d" " -f1,2 $U >actual && + get_needs $U >actual && test_cmp expect actual ' -test_expect_success NOT_MINGW 'setup expect' ' +test_expect_success 'setup expect' ' cat - <<EOF >expect -#S want $B want $S -#E EOF ' -test_expect_success NOT_MINGW 'new clone fetch master and tags' ' +test_expect_success 'new clone fetch master and tags' ' git branch -D cat rm -f $U ( @@ -151,15 +146,14 @@ test_expect_success NOT_MINGW 'new clone fetch master and tags' ' cd clone2 && git init && git remote add origin .. && - GIT_DEBUG_SEND_PACK=3 git fetch 3>../$U && + GIT_TRACE_PACKET=$UPATH git fetch && test $B = $(git rev-parse --verify origin/master) && test $S = $(git rev-parse --verify tag2) && test $B = $(git rev-parse --verify tag2^0) && test $T = $(git rev-parse --verify tag1) && test $A = $(git rev-parse --verify tag1^0) ) && - test -s $U && - cut -d" " -f1,2 $U >actual && + get_needs $U >actual && test_cmp expect actual ' diff --git a/t/t5505-remote.sh b/t/t5505-remote.sh index ccc55ebf4b..dd10ff053c 100755 --- a/t/t5505-remote.sh +++ b/t/t5505-remote.sh @@ -345,7 +345,7 @@ test_expect_success 'fetch mirrors do not act as mirrors during push' ' ) && (cd mirror-fetch/child && git branch -m renamed renamed2 && - git push parent + git push parent : ) && (cd mirror-fetch/parent && git rev-parse --verify renamed && @@ -1003,4 +1003,26 @@ test_expect_success 'remote set-url --delete baz' ' cmp expect actual ' +test_expect_success 'extra args: setup' ' + # add a dummy origin so that this does not trigger failure + git remote add origin . +' + +test_extra_arg () { + test_expect_success "extra args: $*" " + test_must_fail git remote $* bogus_extra_arg 2>actual && + grep '^usage:' actual + " +} + +test_extra_arg add nick url +test_extra_arg rename origin newname +test_extra_arg remove origin +test_extra_arg set-head origin master +# set-branches takes any number of args +test_extra_arg set-url origin newurl oldurl +# show takes any number of args +# prune takes any number of args +# update takes any number of args + test_done diff --git a/t/t5516-fetch-push.sh b/t/t5516-fetch-push.sh index 9a21cd61d7..4691d51b8c 100755 --- a/t/t5516-fetch-push.sh +++ b/t/t5516-fetch-push.sh @@ -1,16 +1,28 @@ #!/bin/sh -test_description='fetching and pushing, with or without wildcard' +test_description='Basic fetch/push functionality. + +This test checks the following functionality: + +* command-line syntax +* refspecs +* fast-forward detection, and overriding it +* configuration +* hooks +* --porcelain output format +* hiderefs +' . ./test-lib.sh D=`pwd` mk_empty () { - rm -fr testrepo && - mkdir testrepo && + repo_name="$1" + rm -fr "$repo_name" && + mkdir "$repo_name" && ( - cd testrepo && + cd "$repo_name" && git init && git config receive.denyCurrentBranch warn && mv .git/hooks .git/hooks-disabled @@ -18,32 +30,33 @@ mk_empty () { } mk_test () { - mk_empty && + repo_name="$1" + shift + + mk_empty "$repo_name" && ( for ref in "$@" do - git push testrepo $the_first_commit:refs/$ref || { - echo "Oops, push refs/$ref failure" - exit 1 - } + git push "$repo_name" $the_first_commit:refs/$ref || + exit done && - cd testrepo && + cd "$repo_name" && for ref in "$@" do - r=$(git show-ref -s --verify refs/$ref) && - test "z$r" = "z$the_first_commit" || { - echo "Oops, refs/$ref is wrong" - exit 1 - } + echo "$the_first_commit" >expect && + git show-ref -s --verify refs/$ref >actual && + test_cmp expect actual || + exit done && git fsck --full ) } mk_test_with_hooks() { + repo_name=$1 mk_test "$@" && ( - cd testrepo && + cd "$repo_name" && mkdir .git/hooks && cd .git/hooks && @@ -75,22 +88,23 @@ mk_test_with_hooks() { } mk_child() { - rm -rf "$1" && - git clone testrepo "$1" + rm -rf "$2" && + git clone "$1" "$2" } check_push_result () { + repo_name="$1" + shift + ( - cd testrepo && - it="$1" && - shift + cd "$repo_name" && + echo "$1" >expect && + shift && for ref in "$@" do - r=$(git show-ref -s --verify refs/$ref) && - test "z$r" = "z$it" || { - echo "Oops, refs/$ref is wrong" - exit 1 - } + git show-ref -s --verify refs/$ref >actual && + test_cmp expect actual || + exit done && git fsck --full ) @@ -113,35 +127,33 @@ test_expect_success setup ' ' test_expect_success 'fetch without wildcard' ' - mk_empty && + mk_empty testrepo && ( cd testrepo && git fetch .. refs/heads/master:refs/remotes/origin/master && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'fetch with wildcard' ' - mk_empty && + mk_empty testrepo && ( cd testrepo && git config remote.up.url .. && git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" && git fetch up && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'fetch with insteadOf' ' - mk_empty && + mk_empty testrepo && ( TRASH=$(pwd)/ && cd testrepo && @@ -150,15 +162,14 @@ test_expect_success 'fetch with insteadOf' ' git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" && git fetch up && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'fetch with pushInsteadOf (should not rewrite)' ' - mk_empty && + mk_empty testrepo && ( TRASH=$(pwd)/ && cd testrepo && @@ -167,321 +178,310 @@ test_expect_success 'fetch with pushInsteadOf (should not rewrite)' ' git config remote.up.fetch "refs/heads/*:refs/remotes/origin/*" && git fetch up && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push without wildcard' ' - mk_empty && + mk_empty testrepo && git push testrepo refs/heads/master:refs/remotes/origin/master && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push with wildcard' ' - mk_empty && + mk_empty testrepo && git push testrepo "refs/heads/*:refs/remotes/origin/*" && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push with insteadOf' ' - mk_empty && + mk_empty testrepo && TRASH="$(pwd)/" && - git config "url.$TRASH.insteadOf" trash/ && + test_config "url.$TRASH.insteadOf" trash/ && git push trash/testrepo refs/heads/master:refs/remotes/origin/master && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push with pushInsteadOf' ' - mk_empty && + mk_empty testrepo && TRASH="$(pwd)/" && - git config "url.$TRASH.pushInsteadOf" trash/ && + test_config "url.$TRASH.pushInsteadOf" trash/ && git push trash/testrepo refs/heads/master:refs/remotes/origin/master && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push with pushInsteadOf and explicit pushurl (pushInsteadOf should not rewrite)' ' - mk_empty && - git config "url.trash2/.pushInsteadOf" testrepo/ && - git config "url.trash3/.pusnInsteadOf" trash/wrong && - git config remote.r.url trash/wrong && - git config remote.r.pushurl "testrepo/" && + mk_empty testrepo && + test_config "url.trash2/.pushInsteadOf" testrepo/ && + test_config "url.trash3/.pusnInsteadOf" trash/wrong && + test_config remote.r.url trash/wrong && + test_config remote.r.pushurl "testrepo/" && git push r refs/heads/master:refs/remotes/origin/master && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) ' test_expect_success 'push with matching heads' ' - mk_test heads/master && - git push testrepo && - check_push_result $the_commit heads/master + mk_test testrepo heads/master && + git push testrepo : && + check_push_result testrepo $the_commit heads/master ' test_expect_success 'push with matching heads on the command line' ' - mk_test heads/master && + mk_test testrepo heads/master && git push testrepo : && - check_push_result $the_commit heads/master + check_push_result testrepo $the_commit heads/master ' test_expect_success 'failed (non-fast-forward) push with matching heads' ' - mk_test heads/master && + mk_test testrepo heads/master && git push testrepo : && git commit --amend -massaged && test_must_fail git push testrepo && - check_push_result $the_commit heads/master && + check_push_result testrepo $the_commit heads/master && git reset --hard $the_commit ' test_expect_success 'push --force with matching heads' ' - mk_test heads/master && + mk_test testrepo heads/master && git push testrepo : && git commit --amend -massaged && - git push --force testrepo && - ! check_push_result $the_commit heads/master && + git push --force testrepo : && + ! check_push_result testrepo $the_commit heads/master && git reset --hard $the_commit ' test_expect_success 'push with matching heads and forced update' ' - mk_test heads/master && + mk_test testrepo heads/master && git push testrepo : && git commit --amend -massaged && git push testrepo +: && - ! check_push_result $the_commit heads/master && + ! check_push_result testrepo $the_commit heads/master && git reset --hard $the_commit ' test_expect_success 'push with no ambiguity (1)' ' - mk_test heads/master && + mk_test testrepo heads/master && git push testrepo master:master && - check_push_result $the_commit heads/master + check_push_result testrepo $the_commit heads/master ' test_expect_success 'push with no ambiguity (2)' ' - mk_test remotes/origin/master && + mk_test testrepo remotes/origin/master && git push testrepo master:origin/master && - check_push_result $the_commit remotes/origin/master + check_push_result testrepo $the_commit remotes/origin/master ' test_expect_success 'push with colon-less refspec, no ambiguity' ' - mk_test heads/master heads/t/master && + mk_test testrepo heads/master heads/t/master && git branch -f t/master master && git push testrepo master && - check_push_result $the_commit heads/master && - check_push_result $the_first_commit heads/t/master + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_first_commit heads/t/master ' test_expect_success 'push with weak ambiguity (1)' ' - mk_test heads/master remotes/origin/master && + mk_test testrepo heads/master remotes/origin/master && git push testrepo master:master && - check_push_result $the_commit heads/master && - check_push_result $the_first_commit remotes/origin/master + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_first_commit remotes/origin/master ' test_expect_success 'push with weak ambiguity (2)' ' - mk_test heads/master remotes/origin/master remotes/another/master && + mk_test testrepo heads/master remotes/origin/master remotes/another/master && git push testrepo master:master && - check_push_result $the_commit heads/master && - check_push_result $the_first_commit remotes/origin/master remotes/another/master + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_first_commit remotes/origin/master remotes/another/master ' test_expect_success 'push with ambiguity' ' - mk_test heads/frotz tags/frotz && - if git push testrepo master:frotz - then - echo "Oops, should have failed" - false - else - check_push_result $the_first_commit heads/frotz tags/frotz - fi + mk_test testrepo heads/frotz tags/frotz && + test_must_fail git push testrepo master:frotz && + check_push_result testrepo $the_first_commit heads/frotz tags/frotz ' test_expect_success 'push with colon-less refspec (1)' ' - mk_test heads/frotz tags/frotz && + mk_test testrepo heads/frotz tags/frotz && git branch -f frotz master && git push testrepo frotz && - check_push_result $the_commit heads/frotz && - check_push_result $the_first_commit tags/frotz + check_push_result testrepo $the_commit heads/frotz && + check_push_result testrepo $the_first_commit tags/frotz ' test_expect_success 'push with colon-less refspec (2)' ' - mk_test heads/frotz tags/frotz && + mk_test testrepo heads/frotz tags/frotz && if git show-ref --verify -q refs/heads/frotz then git branch -D frotz fi && git tag -f frotz && git push -f testrepo frotz && - check_push_result $the_commit tags/frotz && - check_push_result $the_first_commit heads/frotz + check_push_result testrepo $the_commit tags/frotz && + check_push_result testrepo $the_first_commit heads/frotz ' test_expect_success 'push with colon-less refspec (3)' ' - mk_test && + mk_test testrepo && if git show-ref --verify -q refs/tags/frotz then git tag -d frotz fi && git branch -f frotz master && git push testrepo frotz && - check_push_result $the_commit heads/frotz && + check_push_result testrepo $the_commit heads/frotz && test 1 = $( cd testrepo && git show-ref | wc -l ) ' test_expect_success 'push with colon-less refspec (4)' ' - mk_test && + mk_test testrepo && if git show-ref --verify -q refs/heads/frotz then git branch -D frotz fi && git tag -f frotz && git push testrepo frotz && - check_push_result $the_commit tags/frotz && + check_push_result testrepo $the_commit tags/frotz && test 1 = $( cd testrepo && git show-ref | wc -l ) ' test_expect_success 'push head with non-existent, incomplete dest' ' - mk_test && + mk_test testrepo && git push testrepo master:branch && - check_push_result $the_commit heads/branch + check_push_result testrepo $the_commit heads/branch ' test_expect_success 'push tag with non-existent, incomplete dest' ' - mk_test && + mk_test testrepo && git tag -f v1.0 && git push testrepo v1.0:tag && - check_push_result $the_commit tags/tag + check_push_result testrepo $the_commit tags/tag ' test_expect_success 'push sha1 with non-existent, incomplete dest' ' - mk_test && + mk_test testrepo && test_must_fail git push testrepo `git rev-parse master`:foo ' test_expect_success 'push ref expression with non-existent, incomplete dest' ' - mk_test && + mk_test testrepo && test_must_fail git push testrepo master^:branch ' test_expect_success 'push with HEAD' ' - mk_test heads/master && + mk_test testrepo heads/master && git checkout master && git push testrepo HEAD && - check_push_result $the_commit heads/master + check_push_result testrepo $the_commit heads/master ' test_expect_success 'push with HEAD nonexisting at remote' ' - mk_test heads/master && + mk_test testrepo heads/master && git checkout -b local master && git push testrepo HEAD && - check_push_result $the_commit heads/local + check_push_result testrepo $the_commit heads/local ' test_expect_success 'push with +HEAD' ' - mk_test heads/master && + mk_test testrepo heads/master && git checkout master && git branch -D local && git checkout -b local && git push testrepo master local && - check_push_result $the_commit heads/master && - check_push_result $the_commit heads/local && + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_commit heads/local && # Without force rewinding should fail git reset --hard HEAD^ && test_must_fail git push testrepo HEAD && - check_push_result $the_commit heads/local && + check_push_result testrepo $the_commit heads/local && # With force rewinding should succeed git push testrepo +HEAD && - check_push_result $the_first_commit heads/local + check_push_result testrepo $the_first_commit heads/local ' test_expect_success 'push HEAD with non-existent, incomplete dest' ' - mk_test && + mk_test testrepo && git checkout master && git push testrepo HEAD:branch && - check_push_result $the_commit heads/branch + check_push_result testrepo $the_commit heads/branch ' test_expect_success 'push with config remote.*.push = HEAD' ' - mk_test heads/local && + mk_test testrepo heads/local && git checkout master && git branch -f local $the_commit && ( @@ -489,46 +489,68 @@ test_expect_success 'push with config remote.*.push = HEAD' ' git checkout local && git reset --hard $the_first_commit ) && - git config remote.there.url testrepo && - git config remote.there.push HEAD && - git config branch.master.remote there && + test_config remote.there.url testrepo && + test_config remote.there.push HEAD && + test_config branch.master.remote there && + git push && + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_first_commit heads/local +' + +test_expect_success 'push with remote.pushdefault' ' + mk_test up_repo heads/master && + mk_test down_repo heads/master && + test_config remote.up.url up_repo && + test_config remote.down.url down_repo && + test_config branch.master.remote up && + test_config remote.pushdefault down && + test_config push.default matching && git push && - check_push_result $the_commit heads/master && - check_push_result $the_first_commit heads/local + check_push_result up_repo $the_first_commit heads/master && + check_push_result down_repo $the_commit heads/master ' -# clean up the cruft left with the previous one -git config --remove-section remote.there -git config --remove-section branch.master - test_expect_success 'push with config remote.*.pushurl' ' - mk_test heads/master && + mk_test testrepo heads/master && git checkout master && - git config remote.there.url test2repo && - git config remote.there.pushurl testrepo && - git push there && - check_push_result $the_commit heads/master + test_config remote.there.url test2repo && + test_config remote.there.pushurl testrepo && + git push there : && + check_push_result testrepo $the_commit heads/master +' + +test_expect_success 'push with config branch.*.pushremote' ' + mk_test up_repo heads/master && + mk_test side_repo heads/master && + mk_test down_repo heads/master && + test_config remote.up.url up_repo && + test_config remote.pushdefault side_repo && + test_config remote.down.url down_repo && + test_config branch.master.remote up && + test_config branch.master.pushremote down && + test_config push.default matching && + git push && + check_push_result up_repo $the_first_commit heads/master && + check_push_result side_repo $the_first_commit heads/master && + check_push_result down_repo $the_commit heads/master ' -# clean up the cruft left with the previous one -git config --remove-section remote.there - test_expect_success 'push with dry-run' ' - mk_test heads/master && + mk_test testrepo heads/master && ( cd testrepo && old_commit=$(git show-ref -s --verify refs/heads/master) ) && - git push --dry-run testrepo && - check_push_result $old_commit heads/master + git push --dry-run testrepo : && + check_push_result testrepo $old_commit heads/master ' test_expect_success 'push updates local refs' ' - mk_test heads/master && - mk_child child && + mk_test testrepo heads/master && + mk_child testrepo child && ( cd child && git pull .. master && @@ -541,9 +563,9 @@ test_expect_success 'push updates local refs' ' test_expect_success 'push updates up-to-date local refs' ' - mk_test heads/master && - mk_child child1 && - mk_child child2 && + mk_test testrepo heads/master && + mk_child testrepo child1 && + mk_child testrepo child2 && (cd child1 && git pull .. master && git push) && ( cd child2 && @@ -557,8 +579,8 @@ test_expect_success 'push updates up-to-date local refs' ' test_expect_success 'push preserves up-to-date packed refs' ' - mk_test heads/master && - mk_child child && + mk_test testrepo heads/master && + mk_child testrepo child && ( cd child && git push && @@ -569,8 +591,8 @@ test_expect_success 'push preserves up-to-date packed refs' ' test_expect_success 'push does not update local refs on failure' ' - mk_test heads/master && - mk_child child && + mk_test testrepo heads/master && + mk_child testrepo child && mkdir testrepo/.git/hooks && echo "#!/no/frobnication/today" >testrepo/.git/hooks/pre-receive && chmod +x testrepo/.git/hooks/pre-receive && @@ -586,7 +608,7 @@ test_expect_success 'push does not update local refs on failure' ' test_expect_success 'allow deleting an invalid remote ref' ' - mk_test heads/master && + mk_test testrepo heads/master && rm -f testrepo/.git/objects/??/* && git push testrepo :refs/heads/master && (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master) @@ -594,7 +616,7 @@ test_expect_success 'allow deleting an invalid remote ref' ' ' test_expect_success 'pushing valid refs triggers post-receive and post-update hooks' ' - mk_test_with_hooks heads/master heads/next && + mk_test_with_hooks testrepo heads/master heads/next && orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) && newmaster=$(git show-ref -s --verify refs/heads/master) && orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) && @@ -630,7 +652,7 @@ test_expect_success 'pushing valid refs triggers post-receive and post-update ho ' test_expect_success 'deleting dangling ref triggers hooks with correct args' ' - mk_test_with_hooks heads/master && + mk_test_with_hooks testrepo heads/master && rm -f testrepo/.git/objects/??/* && git push testrepo :refs/heads/master && ( @@ -659,7 +681,7 @@ test_expect_success 'deleting dangling ref triggers hooks with correct args' ' ' test_expect_success 'deletion of a non-existent ref is not fed to post-receive and post-update hooks' ' - mk_test_with_hooks heads/master && + mk_test_with_hooks testrepo heads/master && orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) && newmaster=$(git show-ref -s --verify refs/heads/master) && git push testrepo master :refs/heads/nonexistent && @@ -691,7 +713,7 @@ test_expect_success 'deletion of a non-existent ref is not fed to post-receive a ' test_expect_success 'deletion of a non-existent ref alone does trigger post-receive and post-update hooks' ' - mk_test_with_hooks heads/master && + mk_test_with_hooks testrepo heads/master && git push testrepo :refs/heads/nonexistent && ( cd testrepo/.git && @@ -711,7 +733,7 @@ test_expect_success 'deletion of a non-existent ref alone does trigger post-rece ' test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks with correct input' ' - mk_test_with_hooks heads/master heads/next heads/pu && + mk_test_with_hooks testrepo heads/master heads/next heads/pu && orgmaster=$(cd testrepo && git show-ref -s --verify refs/heads/master) && newmaster=$(git show-ref -s --verify refs/heads/master) && orgnext=$(cd testrepo && git show-ref -s --verify refs/heads/next) && @@ -757,14 +779,14 @@ test_expect_success 'mixed ref updates, deletes, invalid deletes trigger hooks w ' test_expect_success 'allow deleting a ref using --delete' ' - mk_test heads/master && + mk_test testrepo heads/master && (cd testrepo && git config receive.denyDeleteCurrent warn) && git push testrepo --delete master && (cd testrepo && test_must_fail git rev-parse --verify refs/heads/master) ' test_expect_success 'allow deleting a tag using --delete' ' - mk_test heads/master && + mk_test testrepo heads/master && git tag -a -m dummy_message deltag heads/master && git push testrepo --tags && (cd testrepo && git rev-parse --verify -q refs/tags/deltag) && @@ -773,17 +795,17 @@ test_expect_success 'allow deleting a tag using --delete' ' ' test_expect_success 'push --delete without args aborts' ' - mk_test heads/master && + mk_test testrepo heads/master && test_must_fail git push testrepo --delete ' test_expect_success 'push --delete refuses src:dest refspecs' ' - mk_test heads/master && + mk_test testrepo heads/master && test_must_fail git push testrepo --delete master:foo ' test_expect_success 'warn on push to HEAD of non-bare repository' ' - mk_test heads/master && + mk_test testrepo heads/master && ( cd testrepo && git checkout master && @@ -794,7 +816,7 @@ test_expect_success 'warn on push to HEAD of non-bare repository' ' ' test_expect_success 'deny push to HEAD of non-bare repository' ' - mk_test heads/master && + mk_test testrepo heads/master && ( cd testrepo && git checkout master && @@ -804,7 +826,7 @@ test_expect_success 'deny push to HEAD of non-bare repository' ' ' test_expect_success 'allow push to HEAD of bare repository (bare)' ' - mk_test heads/master && + mk_test testrepo heads/master && ( cd testrepo && git checkout master && @@ -816,7 +838,7 @@ test_expect_success 'allow push to HEAD of bare repository (bare)' ' ' test_expect_success 'allow push to HEAD of non-bare repository (config)' ' - mk_test heads/master && + mk_test testrepo heads/master && ( cd testrepo && git checkout master && @@ -827,63 +849,63 @@ test_expect_success 'allow push to HEAD of non-bare repository (config)' ' ' test_expect_success 'fetch with branches' ' - mk_empty && + mk_empty testrepo && git branch second $the_first_commit && git checkout second && echo ".." > testrepo/.git/branches/branch1 && ( cd testrepo && git fetch branch1 && - r=$(git show-ref -s --verify refs/heads/branch1) && - test "z$r" = "z$the_commit" && - test 1 = $(git for-each-ref refs/heads | wc -l) + echo "$the_commit commit refs/heads/branch1" >expect && + git for-each-ref refs/heads >actual && + test_cmp expect actual ) && git checkout master ' test_expect_success 'fetch with branches containing #' ' - mk_empty && + mk_empty testrepo && echo "..#second" > testrepo/.git/branches/branch2 && ( cd testrepo && git fetch branch2 && - r=$(git show-ref -s --verify refs/heads/branch2) && - test "z$r" = "z$the_first_commit" && - test 1 = $(git for-each-ref refs/heads | wc -l) + echo "$the_first_commit commit refs/heads/branch2" >expect && + git for-each-ref refs/heads >actual && + test_cmp expect actual ) && git checkout master ' test_expect_success 'push with branches' ' - mk_empty && + mk_empty testrepo && git checkout second && echo "testrepo" > .git/branches/branch1 && git push branch1 && ( cd testrepo && - r=$(git show-ref -s --verify refs/heads/master) && - test "z$r" = "z$the_first_commit" && - test 1 = $(git for-each-ref refs/heads | wc -l) + echo "$the_first_commit commit refs/heads/master" >expect && + git for-each-ref refs/heads >actual && + test_cmp expect actual ) ' test_expect_success 'push with branches containing #' ' - mk_empty && + mk_empty testrepo && echo "testrepo#branch3" > .git/branches/branch2 && git push branch2 && ( cd testrepo && - r=$(git show-ref -s --verify refs/heads/branch3) && - test "z$r" = "z$the_first_commit" && - test 1 = $(git for-each-ref refs/heads | wc -l) + echo "$the_first_commit commit refs/heads/branch3" >expect && + git for-each-ref refs/heads >actual && + test_cmp expect actual ) && git checkout master ' test_expect_success 'push into aliased refs (consistent)' ' - mk_test heads/master && - mk_child child1 && - mk_child child2 && + mk_test testrepo heads/master && + mk_child testrepo child1 && + mk_child testrepo child2 && ( cd child1 && git branch foo && @@ -903,9 +925,9 @@ test_expect_success 'push into aliased refs (consistent)' ' ' test_expect_success 'push into aliased refs (inconsistent)' ' - mk_test heads/master && - mk_child child1 && - mk_child child2 && + mk_test testrepo heads/master && + mk_child testrepo child1 && + mk_child testrepo child2 && ( cd child1 && git branch foo && @@ -930,9 +952,9 @@ test_expect_success 'push into aliased refs (inconsistent)' ' ' test_expect_success 'push requires --force to update lightweight tag' ' - mk_test heads/master && - mk_child child1 && - mk_child child2 && + mk_test testrepo heads/master && + mk_child testrepo child1 && + mk_child testrepo child2 && ( cd child1 && git tag Tag && @@ -951,28 +973,28 @@ test_expect_success 'push requires --force to update lightweight tag' ' ' test_expect_success 'push --porcelain' ' - mk_empty && + mk_empty testrepo && echo >.git/foo "To testrepo" && echo >>.git/foo "* refs/heads/master:refs/remotes/origin/master [new branch]" && echo >>.git/foo "Done" && git push >.git/bar --porcelain testrepo refs/heads/master:refs/remotes/origin/master && ( cd testrepo && - r=$(git show-ref -s --verify refs/remotes/origin/master) && - test "z$r" = "z$the_commit" && - test 1 = $(git for-each-ref refs/remotes/origin | wc -l) + echo "$the_commit commit refs/remotes/origin/master" >expect && + git for-each-ref refs/remotes/origin >actual && + test_cmp expect actual ) && test_cmp .git/foo .git/bar ' test_expect_success 'push --porcelain bad url' ' - mk_empty && + mk_empty testrepo && test_must_fail git push >.git/bar --porcelain asdfasdfasd refs/heads/master:refs/remotes/origin/master && test_must_fail grep -q Done .git/bar ' test_expect_success 'push --porcelain rejected' ' - mk_empty && + mk_empty testrepo && git push testrepo refs/heads/master:refs/remotes/origin/master && (cd testrepo && git reset --hard origin/master^ @@ -986,7 +1008,7 @@ test_expect_success 'push --porcelain rejected' ' ' test_expect_success 'push --porcelain --dry-run rejected' ' - mk_empty && + mk_empty testrepo && git push testrepo refs/heads/master:refs/remotes/origin/master && (cd testrepo && git reset --hard origin/master @@ -1001,25 +1023,25 @@ test_expect_success 'push --porcelain --dry-run rejected' ' ' test_expect_success 'push --prune' ' - mk_test heads/master heads/second heads/foo heads/bar && - git push --prune testrepo && - check_push_result $the_commit heads/master && - check_push_result $the_first_commit heads/second && - ! check_push_result $the_first_commit heads/foo heads/bar + mk_test testrepo heads/master heads/second heads/foo heads/bar && + git push --prune testrepo : && + check_push_result testrepo $the_commit heads/master && + check_push_result testrepo $the_first_commit heads/second && + ! check_push_result testrepo $the_first_commit heads/foo heads/bar ' test_expect_success 'push --prune refspec' ' - mk_test tmp/master tmp/second tmp/foo tmp/bar && + mk_test testrepo tmp/master tmp/second tmp/foo tmp/bar && git push --prune testrepo "refs/heads/*:refs/tmp/*" && - check_push_result $the_commit tmp/master && - check_push_result $the_first_commit tmp/second && - ! check_push_result $the_first_commit tmp/foo tmp/bar + check_push_result testrepo $the_commit tmp/master && + check_push_result testrepo $the_first_commit tmp/second && + ! check_push_result testrepo $the_first_commit tmp/foo tmp/bar ' for configsection in transfer receive do test_expect_success "push to update a ref hidden by $configsection.hiderefs" ' - mk_test heads/master hidden/one hidden/two hidden/three && + mk_test testrepo heads/master hidden/one hidden/two hidden/three && ( cd testrepo && git config $configsection.hiderefs refs/hidden @@ -1027,20 +1049,127 @@ do # push to unhidden ref succeeds normally git push testrepo master:refs/heads/master && - check_push_result $the_commit heads/master && + check_push_result testrepo $the_commit heads/master && # push to update a hidden ref should fail test_must_fail git push testrepo master:refs/hidden/one && - check_push_result $the_first_commit hidden/one && + check_push_result testrepo $the_first_commit hidden/one && # push to delete a hidden ref should fail test_must_fail git push testrepo :refs/hidden/two && - check_push_result $the_first_commit hidden/two && + check_push_result testrepo $the_first_commit hidden/two && # idempotent push to update a hidden ref should fail test_must_fail git push testrepo $the_first_commit:refs/hidden/three && - check_push_result $the_first_commit hidden/three + check_push_result testrepo $the_first_commit hidden/three ' done +test_expect_success 'fetch exact SHA1' ' + mk_test testrepo heads/master hidden/one && + git push testrepo master:refs/hidden/one && + ( + cd testrepo && + git config transfer.hiderefs refs/hidden + ) && + check_push_result testrepo $the_commit hidden/one && + + mk_child testrepo child && + ( + cd child && + + # make sure $the_commit does not exist here + git repack -a -d && + git prune && + test_must_fail git cat-file -t $the_commit && + + # fetching the hidden object should fail by default + test_must_fail git fetch -v ../testrepo $the_commit:refs/heads/copy && + test_must_fail git rev-parse --verify refs/heads/copy && + + # the server side can allow it to succeed + ( + cd ../testrepo && + git config uploadpack.allowtipsha1inwant true + ) && + + git fetch -v ../testrepo $the_commit:refs/heads/copy && + result=$(git rev-parse --verify refs/heads/copy) && + test "$the_commit" = "$result" + ) +' + +test_expect_success 'fetch follows tags by default' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + ( + cd src && + git pull ../testrepo master && + git tag -m "annotated" tag && + git for-each-ref >tmp1 && + ( + cat tmp1 + sed -n "s|refs/heads/master$|refs/remotes/origin/master|p" tmp1 + ) | + sort -k 3 >../expect + ) && + git init dst && + ( + cd dst && + git remote add origin ../src && + git config branch.master.remote origin && + git config branch.master.merge refs/heads/master && + git pull && + git for-each-ref >../actual + ) && + test_cmp expect actual +' + +test_expect_success 'push does not follow tags by default' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + git init --bare dst && + ( + cd src && + git pull ../testrepo master && + git tag -m "annotated" tag && + git checkout -b another && + git commit --allow-empty -m "future commit" && + git tag -m "future" future && + git checkout master && + git for-each-ref refs/heads/master >../expect && + git push ../dst master + ) && + ( + cd dst && + git for-each-ref >../actual + ) && + test_cmp expect actual +' + +test_expect_success 'push --follow-tag only pushes relevant tags' ' + mk_test testrepo heads/master && + rm -fr src dst && + git init src && + git init --bare dst && + ( + cd src && + git pull ../testrepo master && + git tag -m "annotated" tag && + git checkout -b another && + git commit --allow-empty -m "future commit" && + git tag -m "future" future && + git checkout master && + git for-each-ref refs/heads/master refs/tags/tag >../expect + git push --follow-tag ../dst master + ) && + ( + cd dst && + git for-each-ref >../actual + ) && + test_cmp expect actual +' + test_done diff --git a/t/t5517-push-mirror.sh b/t/t5517-push-mirror.sh index e2ad260508..12a5dfb17e 100755 --- a/t/t5517-push-mirror.sh +++ b/t/t5517-push-mirror.sh @@ -256,7 +256,7 @@ test_expect_success 'remote.foo.mirror=no has no effect' ' git branch keep master && git push --mirror up && git branch -D keep && - git push up + git push up : ) && ( cd mirror && diff --git a/t/t5519-push-alternates.sh b/t/t5519-push-alternates.sh index c00c9b071d..11fcd37700 100755 --- a/t/t5519-push-alternates.sh +++ b/t/t5519-push-alternates.sh @@ -40,7 +40,7 @@ test_expect_success 'alice works and pushes' ' cd alice-work && echo more >file && git commit -a -m second && - git push ../alice-pub + git push ../alice-pub : ) ' @@ -57,7 +57,7 @@ test_expect_success 'bob fetches from alice, works and pushes' ' git pull ../alice-pub master && echo more bob >file && git commit -a -m third && - git push ../bob-pub + git push ../bob-pub : ) && # Check that the second commit by Alice is not sent @@ -86,7 +86,7 @@ test_expect_success 'alice works and pushes again' ' cd alice-work && echo more alice >file && git commit -a -m fourth && - git push ../alice-pub + git push ../alice-pub : ) ' @@ -99,7 +99,7 @@ test_expect_success 'bob works and pushes' ' cd bob-work && echo yet more bob >file && git commit -a -m fifth && - git push ../bob-pub + git push ../bob-pub : ) ' @@ -115,7 +115,7 @@ test_expect_success 'alice works and pushes yet again' ' git commit -a -m sixth.2 && echo more and more alice >>file && git commit -a -m sixth.3 && - git push ../alice-pub + git push ../alice-pub : ) ' @@ -136,7 +136,7 @@ test_expect_success 'bob works and pushes again' ' git hash-object -t commit -w commit && echo even more bob >file && git commit -a -m seventh && - git push ../bob-pub + git push ../bob-pub : ) ' diff --git a/t/t5520-pull.sh b/t/t5520-pull.sh index 35304b41e9..6af6c63350 100755 --- a/t/t5520-pull.sh +++ b/t/t5520-pull.sh @@ -96,8 +96,7 @@ test_expect_success '--rebase' ' ' test_expect_success 'pull.rebase' ' git reset --hard before-rebase && - git config --bool pull.rebase true && - test_when_finished "git config --unset pull.rebase" && + test_config pull.rebase true && git pull . copy && test $(git rev-parse HEAD^) = $(git rev-parse copy) && test new = $(git show HEAD:file2) @@ -105,8 +104,7 @@ test_expect_success 'pull.rebase' ' test_expect_success 'branch.to-rebase.rebase' ' git reset --hard before-rebase && - git config --bool branch.to-rebase.rebase true && - test_when_finished "git config --unset branch.to-rebase.rebase" && + test_config branch.to-rebase.rebase true && git pull . copy && test $(git rev-parse HEAD^) = $(git rev-parse copy) && test new = $(git show HEAD:file2) @@ -114,10 +112,8 @@ test_expect_success 'branch.to-rebase.rebase' ' test_expect_success 'branch.to-rebase.rebase should override pull.rebase' ' git reset --hard before-rebase && - git config --bool pull.rebase true && - test_when_finished "git config --unset pull.rebase" && - git config --bool branch.to-rebase.rebase false && - test_when_finished "git config --unset branch.to-rebase.rebase" && + test_config pull.rebase true && + test_config branch.to-rebase.rebase false && git pull . copy && test $(git rev-parse HEAD^) != $(git rev-parse copy) && test new = $(git show HEAD:file2) @@ -171,9 +167,9 @@ test_expect_success 'pull --rebase dies early with dirty working directory' ' git update-ref refs/remotes/me/copy copy^ && COPY=$(git rev-parse --verify me/copy) && git rebase --onto $COPY copy && - git config branch.to-rebase.remote me && - git config branch.to-rebase.merge refs/heads/copy && - git config branch.to-rebase.rebase true && + test_config branch.to-rebase.remote me && + test_config branch.to-rebase.merge refs/heads/copy && + test_config branch.to-rebase.rebase true && echo dirty >> file && git add file && test_must_fail git pull && diff --git a/t/t5531-deep-submodule-push.sh b/t/t5531-deep-submodule-push.sh index 1947c28c64..8c16e045a0 100755 --- a/t/t5531-deep-submodule-push.sh +++ b/t/t5531-deep-submodule-push.sh @@ -16,6 +16,7 @@ test_expect_success setup ' ( cd gar/bage && git init && + git config push.default matching && >junk && git add junk && git commit -m "Initial junk" diff --git a/t/t5541-http-push.sh b/t/t5541-http-push.sh index 8a9dc85931..beb00be4b1 100755 --- a/t/t5541-http-push.sh +++ b/t/t5541-http-push.sh @@ -181,8 +181,7 @@ test_expect_success 'push (chunked)' ' git checkout master && test_commit commit path3 && HEAD=$(git rev-parse --verify HEAD) && - git config http.postbuffer 4 && - test_when_finished "git config --unset http.postbuffer" && + test_config http.postbuffer 4 && git push -v -v origin $BRANCH 2>err && grep "POST git-receive-pack (chunked)" err && (cd "$HTTPD_DOCUMENT_ROOT_PATH"/test_repo.git && diff --git a/t/t5550-http-fetch.sh b/t/t5550-http-fetch.sh index 80d20c876b..f7d0f146f0 100755 --- a/t/t5550-http-fetch.sh +++ b/t/t5550-http-fetch.sh @@ -13,6 +13,7 @@ LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5550'} start_httpd test_expect_success 'setup repository' ' + git config push.default matching && echo content1 >file && git add file && git commit -m one diff --git a/t/t5551-http-fetch.sh b/t/t5551-http-fetch.sh index 47eb76921d..b23efbbfd9 100755 --- a/t/t5551-http-fetch.sh +++ b/t/t5551-http-fetch.sh @@ -13,6 +13,7 @@ LIB_HTTPD_PORT=${LIB_HTTPD_PORT-'5551'} start_httpd test_expect_success 'setup repository' ' + git config push.default matching && echo content >file && git add file && git commit -m one @@ -162,6 +163,30 @@ test_expect_success 'invalid Content-Type rejected' ' grep "not valid:" actual ' +test_expect_success 'create namespaced refs' ' + test_commit namespaced && + git push public HEAD:refs/namespaces/ns/refs/heads/master && + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ + symbolic-ref refs/namespaces/ns/HEAD refs/namespaces/ns/refs/heads/master +' + +test_expect_success 'smart clone respects namespace' ' + git clone "$HTTPD_URL/smart_namespace/repo.git" ns-smart && + echo namespaced >expect && + git --git-dir=ns-smart/.git log -1 --format=%s >actual && + test_cmp expect actual +' + +test_expect_success 'dumb clone via http-backend respects namespace' ' + git --git-dir="$HTTPD_DOCUMENT_ROOT_PATH/repo.git" \ + config http.getanyfile true && + GIT_SMART_HTTP=0 git clone \ + "$HTTPD_URL/smart_namespace/repo.git" ns-dumb && + echo namespaced >expect && + git --git-dir=ns-dumb/.git log -1 --format=%s >actual && + test_cmp expect actual +' + test -n "$GIT_TEST_LONG" && test_set_prereq EXPENSIVE test_expect_success EXPENSIVE 'create 50,000 tags in the repo' ' diff --git a/t/t5570-git-daemon.sh b/t/t5570-git-daemon.sh index a3a4e47e1d..f01edffa3c 100755 --- a/t/t5570-git-daemon.sh +++ b/t/t5570-git-daemon.sh @@ -8,6 +8,7 @@ LIB_GIT_DAEMON_PORT=${LIB_GIT_DAEMON_PORT-5570} start_git_daemon test_expect_success 'setup repository' ' + git config push.default matching && echo content >file && git add file && git commit -m one diff --git a/t/t5700-clone-reference.sh b/t/t5700-clone-reference.sh index c47d450cc3..6537911a43 100755 --- a/t/t5700-clone-reference.sh +++ b/t/t5700-clone-reference.sh @@ -54,11 +54,14 @@ cd "$base_dir" rm -f "$U.D" -test_expect_success 'cloning with reference (no -l -s)' \ -'GIT_DEBUG_SEND_PACK=3 git clone --reference B "file://$(pwd)/A" D 3>"$U.D"' +test_expect_success 'cloning with reference (no -l -s)' ' + GIT_TRACE_PACKET=$U.D git clone --reference B "file://$(pwd)/A" D +' -test_expect_success 'fetched no objects' \ -'! grep "^want" "$U.D"' +test_expect_success 'fetched no objects' ' + test -s "$U.D" && + ! grep " want" "$U.D" +' cd "$base_dir" @@ -173,12 +176,26 @@ test_expect_success 'fetch with incomplete alternates' ' ( cd K && git remote add J "file://$base_dir/J" && - GIT_DEBUG_SEND_PACK=3 git fetch J 3>"$U.K" + GIT_TRACE_PACKET=$U.K git fetch J ) && master_object=$(cd A && git for-each-ref --format="%(objectname)" refs/heads/master) && - ! grep "^want $master_object" "$U.K" && + test -s "$U.K" && + ! grep " want $master_object" "$U.K" && tag_object=$(cd A && git for-each-ref --format="%(objectname)" refs/tags/HEAD) && - ! grep "^want $tag_object" "$U.K" + ! grep " want $tag_object" "$U.K" +' + +test_expect_success 'clone using repo with gitfile as a reference' ' + git clone --separate-git-dir=L A M && + git clone --reference=M A N && + echo "$base_dir/L/objects" >expected && + test_cmp expected "$base_dir/N/.git/objects/info/alternates" +' + +test_expect_success 'clone using repo pointed at by gitfile as reference' ' + git clone --reference=M/.git A O && + echo "$base_dir/L/objects" >expected && + test_cmp expected "$base_dir/O/.git/objects/info/alternates" ' test_done diff --git a/t/t5710-info-alternate.sh b/t/t5710-info-alternate.sh index aa045295de..8956c21617 100755 --- a/t/t5710-info-alternate.sh +++ b/t/t5710-info-alternate.sh @@ -58,13 +58,7 @@ test_expect_success 'creating too deep nesting' \ git clone -l -s D E && git clone -l -s E F && git clone -l -s F G && -git clone -l -s G H' - -test_expect_success 'invalidity of deepest repository' \ -'cd H && { - test_valid_repo - test $? -ne 0 -}' +test_must_fail git clone --bare -l -s G H' cd "$base_dir" diff --git a/t/t5801-remote-helpers.sh b/t/t5801-remote-helpers.sh index f387027c05..4899af3f7a 100755 --- a/t/t5801-remote-helpers.sh +++ b/t/t5801-remote-helpers.sh @@ -6,11 +6,7 @@ test_description='Test remote-helper import and export commands' . ./test-lib.sh - -if ! type "${BASH-bash}" >/dev/null 2>&1; then - skip_all='skipping remote-testgit tests, bash not available' - test_done -fi +. "$TEST_DIRECTORY"/lib-gpg.sh compare_refs() { git --git-dir="$1/.git" rev-parse --verify $2 >expect && @@ -100,39 +96,28 @@ test_expect_failure 'push new branch with old:new refspec' ' test_expect_success 'cloning without refspec' ' GIT_REMOTE_TESTGIT_REFSPEC="" \ - git clone "testgit::${PWD}/server" local2 && + git clone "testgit::${PWD}/server" local2 2>error && + grep "This remote helper should implement refspec capability" error && compare_refs local2 HEAD server HEAD ' test_expect_success 'pulling without refspecs' ' (cd local2 && git reset --hard && - GIT_REMOTE_TESTGIT_REFSPEC="" git pull) && + GIT_REMOTE_TESTGIT_REFSPEC="" git pull 2>../error) && + grep "This remote helper should implement refspec capability" error && compare_refs local2 HEAD server HEAD ' -test_expect_failure 'pushing without refspecs' ' +test_expect_success 'pushing without refspecs' ' test_when_finished "(cd local2 && git reset --hard origin)" && (cd local2 && echo content >>file && git commit -a -m ten && - GIT_REMOTE_TESTGIT_REFSPEC="" git push) && - compare_refs local2 HEAD server HEAD -' - -test_expect_success 'pulling with straight refspec' ' - (cd local2 && - GIT_REMOTE_TESTGIT_REFSPEC="*:*" git pull) && - compare_refs local2 HEAD server HEAD -' - -test_expect_failure 'pushing with straight refspec' ' - test_when_finished "(cd local2 && git reset --hard origin)" && - (cd local2 && - echo content >>file && - git commit -a -m eleven && - GIT_REMOTE_TESTGIT_REFSPEC="*:*" git push) && - compare_refs local2 HEAD server HEAD + GIT_REMOTE_TESTGIT_REFSPEC="" && + export GIT_REMOTE_TESTGIT_REFSPEC && + test_must_fail git push 2>../error) && + grep "remote-helper doesn.t support push; refspec needed" error ' test_expect_success 'pulling without marks' ' @@ -166,4 +151,83 @@ test_expect_success 'push ref with existing object' ' compare_refs local dup server dup ' +test_expect_success GPG 'push signed tag' ' + (cd local && + git checkout master && + git tag -s -m signed-tag signed-tag && + git push origin signed-tag + ) && + compare_refs local signed-tag^{} server signed-tag^{} && + test_must_fail compare_refs local signed-tag server signed-tag +' + +test_expect_success GPG 'push signed tag with signed-tags capability' ' + (cd local && + git checkout master && + git tag -s -m signed-tag signed-tag-2 && + GIT_REMOTE_TESTGIT_SIGNED_TAGS=1 git push origin signed-tag-2 + ) && + compare_refs local signed-tag-2 server signed-tag-2 +' + +test_expect_success 'push update refs' ' + (cd local && + git checkout -b update master && + echo update >>file && + git commit -a -m update && + git push origin update && + git rev-parse --verify remotes/origin/update >expect && + git rev-parse --verify testgit/origin/heads/update >actual && + test_cmp expect actual + ) +' + +test_expect_success 'push update refs failure' ' + (cd local && + git checkout update && + echo "update fail" >>file && + git commit -a -m "update fail" && + git rev-parse --verify testgit/origin/heads/update >expect && + GIT_REMOTE_TESTGIT_PUSH_ERROR="non-fast forward" && + export GIT_REMOTE_TESTGIT_PUSH_ERROR && + test_expect_code 1 git push origin update && + git rev-parse --verify testgit/origin/heads/update >actual && + test_cmp expect actual + ) +' + +test_expect_success 'proper failure checks for fetching' ' + (GIT_REMOTE_TESTGIT_FAILURE=1 && + export GIT_REMOTE_TESTGIT_FAILURE && + cd local && + test_must_fail git fetch 2> error && + cat error && + grep -q "Error while running fast-import" error + ) +' + +test_expect_success 'proper failure checks for pushing' ' + (GIT_REMOTE_TESTGIT_FAILURE=1 && + export GIT_REMOTE_TESTGIT_FAILURE && + cd local && + test_must_fail git push --all 2> error && + cat error && + grep -q "Reading from helper .git-remote-testgit. failed" error + ) +' + +test_expect_success 'push messages' ' + (cd local && + git checkout -b new_branch master && + echo new >>file && + git commit -a -m new && + git push origin new_branch && + git fetch origin && + echo new >>file && + git commit -a -m new && + git push origin new_branch 2> msg && + ! grep "\[new branch\]" msg + ) +' + test_done diff --git a/t/t6006-rev-list-format.sh b/t/t6006-rev-list-format.sh index 3fc3b74c8e..0393c9fd0b 100755 --- a/t/t6006-rev-list-format.sh +++ b/t/t6006-rev-list-format.sh @@ -184,7 +184,7 @@ Test printing of complex bodies This commit message is much longer than the others, and it will be encoded in iso8859-1. We should therefore -include an iso8859 character: ¡bueno! +include an iso8859 character: ¡bueno! EOF test_expect_success 'setup complex body' ' git config i18n.commitencoding iso8859-1 && @@ -192,14 +192,14 @@ git config i18n.commitencoding iso8859-1 && ' test_format complex-encoding %e <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 iso8859-1 commit 131a310eb913d107dd3c09a65d1651175898735d commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 EOF test_format complex-subject %s <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 Test printing of complex bodies commit 131a310eb913d107dd3c09a65d1651175898735d changed foo @@ -208,17 +208,17 @@ added foo EOF test_format complex-body %b <<'EOF' -commit f58db70b055c5718631e5c61528b28b12090cdea +commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 This commit message is much longer than the others, and it will be encoded in iso8859-1. We should therefore -include an iso8859 character: ¡bueno! +include an iso8859 character: ¡bueno! commit 131a310eb913d107dd3c09a65d1651175898735d commit 86c75cfd708a0e5868dc876ed5b8bb66c80b4873 EOF test_expect_success '%x00 shows NUL' ' - echo >expect commit f58db70b055c5718631e5c61528b28b12090cdea && + echo >expect commit 1ed88da4a5b5ed8c449114ac131efc62178734c3 && echo >>expect fooQbar && git rev-list -1 --format=foo%x00bar HEAD >actual.nul && nul_to_q <actual.nul >actual && diff --git a/t/t6012-rev-list-simplify.sh b/t/t6012-rev-list-simplify.sh index 839ad97b79..dd6dc844e7 100755 --- a/t/t6012-rev-list-simplify.sh +++ b/t/t6012-rev-list-simplify.sh @@ -56,19 +56,37 @@ test_expect_success setup ' echo "Final change" >file && test_tick && git commit -a -m "Final change" && - note I + note I && + + git symbolic-ref HEAD refs/heads/unrelated && + git rm -f "*" && + echo "Unrelated branch" >side && + git add side && + test_tick && git commit -m "Side root" && + note J && + + git checkout master && + test_tick && git merge -m "Coolest" unrelated && + note K && + + echo "Immaterial" >elif && + git add elif && + test_tick && git commit -m "Last" && + note L ' FMT='tformat:%P %H | %s' -check_result () { +check_outcome () { + outcome=$1 + shift for c in $1 do echo "$c" done >expect && shift && param="$*" && - test_expect_success "log $param" ' + test_expect_$outcome "log $param" ' git log --pretty="$FMT" --parents $param | unnote >actual && sed -e "s/^.* \([^ ]*\) .*/\1/" >check <actual && @@ -79,11 +97,15 @@ check_result () { ' } -check_result 'I H G F E D C B A' --full-history -check_result 'I H E C B A' --full-history -- file -check_result 'I H E C B A' --full-history --topo-order -- file -check_result 'I H E C B A' --full-history --date-order -- file -check_result 'I E C B A' --simplify-merges -- file +check_result () { + check_outcome success "$@" +} + +check_result 'L K J I H G F E D C B A' --full-history +check_result 'K I H E C B A' --full-history -- file +check_result 'K I H E C B A' --full-history --topo-order -- file +check_result 'K I H E C B A' --full-history --date-order -- file +check_outcome failure 'I E C B A' --simplify-merges -- file check_result 'I B A' -- file check_result 'I B A' --topo-order -- file check_result 'H' --first-parent -- another-file diff --git a/t/t6030-bisect-porcelain.sh b/t/t6030-bisect-porcelain.sh index 8bf99e10a3..064f5cefeb 100755 --- a/t/t6030-bisect-porcelain.sh +++ b/t/t6030-bisect-porcelain.sh @@ -164,7 +164,7 @@ test_expect_success 'bisect start: existing ".git/BISECT_START" not modified if cp .git/BISECT_START saved && test_must_fail git bisect start $HASH4 foo -- && git branch > branch.output && - test_i18ngrep "* (no branch)" branch.output > /dev/null && + test_i18ngrep "* (no branch, bisect started on other)" branch.output > /dev/null && test_cmp saved .git/BISECT_START ' test_expect_success 'bisect start: no ".git/BISECT_START" if mistaken rev' ' @@ -741,4 +741,42 @@ test_expect_success 'bisect: demonstrate identification of damage boundary' " git bisect reset " +cat > expected.bisect-log <<EOF +# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. +# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>. +git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f' +# good: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. +git bisect good 3de952f2416b6084f557ec417709eac740c6818c +# first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. +EOF + +test_expect_success 'bisect log: successfull result' ' + git bisect reset && + git bisect start $HASH4 $HASH2 && + git bisect good && + git bisect log >bisect-log.txt && + test_cmp expected.bisect-log bisect-log.txt && + git bisect reset +' + +cat > expected.bisect-skip-log <<EOF +# bad: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. +# good: [7b7f204a749c3125d5224ed61ea2ae1187ad046f] Add <2: A new day for git> into <hello>. +git bisect start '32a594a3fdac2d57cf6d02987e30eec68511498c' '7b7f204a749c3125d5224ed61ea2ae1187ad046f' +# skip: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. +git bisect skip 3de952f2416b6084f557ec417709eac740c6818c +# only skipped commits left to test +# possible first bad commit: [32a594a3fdac2d57cf6d02987e30eec68511498c] Add <4: Ciao for now> into <hello>. +# possible first bad commit: [3de952f2416b6084f557ec417709eac740c6818c] Add <3: Another new day for git> into <hello>. +EOF + +test_expect_success 'bisect log: only skip commits left' ' + git bisect reset && + git bisect start $HASH4 $HASH2 && + test_must_fail git bisect skip && + git bisect log >bisect-skip-log.txt && + test_cmp expected.bisect-skip-log bisect-skip-log.txt && + git bisect reset +' + test_done diff --git a/t/t7061-wtstatus-ignore.sh b/t/t7061-wtstatus-ignore.sh index 0da1214bcc..460789b4d8 100755 --- a/t/t7061-wtstatus-ignore.sh +++ b/t/t7061-wtstatus-ignore.sh @@ -32,6 +32,25 @@ test_expect_success 'status untracked directory with --ignored -u' ' git status --porcelain --ignored -u >actual && test_cmp expected actual ' +cat >expected <<\EOF +?? untracked/uncommitted +!! untracked/ignored +EOF + +test_expect_success 'status prefixed untracked directory with --ignored' ' + git status --porcelain --ignored untracked/ >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? untracked/uncommitted +!! untracked/ignored +EOF + +test_expect_success 'status prefixed untracked sub-directory with --ignored -u' ' + git status --porcelain --ignored -u untracked/ >actual && + test_cmp expected actual +' cat >expected <<\EOF ?? .gitignore @@ -64,13 +83,35 @@ cat >expected <<\EOF ?? .gitignore ?? actual ?? expected -!! untracked-ignored/ EOF -test_expect_success 'status untracked directory with ignored files with --ignore' ' +test_expect_success 'status empty untracked directory with --ignore' ' rm -rf ignored && mkdir untracked-ignored && mkdir untracked-ignored/test && + git status --porcelain --ignored >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +EOF + +test_expect_success 'status empty untracked directory with --ignore -u' ' + git status --porcelain --ignored -u >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! untracked-ignored/ +EOF + +test_expect_success 'status untracked directory with ignored files with --ignore' ' : >untracked-ignored/ignored && : >untracked-ignored/test/ignored && git status --porcelain --ignored >actual && @@ -122,10 +163,34 @@ cat >expected <<\EOF ?? .gitignore ?? actual ?? expected -!! tracked/ +EOF + +test_expect_success 'status ignored tracked directory and ignored file with --ignore' ' + echo "committed" >>.gitignore && + git status --porcelain --ignored >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +EOF + +test_expect_success 'status ignored tracked directory and ignored file with --ignore -u' ' + git status --porcelain --ignored -u >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! tracked/uncommitted EOF test_expect_success 'status ignored tracked directory and uncommitted file with --ignore' ' + echo "tracked" >.gitignore && : >tracked/uncommitted && git status --porcelain --ignored >actual && test_cmp expected actual @@ -143,4 +208,58 @@ test_expect_success 'status ignored tracked directory and uncommitted file with test_cmp expected actual ' +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! tracked/ignored/ +EOF + +test_expect_success 'status ignored tracked directory with uncommitted file in untracked subdir with --ignore' ' + rm -rf tracked/uncommitted && + mkdir tracked/ignored && + : >tracked/ignored/uncommitted && + git status --porcelain --ignored >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! tracked/ignored/uncommitted +EOF + +test_expect_success 'status ignored tracked directory with uncommitted file in untracked subdir with --ignore -u' ' + git status --porcelain --ignored -u >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! tracked/ignored/uncommitted +EOF + +test_expect_success 'status ignored tracked directory with uncommitted file in tracked subdir with --ignore' ' + : >tracked/ignored/committed && + git add -f tracked/ignored/committed && + git commit -m. && + git status --porcelain --ignored >actual && + test_cmp expected actual +' + +cat >expected <<\EOF +?? .gitignore +?? actual +?? expected +!! tracked/ignored/uncommitted +EOF + +test_expect_success 'status ignored tracked directory with uncommitted file in tracked subdir with --ignore -u' ' + git status --porcelain --ignored -u >actual && + test_cmp expected actual +' + test_done diff --git a/t/t7201-co.sh b/t/t7201-co.sh index be9672e5a0..0c9ec0ad44 100755 --- a/t/t7201-co.sh +++ b/t/t7201-co.sh @@ -431,6 +431,7 @@ test_expect_success 'detach a symbolic link HEAD' ' test_expect_success \ 'checkout with --track fakes a sensible -b <name>' ' + git config remote.origin.fetch "+refs/heads/*:refs/remotes/origin/*" && git update-ref refs/remotes/origin/koala/bear renamer && git checkout --track origin/koala/bear && diff --git a/t/t7300-clean.sh b/t/t7300-clean.sh index ccfb54de7a..710be90489 100755 --- a/t/t7300-clean.sh +++ b/t/t7300-clean.sh @@ -298,6 +298,23 @@ test_expect_success 'git clean -d -x' ' ' +test_expect_success 'git clean -d -x with ignored tracked directory' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git clean -d -x -e src && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test ! -f a.out && + test -f src/part3.c && + test ! -d docs && + test ! -f obj.o && + test ! -d build + +' + test_expect_success 'git clean -X' ' mkdir -p build docs && @@ -332,6 +349,23 @@ test_expect_success 'git clean -d -X' ' ' +test_expect_success 'git clean -d -X with ignored tracked directory' ' + + mkdir -p build docs && + touch a.out src/part3.c docs/manual.txt obj.o build/lib.so && + git clean -d -X -e src && + test -f Makefile && + test -f README && + test -f src/part1.c && + test -f src/part2.c && + test -f a.out && + test ! -f src/part3.c && + test -f docs/manual.txt && + test ! -f obj.o && + test ! -d build + +' + test_expect_success 'clean.requireForce defaults to true' ' git config --unset clean.requireForce && diff --git a/t/t7400-submodule-basic.sh b/t/t7400-submodule-basic.sh index 2683cba7e3..ff265353a3 100755 --- a/t/t7400-submodule-basic.sh +++ b/t/t7400-submodule-basic.sh @@ -757,4 +757,115 @@ test_expect_success 'submodule add with an existing name fails unless forced' ' ) ' +test_expect_success 'set up a second submodule' ' + git submodule add ./init2 example2 && + git commit -m "submodule example2 added" +' + +test_expect_success 'submodule deinit should remove the whole submodule section from .git/config' ' + git config submodule.example.foo bar && + git config submodule.example2.frotz nitfol && + git submodule deinit init && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test -n "$(git config --get-regexp "submodule\.example2\.")" && + test -f example2/.git && + rmdir init +' + +test_expect_success 'submodule deinit . 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 . >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 && + git submodule deinit init example2 >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 +' + +test_expect_success 'submodule deinit fails when the submodule contains modifications unless forced' ' + git submodule update --init && + echo X >>init/s && + test_must_fail git submodule deinit init && + test -n "$(git config --get-regexp "submodule\.example\.")" && + test -f example2/.git && + git submodule deinit -f init >actual && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test_i18ngrep "Cleared directory .init" actual && + rmdir init +' + +test_expect_success 'submodule deinit fails when the submodule contains untracked files unless forced' ' + git submodule update --init && + echo X >>init/untracked && + test_must_fail git submodule deinit init && + test -n "$(git config --get-regexp "submodule\.example\.")" && + test -f example2/.git && + git submodule deinit -f init >actual && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test_i18ngrep "Cleared directory .init" actual && + rmdir init +' + +test_expect_success 'submodule deinit fails when the submodule HEAD does not match unless forced' ' + git submodule update --init && + ( + cd init && + git checkout HEAD^ + ) && + test_must_fail git submodule deinit init && + test -n "$(git config --get-regexp "submodule\.example\.")" && + test -f example2/.git && + git submodule deinit -f init >actual && + test -z "$(git config --get-regexp "submodule\.example\.")" && + test_i18ngrep "Cleared directory .init" actual && + rmdir init +' + +test_expect_success 'submodule deinit is silent when used on an uninitialized submodule' ' + git submodule update --init && + git submodule deinit init >actual && + test_i18ngrep "Submodule .example. (.*) unregistered for path .init" actual && + test_i18ngrep "Cleared directory .init" actual && + git submodule deinit init >actual && + test_i18ngrep ! "Submodule .example. (.*) unregistered for path .init" actual && + test_i18ngrep "Cleared directory .init" actual && + git submodule deinit . >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 && + git submodule deinit . >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 +' + +test_expect_success 'submodule deinit fails when submodule has a .git directory even when forced' ' + git submodule update --init && + ( + cd init && + rm .git && + cp -R ../.git/modules/example .git && + GIT_WORK_TREE=. git config --unset core.worktree + ) && + test_must_fail git submodule deinit init && + test_must_fail git submodule deinit -f init && + test -d init/.git && + test -n "$(git config --get-regexp "submodule\.example\.")" +' + test_done diff --git a/t/t7406-submodule-update.sh b/t/t7406-submodule-update.sh index 1a3d20bdc3..a4ffea0dbe 100755 --- a/t/t7406-submodule-update.sh +++ b/t/t7406-submodule-update.sh @@ -596,14 +596,14 @@ test_expect_success 'submodule add places git-dir in superprojects git-dir recur git log > ../../../expected ) && git commit -m "added subsubmodule" && - git push + git push origin : ) && (cd .git/modules/deeper/submodule/modules/subsubmodule && git log > ../../../../../actual ) && git add deeper/submodule && git commit -m "update submodule" && - git push && + git push origin : && test_cmp actual expected ) ' @@ -665,8 +665,10 @@ test_expect_success 'submodule add properly re-creates deeper level submodules' test_expect_success 'submodule update properly revives a moved submodule' ' (cd super && + H=$(git rev-parse --short HEAD) && git commit -am "pre move" && - git status >expect&& + H2=$(git rev-parse --short HEAD) && + git status | sed "s/$H/XXX/" >expect && H=$(cd submodule2; git rev-parse HEAD) && git rm --cached submodule2 && rm -rf submodule2 && @@ -675,7 +677,7 @@ test_expect_success 'submodule update properly revives a moved submodule' ' git config -f .gitmodules submodule.submodule2.path "moved/sub module" git commit -am "post move" && git submodule update && - git status >actual && + git status | sed "s/$H2/XXX/" >actual && test_cmp expect actual ) ' diff --git a/t/t7500-commit.sh b/t/t7500-commit.sh index 1c908f4d39..436b7b606e 100755 --- a/t/t7500-commit.sh +++ b/t/t7500-commit.sh @@ -36,8 +36,7 @@ test_expect_success 'nonexistent template file should return error' ' ' test_expect_success 'nonexistent template file in config should return error' ' - git config commit.template "$PWD"/notexist && - test_when_finished "git config --unset commit.template" && + test_config commit.template "$PWD"/notexist && ( GIT_EDITOR="echo hello >\"\$1\"" && export GIT_EDITOR && @@ -93,14 +92,13 @@ test_expect_success '-t option should be short for --template' ' test_expect_success 'config-specified template should commit' ' echo "new template" > "$TEMPLATE" && - git config commit.template "$TEMPLATE" && + test_config commit.template "$TEMPLATE" && echo "more content" >> foo && git add foo && ( test_set_editor "$TEST_DIRECTORY"/t7500/add-content && git commit ) && - git config --unset commit.template && commit_msg_is "new templatecommit message" ' diff --git a/t/t7502-commit.sh b/t/t7502-commit.sh index 292bc082b2..a4938b1e45 100755 --- a/t/t7502-commit.sh +++ b/t/t7502-commit.sh @@ -171,10 +171,9 @@ test_expect_success 'verbose' ' test_expect_success 'verbose respects diff config' ' - git config color.diff always && + test_config color.diff always && git status -v >actual && - grep "\[1mdiff --git" actual && - git config --unset color.diff + grep "\[1mdiff --git" actual ' mesg_with_comment_and_newlines=' @@ -263,32 +262,40 @@ test_expect_success 'cleanup commit message (fail on invalid cleanup mode config test_expect_success 'cleanup commit message (no config and no option uses default)' ' echo content >>file && git add file && - test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && - git commit --no-status && + ( + test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && + git commit --no-status + ) && commit_msg_is "commit message" ' test_expect_success 'cleanup commit message (option overrides default)' ' echo content >>file && git add file && - test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && - git commit --cleanup=whitespace --no-status && + ( + test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && + git commit --cleanup=whitespace --no-status + ) && commit_msg_is "commit message # comment" ' test_expect_success 'cleanup commit message (config overrides default)' ' echo content >>file && git add file && - test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && - git -c commit.cleanup=whitespace commit --no-status && + ( + test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && + git -c commit.cleanup=whitespace commit --no-status + ) && commit_msg_is "commit message # comment" ' test_expect_success 'cleanup commit message (option overrides config)' ' echo content >>file && git add file && - test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && - git -c commit.cleanup=whitespace commit --cleanup=default && + ( + test_set_editor "$TEST_DIRECTORY"/t7500/add-content-and-comment && + git -c commit.cleanup=whitespace commit --cleanup=default + ) && commit_msg_is "commit message" ' @@ -417,6 +424,18 @@ test_expect_success 'A single-liner subject with a token plus colon is not a foo ' +test_expect_success 'commit -s places sob on third line after two empty lines' ' + git commit -s --allow-empty --allow-empty-message && + cat <<-EOF >expect && + + + Signed-off-by: $GIT_COMMITTER_NAME <$GIT_COMMITTER_EMAIL> + + EOF + sed -e "/^#/d" -e "s/^:.*//" .git/COMMIT_EDITMSG >actual && + test_cmp expect actual +' + write_script .git/FAKE_EDITOR <<\EOF mv "$1" "$1.orig" ( @@ -427,16 +446,6 @@ EOF echo '## Custom template' >template -clear_config () { - ( - git config --unset-all "$1" - case $? in - 0|5) exit 0 ;; - *) exit 1 ;; - esac - ) -} - try_commit () { git reset --hard && echo >>negative && @@ -452,67 +461,57 @@ try_commit () { try_commit_status_combo () { test_expect_success 'commit' ' - clear_config commit.status && try_commit "" && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit' ' - clear_config commit.status && try_commit "" && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --status' ' - clear_config commit.status && try_commit --status && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --no-status' ' - clear_config commit.status && try_commit --no-status && test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit with commit.status = yes' ' - clear_config commit.status && - git config commit.status yes && + test_config commit.status yes && try_commit "" && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit with commit.status = no' ' - clear_config commit.status && - git config commit.status no && + test_config commit.status no && try_commit "" && test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --status with commit.status = yes' ' - clear_config commit.status && - git config commit.status yes && + test_config commit.status yes && try_commit --status && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --no-status with commit.status = yes' ' - clear_config commit.status && - git config commit.status yes && + test_config commit.status yes && try_commit --no-status && test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --status with commit.status = no' ' - clear_config commit.status && - git config commit.status no && + test_config commit.status no && try_commit --status && test_i18ngrep "^# Changes to be committed:" .git/COMMIT_EDITMSG ' test_expect_success 'commit --no-status with commit.status = no' ' - clear_config commit.status && - git config commit.status no && + test_config commit.status no && try_commit --no-status && test_i18ngrep ! "^# Changes to be committed:" .git/COMMIT_EDITMSG ' @@ -526,8 +525,7 @@ use_template="-t template" try_commit_status_combo test_expect_success 'commit --status with custom comment character' ' - test_when_finished "git config --unset core.commentchar" && - git config core.commentchar ";" && + test_config core.commentchar ";" && try_commit --status && test_i18ngrep "^; Changes to be committed:" .git/COMMIT_EDITMSG ' diff --git a/t/t7508-status.sh b/t/t7508-status.sh index aecb4d1e5f..e2ffdacc26 100755 --- a/t/t7508-status.sh +++ b/t/t7508-status.sh @@ -131,8 +131,7 @@ cat >expect <<\EOF EOF test_expect_success 'status (advice.statusHints false)' ' - test_when_finished "git config --unset advice.statusHints" && - git config advice.statusHints false && + test_config advice.statusHints false && git status >output && test_i18ncmp expect output @@ -332,8 +331,7 @@ test_expect_success 'status -uno' ' ' test_expect_success 'status (status.showUntrackedFiles no)' ' - git config status.showuntrackedfiles no - test_when_finished "git config --unset status.showuntrackedfiles" && + test_config status.showuntrackedfiles no && git status >output && test_i18ncmp expect output ' @@ -348,12 +346,11 @@ cat >expect <<EOF # # Untracked files not listed EOF -git config advice.statusHints false test_expect_success 'status -uno (advice.statusHints false)' ' + test_config advice.statusHints false && git status -uno >output && test_i18ncmp expect output ' -git config --unset advice.statusHints cat >expect << EOF M dir1/modified @@ -400,8 +397,7 @@ test_expect_success 'status -unormal' ' ' test_expect_success 'status (status.showUntrackedFiles normal)' ' - git config status.showuntrackedfiles normal - test_when_finished "git config --unset status.showuntrackedfiles" && + test_config status.showuntrackedfiles normal git status >output && test_i18ncmp expect output ' @@ -459,8 +455,7 @@ test_expect_success 'status -uall' ' ' test_expect_success 'status (status.showUntrackedFiles all)' ' - git config status.showuntrackedfiles all - test_when_finished "git config --unset status.showuntrackedfiles" && + test_config status.showuntrackedfiles all git status >output && test_i18ncmp expect output ' @@ -485,10 +480,9 @@ test_expect_success 'status -s -uall' ' test_cmp expect output ' test_expect_success 'status -s (status.showUntrackedFiles all)' ' - git config status.showuntrackedfiles all + test_config status.showuntrackedfiles all && git status -s >output && rm -rf dir3 && - git config --unset status.showuntrackedfiles && test_cmp expect output ' @@ -588,15 +582,13 @@ cat >expect <<\EOF EOF test_expect_success 'status with color.ui' ' - git config color.ui always && - test_when_finished "git config --unset color.ui" && + test_config color.ui always && git status | test_decode_color >output && test_i18ncmp expect output ' test_expect_success 'status with color.status' ' - git config color.status always && - test_when_finished "git config --unset color.status" && + test_config color.status always && git status | test_decode_color >output && test_i18ncmp expect output ' @@ -720,8 +712,7 @@ EOF test_expect_success 'status without relative paths' ' - git config status.relativePaths false && - test_when_finished "git config --unset status.relativePaths" && + test_config status.relativePaths false && (cd dir1 && git status) >output && test_i18ncmp expect output @@ -740,8 +731,7 @@ EOF test_expect_success 'status -s without relative paths' ' - git config status.relativePaths false && - test_when_finished "git config --unset status.relativePaths" && + test_config status.relativePaths false && (cd dir1 && git status -s) >output && test_cmp expect output @@ -1038,15 +1028,14 @@ test_expect_success '--ignore-submodules=untracked suppresses submodules with un ' test_expect_success '.gitmodules ignore=untracked suppresses submodules with untracked content' ' - git config diff.ignoreSubmodules dirty && + test_config diff.ignoreSubmodules dirty && git status >output && test_i18ncmp expect output && git config --add -f .gitmodules submodule.subname.ignore untracked && git config --add -f .gitmodules submodule.subname.path sm && git status >output && test_i18ncmp expect output && - git config -f .gitmodules --remove-section submodule.subname && - git config --unset diff.ignoreSubmodules + git config -f .gitmodules --remove-section submodule.subname ' test_expect_success '.git/config ignore=untracked suppresses submodules with untracked content' ' @@ -1066,15 +1055,14 @@ test_expect_success '--ignore-submodules=dirty suppresses submodules with untrac ' test_expect_success '.gitmodules ignore=dirty suppresses submodules with untracked content' ' - git config diff.ignoreSubmodules dirty && + test_config diff.ignoreSubmodules dirty && git status >output && ! test -s actual && git config --add -f .gitmodules submodule.subname.ignore dirty && git config --add -f .gitmodules submodule.subname.path sm && git status >output && test_i18ncmp expect output && - git config -f .gitmodules --remove-section submodule.subname && - git config --unset diff.ignoreSubmodules + git config -f .gitmodules --remove-section submodule.subname ' test_expect_success '.git/config ignore=dirty suppresses submodules with untracked content' ' @@ -1291,15 +1279,13 @@ cat > expect << EOF EOF test_expect_success "status (core.commentchar with submodule summary)" ' - test_when_finished "git config --unset core.commentchar" && - git config core.commentchar ";" && + test_config core.commentchar ";" && git status >output && test_i18ncmp expect output ' test_expect_success "status (core.commentchar with two chars with submodule summary)" ' - test_when_finished "git config --unset core.commentchar" && - git config core.commentchar ";;" && + test_config core.commentchar ";;" && git status >output && test_i18ncmp expect output ' diff --git a/t/t7512-status-help.sh b/t/t7512-status-help.sh index 9d4610629d..bf08d4e098 100755 --- a/t/t7512-status-help.sh +++ b/t/t7512-status-help.sh @@ -77,7 +77,7 @@ test_expect_success 'status when rebase in progress before resolving conflicts' ONTO=$(git rev-parse --short HEAD^^) && test_must_fail git rebase HEAD^ --onto HEAD^^ && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $ONTO # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''. # (fix conflicts and then run "git rebase --continue") # (use "git rebase --skip" to skip this patch) @@ -104,7 +104,7 @@ test_expect_success 'status when rebase in progress before rebase --continue' ' echo three >main.txt && git add main.txt && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $ONTO # You are currently rebasing branch '\''rebase_conflicts'\'' on '\''$ONTO'\''. # (all conflicts fixed: run "git rebase --continue") # @@ -136,7 +136,7 @@ test_expect_success 'status during rebase -i when conflicts unresolved' ' ONTO=$(git rev-parse --short rebase_i_conflicts) && test_must_fail git rebase -i rebase_i_conflicts && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $ONTO # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''. # (fix conflicts and then run "git rebase --continue") # (use "git rebase --skip" to skip this patch) @@ -162,7 +162,7 @@ test_expect_success 'status during rebase -i after resolving conflicts' ' test_must_fail git rebase -i rebase_i_conflicts && git add main.txt && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $ONTO # You are currently rebasing branch '\''rebase_i_conflicts_second'\'' on '\''$ONTO'\''. # (all conflicts fixed: run "git rebase --continue") # @@ -188,9 +188,10 @@ test_expect_success 'status when rebasing -i in edit mode' ' export FAKE_LINES && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD~2) && + TGT=$(git rev-parse --short two_rebase_i) && git rebase -i HEAD~2 && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $TGT # You are currently editing a commit while rebasing branch '\''rebase_i_edit'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -215,8 +216,9 @@ test_expect_success 'status when splitting a commit' ' ONTO=$(git rev-parse --short HEAD~3) && git rebase -i HEAD~3 && git reset HEAD^ && + TGT=$(git rev-parse --short HEAD) && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $TGT # You are currently splitting a commit while rebasing branch '\''split_commit'\'' on '\''$ONTO'\''. # (Once your working directory is clean, run "git rebase --continue") # @@ -244,10 +246,11 @@ test_expect_success 'status after editing the last commit with --amend during a export FAKE_LINES && test_when_finished "git rebase --abort" && ONTO=$(git rev-parse --short HEAD~3) && + TGT=$(git rev-parse --short three_amend) && git rebase -i HEAD~3 && git commit --amend -m "foo" && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $TGT # You are currently editing a commit while rebasing branch '\''amend_last'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -277,7 +280,7 @@ test_expect_success 'status: (continue first edit) second edit' ' git rebase -i HEAD~3 && git rebase --continue && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -299,7 +302,7 @@ test_expect_success 'status: (continue first edit) second edit and split' ' git rebase --continue && git reset HEAD^ && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (Once your working directory is clean, run "git rebase --continue") # @@ -326,7 +329,7 @@ test_expect_success 'status: (continue first edit) second edit and amend' ' git rebase --continue && git commit --amend -m "foo" && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -348,7 +351,7 @@ test_expect_success 'status: (amend first edit) second edit' ' git commit --amend -m "a" && git rebase --continue && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -371,7 +374,7 @@ test_expect_success 'status: (amend first edit) second edit and split' ' git rebase --continue && git reset HEAD^ && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (Once your working directory is clean, run "git rebase --continue") # @@ -399,7 +402,7 @@ test_expect_success 'status: (amend first edit) second edit and amend' ' git rebase --continue && git commit --amend -m "d" && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -423,7 +426,7 @@ test_expect_success 'status: (split first edit) second edit' ' git commit -m "e" && git rebase --continue && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -448,7 +451,7 @@ test_expect_success 'status: (split first edit) second edit and split' ' git rebase --continue && git reset HEAD^ && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently splitting a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (Once your working directory is clean, run "git rebase --continue") # @@ -478,7 +481,7 @@ test_expect_success 'status: (split first edit) second edit and amend' ' git rebase --continue && git commit --amend -m "h" && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached from $ONTO # You are currently editing a commit while rebasing branch '\''several_edits'\'' on '\''$ONTO'\''. # (use "git commit --amend" to amend the current commit) # (use "git rebase --continue" once you are satisfied with your changes) @@ -573,9 +576,10 @@ test_expect_success 'status when bisecting' ' git bisect start && git bisect bad && git bisect good one_bisect && - cat >expected <<-\EOF && - # Not currently on any branch. - # You are currently bisecting branch '\''bisect'\''. + TGT=$(git rev-parse --short two_bisect) && + cat >expected <<-EOF && + # HEAD detached at $TGT + # You are currently bisecting, started from branch '\''bisect'\''. # (use "git bisect reset" to get back to the original branch) # nothing to commit (use -u to show untracked files) @@ -597,7 +601,7 @@ test_expect_success 'status when rebase conflicts with statushints disabled' ' ONTO=$(git rev-parse --short HEAD^^) && test_must_fail git rebase HEAD^ --onto HEAD^^ && cat >expected <<-EOF && - # Not currently on any branch. + # HEAD detached at $ONTO # You are currently rebasing branch '\''statushints_disabled'\'' on '\''$ONTO'\''. # # Unmerged paths: @@ -663,5 +667,73 @@ test_expect_success 'status when cherry-picking after resolving conflicts' ' test_i18ncmp expected actual ' +test_expect_success 'status showing detached from a tag' ' + test_commit atag tagging && + git checkout atag && + cat >expected <<-\EOF + # HEAD detached at atag + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + +test_expect_success 'status while reverting commit (conflicts)' ' + git checkout master && + echo before >to-revert.txt && + test_commit before to-revert.txt && + echo old >to-revert.txt && + test_commit old to-revert.txt && + echo new >to-revert.txt && + test_commit new to-revert.txt && + TO_REVERT=$(git rev-parse --short HEAD^) && + test_must_fail git revert $TO_REVERT && + cat >expected <<-EOF + # On branch master + # You are currently reverting commit $TO_REVERT. + # (fix conflicts and run "git revert --continue") + # (use "git revert --abort" to cancel the revert operation) + # + # Unmerged paths: + # (use "git reset HEAD <file>..." to unstage) + # (use "git add <file>..." to mark resolution) + # + # both modified: to-revert.txt + # + no changes added to commit (use "git add" and/or "git commit -a") + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + +test_expect_success 'status while reverting commit (conflicts resolved)' ' + echo reverted >to-revert.txt && + git add to-revert.txt && + cat >expected <<-EOF + # On branch master + # You are currently reverting commit $TO_REVERT. + # (all conflicts fixed: run "git revert --continue") + # (use "git revert --abort" to cancel the revert operation) + # + # Changes to be committed: + # (use "git reset HEAD <file>..." to unstage) + # + # modified: to-revert.txt + # + # Untracked files not listed (use -u option to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' + +test_expect_success 'status after reverting commit' ' + git revert --continue && + cat >expected <<-\EOF + # On branch master + nothing to commit (use -u to show untracked files) + EOF + git status --untracked-files=no >actual && + test_i18ncmp expected actual +' test_done diff --git a/t/t7600-merge.sh b/t/t7600-merge.sh index 5e19598fe7..2f70433568 100755 --- a/t/t7600-merge.sh +++ b/t/t7600-merge.sh @@ -56,7 +56,8 @@ create_merge_msgs () { echo && git log --no-merges ^HEAD c2 c3 } >squash.1-5-9 && - echo >msg.nolog && + : >msg.nologff && + echo >msg.nolognoff && { echo "* tag 'c3':" && echo " commit 3" && @@ -244,8 +245,7 @@ test_expect_success 'merges with --ff-only' ' test_expect_success 'merges with merge.ff=only' ' git reset --hard c1 && test_tick && - test_when_finished "git config --unset merge.ff" && - git config merge.ff only && + test_config merge.ff "only" && test_must_fail git merge c2 && test_must_fail git merge c3 && test_must_fail git merge c2 c3 && @@ -336,7 +336,7 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (no-commit in config)' ' git reset --hard c1 && - git config branch.master.mergeoptions "--no-commit" && + test_config branch.master.mergeoptions "--no-commit" && git merge c2 && verify_merge file result.1-5 && verify_head $c1 && @@ -346,12 +346,11 @@ test_expect_success 'merge c1 with c2 (no-commit in config)' ' test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (log in config)' ' - git config branch.master.mergeoptions "" && git reset --hard c1 && git merge --log c2 && git show -s --pretty=tformat:%s%n%b >expect && - git config branch.master.mergeoptions --log && + test_config branch.master.mergeoptions "--log" && git reset --hard c1 && git merge c2 && git show -s --pretty=tformat:%s%n%b >actual && @@ -360,17 +359,12 @@ test_expect_success 'merge c1 with c2 (log in config)' ' ' test_expect_success 'merge c1 with c2 (log in config gets overridden)' ' - test_when_finished "git config --remove-section branch.master" && - test_when_finished "git config --remove-section merge" && - test_might_fail git config --remove-section branch.master && - test_might_fail git config --remove-section merge && - git reset --hard c1 && git merge c2 && git show -s --pretty=tformat:%s%n%b >expect && - git config branch.master.mergeoptions "--no-log" && - git config merge.log true && + test_config branch.master.mergeoptions "--no-log" && + test_config merge.log "true" && git reset --hard c1 && git merge c2 && git show -s --pretty=tformat:%s%n%b >actual && @@ -380,7 +374,7 @@ test_expect_success 'merge c1 with c2 (log in config gets overridden)' ' test_expect_success 'merge c1 with c2 (squash in config)' ' git reset --hard c1 && - git config branch.master.mergeoptions "--squash" && + test_config branch.master.mergeoptions "--squash" && git merge c2 && verify_merge file result.1-5 && verify_head $c1 && @@ -392,7 +386,7 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'override config option -n with --summary' ' git reset --hard c1 && - git config branch.master.mergeoptions "-n" && + test_config branch.master.mergeoptions "-n" && test_tick && git merge --summary c2 >diffstat.txt && verify_merge file result.1-5 msg.1-5 && @@ -406,7 +400,7 @@ test_expect_success 'override config option -n with --summary' ' test_expect_success 'override config option -n with --stat' ' git reset --hard c1 && - git config branch.master.mergeoptions "-n" && + test_config branch.master.mergeoptions "-n" && test_tick && git merge --stat c2 >diffstat.txt && verify_merge file result.1-5 msg.1-5 && @@ -422,7 +416,7 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'override config option --stat' ' git reset --hard c1 && - git config branch.master.mergeoptions "--stat" && + test_config branch.master.mergeoptions "--stat" && test_tick && git merge -n c2 >diffstat.txt && verify_merge file result.1-5 msg.1-5 && @@ -438,7 +432,7 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (override --no-commit)' ' git reset --hard c1 && - git config branch.master.mergeoptions "--no-commit" && + test_config branch.master.mergeoptions "--no-commit" && test_tick && git merge --commit c2 && verify_merge file result.1-5 msg.1-5 && @@ -449,7 +443,7 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c2 (override --squash)' ' git reset --hard c1 && - git config branch.master.mergeoptions "--squash" && + test_config branch.master.mergeoptions "--squash" && test_tick && git merge --no-squash c2 && verify_merge file result.1-5 msg.1-5 && @@ -460,7 +454,6 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 (no-ff)' ' git reset --hard c0 && - git config branch.master.mergeoptions "" && test_tick && git merge --no-ff c1 && verify_merge file result.1 && @@ -471,10 +464,9 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c0 with c1 (merge.ff=false)' ' git reset --hard c0 && - git config merge.ff false && + test_config merge.ff "false" && test_tick && git merge c1 && - git config --remove-section merge && verify_merge file result.1 && verify_parents $c0 $c1 ' @@ -482,22 +474,19 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'combine branch.master.mergeoptions with merge.ff' ' git reset --hard c0 && - git config branch.master.mergeoptions --ff && - git config merge.ff false && + test_config branch.master.mergeoptions "--ff" && + test_config merge.ff "false" && test_tick && git merge c1 && - git config --remove-section "branch.master" && - git config --remove-section "merge" && verify_merge file result.1 && verify_parents "$c0" ' test_expect_success 'tolerate unknown values for merge.ff' ' git reset --hard c0 && - git config merge.ff something-new && + test_config merge.ff "something-new" && test_tick && git merge c1 2>message && - git config --remove-section "merge" && verify_head "$c1" && test_cmp empty message ' @@ -515,7 +504,7 @@ test_expect_success 'combining --ff-only and --no-ff is refused' ' test_expect_success 'merge c0 with c1 (ff overrides no-ff)' ' git reset --hard c0 && - git config branch.master.mergeoptions "--no-ff" && + test_config branch.master.mergeoptions "--no-ff" && git merge --ff c1 && verify_merge file result.1 && verify_head $c1 @@ -525,14 +514,20 @@ test_expect_success 'merge log message' ' git reset --hard c0 && git merge --no-log c2 && git show -s --pretty=format:%b HEAD >msg.act && - test_cmp msg.nolog msg.act && + test_cmp msg.nologff msg.act && + + git reset --hard c0 && + test_config branch.master.mergeoptions "--no-ff" && + git merge --no-log c2 && + git show -s --pretty=format:%b HEAD >msg.act && + test_cmp msg.nolognoff msg.act && git merge --log c3 && git show -s --pretty=format:%b HEAD >msg.act && test_cmp msg.log msg.act && git reset --hard HEAD^ && - git config merge.log yes && + test_config merge.log "yes" && git merge c3 && git show -s --pretty=format:%b HEAD >msg.act && test_cmp msg.log msg.act @@ -542,7 +537,6 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' git reset --hard c1 && - git config branch.master.mergeoptions "" && test_tick && git merge c0 c2 c0 c1 && verify_merge file result.1-5 && @@ -553,7 +547,6 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c0, c2, c0, and c1' ' git reset --hard c1 && - git config branch.master.mergeoptions "" && test_tick && git merge c0 c2 c0 c1 && verify_merge file result.1-5 && @@ -564,7 +557,6 @@ test_debug 'git log --graph --decorate --oneline --all' test_expect_success 'merge c1 with c1 and c2' ' git reset --hard c1 && - git config branch.master.mergeoptions "" && test_tick && git merge c1 c2 && verify_merge file result.1-5 && diff --git a/t/t7612-merge-verify-signatures.sh b/t/t7612-merge-verify-signatures.sh new file mode 100755 index 0000000000..21a0bf8fb8 --- /dev/null +++ b/t/t7612-merge-verify-signatures.sh @@ -0,0 +1,61 @@ +#!/bin/sh + +test_description='merge signature verification tests' +. ./test-lib.sh +. "$TEST_DIRECTORY/lib-gpg.sh" + +test_expect_success GPG 'create signed commits' ' + echo 1 >file && git add file && + test_tick && git commit -m initial && + git tag initial && + + git checkout -b side-signed && + echo 3 >elif && git add elif && + test_tick && git commit -S -m "signed on side" && + git checkout initial && + + git checkout -b side-unsigned && + echo 3 >foo && git add foo && + test_tick && git commit -m "unsigned on side" && + git checkout initial && + + git checkout -b side-bad && + echo 3 >bar && git add bar && + test_tick && git commit -S -m "bad on side" && + git cat-file commit side-bad >raw && + sed -e "s/bad/forged bad/" raw >forged && + git hash-object -w -t commit forged >forged.commit && + git checkout initial && + + git checkout -b side-untrusted && + echo 3 >baz && git add baz && + test_tick && git commit -SB7227189 -m "untrusted on side" + + git checkout master +' + +test_expect_success GPG 'merge unsigned commit with verification' ' + test_must_fail git merge --ff-only --verify-signatures side-unsigned 2>mergeerror && + test_i18ngrep "does not have a GPG signature" mergeerror +' + +test_expect_success GPG 'merge commit with bad signature with verification' ' + test_must_fail git merge --ff-only --verify-signatures $(cat forged.commit) 2>mergeerror && + test_i18ngrep "has a bad GPG signature" mergeerror +' + +test_expect_success GPG 'merge commit with untrusted signature with verification' ' + test_must_fail git merge --ff-only --verify-signatures side-untrusted 2>mergeerror && + test_i18ngrep "has an untrusted GPG signature" mergeerror +' + +test_expect_success GPG 'merge signed commit with verification' ' + git merge --verbose --ff-only --verify-signatures side-signed >mergeoutput && + test_i18ngrep "has a good GPG signature" mergeoutput +' + +test_expect_success GPG 'merge commit with bad signature without verification' ' + git merge $(cat forged.commit) +' + +test_done diff --git a/t/t7800-difftool.sh b/t/t7800-difftool.sh index eb1d3f85b5..d46f0411bd 100755 --- a/t/t7800-difftool.sh +++ b/t/t7800-difftool.sh @@ -1,6 +1,6 @@ #!/bin/sh # -# Copyright (c) 2009, 2010 David Aguilar +# Copyright (c) 2009, 2010, 2012, 2013 David Aguilar # test_description='git-difftool @@ -10,47 +10,19 @@ Testing basic diff tool invocation . ./test-lib.sh -remove_config_vars() +difftool_test_setup () { - # Unset all config variables used by git-difftool - git config --unset diff.tool - git config --unset diff.guitool - git config --unset difftool.test-tool.cmd - git config --unset difftool.prompt - git config --unset merge.tool - git config --unset mergetool.test-tool.cmd - git config --unset mergetool.prompt - return 0 + test_config diff.tool test-tool && + test_config difftool.test-tool.cmd 'cat "$LOCAL"' && + test_config difftool.bogus-tool.cmd false } -restore_test_defaults() -{ - # Restores the test defaults used by several tests - remove_config_vars - unset GIT_DIFF_TOOL - unset GIT_DIFFTOOL_PROMPT - unset GIT_DIFFTOOL_NO_PROMPT - git config diff.tool test-tool && - git config difftool.test-tool.cmd 'cat $LOCAL' - git config difftool.bogus-tool.cmd false -} - -prompt_given() +prompt_given () { prompt="$1" test "$prompt" = "Launch 'test-tool' [Y/n]: branch" } -stdin_contains() -{ - grep >/dev/null "$1" -} - -stdin_doesnot_contain() -{ - ! stdin_contains "$1" -} - # Create a file on master and change it on branch test_expect_success PERL 'setup' ' echo master >file && @@ -65,249 +37,237 @@ test_expect_success PERL 'setup' ' # Configure a custom difftool.<tool>.cmd and use it test_expect_success PERL 'custom commands' ' - restore_test_defaults && - git config difftool.test-tool.cmd "cat \$REMOTE" && + difftool_test_setup && + test_config difftool.test-tool.cmd "cat \"\$REMOTE\"" && + echo master >expect && + git difftool --no-prompt branch >actual && + test_cmp expect actual && - diff=$(git difftool --no-prompt branch) && - test "$diff" = "master" && - - restore_test_defaults && - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" + test_config difftool.test-tool.cmd "cat \"\$LOCAL\"" && + echo branch >expect && + git difftool --no-prompt branch >actual && + test_cmp expect actual ' -# Ensures that a custom difftool.<tool>.cmd overrides built-ins -test_expect_success PERL 'custom commands override built-ins' ' - restore_test_defaults && - git config difftool.defaults.cmd "cat \$REMOTE" && - - diff=$(git difftool --tool defaults --no-prompt branch) && - test "$diff" = "master" && - - git config --unset difftool.defaults.cmd +test_expect_success PERL 'custom tool commands override built-ins' ' + test_config difftool.vimdiff.cmd "cat \"\$REMOTE\"" && + echo master >expect && + git difftool --tool vimdiff --no-prompt branch >actual && + test_cmp expect actual ' -# Ensures that git-difftool ignores bogus --tool values test_expect_success PERL 'difftool ignores bad --tool values' ' - diff=$(git difftool --no-prompt --tool=bad-tool branch) - test "$?" = 1 && - test "$diff" = "" + : >expect && + test_expect_code 1 \ + git difftool --no-prompt --tool=bad-tool branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool forwards arguments to diff' ' + difftool_test_setup && >for-diff && git add for-diff && echo changes>for-diff && git add for-diff && - diff=$(git difftool --cached --no-prompt -- for-diff) && - test "$diff" = "" && + : >expect && + git difftool --cached --no-prompt -- for-diff >actual && + test_cmp expect actual && git reset -- for-diff && rm for-diff ' test_expect_success PERL 'difftool honors --gui' ' - git config merge.tool bogus-tool && - git config diff.tool bogus-tool && - git config diff.guitool test-tool && + difftool_test_setup && + test_config merge.tool bogus-tool && + test_config diff.tool bogus-tool && + test_config diff.guitool test-tool && - diff=$(git difftool --no-prompt --gui branch) && - test "$diff" = "branch" && - - restore_test_defaults + echo branch >expect && + git difftool --no-prompt --gui branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --gui last setting wins' ' - git config diff.guitool bogus-tool && - git difftool --no-prompt --gui --no-gui && - - git config merge.tool bogus-tool && - git config diff.tool bogus-tool && - git config diff.guitool test-tool && - diff=$(git difftool --no-prompt --no-gui --gui branch) && - test "$diff" = "branch" && + difftool_test_setup && + : >expect && + git difftool --no-prompt --gui --no-gui >actual && + test_cmp expect actual && - restore_test_defaults + test_config merge.tool bogus-tool && + test_config diff.tool bogus-tool && + test_config diff.guitool test-tool && + echo branch >expect && + git difftool --no-prompt --no-gui --gui branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --gui works without configured diff.guitool' ' - git config diff.tool test-tool && - - diff=$(git difftool --no-prompt --gui branch) && - test "$diff" = "branch" && - - restore_test_defaults + difftool_test_setup && + echo branch >expect && + git difftool --no-prompt --gui branch >actual && + test_cmp expect actual ' # Specify the diff tool using $GIT_DIFF_TOOL test_expect_success PERL 'GIT_DIFF_TOOL variable' ' - test_might_fail git config --unset diff.tool && - GIT_DIFF_TOOL=test-tool && - export GIT_DIFF_TOOL && - - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" && - - restore_test_defaults + difftool_test_setup && + git config --unset diff.tool && + echo branch >expect && + GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual && + test_cmp expect actual ' # Test the $GIT_*_TOOL variables and ensure # that $GIT_DIFF_TOOL always wins unless --tool is specified test_expect_success PERL 'GIT_DIFF_TOOL overrides' ' - git config diff.tool bogus-tool && - git config merge.tool bogus-tool && + difftool_test_setup && + test_config diff.tool bogus-tool && + test_config merge.tool bogus-tool && - GIT_DIFF_TOOL=test-tool && - export GIT_DIFF_TOOL && + echo branch >expect && + GIT_DIFF_TOOL=test-tool git difftool --no-prompt branch >actual && + test_cmp expect actual && - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" && - - GIT_DIFF_TOOL=bogus-tool && - export GIT_DIFF_TOOL && - - diff=$(git difftool --no-prompt --tool=test-tool branch) && - test "$diff" = "branch" && - - restore_test_defaults + test_config diff.tool bogus-tool && + test_config merge.tool bogus-tool && + GIT_DIFF_TOOL=bogus-tool \ + git difftool --no-prompt --tool=test-tool branch >actual && + test_cmp expect actual ' # Test that we don't have to pass --no-prompt to difftool # when $GIT_DIFFTOOL_NO_PROMPT is true test_expect_success PERL 'GIT_DIFFTOOL_NO_PROMPT variable' ' - GIT_DIFFTOOL_NO_PROMPT=true && - export GIT_DIFFTOOL_NO_PROMPT && - - diff=$(git difftool branch) && - test "$diff" = "branch" && - - restore_test_defaults + difftool_test_setup && + echo branch >expect && + GIT_DIFFTOOL_NO_PROMPT=true git difftool branch >actual && + test_cmp expect actual ' # git-difftool supports the difftool.prompt variable. # Test that GIT_DIFFTOOL_PROMPT can override difftool.prompt = false test_expect_success PERL 'GIT_DIFFTOOL_PROMPT variable' ' - git config difftool.prompt false && - GIT_DIFFTOOL_PROMPT=true && - export GIT_DIFFTOOL_PROMPT && - - prompt=$(echo | git difftool branch | tail -1) && - prompt_given "$prompt" && - - restore_test_defaults + difftool_test_setup && + test_config difftool.prompt false && + echo >input && + GIT_DIFFTOOL_PROMPT=true git difftool branch <input >output && + prompt=$(tail -1 <output) && + prompt_given "$prompt" ' # Test that we don't have to pass --no-prompt when difftool.prompt is false test_expect_success PERL 'difftool.prompt config variable is false' ' - git config difftool.prompt false && - - diff=$(git difftool branch) && - test "$diff" = "branch" && - - restore_test_defaults + difftool_test_setup && + test_config difftool.prompt false && + echo branch >expect && + git difftool branch >actual && + test_cmp expect actual ' # Test that we don't have to pass --no-prompt when mergetool.prompt is false test_expect_success PERL 'difftool merge.prompt = false' ' + difftool_test_setup && test_might_fail git config --unset difftool.prompt && - git config mergetool.prompt false && - - diff=$(git difftool branch) && - test "$diff" = "branch" && - - restore_test_defaults + test_config mergetool.prompt false && + echo branch >expect && + git difftool branch >actual && + test_cmp expect actual ' # Test that the -y flag can override difftool.prompt = true test_expect_success PERL 'difftool.prompt can overridden with -y' ' - git config difftool.prompt true && - - diff=$(git difftool -y branch) && - test "$diff" = "branch" && - - restore_test_defaults + difftool_test_setup && + test_config difftool.prompt true && + echo branch >expect && + git difftool -y branch >actual && + test_cmp expect actual ' # Test that the --prompt flag can override difftool.prompt = false test_expect_success PERL 'difftool.prompt can overridden with --prompt' ' - git config difftool.prompt false && - - prompt=$(echo | git difftool --prompt branch | tail -1) && - prompt_given "$prompt" && - - restore_test_defaults + difftool_test_setup && + test_config difftool.prompt false && + echo >input && + git difftool --prompt branch <input >output && + prompt=$(tail -1 <output) && + prompt_given "$prompt" ' # Test that the last flag passed on the command-line wins test_expect_success PERL 'difftool last flag wins' ' - diff=$(git difftool --prompt --no-prompt branch) && - test "$diff" = "branch" && - - restore_test_defaults && - - prompt=$(echo | git difftool --no-prompt --prompt branch | tail -1) && - prompt_given "$prompt" && - - restore_test_defaults + difftool_test_setup && + echo branch >expect && + git difftool --prompt --no-prompt branch >actual && + test_cmp expect actual && + echo >input && + git difftool --no-prompt --prompt branch <input >output && + prompt=$(tail -1 <output) && + prompt_given "$prompt" ' # git-difftool falls back to git-mergetool config variables # so test that behavior here test_expect_success PERL 'difftool + mergetool config variables' ' - remove_config_vars && - git config merge.tool test-tool && - git config mergetool.test-tool.cmd "cat \$LOCAL" && - - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" && + test_config merge.tool test-tool && + test_config mergetool.test-tool.cmd "cat \$LOCAL" && + echo branch >expect && + git difftool --no-prompt branch >actual && + test_cmp expect actual && # set merge.tool to something bogus, diff.tool to test-tool - git config merge.tool bogus-tool && - git config diff.tool test-tool && - - diff=$(git difftool --no-prompt branch) && - test "$diff" = "branch" && - - restore_test_defaults + test_config merge.tool bogus-tool && + test_config diff.tool test-tool && + git difftool --no-prompt branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool.<tool>.path' ' - git config difftool.tkdiff.path echo && - diff=$(git difftool --tool=tkdiff --no-prompt branch) && - git config --unset difftool.tkdiff.path && - lines=$(echo "$diff" | grep file | wc -l) && - test "$lines" -eq 1 && - - restore_test_defaults + test_config difftool.tkdiff.path echo && + git difftool --tool=tkdiff --no-prompt branch >output && + lines=$(grep file output | wc -l) && + test "$lines" -eq 1 ' test_expect_success PERL 'difftool --extcmd=cat' ' - diff=$(git difftool --no-prompt --extcmd=cat branch) && - test "$diff" = branch"$LF"master + echo branch >expect && + echo master >>expect && + git difftool --no-prompt --extcmd=cat branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --extcmd cat' ' - diff=$(git difftool --no-prompt --extcmd cat branch) && - test "$diff" = branch"$LF"master + echo branch >expect && + echo master >>expect && + git difftool --no-prompt --extcmd=cat branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool -x cat' ' - diff=$(git difftool --no-prompt -x cat branch) && - test "$diff" = branch"$LF"master + echo branch >expect && + echo master >>expect && + git difftool --no-prompt -x cat branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --extcmd echo arg1' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"echo\ \$1\" branch) && - test "$diff" = file + echo file >expect && + git difftool --no-prompt \ + --extcmd sh\ -c\ \"echo\ \$1\" branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --extcmd cat arg1' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$1\" branch) && - test "$diff" = master + echo master >expect && + git difftool --no-prompt \ + --extcmd sh\ -c\ \"cat\ \$1\" branch >actual && + test_cmp expect actual ' test_expect_success PERL 'difftool --extcmd cat arg2' ' - diff=$(git difftool --no-prompt --extcmd sh\ -c\ \"cat\ \$2\" branch) && - test "$diff" = branch + echo branch >expect && + git difftool --no-prompt \ + --extcmd sh\ -c\ \"cat\ \$2\" branch >actual && + test_cmp expect actual ' # Create a second file on master and a different version on branch @@ -324,26 +284,26 @@ test_expect_success PERL 'setup with 2 files different' ' ' test_expect_success PERL 'say no to the first file' ' - diff=$( (echo n; echo) | git difftool -x cat branch ) && - - echo "$diff" | stdin_contains m2 && - echo "$diff" | stdin_contains br2 && - echo "$diff" | stdin_doesnot_contain master && - echo "$diff" | stdin_doesnot_contain branch + (echo n && echo) >input && + git difftool -x cat branch <input >output && + grep m2 output && + grep br2 output && + ! grep master output && + ! grep branch output ' test_expect_success PERL 'say no to the second file' ' - diff=$( (echo; echo n) | git difftool -x cat branch ) && - - echo "$diff" | stdin_contains master && - echo "$diff" | stdin_contains branch && - echo "$diff" | stdin_doesnot_contain m2 && - echo "$diff" | stdin_doesnot_contain br2 + (echo && echo n) >input && + git difftool -x cat branch <input >output && + grep master output && + grep branch output && + ! grep m2 output && + ! grep br2 output ' test_expect_success PERL 'difftool --tool-help' ' - tool_help=$(git difftool --tool-help) && - echo "$tool_help" | stdin_contains tool + git difftool --tool-help >output && + grep tool output ' test_expect_success PERL 'setup change in subdirectory' ' @@ -354,34 +314,104 @@ test_expect_success PERL 'setup change in subdirectory' ' git commit -m "added sub/sub" && echo test >>file && echo test >>sub/sub && - git add . && + git add file sub/sub && git commit -m "modified both" ' -test_expect_success PERL 'difftool -d' ' - diff=$(git difftool -d --extcmd ls branch) && - echo "$diff" | stdin_contains sub && - echo "$diff" | stdin_contains file +run_dir_diff_test () { + test_expect_success PERL "$1 --no-symlinks" " + symlinks=--no-symlinks && + $2 + " + test_expect_success PERL,SYMLINKS "$1 --symlinks" " + symlinks=--symlinks && + $2 + " +} + +run_dir_diff_test 'difftool -d' ' + git difftool -d $symlinks --extcmd ls branch >output && + grep sub output && + grep file output ' -test_expect_success PERL 'difftool --dir-diff' ' - diff=$(git difftool --dir-diff --extcmd ls branch) && - echo "$diff" | stdin_contains sub && - echo "$diff" | stdin_contains file +run_dir_diff_test 'difftool --dir-diff' ' + git difftool --dir-diff $symlinks --extcmd ls branch >output && + grep sub output && + grep file output ' -test_expect_success PERL 'difftool --dir-diff ignores --prompt' ' - diff=$(git difftool --dir-diff --prompt --extcmd ls branch) && - echo "$diff" | stdin_contains sub && - echo "$diff" | stdin_contains file +run_dir_diff_test 'difftool --dir-diff ignores --prompt' ' + git difftool --dir-diff $symlinks --prompt --extcmd ls branch >output && + grep sub output && + grep file output ' -test_expect_success PERL 'difftool --dir-diff from subdirectory' ' +run_dir_diff_test 'difftool --dir-diff from subdirectory' ' ( cd sub && - diff=$(git difftool --dir-diff --extcmd ls branch) && - echo "$diff" | stdin_contains sub && - echo "$diff" | stdin_contains file + git difftool --dir-diff $symlinks --extcmd ls branch >output && + grep sub output && + grep file output + ) +' + +run_dir_diff_test 'difftool --dir-diff when worktree file is missing' ' + test_when_finished git reset --hard && + rm file2 && + git difftool --dir-diff $symlinks --extcmd ls branch master >output && + grep file2 output +' + +write_script .git/CHECK_SYMLINKS <<\EOF +for f in file file2 sub/sub +do + echo "$f" + readlink "$2/$f" +done >actual +EOF + +test_expect_success PERL,SYMLINKS 'difftool --dir-diff --symlink without unstaged changes' ' + cat >expect <<-EOF && + file + $(pwd)/file + file2 + $(pwd)/file2 + sub/sub + $(pwd)/sub/sub + EOF + git difftool --dir-diff --symlink \ + --extcmd "./.git/CHECK_SYMLINKS" branch HEAD && + test_cmp actual expect +' + +write_script modify-file <<\EOF +echo "new content" >file +EOF + +test_expect_success PERL 'difftool --no-symlinks does not overwrite working tree file ' ' + echo "orig content" >file && + git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-file" branch && + echo "new content" >expect && + test_cmp expect file +' + +write_script modify-both-files <<\EOF +echo "wt content" >file && +echo "tmp content" >"$2/file" && +echo "$2" >tmpdir +EOF + +test_expect_success PERL 'difftool --no-symlinks detects conflict ' ' + ( + TMPDIR=$TRASH_DIRECTORY && + export TMPDIR && + echo "orig content" >file && + test_must_fail git difftool --dir-diff --no-symlinks --extcmd "$(pwd)/modify-both-files" branch && + echo "wt content" >expect && + test_cmp expect file && + echo "tmp content" >expect && + test_cmp expect "$(cat tmpdir)/file" ) ' diff --git a/t/t9114-git-svn-dcommit-merge.sh b/t/t9114-git-svn-dcommit-merge.sh index 3077851015..f524d2f383 100755 --- a/t/t9114-git-svn-dcommit-merge.sh +++ b/t/t9114-git-svn-dcommit-merge.sh @@ -48,7 +48,7 @@ test_expect_success 'setup svn repository' ' test_expect_success 'setup git mirror and merge' ' git svn init "$svnrepo" -t tags -T trunk -b branches && git svn fetch && - git checkout --track -b svn remotes/trunk && + git checkout -b svn remotes/trunk && git checkout -b merge && echo new file > new_file && git add new_file && diff --git a/t/t9147-git-svn-include-paths.sh b/t/t9147-git-svn-include-paths.sh new file mode 100755 index 0000000000..a90ff58629 --- /dev/null +++ b/t/t9147-git-svn-include-paths.sh @@ -0,0 +1,149 @@ +#!/bin/sh +# +# Copyright (c) 2013 Paul Walmsley - based on t9134 by Vitaly Shukela +# + +test_description='git svn property tests' +. ./lib-git-svn.sh + +test_expect_success 'setup test repository' ' + svn_cmd co "$svnrepo" s && + ( + cd s && + mkdir qqq www xxx && + echo test_qqq > qqq/test_qqq.txt && + echo test_www > www/test_www.txt && + echo test_xxx > xxx/test_xxx.txt && + svn_cmd add qqq && + svn_cmd add www && + svn_cmd add xxx && + svn_cmd commit -m "create some files" && + svn_cmd up && + echo hi >> www/test_www.txt && + svn_cmd commit -m "modify www/test_www.txt" && + svn_cmd up + ) +' + +test_expect_success 'clone an SVN repository with filter to include qqq directory' ' + git svn clone --include-paths="qqq" "$svnrepo" g && + echo test_qqq > expect && + for i in g/*/*.txt; do cat $i >> expect2; done && + test_cmp expect expect2 +' + + +test_expect_success 'init+fetch an SVN repository with included qqq directory' ' + git svn init "$svnrepo" c && + ( cd c && git svn fetch --include-paths="qqq" ) && + rm expect2 && + echo test_qqq > expect && + for i in c/*/*.txt; do cat $i >> expect2; done && + test_cmp expect expect2 +' + +test_expect_success 'verify include-paths config saved by clone' ' + ( + cd g && + git config --get svn-remote.svn.include-paths | fgrep "qqq" + ) +' + +test_expect_success 'SVN-side change outside of www' ' + ( + cd s && + echo b >> qqq/test_qqq.txt && + svn_cmd commit -m "SVN-side change outside of www" && + svn_cmd up && + svn_cmd log -v | fgrep "SVN-side change outside of www" + ) +' + +test_expect_success 'update git svn-cloned repo (config include)' ' + ( + cd g && + git svn rebase && + printf "test_qqq\nb\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_expect_success 'update git svn-cloned repo (option include)' ' + ( + cd c && + git svn rebase --include-paths="qqq" && + printf "test_qqq\nb\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_expect_success 'SVN-side change inside of ignored www' ' + ( + cd s && + echo zaq >> www/test_www.txt + svn_cmd commit -m "SVN-side change inside of www/test_www.txt" && + svn_cmd up && + svn_cmd log -v | fgrep "SVN-side change inside of www/test_www.txt" + ) +' + +test_expect_success 'update git svn-cloned repo (config include)' ' + ( + cd g && + git svn rebase && + printf "test_qqq\nb\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_expect_success 'update git svn-cloned repo (option include)' ' + ( + cd c && + git svn rebase --include-paths="qqq" && + printf "test_qqq\nb\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_expect_success 'SVN-side change in and out of included qqq' ' + ( + cd s && + echo cvf >> www/test_www.txt + echo ygg >> qqq/test_qqq.txt + svn_cmd commit -m "SVN-side change in and out of ignored www" && + svn_cmd up && + svn_cmd log -v | fgrep "SVN-side change in and out of ignored www" + ) +' + +test_expect_success 'update git svn-cloned repo again (config include)' ' + ( + cd g && + git svn rebase && + printf "test_qqq\nb\nygg\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_expect_success 'update git svn-cloned repo again (option include)' ' + ( + cd c && + git svn rebase --include-paths="qqq" && + printf "test_qqq\nb\nygg\n" > expect && + for i in */*.txt; do cat $i >> expect2; done && + test_cmp expect2 expect && + rm expect expect2 + ) +' + +test_done diff --git a/t/t9161-git-svn-mergeinfo-push.sh b/t/t9161-git-svn-mergeinfo-push.sh index 6ef0c0bde3..1eab7015c7 100755 --- a/t/t9161-git-svn-mergeinfo-push.sh +++ b/t/t9161-git-svn-mergeinfo-push.sh @@ -88,7 +88,6 @@ test_expect_success 'check reintegration mergeinfo' ' test "$mergeinfo" = "/branches/svnb1:2-4,7-9,13-18 /branches/svnb2:3,8,16-17 /branches/svnb3:4,9 -/branches/svnb4:5-6,10-12 /branches/svnb5:6,11" ' diff --git a/t/t9167-git-svn-cmd-branch-subproject.sh b/t/t9167-git-svn-cmd-branch-subproject.sh new file mode 100755 index 0000000000..53def876ed --- /dev/null +++ b/t/t9167-git-svn-cmd-branch-subproject.sh @@ -0,0 +1,48 @@ +#!/bin/sh +# +# Copyright (c) 2013 Tobias Schulte +# + +test_description='git svn branch for subproject clones' +. ./lib-git-svn.sh + +test_expect_success 'initialize svnrepo' ' + mkdir import && + ( + cd import && + mkdir -p trunk/project branches tags && + ( + cd trunk/project && + echo foo > foo + ) && + svn_cmd import -m "import for git-svn" . "$svnrepo" >/dev/null + ) && + rm -rf import && + svn_cmd co "$svnrepo"/trunk/project trunk/project && + ( + cd trunk/project && + echo bar >> foo && + svn_cmd ci -m "updated trunk" + ) && + rm -rf trunk +' + +test_expect_success 'import into git' ' + git svn init --trunk=trunk/project --branches=branches/*/project \ + --tags=tags/*/project "$svnrepo" && + git svn fetch && + git checkout remotes/trunk +' + +test_expect_success 'git svn branch tests' ' + test_must_fail git svn branch a && + git svn branch --parents a && + test_must_fail git svn branch -t tag1 && + git svn branch --parents -t tag1 && + test_must_fail git svn branch --tag tag2 && + git svn branch --parents --tag tag2 && + test_must_fail git svn tag tag3 && + git svn tag --parents tag3 +' + +test_done diff --git a/t/t9350-fast-export.sh b/t/t9350-fast-export.sh index 9320b4f94c..2471bc6777 100755 --- a/t/t9350-fast-export.sh +++ b/t/t9350-fast-export.sh @@ -146,6 +146,12 @@ test_expect_success 'signed-tags=strip' ' ' +test_expect_success 'signed-tags=warn-strip' ' + git fast-export --signed-tags=warn-strip sign-your-name >output 2>err && + ! grep PGP output && + test -s err +' + test_expect_success 'setup submodule' ' git checkout -f master && diff --git a/t/t9400-git-cvsserver-server.sh b/t/t9400-git-cvsserver-server.sh index 9502f2438a..043138631b 100755 --- a/t/t9400-git-cvsserver-server.sh +++ b/t/t9400-git-cvsserver-server.sh @@ -36,6 +36,7 @@ export CVSROOT CVS_SERVER rm -rf "$CVSWORK" "$SERVERDIR" test_expect_success 'setup' ' + git config push.default matching && echo >empty && git add empty && git commit -q -m "First Commit" && diff --git a/t/t9401-git-cvsserver-crlf.sh b/t/t9401-git-cvsserver-crlf.sh index 1c5bc84fa7..8c3db76301 100755 --- a/t/t9401-git-cvsserver-crlf.sh +++ b/t/t9401-git-cvsserver-crlf.sh @@ -84,6 +84,7 @@ export CVSROOT CVS_SERVER rm -rf "$CVSWORK" "$SERVERDIR" test_expect_success 'setup' ' + git config push.default matching && echo "Simple text file" >textfile.c && echo "File with embedded NUL: Q <- there" | q_to_nul > binfile.bin && mkdir subdir && diff --git a/t/t9500-gitweb-standalone-no-errors.sh b/t/t9500-gitweb-standalone-no-errors.sh index 90bb6050c1..6783c14c1a 100755 --- a/t/t9500-gitweb-standalone-no-errors.sh +++ b/t/t9500-gitweb-standalone-no-errors.sh @@ -539,8 +539,7 @@ test_expect_success \ test_when_finished "GIT_COMMITTER_NAME=\"C O Mitter\"" && echo "ISO-8859-1" >> file && git add file && - git config i18n.commitencoding ISO-8859-1 && - test_when_finished "git config --unset i18n.commitencoding" && + test_config i18n.commitencoding ISO-8859-1 && git commit -F "$TEST_DIRECTORY"/t3900/ISO8859-1.txt && gitweb_run "p=.git;a=commit"' diff --git a/t/t9808-git-p4-chdir.sh b/t/t9808-git-p4-chdir.sh index dc92e60cd6..11d2b5102c 100755 --- a/t/t9808-git-p4-chdir.sh +++ b/t/t9808-git-p4-chdir.sh @@ -42,6 +42,47 @@ test_expect_success 'P4CONFIG and relative dir clone' ' ) ' +# Common setup using .p4config to set P4CLIENT and P4PORT breaks +# if clone destination is relative. Make sure that chdir() expands +# the relative path in --dest to absolute. +test_expect_success 'p4 client root would be relative due to clone --dest' ' + test_when_finished cleanup_git && + ( + echo P4PORT=$P4PORT >git/.p4config && + P4CONFIG=.p4config && + export P4CONFIG && + unset P4PORT && + git p4 clone --dest="git" //depot + ) +' + +# When the p4 client Root is a symlink, make sure chdir() does not use +# getcwd() to convert it to a physical path. +test_expect_success SYMLINKS 'p4 client root symlink should stay symbolic' ' + physical="$TRASH_DIRECTORY/physical" && + symbolic="$TRASH_DIRECTORY/symbolic" && + test_when_finished "rm -rf \"$physical\"" && + test_when_finished "rm \"$symbolic\"" && + mkdir -p "$physical" && + ln -s "$physical" "$symbolic" && + test_when_finished cleanup_git && + ( + P4CLIENT=client-sym && + p4 client -i <<-EOF && + Client: $P4CLIENT + Description: $P4CLIENT + Root: $symbolic + LineEnd: unix + View: //depot/... //$P4CLIENT/... + EOF + git p4 clone --dest="$git" //depot && + cd "$git" && + test_commit file2 && + git config git-p4.skipSubmitEdit true && + git p4 submit + ) +' + test_expect_success 'kill p4d' ' kill_p4d ' diff --git a/t/t9902-completion.sh b/t/t9902-completion.sh index adc1372b3c..6d9d1418a0 100755 --- a/t/t9902-completion.sh +++ b/t/t9902-completion.sh @@ -69,6 +69,7 @@ run_completion () local -a COMPREPLY _words local _cword _words=( $1 ) + test "${1: -1}" == ' ' && _words+=('') (( _cword = ${#_words[@]} - 1 )) __git_wrap__git_main && print_comp } @@ -104,6 +105,23 @@ test_gitcomp () test_cmp expected out } +# Test __gitcomp_nl +# Arguments are: +# 1: current word (cur) +# -: the rest are passed to __gitcomp_nl +test_gitcomp_nl () +{ + local -a COMPREPLY && + sed -e 's/Z$//' >expected && + cur="$1" && + shift && + __gitcomp_nl "$@" && + print_comp && + test_cmp expected out +} + +invalid_variable_name='${foo.bar}' + test_expect_success '__gitcomp - trailing space - options' ' test_gitcomp "--re" "--dry-run --reuse-message= --reedit-message= --reset-author" <<-EOF @@ -147,8 +165,51 @@ test_expect_success '__gitcomp - suffix' ' EOF ' +test_expect_success '__gitcomp - doesnt fail because of invalid variable name' ' + __gitcomp "$invalid_variable_name" +' + +read -r -d "" refs <<-\EOF +maint +master +next +pu +EOF + +test_expect_success '__gitcomp_nl - trailing space' ' + test_gitcomp_nl "m" "$refs" <<-EOF + maint Z + master Z + EOF +' + +test_expect_success '__gitcomp_nl - prefix' ' + test_gitcomp_nl "--fixup=m" "$refs" "--fixup=" "m" <<-EOF + --fixup=maint Z + --fixup=master Z + EOF +' + +test_expect_success '__gitcomp_nl - suffix' ' + test_gitcomp_nl "branch.ma" "$refs" "branch." "ma" "." <<-\EOF + branch.maint.Z + branch.master.Z + EOF +' + +test_expect_success '__gitcomp_nl - no suffix' ' + test_gitcomp_nl "ma" "$refs" "" "ma" "" <<-\EOF + maintZ + masterZ + EOF +' + +test_expect_success '__gitcomp_nl - doesnt fail because of invalid variable name' ' + __gitcomp_nl "$invalid_variable_name" +' + test_expect_success 'basic' ' - run_completion "git \"\"" && + run_completion "git " && # built-in grep -q "^add \$" out && # script @@ -271,7 +332,7 @@ test_expect_success 'complete tree filename with spaces' ' EOF ' -test_expect_failure 'complete tree filename with metacharacters' ' +test_expect_success 'complete tree filename with metacharacters' ' echo content >"name with \${meta}" && git add . && git commit -m meta && diff --git a/t/t9903-bash-prompt.sh b/t/t9903-bash-prompt.sh index 2101d914f2..083b319ed1 100755 --- a/t/t9903-bash-prompt.sh +++ b/t/t9903-bash-prompt.sh @@ -28,6 +28,10 @@ test_expect_success 'setup for prompt tests' ' git checkout -b b2 master && echo 0 > file && git commit -m "second b2" file && + echo 00 > file && + git commit -m "another b2" file && + echo 000 > file && + git commit -m "yet another b2" file && git checkout master ' @@ -59,7 +63,7 @@ test_expect_success 'gitdir - .git directory in cwd' ' ' test_expect_success 'gitdir - .git directory in parent' ' - echo "$TRASH_DIRECTORY/.git" > expected && + echo "$(pwd -P)/.git" > expected && ( cd subdir/subsubdir && __gitdir > "$actual" @@ -77,7 +81,7 @@ test_expect_success 'gitdir - cwd is a .git directory' ' ' test_expect_success 'gitdir - parent is a .git directory' ' - echo "$TRASH_DIRECTORY/.git" > expected && + echo "$(pwd -P)/.git" > expected && ( cd .git/refs/heads && __gitdir > "$actual" @@ -115,7 +119,7 @@ test_expect_success 'gitdir - non-existing $GIT_DIR' ' ' test_expect_success 'gitdir - gitfile in cwd' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + echo "$(pwd -P)/otherrepo/.git" > expected && echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && test_when_finished "rm -f subdir/.git" && ( @@ -126,7 +130,7 @@ test_expect_success 'gitdir - gitfile in cwd' ' ' test_expect_success 'gitdir - gitfile in parent' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + echo "$(pwd -P)/otherrepo/.git" > expected && echo "gitdir: $TRASH_DIRECTORY/otherrepo/.git" > subdir/.git && test_when_finished "rm -f subdir/.git" && ( @@ -137,7 +141,7 @@ test_expect_success 'gitdir - gitfile in parent' ' ' test_expect_success SYMLINKS 'gitdir - resulting path avoids symlinks' ' - echo "$TRASH_DIRECTORY/otherrepo/.git" > expected && + echo "$(pwd -P)/otherrepo/.git" > expected && mkdir otherrepo/dir && test_when_finished "rm -rf otherrepo/dir" && ln -s otherrepo/dir link && @@ -243,10 +247,12 @@ test_expect_success 'prompt - inside bare repository' ' ' test_expect_success 'prompt - interactive rebase' ' - printf " (b1|REBASE-i)" > expected + printf " (b1|REBASE-i 2/3)" > expected echo "#!$SHELL_PATH" >fake_editor.sh && cat >>fake_editor.sh <<\EOF && -echo "edit $(git log -1 --format="%h")" > "$1" +echo "exec echo" > "$1" +echo "edit $(git log -1 --format="%h")" >> "$1" +echo "exec echo" >> "$1" EOF test_when_finished "rm -f fake_editor.sh" && chmod a+x fake_editor.sh && @@ -260,7 +266,7 @@ EOF ' test_expect_success 'prompt - rebase merge' ' - printf " (b2|REBASE-m)" > expected && + printf " (b2|REBASE-m 1/3)" > expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase --merge b1 b2 && @@ -270,7 +276,7 @@ test_expect_success 'prompt - rebase merge' ' ' test_expect_success 'prompt - rebase' ' - printf " ((t2)|REBASE)" > expected && + printf " ((t2)|REBASE 1/3)" > expected && git checkout b2 && test_when_finished "git checkout master" && test_must_fail git rebase b1 b2 && diff --git a/t/test-lib-functions.sh b/t/test-lib-functions.sh index 3fc9cc9288..52510094ad 100644 --- a/t/test-lib-functions.sh +++ b/t/test-lib-functions.sh @@ -139,12 +139,12 @@ test_pause () { fi } -# Call test_commit with the arguments "<message> [<file> [<contents>]]" +# Call test_commit with the arguments "<message> [<file> [<contents> [<tag>]]]" # # This will commit a file with the given contents and the given commit -# message. It will also add a tag with <message> as name. +# message, and tag the resulting commit with the given tag name. # -# Both <file> and <contents> default to <message>. +# <file>, <contents>, and <tag> all default to <message>. test_commit () { notick= && @@ -172,7 +172,7 @@ test_commit () { test_tick fi && git commit $signoff -m "$1" && - git tag "$1" + git tag "${4:-$1}" } # Call test_merge with the arguments "<message> <commit>", where <commit> @@ -540,6 +540,9 @@ test_must_fail () { elif test $exit_code = 127; then echo >&2 "test_must_fail: command not found: $*" return 1 + elif test $exit_code = 126; then + echo >&2 "test_must_fail: valgrind error: $*" + return 1 fi return 0 } diff --git a/t/test-lib.sh b/t/test-lib.sh index 657b0bd862..eff3a653d1 100644 --- a/t/test-lib.sh +++ b/t/test-lib.sh @@ -54,8 +54,8 @@ done,*) # do not redirect again ;; *' --tee '*|*' --va'*) - mkdir -p test-results - BASE=test-results/$(basename "$0" .sh) + mkdir -p "$TEST_OUTPUT_DIRECTORY/test-results" + BASE="$TEST_OUTPUT_DIRECTORY/test-results/$(basename "$0" .sh)" (GIT_TEST_TEE_STARTED=done ${SHELL_PATH} "$0" "$@" 2>&1; echo $? > $BASE.exit) | tee $BASE.out test "$(cat $BASE.exit)" = 0 @@ -193,7 +193,11 @@ do --no-color) color=; shift ;; --va|--val|--valg|--valgr|--valgri|--valgrin|--valgrind) - valgrind=t; verbose=t; shift ;; + valgrind=memcheck + shift ;; + --valgrind=*) + valgrind=$(expr "z$1" : 'z[^=]*=\(.*\)') + shift ;; --tee) shift ;; # was handled already --root=*) @@ -204,6 +208,8 @@ do esac done +test -n "$valgrind" && verbose=t + if test -n "$color" then say_color () { @@ -530,6 +536,8 @@ then PATH=$GIT_VALGRIND/bin:$PATH GIT_EXEC_PATH=$GIT_VALGRIND/bin export GIT_VALGRIND + GIT_VALGRIND_MODE="$valgrind" + export GIT_VALGRIND_MODE elif test -n "$GIT_TEST_INSTALLED" then GIT_EXEC_PATH=$($GIT_TEST_INSTALLED/git --exec-path) || diff --git a/t/valgrind/analyze.sh b/t/valgrind/analyze.sh index d8105d9fab..2ffc80f721 100755 --- a/t/valgrind/analyze.sh +++ b/t/valgrind/analyze.sh @@ -1,6 +1,10 @@ #!/bin/sh -out_prefix=$(dirname "$0")/../test-results/valgrind.out +# Get TEST_OUTPUT_DIRECTORY from GIT-BUILD-OPTIONS if it's there... +. "$(dirname "$0")/../../GIT-BUILD-OPTIONS" +# ... otherwise set it to the default value. +: ${TEST_OUTPUT_DIRECTORY=$(dirname "$0")/..} + output= count=0 total_count=0 @@ -115,7 +119,7 @@ handle_one () { finish_output } -for test_script in "$(dirname "$0")"/../test-results/*.out +for test_script in "$TEST_OUTPUT_DIRECTORY"/test-results/*.out do handle_one $test_script done diff --git a/t/valgrind/valgrind.sh b/t/valgrind/valgrind.sh index 582b4dca94..6b87c91b60 100755 --- a/t/valgrind/valgrind.sh +++ b/t/valgrind/valgrind.sh @@ -2,20 +2,27 @@ base=$(basename "$0") -TRACK_ORIGINS= +TOOL_OPTIONS='--leak-check=no' -VALGRIND_VERSION=$(valgrind --version) -VALGRIND_MAJOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*\([0-9]*\)') -VALGRIND_MINOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*[0-9]*\.\([0-9]*\)') -test 3 -gt "$VALGRIND_MAJOR" || -test 3 -eq "$VALGRIND_MAJOR" -a 4 -gt "$VALGRIND_MINOR" || -TRACK_ORIGINS=--track-origins=yes +case "$GIT_VALGRIND_MODE" in +memcheck-fast) + ;; +memcheck) + VALGRIND_VERSION=$(valgrind --version) + VALGRIND_MAJOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*\([0-9]*\)') + VALGRIND_MINOR=$(expr "$VALGRIND_VERSION" : '[^0-9]*[0-9]*\.\([0-9]*\)') + test 3 -gt "$VALGRIND_MAJOR" || + test 3 -eq "$VALGRIND_MAJOR" -a 4 -gt "$VALGRIND_MINOR" || + TOOL_OPTIONS="$TOOL_OPTIONS --track-origins=yes" + ;; +*) + TOOL_OPTIONS="--tool=$GIT_VALGRIND_MODE" +esac exec valgrind -q --error-exitcode=126 \ - --leak-check=no \ - --suppressions="$GIT_VALGRIND/default.supp" \ --gen-suppressions=all \ - $TRACK_ORIGINS \ + --suppressions="$GIT_VALGRIND/default.supp" \ + $TOOL_OPTIONS \ --log-fd=4 \ --input-fd=4 \ $GIT_VALGRIND_OPTIONS \ diff --git a/test-chmtime.c b/test-chmtime.c index 02b42badd5..94903c4bff 100644 --- a/test-chmtime.c +++ b/test-chmtime.c @@ -56,7 +56,7 @@ static int timespec_arg(const char *arg, long int *set_time, int *set_eq) return 1; } -int main(int argc, const char *argv[]) +int main(int argc, char *argv[]) { static int verbose; diff --git a/test-index-version.c b/test-index-version.c index bfaad9e09e..05d4699c4a 100644 --- a/test-index-version.c +++ b/test-index-version.c @@ -1,6 +1,6 @@ #include "cache.h" -int main(int argc, const char **argv) +int main(int argc, char **argv) { struct cache_header hdr; int version; diff --git a/test-mergesort.c b/test-mergesort.c index 3f388b4ce0..ea3b959e94 100644 --- a/test-mergesort.c +++ b/test-mergesort.c @@ -22,7 +22,7 @@ static int compare_strings(const void *a, const void *b) return strcmp(x->text, y->text); } -int main(int argc, const char **argv) +int main(int argc, char **argv) { struct line *line, *p = NULL, *lines = NULL; struct strbuf sb = STRBUF_INIT; diff --git a/test-parse-options.c b/test-parse-options.c index 3c9510a701..434e8b8929 100644 --- a/test-parse-options.c +++ b/test-parse-options.c @@ -29,7 +29,7 @@ static int number_callback(const struct option *opt, const char *arg, int unset) return 0; } -int main(int argc, const char **argv) +int main(int argc, char **argv) { const char *prefix = "prefix/"; const char *usage[] = { @@ -81,7 +81,7 @@ int main(int argc, const char **argv) }; int i; - argc = parse_options(argc, argv, prefix, options, usage, 0); + argc = parse_options(argc, (const char **)argv, prefix, options, usage, 0); printf("boolean: %d\n", boolean); printf("integer: %u\n", integer); diff --git a/test-subprocess.c b/test-subprocess.c index f2d4c0d22b..93525eb7be 100644 --- a/test-subprocess.c +++ b/test-subprocess.c @@ -1,7 +1,7 @@ #include "cache.h" #include "run-command.h" -int main(int argc, const char **argv) +int main(int argc, char **argv) { struct child_process cp; int nogit = 0; @@ -15,6 +15,6 @@ int main(int argc, const char **argv) } memset(&cp, 0, sizeof(cp)); cp.git_cmd = 1; - cp.argv = argv + 1; + cp.argv = (const char **)argv + 1; return run_command(&cp); } diff --git a/test-svn-fe.c b/test-svn-fe.c index 0f2d9a4a3d..120ec96b0d 100644 --- a/test-svn-fe.c +++ b/test-svn-fe.c @@ -24,7 +24,7 @@ static int apply_delta(int argc, char *argv[]) die_errno("cannot open preimage"); if (buffer_init(&delta, argv[3])) die_errno("cannot open delta"); - if (svndiff0_apply(&delta, (off_t) strtoull(argv[4], NULL, 0), + if (svndiff0_apply(&delta, (off_t) strtoumax(argv[4], NULL, 0), &preimage_view, stdout)) return 1; if (buffer_deinit(&preimage)) diff --git a/transport-helper.c b/transport-helper.c index dcd8d97411..2f5ac3fbee 100644 --- a/transport-helper.c +++ b/transport-helper.c @@ -11,6 +11,7 @@ #include "thread-utils.h" #include "sigchain.h" #include "argv-array.h" +#include "refs.h" static int debug; @@ -25,6 +26,7 @@ struct helper_data { option : 1, push : 1, connect : 1, + signed_tags : 1, no_disconnect_req : 1; char *export_marks; char *import_marks; @@ -46,7 +48,7 @@ static void sendline(struct helper_data *helper, struct strbuf *buffer) die_errno("Full write to remote helper failed"); } -static int recvline_fh(FILE *helper, struct strbuf *buffer) +static int recvline_fh(FILE *helper, struct strbuf *buffer, const char *name) { strbuf_reset(buffer); if (debug) @@ -54,7 +56,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer) if (strbuf_getline(buffer, helper, '\n') == EOF) { if (debug) fprintf(stderr, "Debug: Remote helper quit.\n"); - exit(128); + die("Reading from helper 'git-remote-%s' failed", name); } if (debug) @@ -64,7 +66,7 @@ static int recvline_fh(FILE *helper, struct strbuf *buffer) static int recvline(struct helper_data *helper, struct strbuf *buffer) { - return recvline_fh(helper->out, buffer); + return recvline_fh(helper->out, buffer, helper->name); } static void xchgline(struct helper_data *helper, struct strbuf *buffer) @@ -191,6 +193,8 @@ static struct child_process *get_helper(struct transport *transport) refspecs[refspec_nr++] = xstrdup(capname + strlen("refspec ")); } else if (!strcmp(capname, "connect")) { data->connect = 1; + } else if (!strcmp(capname, "signed-tags")) { + data->signed_tags = 1; } else if (!prefixcmp(capname, "export-marks ")) { struct strbuf arg = STRBUF_INIT; strbuf_addstr(&arg, "--export-marks="); @@ -211,10 +215,11 @@ static struct child_process *get_helper(struct transport *transport) int i; data->refspec_nr = refspec_nr; data->refspecs = parse_fetch_refspec(refspec_nr, refspecs); - for (i = 0; i < refspec_nr; i++) { + for (i = 0; i < refspec_nr; i++) free((char *)refspecs[i]); - } free(refspecs); + } else if (data->import || data->bidi_import || data->export) { + warning("This remote helper should implement refspec capability."); } strbuf_release(&buf); if (debug) @@ -410,9 +415,11 @@ static int get_exporter(struct transport *transport, /* we need to duplicate helper->in because we want to use it after * fastexport is done with it. */ fastexport->out = dup(helper->in); - fastexport->argv = xcalloc(5 + revlist_args->nr, sizeof(*fastexport->argv)); + fastexport->argv = xcalloc(6 + revlist_args->nr, sizeof(*fastexport->argv)); fastexport->argv[argc++] = "fast-export"; fastexport->argv[argc++] = "--use-done-feature"; + fastexport->argv[argc++] = data->signed_tags ? + "--signed-tags=verbatim" : "--signed-tags=warn-strip"; if (data->export_marks) fastexport->argv[argc++] = data->export_marks; if (data->import_marks) @@ -469,7 +476,7 @@ static int fetch_with_import(struct transport *transport, * were fetching. * * (If no "refspec" capability was specified, for historical - * reasons we default to *:*.) + * reasons we default to the equivalent of *:*.) * * Store the result in to_fetch[i].old_sha1. Callers such * as "git fetch" can use the value to write feedback to the @@ -536,7 +543,7 @@ static int process_connect_service(struct transport *transport, goto exit; sendline(data, &cmdbuf); - recvline_fh(input, &cmdbuf); + recvline_fh(input, &cmdbuf, name); if (!strcmp(cmdbuf.buf, "")) { data->no_disconnect_req = 1; if (debug) @@ -618,7 +625,7 @@ static int fetch(struct transport *transport, return -1; } -static void push_update_ref_status(struct strbuf *buf, +static int push_update_ref_status(struct strbuf *buf, struct ref **ref, struct ref *remote_refs) { @@ -684,7 +691,7 @@ static void push_update_ref_status(struct strbuf *buf, *ref = find_ref_by_name(remote_refs, refname); if (!*ref) { warning("helper reported unexpected status of %s", refname); - return; + return 1; } if ((*ref)->status != REF_STATUS_NONE) { @@ -693,11 +700,12 @@ static void push_update_ref_status(struct strbuf *buf, * status reported by the remote helper if the latter is 'no match'. */ if (status == REF_STATUS_NONE) - return; + return 1; } (*ref)->status = status; (*ref)->remote_status = msg; + return !(status == REF_STATUS_OK); } static void push_update_refs_status(struct helper_data *data, @@ -706,11 +714,24 @@ static void push_update_refs_status(struct helper_data *data, struct strbuf buf = STRBUF_INIT; struct ref *ref = remote_refs; for (;;) { + char *private; + recvline(data, &buf); if (!buf.len) break; - push_update_ref_status(&buf, &ref, remote_refs); + if (push_update_ref_status(&buf, &ref, remote_refs)) + continue; + + if (!data->refspecs) + continue; + + /* propagate back the update to the remote namespace */ + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); + if (!private) + continue; + update_ref("update by helper", private, ref->new_sha1, NULL, 0, 0); + free(private); } strbuf_release(&buf); } @@ -785,6 +806,9 @@ static int push_refs_with_export(struct transport *transport, struct string_list revlist_args = STRING_LIST_INIT_NODUP; struct strbuf buf = STRBUF_INIT; + if (!data->refspecs) + die("remote-helper doesn't support push; refspec needed"); + helper = get_helper(transport); write_constant(helper->in, "export\n"); @@ -795,22 +819,19 @@ static int push_refs_with_export(struct transport *transport, char *private; unsigned char sha1[20]; - if (!data->refspecs) - continue; + if (ref->deletion) + die("remote-helpers do not support ref deletion"); + private = apply_refspecs(data->refspecs, data->refspec_nr, ref->name); if (private && !get_sha1(private, sha1)) { strbuf_addf(&buf, "^%s", private); string_list_append(&revlist_args, strbuf_detach(&buf, NULL)); + hashcpy(ref->old_sha1, sha1); } free(private); - if (ref->deletion) { - die("remote-helpers do not support ref deletion"); - } - if (ref->peer_ref) string_list_append(&revlist_args, ref->peer_ref->name); - } if (get_exporter(transport, &exporter, &revlist_args)) diff --git a/transport.c b/transport.c index e6f9346c76..ba5d8afb1b 100644 --- a/transport.c +++ b/transport.c @@ -508,7 +508,7 @@ static struct ref *get_refs_via_connect(struct transport *transport, int for_pus struct ref *refs; connect_setup(transport, for_push, 0); - get_remote_heads(data->fd[0], &refs, + get_remote_heads(data->fd[0], NULL, 0, &refs, for_push ? REF_NORMAL : 0, &data->extra_have); data->got_remote_heads = 1; @@ -519,11 +519,9 @@ static int fetch_refs_via_pack(struct transport *transport, int nr_heads, struct ref **to_fetch) { struct git_transport_data *data = transport->data; - struct string_list sought = STRING_LIST_INIT_DUP; const struct ref *refs; char *dest = xstrdup(transport->url); struct fetch_pack_args args; - int i; struct ref *refs_tmp = NULL; memset(&args, 0, sizeof(args)); @@ -537,18 +535,16 @@ static int fetch_refs_via_pack(struct transport *transport, args.no_progress = !transport->progress; args.depth = data->options.depth; - for (i = 0; i < nr_heads; i++) - string_list_append(&sought, to_fetch[i]->name); - if (!data->got_remote_heads) { connect_setup(transport, 0, 0); - get_remote_heads(data->fd[0], &refs_tmp, 0, NULL); + get_remote_heads(data->fd[0], NULL, 0, &refs_tmp, 0, NULL); data->got_remote_heads = 1; } refs = fetch_pack(&args, data->fd, data->conn, refs_tmp ? refs_tmp : transport->remote_refs, - dest, &sought, &transport->pack_lockfile); + dest, to_fetch, nr_heads, + &transport->pack_lockfile); close(data->fd[0]); close(data->fd[1]); if (finish_connect(data->conn)) @@ -558,7 +554,6 @@ static int fetch_refs_via_pack(struct transport *transport, free_refs(refs_tmp); - string_list_clear(&sought, 0); free(dest); return (refs ? 0 : -1); } @@ -800,7 +795,7 @@ static int git_transport_push(struct transport *transport, struct ref *remote_re struct ref *tmp_refs; connect_setup(transport, 1, 0); - get_remote_heads(data->fd[0], &tmp_refs, REF_NORMAL, NULL); + get_remote_heads(data->fd[0], NULL, 0, &tmp_refs, REF_NORMAL, NULL); data->got_remote_heads = 1; } @@ -1133,6 +1128,8 @@ int transport_push(struct transport *transport, match_flags |= MATCH_REFS_MIRROR; if (flags & TRANSPORT_PUSH_PRUNE) match_flags |= MATCH_REFS_PRUNE; + if (flags & TRANSPORT_PUSH_FOLLOW_TAGS) + match_flags |= MATCH_REFS_FOLLOW_TAGS; if (match_push_refs(local_refs, &remote_refs, refspec_nr, refspec, match_flags)) { diff --git a/transport.h b/transport.h index e7beb815dd..fcb1d25d96 100644 --- a/transport.h +++ b/transport.h @@ -105,6 +105,7 @@ struct transport { #define TRANSPORT_PUSH_PRUNE 128 #define TRANSPORT_RECURSE_SUBMODULES_ON_DEMAND 256 #define TRANSPORT_PUSH_NO_HOOK 512 +#define TRANSPORT_PUSH_FOLLOW_TAGS 1024 #define TRANSPORT_SUMMARY_WIDTH (2 * DEFAULT_ABBREV + 3) #define TRANSPORT_SUMMARY(x) (int)(TRANSPORT_SUMMARY_WIDTH + strlen(x) - gettext_width(x)), (x) diff --git a/unpack-trees.c b/unpack-trees.c index 09e53df3b2..ede4299b83 100644 --- a/unpack-trees.c +++ b/unpack-trees.c @@ -1026,10 +1026,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options o->el = ⪙ } - if (o->dir) { - o->path_exclude_check = xmalloc(sizeof(struct path_exclude_check)); - path_exclude_check_init(o->path_exclude_check, o->dir); - } memset(&o->result, 0, sizeof(o->result)); o->result.initialized = 1; o->result.timestamp.sec = o->src_index->timestamp.sec; @@ -1155,10 +1151,6 @@ int unpack_trees(unsigned len, struct tree_desc *t, struct unpack_trees_options done: clear_exclude_list(&el); - if (o->path_exclude_check) { - path_exclude_check_clear(o->path_exclude_check); - free(o->path_exclude_check); - } return ret; return_failed: @@ -1375,7 +1367,7 @@ static int check_ok_to_remove(const char *name, int len, int dtype, return 0; if (o->dir && - is_path_excluded(o->path_exclude_check, name, -1, &dtype)) + is_excluded(o->dir, name, &dtype)) /* * ce->name is explicitly excluded, so it is Ok to * overwrite it. diff --git a/unpack-trees.h b/unpack-trees.h index ec74a9f19a..5e432f576e 100644 --- a/unpack-trees.h +++ b/unpack-trees.h @@ -52,7 +52,6 @@ struct unpack_trees_options { const char *prefix; int cache_bottom; struct dir_struct *dir; - struct path_exclude_check *path_exclude_check; struct pathspec *pathspec; merge_fn_t fn; const char *msgs[NB_UNPACK_TREES_ERROR_TYPES]; diff --git a/upload-pack.c b/upload-pack.c index 948cfffe13..127e59a603 100644 --- a/upload-pack.c +++ b/upload-pack.c @@ -26,6 +26,7 @@ static const char upload_pack_usage[] = "git upload-pack [--strict] [--timeout=< #define SHALLOW (1u << 16) #define NOT_SHALLOW (1u << 17) #define CLIENT_SHALLOW (1u << 18) +#define HIDDEN_REF (1u << 19) static unsigned long oldest_have; @@ -33,6 +34,7 @@ static int multi_ack; static int no_done; static int use_thin_pack, use_ofs_delta, use_include_tag; static int no_progress, daemon_mode; +static int allow_tip_sha1_in_want; static int shallow_nr; static struct object_array have_obj; static struct object_array want_obj; @@ -42,7 +44,6 @@ static unsigned int timeout; * otherwise maximum packet size (up to 65520 bytes). */ static int use_sideband; -static int debug_fd; static int advertise_refs; static int stateless_rpc; @@ -51,13 +52,6 @@ static void reset_timeout(void) alarm(timeout); } -static int strip(char *line, int len) -{ - if (len && line[len-1] == '\n') - line[--len] = 0; - return len; -} - static ssize_t send_client_data(int fd, const char *data, ssize_t sz) { if (use_sideband) @@ -70,7 +64,8 @@ static ssize_t send_client_data(int fd, const char *data, ssize_t sz) xwrite(fd, data, sz); return sz; } - return safe_write(fd, data, sz); + write_or_die(fd, data, sz); + return sz; } static FILE *pack_pipe = NULL; @@ -413,7 +408,6 @@ static int ok_to_give_up(void) static int get_common_commits(void) { - static char line[1000]; unsigned char sha1[20]; char last_hex[41]; int got_common = 0; @@ -423,10 +417,10 @@ static int get_common_commits(void) save_commit_buffer = 0; for (;;) { - int len = packet_read_line(0, line, sizeof(line)); + char *line = packet_read_line(0, NULL); reset_timeout(); - if (!len) { + if (!line) { if (multi_ack == 2 && got_common && !got_other && ok_to_give_up()) { sent_ready = 1; @@ -445,7 +439,6 @@ static int get_common_commits(void) got_other = 0; continue; } - strip(line, len); if (!prefixcmp(line, "have ")) { switch (got_sha1(line+5, sha1)) { case -1: /* they have what we do not */ @@ -485,6 +478,12 @@ static int get_common_commits(void) } } +static int is_our_ref(struct object *o) +{ + return o->flags & + ((allow_tip_sha1_in_want ? HIDDEN_REF : 0) | OUR_REF); +} + static void check_non_tip(void) { static const char *argv[] = { @@ -521,7 +520,7 @@ static void check_non_tip(void) o = get_indexed_object(--i); if (!o) continue; - if (!(o->flags & OUR_REF)) + if (!is_our_ref(o)) continue; memcpy(namebuf + 1, sha1_to_hex(o->sha1), 40); if (write_in_full(cmd.in, namebuf, 42) < 0) @@ -530,7 +529,7 @@ static void check_non_tip(void) namebuf[40] = '\n'; for (i = 0; i < want_obj.nr; i++) { o = want_obj.objects[i].item; - if (o->flags & OUR_REF) + if (is_our_ref(o)) continue; memcpy(namebuf, sha1_to_hex(o->sha1), 40); if (write_in_full(cmd.in, namebuf, 41) < 0) @@ -564,7 +563,7 @@ error: /* Pick one of them (we know there at least is one) */ for (i = 0; i < want_obj.nr; i++) { o = want_obj.objects[i].item; - if (!(o->flags & OUR_REF)) + if (!is_our_ref(o)) die("git upload-pack: not our ref %s", sha1_to_hex(o->sha1)); } @@ -573,36 +572,33 @@ error: static void receive_needs(void) { struct object_array shallows = OBJECT_ARRAY_INIT; - static char line[1000]; - int len, depth = 0; + int depth = 0; int has_non_tip = 0; shallow_nr = 0; - if (debug_fd) - write_str_in_full(debug_fd, "#S\n"); for (;;) { struct object *o; const char *features; unsigned char sha1_buf[20]; - len = packet_read_line(0, line, sizeof(line)); + char *line = packet_read_line(0, NULL); reset_timeout(); - if (!len) + if (!line) break; - if (debug_fd) - write_in_full(debug_fd, line, len); if (!prefixcmp(line, "shallow ")) { unsigned char sha1[20]; struct object *object; - if (get_sha1(line + 8, sha1)) + if (get_sha1_hex(line + 8, sha1)) die("invalid shallow line: %s", line); object = parse_object(sha1); if (!object) - die("did not find object for %s", line); + continue; if (object->type != OBJ_COMMIT) die("invalid shallow object %s", sha1_to_hex(sha1)); - object->flags |= CLIENT_SHALLOW; - add_object_array(object, NULL, &shallows); + if (!(object->flags & CLIENT_SHALLOW)) { + object->flags |= CLIENT_SHALLOW; + add_object_array(object, NULL, &shallows); + } continue; } if (!prefixcmp(line, "deepen ")) { @@ -644,13 +640,11 @@ static void receive_needs(void) sha1_to_hex(sha1_buf)); if (!(o->flags & WANTED)) { o->flags |= WANTED; - if (!(o->flags & OUR_REF)) + if (!is_our_ref(o)) has_non_tip = 1; add_object_array(o, NULL, &want_obj); } } - if (debug_fd) - write_str_in_full(debug_fd, "#E\n"); /* * We have sent all our refs already, and the other end @@ -730,8 +724,10 @@ static int mark_our_ref(const char *refname, const unsigned char *sha1, int flag { struct object *o = lookup_unknown_object(sha1); - if (ref_is_hidden(refname)) + if (ref_is_hidden(refname)) { + o->flags |= HIDDEN_REF; return 1; + } if (!o) die("git upload-pack: cannot find object %s:", sha1_to_hex(sha1)); o->flags |= OUR_REF; @@ -750,9 +746,10 @@ static int send_ref(const char *refname, const unsigned char *sha1, int flag, vo return 0; if (capabilities) - packet_write(1, "%s %s%c%s%s agent=%s\n", + packet_write(1, "%s %s%c%s%s%s agent=%s\n", sha1_to_hex(sha1), refname_nons, 0, capabilities, + allow_tip_sha1_in_want ? " allow-tip-sha1-in-want" : "", stateless_rpc ? " no-done" : "", git_user_agent_sanitized()); else @@ -786,6 +783,8 @@ static void upload_pack(void) static int upload_pack_config(const char *var, const char *value, void *unused) { + if (!strcmp("uploadpack.allowtipsha1inwant", var)) + allow_tip_sha1_in_want = git_config_bool(var, value); return parse_hide_refs_config(var, value, "uploadpack"); } @@ -841,8 +840,6 @@ int main(int argc, char **argv) if (is_repository_shallow()) die("attempt to fetch/clone from a shallow repository"); git_config(upload_pack_config, NULL); - if (getenv("GIT_DEBUG_SEND_PACK")) - debug_fd = atoi(getenv("GIT_DEBUG_SEND_PACK")); upload_pack(); return 0; } @@ -9,6 +9,20 @@ struct interval { int last; }; +size_t display_mode_esc_sequence_len(const char *s) +{ + const char *p = s; + if (*p++ != '\033') + return 0; + if (*p++ != '[') + return 0; + while (isdigit(*p) || *p == ';') + p++; + if (*p++ != 'm') + return 0; + return p - s; +} + /* auxiliary function for binary search in interval table */ static int bisearch(ucs_char_t ucs, const struct interval *table, int max) { @@ -252,18 +266,26 @@ int utf8_width(const char **start, size_t *remainder_p) * string, assuming that the string is utf8. Returns strlen() instead * if the string does not look like a valid utf8 string. */ -int utf8_strwidth(const char *string) +int utf8_strnwidth(const char *string, int len, int skip_ansi) { int width = 0; const char *orig = string; - while (1) { - if (!string) - return strlen(orig); - if (!*string) - return width; + if (len == -1) + len = strlen(string); + while (string && string < orig + len) { + int skip; + while (skip_ansi && + (skip = display_mode_esc_sequence_len(string)) != 0) + string += skip; width += utf8_width(&string, NULL); } + return string ? width : len; +} + +int utf8_strwidth(const char *string) +{ + return utf8_strnwidth(string, -1, 0); } int is_utf8(const char *text) @@ -303,20 +325,6 @@ static void strbuf_add_indented_text(struct strbuf *buf, const char *text, } } -static size_t display_mode_esc_sequence_len(const char *s) -{ - const char *p = s; - if (*p++ != '\033') - return 0; - if (*p++ != '[') - return 0; - while (isdigit(*p) || *p == ';') - p++; - if (*p++ != 'm') - return 0; - return p - s; -} - /* * Wrap the text, if necessary. The variable indent is the indent for the * first line, indent2 is the indent for all other lines. @@ -413,6 +421,52 @@ void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, free(tmp); } +void strbuf_utf8_replace(struct strbuf *sb_src, int pos, int width, + const char *subst) +{ + struct strbuf sb_dst = STRBUF_INIT; + char *src = sb_src->buf; + char *end = src + sb_src->len; + char *dst; + int w = 0, subst_len = 0; + + if (subst) + subst_len = strlen(subst); + strbuf_grow(&sb_dst, sb_src->len + subst_len); + dst = sb_dst.buf; + + while (src < end) { + char *old; + size_t n; + + while ((n = display_mode_esc_sequence_len(src))) { + memcpy(dst, src, n); + src += n; + dst += n; + } + + old = src; + n = utf8_width((const char**)&src, NULL); + if (!src) /* broken utf-8, do nothing */ + return; + if (n && w >= pos && w < pos + width) { + if (subst) { + memcpy(dst, subst, subst_len); + dst += subst_len; + subst = NULL; + } + w += n; + continue; + } + memcpy(dst, old, src - old); + dst += src - old; + w += n; + } + strbuf_setlen(&sb_dst, dst - sb_dst.buf); + strbuf_swap(sb_src, &sb_dst); + strbuf_release(&sb_dst); +} + int is_encoding_utf8(const char *name) { if (!name) @@ -460,7 +514,7 @@ int utf8_fprintf(FILE *stream, const char *format, ...) #else typedef char * iconv_ibp; #endif -char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv) +char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv, int *outsz_p) { size_t outsz, outalloc; char *out, *outpos; @@ -494,13 +548,17 @@ char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv) } else { *outpos = '\0'; + if (outsz_p) + *outsz_p = outpos - out; break; } } return out; } -char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding) +char *reencode_string_len(const char *in, int insz, + const char *out_encoding, const char *in_encoding, + int *outsz) { iconv_t conv; char *out; @@ -526,7 +584,7 @@ char *reencode_string(const char *in, const char *out_encoding, const char *in_e return NULL; } - out = reencode_string_iconv(in, strlen(in), conv); + out = reencode_string_iconv(in, insz, conv, outsz); iconv_close(conv); return out; } @@ -3,7 +3,9 @@ typedef unsigned int ucs_char_t; /* assuming 32bit int */ +size_t display_mode_esc_sequence_len(const char *s); int utf8_width(const char **start, size_t *remainder_p); +int utf8_strnwidth(const char *string, int len, int skip_ansi); int utf8_strwidth(const char *string); int is_utf8(const char *text); int is_encoding_utf8(const char *name); @@ -14,14 +16,29 @@ void strbuf_add_wrapped_text(struct strbuf *buf, const char *text, int indent, int indent2, int width); void strbuf_add_wrapped_bytes(struct strbuf *buf, const char *data, int len, int indent, int indent2, int width); +void strbuf_utf8_replace(struct strbuf *sb, int pos, int width, + const char *subst); #ifndef NO_ICONV -char *reencode_string_iconv(const char *in, size_t insz, iconv_t conv); -char *reencode_string(const char *in, const char *out_encoding, const char *in_encoding); +char *reencode_string_iconv(const char *in, size_t insz, + iconv_t conv, int *outsz); +char *reencode_string_len(const char *in, int insz, + const char *out_encoding, + const char *in_encoding, + int *outsz); #else -#define reencode_string(a,b,c) NULL +#define reencode_string_len(a,b,c,d,e) NULL #endif +static inline char *reencode_string(const char *in, + const char *out_encoding, + const char *in_encoding) +{ + return reencode_string_len(in, strlen(in), + out_encoding, in_encoding, + NULL); +} + int mbs_chrlen(const char **text, size_t *remainder_p, const char *encoding); #endif diff --git a/write_or_die.c b/write_or_die.c index 960f448cff..b50f99a936 100644 --- a/write_or_die.c +++ b/write_or_die.c @@ -1,5 +1,15 @@ #include "cache.h" +static void check_pipe(int err) +{ + if (err == EPIPE) { + signal(SIGPIPE, SIG_DFL); + raise(SIGPIPE); + /* Should never happen, but just in case... */ + exit(141); + } +} + /* * Some cases use stdio, but want to flush after the write * to get error handling (and to get better interactive @@ -34,8 +44,7 @@ void maybe_flush_or_die(FILE *f, const char *desc) return; } if (fflush(f)) { - if (errno == EPIPE) - exit(0); + check_pipe(errno); die_errno("write failure on '%s'", desc); } } @@ -50,8 +59,7 @@ void fsync_or_die(int fd, const char *msg) void write_or_die(int fd, const void *buf, size_t count) { if (write_in_full(fd, buf, count) < 0) { - if (errno == EPIPE) - exit(0); + check_pipe(errno); die_errno("write error"); } } @@ -59,8 +67,7 @@ void write_or_die(int fd, const void *buf, size_t count) int write_or_whine_pipe(int fd, const void *buf, size_t count, const char *msg) { if (write_in_full(fd, buf, count) < 0) { - if (errno == EPIPE) - exit(0); + check_pipe(errno); fprintf(stderr, "%s: write error (%s)\n", msg, strerror(errno)); return 0; diff --git a/wt-status.c b/wt-status.c index 81e4fa519f..bf84a86ee3 100644 --- a/wt-status.c +++ b/wt-status.c @@ -511,9 +511,12 @@ static void wt_status_collect_untracked(struct wt_status *s) if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES) dir.flags |= DIR_SHOW_OTHER_DIRECTORIES | DIR_HIDE_EMPTY_DIRECTORIES; + if (s->show_ignored_files) + dir.flags |= DIR_SHOW_IGNORED_TOO; setup_standard_excludes(&dir); fill_directory(&dir, s->pathspec); + for (i = 0; i < dir.nr; i++) { struct dir_entry *ent = dir.entries[i]; if (cache_name_is_other(ent->name, ent->len) && @@ -522,22 +525,17 @@ static void wt_status_collect_untracked(struct wt_status *s) free(ent); } - if (s->show_ignored_files) { - dir.nr = 0; - dir.flags = DIR_SHOW_IGNORED; - if (s->show_untracked_files != SHOW_ALL_UNTRACKED_FILES) - dir.flags |= DIR_SHOW_OTHER_DIRECTORIES; - fill_directory(&dir, s->pathspec); - for (i = 0; i < dir.nr; i++) { - struct dir_entry *ent = dir.entries[i]; - if (cache_name_is_other(ent->name, ent->len) && - match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) - string_list_insert(&s->ignored, ent->name); - free(ent); - } + for (i = 0; i < dir.ignored_nr; i++) { + struct dir_entry *ent = dir.ignored[i]; + if (cache_name_is_other(ent->name, ent->len) && + match_pathspec(s->pathspec, ent->name, ent->len, 0, NULL)) + string_list_insert(&s->ignored, ent->name); + free(ent); } free(dir.entries); + free(dir.ignored); + clear_directory(&dir); if (advice_status_u_option) { struct timeval t_end; @@ -965,13 +963,32 @@ static void show_cherry_pick_in_progress(struct wt_status *s, wt_status_print_trailer(s); } +static void show_revert_in_progress(struct wt_status *s, + struct wt_status_state *state, + const char *color) +{ + status_printf_ln(s, color, _("You are currently reverting commit %s."), + find_unique_abbrev(state->revert_head_sha1, DEFAULT_ABBREV)); + if (advice_status_hints) { + if (has_unmerged(s)) + status_printf_ln(s, color, + _(" (fix conflicts and run \"git revert --continue\")")); + else + status_printf_ln(s, color, + _(" (all conflicts fixed: run \"git revert --continue\")")); + status_printf_ln(s, color, + _(" (use \"git revert --abort\" to cancel the revert operation)")); + } + wt_status_print_trailer(s); +} + static void show_bisect_in_progress(struct wt_status *s, struct wt_status_state *state, const char *color) { if (state->branch) status_printf_ln(s, color, - _("You are currently bisecting branch '%s'."), + _("You are currently bisecting, started from branch '%s'."), state->branch); else status_printf_ln(s, color, @@ -985,96 +1002,172 @@ static void show_bisect_in_progress(struct wt_status *s, /* * Extract branch information from rebase/bisect */ -static void read_and_strip_branch(struct strbuf *sb, - const char **branch, - const char *path) +static char *read_and_strip_branch(const char *path) { + struct strbuf sb = STRBUF_INIT; unsigned char sha1[20]; - strbuf_reset(sb); - if (strbuf_read_file(sb, git_path("%s", path), 0) <= 0) - return; + if (strbuf_read_file(&sb, git_path("%s", path), 0) <= 0) + goto got_nothing; - while (sb->len && sb->buf[sb->len - 1] == '\n') - strbuf_setlen(sb, sb->len - 1); - if (!sb->len) - return; - if (!prefixcmp(sb->buf, "refs/heads/")) - *branch = sb->buf + strlen("refs/heads/"); - else if (!prefixcmp(sb->buf, "refs/")) - *branch = sb->buf; - else if (!get_sha1_hex(sb->buf, sha1)) { + while (&sb.len && sb.buf[sb.len - 1] == '\n') + strbuf_setlen(&sb, sb.len - 1); + if (!sb.len) + goto got_nothing; + if (!prefixcmp(sb.buf, "refs/heads/")) + strbuf_remove(&sb,0, strlen("refs/heads/")); + else if (!prefixcmp(sb.buf, "refs/")) + ; + else if (!get_sha1_hex(sb.buf, sha1)) { const char *abbrev; abbrev = find_unique_abbrev(sha1, DEFAULT_ABBREV); - strbuf_reset(sb); - strbuf_addstr(sb, abbrev); - *branch = sb->buf; - } else if (!strcmp(sb->buf, "detached HEAD")) /* rebase */ - ; + strbuf_reset(&sb); + strbuf_addstr(&sb, abbrev); + } else if (!strcmp(sb.buf, "detached HEAD")) /* rebase */ + goto got_nothing; else /* bisect */ - *branch = sb->buf; + ; + return strbuf_detach(&sb, NULL); + +got_nothing: + strbuf_release(&sb); + return NULL; } -static void wt_status_print_state(struct wt_status *s) +struct grab_1st_switch_cbdata { + int found; + struct strbuf buf; + unsigned char nsha1[20]; +}; + +static int grab_1st_switch(unsigned char *osha1, unsigned char *nsha1, + const char *email, unsigned long timestamp, int tz, + const char *message, void *cb_data) { - const char *state_color = color(WT_STATUS_HEADER, s); - struct strbuf branch = STRBUF_INIT; - struct strbuf onto = STRBUF_INIT; - struct wt_status_state state; - struct stat st; + struct grab_1st_switch_cbdata *cb = cb_data; + const char *target = NULL, *end; - memset(&state, 0, sizeof(state)); + if (prefixcmp(message, "checkout: moving from ")) + return 0; + message += strlen("checkout: moving from "); + target = strstr(message, " to "); + if (!target) + return 0; + target += strlen(" to "); + strbuf_reset(&cb->buf); + hashcpy(cb->nsha1, nsha1); + for (end = target; *end && *end != '\n'; end++) + ; + strbuf_add(&cb->buf, target, end - target); + cb->found = 1; + return 1; +} + +static void wt_status_get_detached_from(struct wt_status_state *state) +{ + struct grab_1st_switch_cbdata cb; + struct commit *commit; + unsigned char sha1[20]; + char *ref = NULL; + + strbuf_init(&cb.buf, 0); + if (for_each_reflog_ent_reverse("HEAD", grab_1st_switch, &cb) <= 0) { + strbuf_release(&cb.buf); + return; + } + + if (dwim_ref(cb.buf.buf, cb.buf.len, sha1, &ref) == 1 && + /* sha1 is a commit? match without further lookup */ + (!hashcmp(cb.nsha1, sha1) || + /* perhaps sha1 is a tag, try to dereference to a commit */ + ((commit = lookup_commit_reference_gently(sha1, 1)) != NULL && + !hashcmp(cb.nsha1, commit->object.sha1)))) { + int ofs; + if (!prefixcmp(ref, "refs/tags/")) + ofs = strlen("refs/tags/"); + else if (!prefixcmp(ref, "refs/remotes/")) + ofs = strlen("refs/remotes/"); + else + ofs = 0; + state->detached_from = xstrdup(ref + ofs); + } else + state->detached_from = + xstrdup(find_unique_abbrev(cb.nsha1, DEFAULT_ABBREV)); + hashcpy(state->detached_sha1, cb.nsha1); + + free(ref); + strbuf_release(&cb.buf); +} + +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; + state->merge_in_progress = 1; } else if (!stat(git_path("rebase-apply"), &st)) { if (!stat(git_path("rebase-apply/applying"), &st)) { - state.am_in_progress = 1; + state->am_in_progress = 1; if (!stat(git_path("rebase-apply/patch"), &st) && !st.st_size) - state.am_empty_patch = 1; + state->am_empty_patch = 1; } else { - state.rebase_in_progress = 1; - read_and_strip_branch(&branch, &state.branch, - "rebase-apply/head-name"); - read_and_strip_branch(&onto, &state.onto, - "rebase-apply/onto"); + state->rebase_in_progress = 1; + state->branch = read_and_strip_branch("rebase-apply/head-name"); + state->onto = read_and_strip_branch("rebase-apply/onto"); } } else if (!stat(git_path("rebase-merge"), &st)) { if (!stat(git_path("rebase-merge/interactive"), &st)) - state.rebase_interactive_in_progress = 1; + state->rebase_interactive_in_progress = 1; else - state.rebase_in_progress = 1; - read_and_strip_branch(&branch, &state.branch, - "rebase-merge/head-name"); - read_and_strip_branch(&onto, &state.onto, - "rebase-merge/onto"); + state->rebase_in_progress = 1; + state->branch = read_and_strip_branch("rebase-merge/head-name"); + state->onto = read_and_strip_branch("rebase-merge/onto"); } else if (!stat(git_path("CHERRY_PICK_HEAD"), &st)) { - state.cherry_pick_in_progress = 1; + state->cherry_pick_in_progress = 1; } if (!stat(git_path("BISECT_LOG"), &st)) { - state.bisect_in_progress = 1; - read_and_strip_branch(&branch, &state.branch, - "BISECT_START"); + state->bisect_in_progress = 1; + state->branch = read_and_strip_branch("BISECT_START"); } + if (!stat(git_path("REVERT_HEAD"), &st) && + !get_sha1("REVERT_HEAD", sha1)) { + state->revert_in_progress = 1; + hashcpy(state->revert_head_sha1, sha1); + } + + if (get_detached_from) + wt_status_get_detached_from(state); +} - if (state.merge_in_progress) - show_merge_in_progress(s, &state, state_color); - else if (state.am_in_progress) - show_am_in_progress(s, &state, state_color); - else if (state.rebase_in_progress || state.rebase_interactive_in_progress) - show_rebase_in_progress(s, &state, state_color); - else if (state.cherry_pick_in_progress) - show_cherry_pick_in_progress(s, &state, state_color); - if (state.bisect_in_progress) - show_bisect_in_progress(s, &state, state_color); - strbuf_release(&branch); - strbuf_release(&onto); +static void wt_status_print_state(struct wt_status *s, + struct wt_status_state *state) +{ + const char *state_color = color(WT_STATUS_HEADER, s); + if (state->merge_in_progress) + show_merge_in_progress(s, state, state_color); + else if (state->am_in_progress) + show_am_in_progress(s, state, state_color); + else if (state->rebase_in_progress || state->rebase_interactive_in_progress) + show_rebase_in_progress(s, state, state_color); + else if (state->cherry_pick_in_progress) + show_cherry_pick_in_progress(s, state, state_color); + else if (state->revert_in_progress) + show_revert_in_progress(s, state, state_color); + if (state->bisect_in_progress) + show_bisect_in_progress(s, state, state_color); } void wt_status_print(struct wt_status *s) { const char *branch_color = color(WT_STATUS_ONBRANCH, s); const char *branch_status_color = color(WT_STATUS_HEADER, s); + struct wt_status_state state; + + memset(&state, 0, sizeof(state)); + wt_status_get_state(&state, + s->branch && !strcmp(s->branch, "HEAD")); if (s->branch) { const char *on_what = _("On branch "); @@ -1082,9 +1175,19 @@ void wt_status_print(struct wt_status *s) if (!prefixcmp(branch_name, "refs/heads/")) branch_name += 11; else if (!strcmp(branch_name, "HEAD")) { - branch_name = ""; branch_status_color = color(WT_STATUS_NOBRANCH, s); - on_what = _("Not currently on any branch."); + if (state.detached_from) { + unsigned char sha1[20]; + branch_name = state.detached_from; + if (!get_sha1("HEAD", sha1) && + !hashcmp(sha1, state.detached_sha1)) + on_what = _("HEAD detached at "); + else + on_what = _("HEAD detached from "); + } else { + branch_name = ""; + on_what = _("Not currently on any branch."); + } } status_printf(s, color(WT_STATUS_HEADER, s), ""); status_printf_more(s, branch_status_color, "%s", on_what); @@ -1093,7 +1196,11 @@ void wt_status_print(struct wt_status *s) wt_status_print_tracking(s); } - wt_status_print_state(s); + wt_status_print_state(s, &state); + free(state.branch); + free(state.onto); + free(state.detached_from); + if (s->is_initial) { status_printf_ln(s, color(WT_STATUS_HEADER, s), ""); status_printf_ln(s, color(WT_STATUS_HEADER, s), _("Initial commit")); diff --git a/wt-status.h b/wt-status.h index 74208c06fd..4121bc208d 100644 --- a/wt-status.h +++ b/wt-status.h @@ -80,13 +80,18 @@ struct wt_status_state { int rebase_interactive_in_progress; int cherry_pick_in_progress; int bisect_in_progress; - const char *branch; - const char *onto; + int revert_in_progress; + char *branch; + char *onto; + char *detached_from; + unsigned char detached_sha1[20]; + unsigned char revert_head_sha1[20]; }; 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); void wt_shortstatus_print(struct wt_status *s); void wt_porcelain_print(struct wt_status *s); @@ -168,13 +168,8 @@ void git_deflate_init(git_zstream *strm, int level) strm->z.msg ? strm->z.msg : "no message"); } -void git_deflate_init_gzip(git_zstream *strm, int level) +static void do_git_deflate_init(git_zstream *strm, int level, int windowBits) { - /* - * Use default 15 bits, +16 is to generate gzip header/trailer - * instead of the zlib wrapper. - */ - const int windowBits = 15 + 16; int status; zlib_pre_call(strm); @@ -188,6 +183,24 @@ void git_deflate_init_gzip(git_zstream *strm, int level) strm->z.msg ? strm->z.msg : "no message"); } +void git_deflate_init_gzip(git_zstream *strm, int level) +{ + /* + * Use default 15 bits, +16 is to generate gzip header/trailer + * instead of the zlib wrapper. + */ + do_git_deflate_init(strm, level, 15 + 16); +} + +void git_deflate_init_raw(git_zstream *strm, int level) +{ + /* + * Use default 15 bits, negate the value to get raw compressed + * data without zlib header and trailer. + */ + do_git_deflate_init(strm, level, -15); +} + int git_deflate_abort(git_zstream *strm) { int status; |